From c95171ab83e268799f52812a5742e0dbcd4254b7 Mon Sep 17 00:00:00 2001 From: DanielEliraz Date: Thu, 18 May 2023 14:17:53 +0300 Subject: [PATCH 1/5] Revert "Init (#920)" This reverts commit 63ec3ca757e657ab3f823702b4e1633a74e9c7f9. --- lib/android/app/src/main/AndroidManifest.xml | 6 ++++ .../RNNotificationsPackage.java | 26 +++++++++++------ .../core/NotificationIntentAdapter.java | 26 +++++++++++++---- .../core/ProxyService.java | 29 +++++++++++++++++++ .../core/notification/PushNotification.java | 28 ++++++++++++++++-- 5 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 lib/android/app/src/main/java/com/wix/reactnativenotifications/core/ProxyService.java diff --git a/lib/android/app/src/main/AndroidManifest.xml b/lib/android/app/src/main/AndroidManifest.xml index a974c28c6..24cd22696 100644 --- a/lib/android/app/src/main/AndroidManifest.xml +++ b/lib/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,12 @@ package="com.wix.reactnativenotifications"> + + + + diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java index be4c59ab4..a249c6ad3 100644 --- a/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java @@ -17,7 +17,6 @@ import com.wix.reactnativenotifications.core.NotificationIntentAdapter; import com.wix.reactnativenotifications.core.notification.IPushNotification; import com.wix.reactnativenotifications.core.notification.PushNotification; -import com.wix.reactnativenotifications.core.notification.PushNotificationProps; import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer; import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer; @@ -62,18 +61,14 @@ public void onActivityCreated(Activity activity, Bundle savedInstanceState) { final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext()); notificationsDrawer.onNewActivity(activity); - Intent intent = activity.getIntent(); - if (NotificationIntentAdapter.canHandleIntent(intent)) { - Bundle notificationData = intent.getExtras(); - final IPushNotification pushNotification = PushNotification.get(mApplication.getApplicationContext(), notificationData); - if (pushNotification != null) { - pushNotification.onOpened(); - } - } + callOnOpenedIfNeed(activity); } @Override public void onActivityStarted(Activity activity) { + if (InitialNotificationHolder.getInstance().get() == null) { + callOnOpenedIfNeed(activity); + } } @Override @@ -95,4 +90,17 @@ public void onActivitySaveInstanceState(Activity activity, Bundle outState) { @Override public void onActivityDestroyed(Activity activity) { } + + private void callOnOpenedIfNeed(Activity activity) { + Intent intent = activity.getIntent(); + if (NotificationIntentAdapter.canHandleIntent(intent)) { + Context appContext = mApplication.getApplicationContext(); + Bundle notificationData = NotificationIntentAdapter.canHandleTrampolineActivity(appContext) ? + intent.getExtras() : NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent); + final IPushNotification pushNotification = PushNotification.get(appContext, notificationData); + if (pushNotification != null) { + pushNotification.onOpened(); + } + } + } } diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java index 08f9772f0..70f609a81 100644 --- a/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java @@ -1,9 +1,10 @@ package com.wix.reactnativenotifications.core; +import android.annotation.SuppressLint; import android.app.PendingIntent; +import android.app.TaskStackBuilder; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.Bundle; import com.wix.reactnativenotifications.core.notification.PushNotificationProps; @@ -11,16 +12,29 @@ public class NotificationIntentAdapter { private static final String PUSH_NOTIFICATION_EXTRA_NAME = "pushNotification"; + @SuppressLint("UnspecifiedImmutableFlag") public static PendingIntent createPendingNotificationIntent(Context appContext, PushNotificationProps notification) { - Intent intent = new AppLaunchHelper().getLaunchIntent(appContext); - intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - return PendingIntent.getActivity(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + if (canHandleTrampolineActivity(appContext)) { + Intent intent = new Intent(appContext, ProxyService.class); + intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle()); + return PendingIntent.getService(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT); } else { - return PendingIntent.getActivity(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT); + Intent mainActivityIntent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName()); + mainActivityIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle()); + TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(appContext); + taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent); + return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); } } + public static boolean canHandleTrampolineActivity(Context appContext) { + return android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R || appContext.getApplicationInfo().targetSdkVersion < 31; + } + + public static Bundle extractPendingNotificationDataFromIntent(Intent intent) { + return intent.getBundleExtra(PUSH_NOTIFICATION_EXTRA_NAME); + } + public static boolean canHandleIntent(Intent intent) { if (intent != null) { Bundle notificationData = intent.getExtras(); diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/ProxyService.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/ProxyService.java new file mode 100644 index 000000000..be52912ae --- /dev/null +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/ProxyService.java @@ -0,0 +1,29 @@ +package com.wix.reactnativenotifications.core; + +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import com.wix.reactnativenotifications.BuildConfig; +import com.wix.reactnativenotifications.core.notification.IPushNotification; +import com.wix.reactnativenotifications.core.notification.PushNotification; + +public class ProxyService extends IntentService { + + private static final String TAG = ProxyService.class.getSimpleName(); + + public ProxyService() { + super("notificationsProxyService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (BuildConfig.DEBUG) Log.d(TAG, "New intent: "+intent); + final Bundle notificationData = NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent); + final IPushNotification pushNotification = PushNotification.get(this, notificationData); + if (pushNotification != null) { + pushNotification.onOpened(); + } + } +} diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java index 72cfd4d39..eade08d85 100644 --- a/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java @@ -97,16 +97,22 @@ protected int postNotification(Integer notificationId) { protected void digestNotification() { if (!mAppLifecycleFacade.isReactInitialized()) { setAsInitialNotification(); + launchOrResumeApp(); return; } final ReactContext reactContext = mAppLifecycleFacade.getRunningReactContext(); if (reactContext.getCurrentActivity() == null) { setAsInitialNotification(); - return; } - dispatchImmediately(); + if (mAppLifecycleFacade.isAppVisible()) { + dispatchImmediately(); + } else if (mAppLifecycleFacade.isAppDestroyed()) { + launchOrResumeApp(); + } else { + dispatchUponVisibility(); + } } protected PushNotificationProps createProps(Bundle bundle) { @@ -121,6 +127,17 @@ protected void dispatchImmediately() { notifyOpenedToJS(); } + protected void dispatchUponVisibility() { + mAppLifecycleFacade.addVisibilityListener(getIntermediateAppVisibilityListener()); + + // Make the app visible so that we'll dispatch the notification opening when visibility changes to 'true' (see + // above listener registration). + launchOrResumeApp(); + } + + protected AppVisibilityListener getIntermediateAppVisibilityListener() { + return mAppVisibilityListener; + } protected Notification buildNotification(PendingIntent intent) { return getNotificationBuilder(intent).build(); @@ -195,6 +212,13 @@ private void notifyOpenedToJS() { mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, response, mAppLifecycleFacade.getRunningReactContext()); } + protected void launchOrResumeApp() { + if (NotificationIntentAdapter.canHandleTrampolineActivity(mContext)) { + final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext); + mContext.startActivity(intent); + } + } + private int getAppResourceId(String resName, String resType) { return mContext.getResources().getIdentifier(resName, resType, mContext.getPackageName()); } From d13220c37dfb0efdba14b5ee384fcc3a4aedd70e Mon Sep 17 00:00:00 2001 From: danielel Date: Thu, 18 May 2023 12:13:57 +0300 Subject: [PATCH 2/5] fix-ios-test --- scripts/test-unit.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/scripts/test-unit.js b/scripts/test-unit.js index 83be3ee86..127a428fc 100644 --- a/scripts/test-unit.js +++ b/scripts/test-unit.js @@ -23,29 +23,35 @@ function runAndroidUnitTests() { } function runIosUnitTests() { - const conf = release ? `Release` : `Debug`; + exec.execSync('npm run build'); exec.execSync('npm run pod-install'); + testTarget('NotificationsExampleApp', 'iPhone 11', '13.7'); + // testTarget('NotificationsExampleAppIOS12', 'iPhone X', '12.4'); +} + +function testTarget(scheme, device, OS = 'latest') { + const conf = release ? `Release` : `Debug`; exec.execSync(`cd ./example/ios && RCT_NO_LAUNCH_PACKAGER=true xcodebuild build build-for-testing - -scheme "NotificationsExampleApp" + -scheme "${scheme}" -workspace NotificationsExampleApp.xcworkspace -sdk iphonesimulator -configuration ${conf} - -derivedDataPath ./example/ios/DerivedData/NotificationsExampleApp + -derivedDataPath ./DerivedData/NotificationsExampleApp -quiet - -UseModernBuildSystem=NO + -UseModernBuildSystem=YES ONLY_ACTIVE_ARCH=YES`); exec.execSync(`cd ./example/ios && RCT_NO_LAUNCH_PACKAGER=true xcodebuild test-without-building - -scheme "NotificationsExampleApp" + -scheme "${scheme}" -workspace NotificationsExampleApp.xcworkspace -sdk iphonesimulator -configuration ${conf} - -destination 'platform=iOS Simulator,name=iPhone 11' - -derivedDataPath ./example/ios/DerivedData/NotificationsExampleApp + -destination 'platform=iOS Simulator,name=${device},OS=${OS}' + -derivedDataPath ./DerivedData/NotificationsExampleApp ONLY_ACTIVE_ARCH=YES`); } From c5ef0e4a7c8961a7abf6adc035927041d643bea3 Mon Sep 17 00:00:00 2001 From: danielel Date: Thu, 18 May 2023 14:52:41 +0300 Subject: [PATCH 3/5] remove jenkins leftovers --- package.json | 2 +- scripts/test-unit.js | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index 9b6432bb9..a91cc9fe6 100644 --- a/package.json +++ b/package.json @@ -114,4 +114,4 @@ "html" ] } -} \ No newline at end of file +} diff --git a/scripts/test-unit.js b/scripts/test-unit.js index 127a428fc..4a89b306e 100644 --- a/scripts/test-unit.js +++ b/scripts/test-unit.js @@ -14,11 +14,6 @@ function run() { function runAndroidUnitTests() { const conf = release ? 'testReactNative60ReleaseUnitTest' : 'testReactNative60DebugUnitTest'; - if (android && process.env.JENKINS_CI) { - const sdkmanager = '/usr/local/share/android-sdk/tools/bin/sdkmanager'; - exec.execSync(`yes | ${sdkmanager} --licenses`); - // exec.execSync(`echo y | ${sdkmanager} --update && echo y | ${sdkmanager} --licenses`); - } exec.execSync(`cd lib/android && ./gradlew ${conf}`); } From e014408624b002f3c3c14913efd1bda2e981b421 Mon Sep 17 00:00:00 2001 From: danielel Date: Thu, 18 May 2023 15:16:46 +0300 Subject: [PATCH 4/5] bump iphone --- scripts/test-unit.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/test-unit.js b/scripts/test-unit.js index 4a89b306e..cf90e103b 100644 --- a/scripts/test-unit.js +++ b/scripts/test-unit.js @@ -20,8 +20,7 @@ function runAndroidUnitTests() { function runIosUnitTests() { exec.execSync('npm run build'); exec.execSync('npm run pod-install'); - testTarget('NotificationsExampleApp', 'iPhone 11', '13.7'); - // testTarget('NotificationsExampleAppIOS12', 'iPhone X', '12.4'); + testTarget('NotificationsExampleApp', 'iPhone 12', '14.4'); } function testTarget(scheme, device, OS = 'latest') { From 10f7d174004a1a5d16d1a71fa424c01d5834aeb0 Mon Sep 17 00:00:00 2001 From: danielel Date: Thu, 18 May 2023 15:17:04 +0300 Subject: [PATCH 5/5] enlarge java heap --- lib/android/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index ccb748f58..9b2f6b092 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -10,7 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit