Skip to content

Switch app ID to those of the main app #1586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ android {
}

defaultConfig {
applicationId "com.zulip.flutter"
applicationId "com.zulipmobile"
minSdkVersion 28
targetSdkVersion flutter.targetSdkVersion
// These are synced to local.properties from pubspec.yaml by the flutter tool.
Expand Down
6 changes: 3 additions & 3 deletions docs/howto/push-notifications-ios-simulator.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ receive a notification on the iOS Simulator for the zulip-flutter app.
Tapping on the notification should route to the respective conversation.

```shell-session
$ xcrun simctl push [device-id] com.zulip.flutter [payload json path]
$ xcrun simctl push [device-id] org.zulip.Zulip [payload json path]
```

<details>
<summary>Example output:</summary>

```shell-session
$ xcrun simctl push 90CC33B2-679B-4053-B380-7B986A29F28C com.zulip.flutter ./dm.json
Notification sent to 'com.zulip.flutter'
$ xcrun simctl push 90CC33B2-679B-4053-B380-7B986A29F28C org.zulip.Zulip ./dm.json
Notification sent to 'org.zulip.Zulip'
```

</details>
Expand Down
6 changes: 3 additions & 3 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zulip.flutter;
PRODUCT_BUNDLE_IDENTIFIER = org.zulip.Zulip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -522,7 +522,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zulip.flutter;
PRODUCT_BUNDLE_IDENTIFIER = org.zulip.Zulip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -546,7 +546,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zulip.flutter;
PRODUCT_BUNDLE_IDENTIFIER = org.zulip.Zulip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand Down
2 changes: 1 addition & 1 deletion ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.zulip.flutter</string>
<string>org.zulip.Zulip</string>
<key>CFBundleURLSchemes</key>
<array>
<string>zulip</string>
Expand Down
2 changes: 1 addition & 1 deletion lib/model/store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ class LiveGlobalStore extends GlobalStore {
// What directory should we use?
// path_provider's getApplicationSupportDirectory:
// on Android, -> Flutter's PathUtils.getFilesDir -> https://developer.android.com/reference/android/content/Context#getFilesDir()
// -> empirically /data/data/com.zulip.flutter/files/
// -> empirically /data/data/com.zulipmobile/files/
// on iOS, -> "Library/Application Support" via https://developer.apple.com/documentation/foundation/nssearchpathdirectory/nsapplicationsupportdirectory
// on Linux, -> "${XDG_DATA_HOME:-~/.local/share}/com.zulip.flutter/"
// All seem reasonable.
Expand Down
16 changes: 8 additions & 8 deletions lib/notifications/display.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,24 @@ class NotificationChannelManager {
/// For example, for a resource `@raw/chime3`, where `raw` would be the
/// resource type and `chime3` would be the resource name it generates the
/// following URL:
/// `android.resource://com.zulip.flutter/raw/chime3`
/// `android.resource://com.zulipmobile/raw/chime3`
///
/// Based on: https://stackoverflow.com/a/38340580
static Uri _resourceUrlFromName({
static Future<String> _resourceUrlFromName({
required String resourceTypeName,
required String resourceEntryName,
}) {
const packageName = 'com.zulip.flutter'; // TODO(#407)
}) async {
final packageInfo = await ZulipBinding.instance.packageInfo;

// URL scheme for Android resource url.
// See: https://developer.android.com/reference/android/content/ContentResolver#SCHEME_ANDROID_RESOURCE
const schemeAndroidResource = 'android.resource';

return Uri(
scheme: schemeAndroidResource,
host: packageName,
host: packageInfo!.packageName,
pathSegments: <String>[resourceTypeName, resourceEntryName],
);
).toString();
}

/// Prepare our notification sounds; return a URL for our default sound.
Expand All @@ -87,9 +87,9 @@ class NotificationChannelManager {
/// Returns a URL for our default notification sound: either in shared storage
/// if we successfully copied it there, or else as our internal resource file.
static Future<String> _ensureInitNotificationSounds() async {
String defaultSoundUrl = _resourceUrlFromName(
String defaultSoundUrl = await _resourceUrlFromName(
resourceTypeName: 'raw',
resourceEntryName: kDefaultNotificationSound.resourceName).toString();
resourceEntryName: kDefaultNotificationSound.resourceName);

final shouldUseResourceFile = switch (await ZulipBinding.instance.deviceInfo) {
// Before Android 10 Q, we don't attempt to put the sounds in shared media storage.
Expand Down
31 changes: 27 additions & 4 deletions test/notifications/display_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ void main() {
NotificationChannelManager.kDefaultNotificationSound.resourceName;
String fakeStoredUrl(String resourceName) =>
testBinding.androidNotificationHost.fakeStoredNotificationSoundUrl(resourceName);
String fakeResourceUrl(String resourceName) =>
'android.resource://com.zulip.flutter/raw/$resourceName';
String fakeResourceUrl({required String resourceName, String? packageName}) =>
'android.resource://${packageName ?? eg.packageInfo().packageName}/raw/$resourceName';

test('on Android 28 (and lower) resource file is used for notification sound', () async {
addTearDown(testBinding.reset);
Expand All @@ -227,7 +227,30 @@ void main() {
.isEmpty();
check(androidNotificationHost.takeCreatedChannels())
.single
.soundUrl.equals(fakeResourceUrl(defaultSoundResourceName));
.soundUrl.equals(fakeResourceUrl(resourceName: defaultSoundResourceName));
});

test('generates resource file URL from app package name', () async {
addTearDown(testBinding.reset);
final androidNotificationHost = testBinding.androidNotificationHost;

testBinding.packageInfoResult = eg.packageInfo(packageName: 'com.example.test');

// Force the default sound URL to be the resource file URL, by forcing
// the Android version to the one where we don't store sounds through the
// media store.
testBinding.deviceInfoResult =
const AndroidDeviceInfo(sdkInt: 28, release: '9');

await NotificationChannelManager.ensureChannel();
check(androidNotificationHost.takeCopySoundResourceToMediaStoreCalls())
.isEmpty();
check(androidNotificationHost.takeCreatedChannels())
.single
.soundUrl.equals(fakeResourceUrl(
resourceName: defaultSoundResourceName,
packageName: 'com.example.test',
));
});

test('notification sound resource files are being copied to the media store', () async {
Expand Down Expand Up @@ -315,7 +338,7 @@ void main() {
.isEmpty();
check(androidNotificationHost.takeCreatedChannels())
.single
.soundUrl.equals(fakeResourceUrl(defaultSoundResourceName));
.soundUrl.equals(fakeResourceUrl(resourceName: defaultSoundResourceName));
});
});

Expand Down