Skip to content

Commit 102d64f

Browse files
authored
Revert "Fix for Android trampoline restriction" (wix#969)
* Revert "Init (wix#920)" This reverts commit 63ec3ca. * fix-ios-test * remove jenkins leftovers * bump iphone * enlarge java heap
1 parent 63ec3ca commit 102d64f

File tree

8 files changed

+112
-31
lines changed

8 files changed

+112
-31
lines changed

lib/android/app/src/main/AndroidManifest.xml

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
package="com.wix.reactnativenotifications">
55

66
<application>
7+
8+
<!--
9+
A proxy-service that gives the library an opportunity to do some work before launching/resuming the actual application task.
10+
-->
11+
<service android:name=".core.ProxyService"/>
12+
713
<service
814
android:name=".fcm.FcmInstanceIdListenerService"
915
android:exported="true">

lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java

+17-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.wix.reactnativenotifications.core.NotificationIntentAdapter;
1818
import com.wix.reactnativenotifications.core.notification.IPushNotification;
1919
import com.wix.reactnativenotifications.core.notification.PushNotification;
20-
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
2120
import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer;
2221
import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer;
2322

@@ -62,18 +61,14 @@ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
6261
final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext());
6362
notificationsDrawer.onNewActivity(activity);
6463

65-
Intent intent = activity.getIntent();
66-
if (NotificationIntentAdapter.canHandleIntent(intent)) {
67-
Bundle notificationData = intent.getExtras();
68-
final IPushNotification pushNotification = PushNotification.get(mApplication.getApplicationContext(), notificationData);
69-
if (pushNotification != null) {
70-
pushNotification.onOpened();
71-
}
72-
}
64+
callOnOpenedIfNeed(activity);
7365
}
7466

7567
@Override
7668
public void onActivityStarted(Activity activity) {
69+
if (InitialNotificationHolder.getInstance().get() == null) {
70+
callOnOpenedIfNeed(activity);
71+
}
7772
}
7873

7974
@Override
@@ -95,4 +90,17 @@ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
9590
@Override
9691
public void onActivityDestroyed(Activity activity) {
9792
}
93+
94+
private void callOnOpenedIfNeed(Activity activity) {
95+
Intent intent = activity.getIntent();
96+
if (NotificationIntentAdapter.canHandleIntent(intent)) {
97+
Context appContext = mApplication.getApplicationContext();
98+
Bundle notificationData = NotificationIntentAdapter.canHandleTrampolineActivity(appContext) ?
99+
intent.getExtras() : NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent);
100+
final IPushNotification pushNotification = PushNotification.get(appContext, notificationData);
101+
if (pushNotification != null) {
102+
pushNotification.onOpened();
103+
}
104+
}
105+
}
98106
}

lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
11
package com.wix.reactnativenotifications.core;
22

3+
import android.annotation.SuppressLint;
34
import android.app.PendingIntent;
5+
import android.app.TaskStackBuilder;
46
import android.content.Context;
57
import android.content.Intent;
6-
import android.os.Build;
78
import android.os.Bundle;
89

910
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
1011

1112
public class NotificationIntentAdapter {
1213
private static final String PUSH_NOTIFICATION_EXTRA_NAME = "pushNotification";
1314

15+
@SuppressLint("UnspecifiedImmutableFlag")
1416
public static PendingIntent createPendingNotificationIntent(Context appContext, PushNotificationProps notification) {
15-
Intent intent = new AppLaunchHelper().getLaunchIntent(appContext);
16-
intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
17-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
18-
return PendingIntent.getActivity(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
17+
if (canHandleTrampolineActivity(appContext)) {
18+
Intent intent = new Intent(appContext, ProxyService.class);
19+
intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
20+
return PendingIntent.getService(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT);
1921
} else {
20-
return PendingIntent.getActivity(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT);
22+
Intent mainActivityIntent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
23+
mainActivityIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
24+
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(appContext);
25+
taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent);
26+
return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
2127
}
2228
}
2329

30+
public static boolean canHandleTrampolineActivity(Context appContext) {
31+
return android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R || appContext.getApplicationInfo().targetSdkVersion < 31;
32+
}
33+
34+
public static Bundle extractPendingNotificationDataFromIntent(Intent intent) {
35+
return intent.getBundleExtra(PUSH_NOTIFICATION_EXTRA_NAME);
36+
}
37+
2438
public static boolean canHandleIntent(Intent intent) {
2539
if (intent != null) {
2640
Bundle notificationData = intent.getExtras();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.wix.reactnativenotifications.core;
2+
3+
import android.app.IntentService;
4+
import android.content.Intent;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
8+
import com.wix.reactnativenotifications.BuildConfig;
9+
import com.wix.reactnativenotifications.core.notification.IPushNotification;
10+
import com.wix.reactnativenotifications.core.notification.PushNotification;
11+
12+
public class ProxyService extends IntentService {
13+
14+
private static final String TAG = ProxyService.class.getSimpleName();
15+
16+
public ProxyService() {
17+
super("notificationsProxyService");
18+
}
19+
20+
@Override
21+
protected void onHandleIntent(Intent intent) {
22+
if (BuildConfig.DEBUG) Log.d(TAG, "New intent: "+intent);
23+
final Bundle notificationData = NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent);
24+
final IPushNotification pushNotification = PushNotification.get(this, notificationData);
25+
if (pushNotification != null) {
26+
pushNotification.onOpened();
27+
}
28+
}
29+
}

lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java

+26-2
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,22 @@ protected int postNotification(Integer notificationId) {
9797
protected void digestNotification() {
9898
if (!mAppLifecycleFacade.isReactInitialized()) {
9999
setAsInitialNotification();
100+
launchOrResumeApp();
100101
return;
101102
}
102103

103104
final ReactContext reactContext = mAppLifecycleFacade.getRunningReactContext();
104105
if (reactContext.getCurrentActivity() == null) {
105106
setAsInitialNotification();
106-
return;
107107
}
108108

109-
dispatchImmediately();
109+
if (mAppLifecycleFacade.isAppVisible()) {
110+
dispatchImmediately();
111+
} else if (mAppLifecycleFacade.isAppDestroyed()) {
112+
launchOrResumeApp();
113+
} else {
114+
dispatchUponVisibility();
115+
}
110116
}
111117

112118
protected PushNotificationProps createProps(Bundle bundle) {
@@ -121,6 +127,17 @@ protected void dispatchImmediately() {
121127
notifyOpenedToJS();
122128
}
123129

130+
protected void dispatchUponVisibility() {
131+
mAppLifecycleFacade.addVisibilityListener(getIntermediateAppVisibilityListener());
132+
133+
// Make the app visible so that we'll dispatch the notification opening when visibility changes to 'true' (see
134+
// above listener registration).
135+
launchOrResumeApp();
136+
}
137+
138+
protected AppVisibilityListener getIntermediateAppVisibilityListener() {
139+
return mAppVisibilityListener;
140+
}
124141

125142
protected Notification buildNotification(PendingIntent intent) {
126143
return getNotificationBuilder(intent).build();
@@ -195,6 +212,13 @@ private void notifyOpenedToJS() {
195212
mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, response, mAppLifecycleFacade.getRunningReactContext());
196213
}
197214

215+
protected void launchOrResumeApp() {
216+
if (NotificationIntentAdapter.canHandleTrampolineActivity(mContext)) {
217+
final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext);
218+
mContext.startActivity(intent);
219+
}
220+
}
221+
198222
private int getAppResourceId(String resName, String resType) {
199223
return mContext.getResources().getIdentifier(resName, resType, mContext.getPackageName());
200224
}

lib/android/gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# Specifies the JVM arguments used for the daemon process.
1111
# The setting is particularly useful for tweaking memory settings.
1212
# Default value: -Xmx10248m -XX:MaxPermSize=256m
13-
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
13+
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
1414

1515
# When configured, Gradle will run in incubating parallel mode.
1616
# This option should only be used with decoupled projects. More details, visit

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,4 @@
114114
"html"
115115
]
116116
}
117-
}
117+
}

scripts/test-unit.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,38 @@ function run() {
1414

1515
function runAndroidUnitTests() {
1616
const conf = release ? 'testReactNative60ReleaseUnitTest' : 'testReactNative60DebugUnitTest';
17-
if (android && process.env.JENKINS_CI) {
18-
const sdkmanager = '/usr/local/share/android-sdk/tools/bin/sdkmanager';
19-
exec.execSync(`yes | ${sdkmanager} --licenses`);
20-
// exec.execSync(`echo y | ${sdkmanager} --update && echo y | ${sdkmanager} --licenses`);
21-
}
2217
exec.execSync(`cd lib/android && ./gradlew ${conf}`);
2318
}
2419

2520
function runIosUnitTests() {
26-
const conf = release ? `Release` : `Debug`;
21+
exec.execSync('npm run build');
2722
exec.execSync('npm run pod-install');
23+
testTarget('NotificationsExampleApp', 'iPhone 12', '14.4');
24+
}
25+
26+
function testTarget(scheme, device, OS = 'latest') {
27+
const conf = release ? `Release` : `Debug`;
2828
exec.execSync(`cd ./example/ios &&
2929
RCT_NO_LAUNCH_PACKAGER=true
3030
xcodebuild build build-for-testing
31-
-scheme "NotificationsExampleApp"
31+
-scheme "${scheme}"
3232
-workspace NotificationsExampleApp.xcworkspace
3333
-sdk iphonesimulator
3434
-configuration ${conf}
35-
-derivedDataPath ./example/ios/DerivedData/NotificationsExampleApp
35+
-derivedDataPath ./DerivedData/NotificationsExampleApp
3636
-quiet
37-
-UseModernBuildSystem=NO
37+
-UseModernBuildSystem=YES
3838
ONLY_ACTIVE_ARCH=YES`);
3939

4040
exec.execSync(`cd ./example/ios &&
4141
RCT_NO_LAUNCH_PACKAGER=true
4242
xcodebuild test-without-building
43-
-scheme "NotificationsExampleApp"
43+
-scheme "${scheme}"
4444
-workspace NotificationsExampleApp.xcworkspace
4545
-sdk iphonesimulator
4646
-configuration ${conf}
47-
-destination 'platform=iOS Simulator,name=iPhone 11'
48-
-derivedDataPath ./example/ios/DerivedData/NotificationsExampleApp
47+
-destination 'platform=iOS Simulator,name=${device},OS=${OS}'
48+
-derivedDataPath ./DerivedData/NotificationsExampleApp
4949
ONLY_ACTIVE_ARCH=YES`);
5050
}
5151

0 commit comments

Comments
 (0)