Skip to content
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

Fix HMS activity open #1533

Merged
merged 2 commits into from
Feb 16, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static void processIntent(Context context, Intent intent) {
if (!(context instanceof Activity))
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.ERROR, "NotificationOpenedProcessor processIntent from an non Activity context: " + context);
else OneSignal.handleNotificationOpen((Activity) context, intentExtras.getDataArray(),
intent.getBooleanExtra("from_alert", false), OSNotificationFormatHelper.getOSNotificationIdFromJson(intentExtras.getJsonData()));
false, OSNotificationFormatHelper.getOSNotificationIdFromJson(intentExtras.getJsonData()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,15 @@ private static void handleProcessJsonOpenData(@NonNull Activity activity, @NonNu
OneSignal.handleNotificationOpen(
activity,
new JSONArray().put(jsonData),
false,
true,
OSNotificationFormatHelper.getOSNotificationIdFromJson(jsonData)
);
}

// HMS notification with Message Type being Message won't trigger Activity reverse trampolining logic
// for this case OneSignal rely on NotificationOpenedActivityHMS activity
// Last EMUI (12 to the date) is based on Android 10, so no
// Activity trampolining restriction exist for HMS devices
public static void processDataMessageReceived(@NonNull final Context context, @Nullable String data) {
OneSignal.initWithContext(context);
if (data == null)
Expand Down
34 changes: 32 additions & 2 deletions OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java
Original file line number Diff line number Diff line change
Expand Up @@ -2336,7 +2336,7 @@ static void fireForegroundHandlers(OSNotificationController notificationControll
/**
* Method called when opening a notification
*/
static void handleNotificationOpen(final Activity context, final JSONArray data, final boolean fromAlert, @Nullable final String notificationId) {
static void handleNotificationOpen(final Activity context, final JSONArray data, final boolean startLauncherActivity, @Nullable final String notificationId) {
// Delay call until remote params are set
if (taskRemoteController.shouldQueueTaskForInit(OSTaskRemoteController.HANDLE_NOTIFICATION_OPEN)) {
logger.error("Waiting for remote params. " +
Expand All @@ -2346,7 +2346,7 @@ static void handleNotificationOpen(final Activity context, final JSONArray data,
public void run() {
if (appContext != null) {
logger.debug("Running " + OSTaskRemoteController.HANDLE_NOTIFICATION_OPEN + " operation from pending queue.");
handleNotificationOpen(context, data, fromAlert, notificationId);
handleNotificationOpen(context, data, startLauncherActivity, notificationId);
}
}
});
Expand All @@ -2364,11 +2364,41 @@ public void run() {

if (shouldInitDirectSessionFromNotificationOpen(context, data)) {
applicationOpenedByNotification(notificationId);

if (startLauncherActivity) {
// Start activity with an activity trampolining
startOrResumeApp(context);
}
}

runNotificationOpenedCallback(data);
}

// Reverse activity trampolining is used for most notifications.
// This method is only used if the push provider does support it.
// This opens the app in the same way an Android home screen launcher does.
// This means we expect the following behavior:
// 1. Starts the Activity defined in the app's AndroidManifest.xml as "android.intent.action.MAIN"
// 2. If the app is already running, instead the last activity will be resumed
// 3. If the app is not running (due to being push out of memory), the last activity will be resumed
// 4. If the app is no longer in the recent apps list, it is not resumed, same as #1 above.
// - App is removed from the recent app's list if it is swiped away or "clear all" is pressed.
static boolean startOrResumeApp(@NonNull Activity activity) {
Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName());
logger.debug("startOrResumeApp from context: " + activity + " isRoot: " + activity.isTaskRoot() + " with launchIntent: " + launchIntent);

// Not all apps have a launcher intent, such as one that only provides a homescreen widget
if (launchIntent == null)
return false;
// Removing package from the intent, this treats the app as if it was started externally.
// This gives us the resume app behavior noted above.
// Android 11 no longer requires nulling this out to get this behavior.
launchIntent.setPackage(null);

activity.startActivity(launchIntent);
return true;
}

private static boolean shouldInitDirectSessionFromNotificationOpen(Activity context, final JSONArray data) {
if (inForeground) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ public static JSONObject bundleAsJSONObject(Bundle bundle) {
return NotificationBundleProcessor.bundleAsJSONObject(bundle);
}

public static void OneSignal_handleNotificationOpen(Activity context, final JSONArray data, final boolean fromAlert, final String notificationId) {
OneSignal.handleNotificationOpen(context, data, fromAlert, notificationId);
public static void OneSignal_handleNotificationOpen(Activity context, final JSONArray data, final boolean fromHMSMessage, final String notificationId) {
OneSignal.handleNotificationOpen(context, data, fromHMSMessage, notificationId);
}

public static BigInteger OneSignal_getAccentColor(JSONObject fcmJson) {
Expand Down