From 23657fdcaa686c5e205c0027511a736dc39f7580 Mon Sep 17 00:00:00 2001 From: Nan Date: Thu, 4 Nov 2021 23:59:06 -0700 Subject: [PATCH 1/5] Revert `NotificationWorker` back to `Worker` - Reverts `NotificationWorker` from being a `ListenableWorker` back to `Worker` - Removed all code related to the ListenableWorker implementation of NotificationWorker --- OneSignalSDK/build.gradle | 1 - OneSignalSDK/onesignal/build.gradle | 2 - .../NotificationBundleProcessor.java | 20 +---- .../onesignal/NotificationSummaryManager.java | 2 +- .../onesignal/OSNotificationController.java | 10 +-- .../OSNotificationGenerationJob.java | 15 ---- .../OSNotificationRestoreWorkManager.java | 7 +- .../onesignal/OSNotificationWorkManager.java | 79 +++++-------------- .../onesignal/OSReceiveReceiptController.java | 13 +-- OneSignalSDK/unittest/build.gradle | 1 - .../OneSignalPackagePrivateHelper.java | 2 - 11 files changed, 31 insertions(+), 121 deletions(-) diff --git a/OneSignalSDK/build.gradle b/OneSignalSDK/build.gradle index a7ec6f7e97..024b41090a 100644 --- a/OneSignalSDK/build.gradle +++ b/OneSignalSDK/build.gradle @@ -8,7 +8,6 @@ buildscript { targetSdkVersion: 30 ] androidGradlePluginVersion = '3.6.2' - androidConcurrentFutures = '1.1.0' googleServicesGradlePluginVersion = '4.3.2' huaweiAgconnectVersion = '1.2.1.301' huaweiHMSPushVersion = '5.3.0.304' diff --git a/OneSignalSDK/onesignal/build.gradle b/OneSignalSDK/onesignal/build.gradle index eec42a6758..20759cd461 100644 --- a/OneSignalSDK/onesignal/build.gradle +++ b/OneSignalSDK/onesignal/build.gradle @@ -48,8 +48,6 @@ dependencies { // Required for GoogleApiAvailability implementation 'com.google.android.gms:play-services-base:[17.0.0, 17.6.99]' - implementation("androidx.concurrent:concurrent-futures:$androidConcurrentFutures") - // firebase-messaging:18.0.0 is the last version before going to AndroidX // firebase-messaging:19.0.0 is the first version using AndroidX api 'com.google.firebase:firebase-messaging:[19.0.0, 22.0.99]' diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java index a7b4f41ba0..2ba63d2e4e 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java @@ -38,8 +38,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.work.ListenableWorker; import com.onesignal.OneSignalDbContract.NotificationTable; @@ -100,8 +98,7 @@ public void onResult(boolean result) { jsonStrPayload, shownTimeStamp, isRestoring, - false, - true); + false); // Delay to prevent CPU spikes. // Normally more than one notification is restored at a time. @@ -164,11 +161,6 @@ private static int processJobForDisplay(OSNotificationController notificationCon String osNotificationId = OSNotificationFormatHelper.getOSNotificationIdFromJson(notificationController.getNotificationJob().getJsonPayload()); OSNotificationWorkManager.removeNotificationIdProcessed(osNotificationId); OneSignal.handleNotificationReceived(notificationJob); - } else { - CallbackToFutureAdapter.Completer callbackCompleter = notificationJob.getCallbackCompleter(); - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Process notification restored or IAM with callback completer: " + callbackCompleter); - if (callbackCompleter != null) - callbackCompleter.set(ListenableWorker.Result.success()); } return androidNotificationId; @@ -183,22 +175,17 @@ private static boolean shouldDisplayNotification(OSNotificationGenerationJob not */ static void processNotification(OSNotificationGenerationJob notificationJob, boolean opened, boolean notificationDisplayed) { saveNotification(notificationJob, opened); - CallbackToFutureAdapter.Completer callbackCompleter = notificationJob.getCallbackCompleter(); if (!notificationDisplayed) { // Notification channel disable or not displayed // save notification as dismissed to avoid user re-enabling channel and notification being displayed due to restore markNotificationAsDismissed(notificationJob); - - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Process notification not displayed with callback completer: " + callbackCompleter); - if (callbackCompleter != null) - callbackCompleter.set(ListenableWorker.Result.success()); return; } // Logic for when the notification is displayed String notificationId = notificationJob.getApiNotificationId(); - OSReceiveReceiptController.getInstance().sendReceiveReceipt(callbackCompleter, notificationId); + OSReceiveReceiptController.getInstance().sendReceiveReceipt(notificationId); OneSignal.getSessionManager().onNotificationReceived(notificationId); } @@ -439,8 +426,7 @@ public void onResult(boolean result) { jsonPayload.toString(), timestamp, isRestoring, - isHighPriority, - true); + isHighPriority); bundleResult.setWorkManagerProcessing(true); notificationProcessingCallback.onResult(true); diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationSummaryManager.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationSummaryManager.java index fa19caea75..7103b84fb6 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationSummaryManager.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationSummaryManager.java @@ -146,7 +146,7 @@ private static void restoreSummary(Context context, String group) { null ); - OSNotificationRestoreWorkManager.showNotificationsFromCursor(context, cursor, 0, true); + OSNotificationRestoreWorkManager.showNotificationsFromCursor(context, cursor, 0); } catch (Throwable t) { OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error restoring notification records! ", t); } finally { diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationController.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationController.java index e08306287a..04cd0b3e9a 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationController.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationController.java @@ -34,8 +34,6 @@ import android.content.Context; import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.work.ListenableWorker; import org.json.JSONObject; @@ -46,7 +44,6 @@ public class OSNotificationController { static final String GOOGLE_SENT_TIME_KEY = "google.sent_time"; static final String GOOGLE_TTL_KEY = "google.ttl"; - private final CallbackToFutureAdapter.Completer callbackCompleter; private final OSNotificationGenerationJob notificationJob; private boolean restoring; private boolean fromBackgroundLogic; @@ -55,12 +52,9 @@ public class OSNotificationController { this.restoring = restoring; this.fromBackgroundLogic = fromBackgroundLogic; this.notificationJob = notificationJob; - this.callbackCompleter = notificationJob.getCallbackCompleter(); } - OSNotificationController(CallbackToFutureAdapter.Completer callbackCompleter, - Context context, OSNotification notification, JSONObject jsonPayload, boolean restoring, boolean fromBackgroundLogic, Long timestamp) { - this.callbackCompleter = callbackCompleter; + OSNotificationController(Context context, OSNotification notification, JSONObject jsonPayload, boolean restoring, boolean fromBackgroundLogic, Long timestamp) { this.restoring = restoring; this.fromBackgroundLogic = fromBackgroundLogic; @@ -74,7 +68,7 @@ public class OSNotificationController { * @see OSNotificationGenerationJob */ private OSNotificationGenerationJob createNotificationJobFromCurrent(Context context, OSNotification notification, JSONObject jsonPayload, Long timestamp) { - OSNotificationGenerationJob notificationJob = new OSNotificationGenerationJob(callbackCompleter, context); + OSNotificationGenerationJob notificationJob = new OSNotificationGenerationJob(context); notificationJob.setJsonPayload(jsonPayload); notificationJob.setShownTimeStamp(timestamp); notificationJob.setRestoring(restoring); diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationGenerationJob.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationGenerationJob.java index 1da9a0a664..0f56636196 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationGenerationJob.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationGenerationJob.java @@ -30,17 +30,12 @@ import android.content.Context; import android.net.Uri; -import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.work.ListenableWorker; - import org.json.JSONObject; import java.security.SecureRandom; public class OSNotificationGenerationJob { - private CallbackToFutureAdapter.Completer callbackCompleter; private OSNotification notification; private Context context; private JSONObject jsonPayload; @@ -56,11 +51,6 @@ public class OSNotificationGenerationJob { private Uri orgSound; OSNotificationGenerationJob(Context context) { - this(null, context); - } - - OSNotificationGenerationJob(CallbackToFutureAdapter.Completer callbackCompleter, Context context) { - this.callbackCompleter = callbackCompleter; this.context = context; } @@ -74,11 +64,6 @@ public class OSNotificationGenerationJob { this.notification = notification; } - @Nullable - public CallbackToFutureAdapter.Completer getCallbackCompleter() { - return callbackCompleter; - } - /** * Get the notification title from the payload */ diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationRestoreWorkManager.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationRestoreWorkManager.java index b803934b13..fcc809f0aa 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationRestoreWorkManager.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationRestoreWorkManager.java @@ -104,7 +104,7 @@ private static void queryAndRestoreNotificationsAndBadgeCount( OneSignalDbContract.NotificationTable._ID + " DESC", // sort order, new to old NotificationLimitManager.MAX_NUMBER_OF_NOTIFICATIONS_STR // limit ); - showNotificationsFromCursor(context, cursor, DELAY_BETWEEN_NOTIFICATION_RESTORES_MS, false); + showNotificationsFromCursor(context, cursor, DELAY_BETWEEN_NOTIFICATION_RESTORES_MS); BadgeCountUpdater.update(dbHelper, context); } catch (Throwable t) { OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Error restoring notification records! ", t); @@ -144,7 +144,7 @@ private static void skipVisibleNotifications(Context context, StringBuilder dbQu * @param cursor - Source cursor to generate notifications from * @param delay - Delay to slow down process to ensure we don't spike CPU and I/O on the device */ - static void showNotificationsFromCursor(Context context, Cursor cursor, int delay, boolean needsWorkerThread) { + static void showNotificationsFromCursor(Context context, Cursor cursor, int delay) { if (!cursor.moveToFirst()) return; @@ -161,8 +161,7 @@ static void showNotificationsFromCursor(Context context, Cursor cursor, int dela fullData, dateTime, true, - false, - needsWorkerThread + false ); if (delay > 0) diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationWorkManager.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationWorkManager.java index 07d7ceb578..3cb4d04423 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationWorkManager.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSNotificationWorkManager.java @@ -3,17 +3,13 @@ import android.content.Context; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; import androidx.work.Data; import androidx.work.ExistingWorkPolicy; -import androidx.work.ListenableWorker; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; +import androidx.work.Worker; import androidx.work.WorkerParameters; -import com.google.common.util.concurrent.ListenableFuture; - import org.json.JSONException; import org.json.JSONObject; @@ -23,7 +19,6 @@ class OSNotificationWorkManager { - private static final String OS_NOTIFICATION_ID = "os_bnotification_id"; private static final String ANDROID_NOTIF_ID_WORKER_DATA_PARAM = "android_notif_id"; private static final String JSON_PAYLOAD_WORKER_DATA_PARAM = "json_payload"; private static final String TIMESTAMP_WORKER_DATA_PARAM = "timestamp"; @@ -54,20 +49,9 @@ static void removeNotificationIdProcessed(String osNotificationId) { } static void beginEnqueueingWork(Context context, String osNotificationId, int androidNotificationId, String jsonPayload, long timestamp, - boolean isRestoring, boolean isHighPriority, boolean needsWorkerThread) { - if (!needsWorkerThread) { - try { - JSONObject jsonPayloadObject = new JSONObject(jsonPayload); - processNotificationData(context, androidNotificationId, jsonPayloadObject, isRestoring, timestamp); - } catch (JSONException e) { - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.ERROR, "Error occurred parsing jsonPayload to JSONObject in beginEnqueueingWork e: " + e.getMessage()); - e.printStackTrace(); - } - return; - } + boolean isRestoring, boolean isHighPriority) { // TODO: Need to figure out how to implement the isHighPriority param Data inputData = new Data.Builder() - .putString(OS_NOTIFICATION_ID, osNotificationId) .putInt(ANDROID_NOTIF_ID_WORKER_DATA_PARAM, androidNotificationId) .putString(JSON_PAYLOAD_WORKER_DATA_PARAM, jsonPayload) .putLong(TIMESTAMP_WORKER_DATA_PARAM, timestamp) @@ -83,7 +67,7 @@ static void beginEnqueueingWork(Context context, String osNotificationId, int an .enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest); } - public static class NotificationWorker extends ListenableWorker { + public static class NotificationWorker extends Worker { public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); @@ -91,21 +75,7 @@ public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters wo @NonNull @Override - public ListenableFuture startWork() { - return CallbackToFutureAdapter.getFuture(new CallbackToFutureAdapter.Resolver() { - @Nullable - @Override - public Object attachCompleter(@NonNull CallbackToFutureAdapter.Completer completer) throws Exception { - String notificationId = NotificationWorker.this.doWork(completer); - - // This value is used only for debug purposes: it will be used - // in toString() of returned future or error cases. - return "NotificationWorkerFutureCallback_" + notificationId; - } - }); - } - - private String doWork(@NonNull CallbackToFutureAdapter.Completer completer) { + public Result doWork() { Data inputData = getInputData(); try { OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "NotificationWorker running doWork with data: " + inputData); @@ -116,7 +86,6 @@ private String doWork(@NonNull CallbackToFutureAdapter.Completer complet boolean isRestoring = inputData.getBoolean(IS_RESTORING_WORKER_DATA_PARAM, false); processNotificationData( - completer, getApplicationContext(), androidNotificationId, jsonPayload, @@ -125,36 +94,30 @@ private String doWork(@NonNull CallbackToFutureAdapter.Completer complet } catch (JSONException e) { OneSignal.onesignalLog(OneSignal.LOG_LEVEL.ERROR, "Error occurred doing work for job with id: " + getId().toString()); e.printStackTrace(); - completer.setException(e); + return Result.failure(); } - return inputData.getString(OS_NOTIFICATION_ID); + return Result.success(); } - } - static void processNotificationData(Context context, int androidNotificationId, JSONObject jsonPayload, - boolean isRestoring, Long timestamp) { - processNotificationData(null, context, androidNotificationId, jsonPayload, isRestoring, timestamp); - } + private void processNotificationData(Context context, int androidNotificationId, JSONObject jsonPayload, + boolean isRestoring, Long timestamp) { + OSNotification notification = new OSNotification(null, jsonPayload, androidNotificationId); + OSNotificationController controller = new OSNotificationController(context, notification, jsonPayload, isRestoring, true, timestamp); + OSNotificationReceivedEvent notificationReceived = new OSNotificationReceivedEvent(controller, notification); - static void processNotificationData(CallbackToFutureAdapter.Completer completer, - Context context, int androidNotificationId, JSONObject jsonPayload, - boolean isRestoring, Long timestamp) { - OSNotification notification = new OSNotification(null, jsonPayload, androidNotificationId); - OSNotificationController controller = new OSNotificationController(completer, context, notification, jsonPayload, isRestoring, true, timestamp); - OSNotificationReceivedEvent notificationReceived = new OSNotificationReceivedEvent(controller, notification); + if (OneSignal.remoteNotificationReceivedHandler != null) + try { + OneSignal.remoteNotificationReceivedHandler.remoteNotificationReceived(context, notificationReceived); + } catch (Throwable t) { + OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "remoteNotificationReceived throw an exception. Displaying normal OneSignal notification.", t); + notificationReceived.complete(notification); - if (OneSignal.remoteNotificationReceivedHandler != null) - try { - OneSignal.remoteNotificationReceivedHandler.remoteNotificationReceived(context, notificationReceived); - } catch (Throwable t) { - OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "remoteNotificationReceived throw an exception. Displaying normal OneSignal notification.", t); + throw t; + } + else { + OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "remoteNotificationReceivedHandler not setup, displaying normal OneSignal notification"); notificationReceived.complete(notification); - - throw t; } - else { - OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "remoteNotificationReceivedHandler not setup, displaying normal OneSignal notification"); - notificationReceived.complete(notification); } } } diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java index 84e221c7d3..4ae0fac560 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java @@ -28,8 +28,6 @@ package com.onesignal; import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.work.ListenableWorker; class OSReceiveReceiptController { @@ -51,14 +49,13 @@ synchronized public static OSReceiveReceiptController getInstance() { return sInstance; } - void sendReceiveReceipt(final CallbackToFutureAdapter.Completer callbackCompleter, @NonNull final String notificationId) { + void sendReceiveReceipt(@NonNull final String notificationId) { final String appId = OneSignal.appId == null || OneSignal.appId.isEmpty() ? OneSignal.getSavedAppId() : OneSignal.appId; final String playerId = OneSignal.getUserId(); Integer deviceType = null; if (!remoteParamController.isReceiveReceiptEnabled()) { OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "sendReceiveReceipt disable"); - endCallbackCompleterWithSuccess(callbackCompleter); return; } @@ -78,13 +75,11 @@ public void run() { @Override void onSuccess(String response) { OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Receive receipt sent for notificationID: " + notificationId); - endCallbackCompleterWithSuccess(callbackCompleter); } @Override void onFailure(int statusCode, String response, Throwable throwable) { OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Receive receipt failed with statusCode: " + statusCode + " response: " + response); - endCallbackCompleterWithSuccess(callbackCompleter); } }); } @@ -92,10 +87,4 @@ void onFailure(int statusCode, String response, Throwable throwable) { taskController.delayTaskByRandom(receiveReceiptRunnable); } - - private void endCallbackCompleterWithSuccess(CallbackToFutureAdapter.Completer callbackCompleter) { - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Receive receipt ending with success callback completer: " + callbackCompleter); - if (callbackCompleter != null) - callbackCompleter.set(ListenableWorker.Result.success()); - } } diff --git a/OneSignalSDK/unittest/build.gradle b/OneSignalSDK/unittest/build.gradle index 0c4abb5d72..8fa349173a 100644 --- a/OneSignalSDK/unittest/build.gradle +++ b/OneSignalSDK/unittest/build.gradle @@ -73,7 +73,6 @@ dependencies { testImplementation "androidx.test:core:$androidTestCoreVersion" testImplementation "androidx.work:work-testing:$androidWorkTestVersion" - testImplementation("androidx.concurrent:concurrent-futures:$androidConcurrentFutures") testImplementation "org.robolectric:robolectric:$roboelectricVersion" testImplementation "org.awaitility:awaitility:$awaitilityVersion" diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java index 50dcd2e862..82b65b84cb 100644 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java +++ b/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java @@ -8,8 +8,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.work.ListenableWorker; import com.huawei.hms.push.RemoteMessage; import com.onesignal.influence.data.OSTrackerFactory; From 6a53b9c4d89c2bdd137d889a38c0a724f27bbdeb Mon Sep 17 00:00:00 2001 From: Nan Date: Tue, 9 Nov 2021 10:06:16 -0800 Subject: [PATCH 2/5] Use a Worker with a delay to send Receive Receipts - Add a `ReceiveReceiptWorker` to call `sendReceiveReceipt(notificationId)` --- .../NotificationBundleProcessor.java | 3 +- .../onesignal/OSReceiveReceiptController.java | 122 ++++++++++++------ .../src/main/java/com/onesignal/OSUtils.java | 4 + 3 files changed, 91 insertions(+), 38 deletions(-) diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java index 2ba63d2e4e..026cc7f32e 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationBundleProcessor.java @@ -185,7 +185,8 @@ static void processNotification(OSNotificationGenerationJob notificationJob, boo // Logic for when the notification is displayed String notificationId = notificationJob.getApiNotificationId(); - OSReceiveReceiptController.getInstance().sendReceiveReceipt(notificationId); + Context context = notificationJob.getContext(); + OSReceiveReceiptController.getInstance().beginEnqueueingWork(context, notificationId); OneSignal.getSessionManager().onNotificationReceived(notificationId); } diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java index 4ae0fac560..c50e92744a 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java @@ -27,64 +27,112 @@ package com.onesignal; +import android.content.Context; + import androidx.annotation.NonNull; +import androidx.work.Constraints; +import androidx.work.Data; +import androidx.work.ExistingWorkPolicy; +import androidx.work.NetworkType; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkManager; +import androidx.work.Worker; +import androidx.work.WorkerParameters; + +import java.util.concurrent.TimeUnit; class OSReceiveReceiptController { - private final OSDelayTaskController taskController; - private final OSReceiveReceiptRepository repository; + private static final String OS_NOTIFICATION_ID = "os_notification_id"; + private int minDelay = 0; + private int maxDelay = 25; + private final OSRemoteParamController remoteParamController; - private static OSReceiveReceiptController sInstance; - private OSReceiveReceiptController(OSRemoteParamController remoteParamController, OSDelayTaskController taskController) { - this.remoteParamController = remoteParamController; - this.taskController = taskController; - this.repository = new OSReceiveReceiptRepository(); + private OSReceiveReceiptController() { + this.remoteParamController = OneSignal.getRemoteParamController(); } synchronized public static OSReceiveReceiptController getInstance() { if (sInstance == null) - sInstance = new OSReceiveReceiptController(OneSignal.getRemoteParamController(), OneSignal.getDelayTaskController()); + sInstance = new OSReceiveReceiptController(); return sInstance; } - void sendReceiveReceipt(@NonNull final String notificationId) { - final String appId = OneSignal.appId == null || OneSignal.appId.isEmpty() ? OneSignal.getSavedAppId() : OneSignal.appId; - final String playerId = OneSignal.getUserId(); - Integer deviceType = null; - + void beginEnqueueingWork(Context context, String osNotificationId) { if (!remoteParamController.isReceiveReceiptEnabled()) { - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "sendReceiveReceipt disable"); + OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "sendReceiveReceipt disabled"); return; } - try { - deviceType = new OSUtils().getDeviceType(); - } catch (NullPointerException e) { - e.printStackTrace(); + int delay = OSUtils.getRandomDelay(minDelay, maxDelay); + + Data inputData = new Data.Builder() + .putString(OS_NOTIFICATION_ID, osNotificationId) + .build(); + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(ReceiveReceiptWorker.class) + .setConstraints(constraints) + .setInitialDelay(delay, TimeUnit.SECONDS) + .setInputData(inputData) + .build(); + + OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OSReceiveReceiptController enqueueing send receive receipt work with notificationId: " + osNotificationId + " and delay: " + delay + " seconds"); + + WorkManager.getInstance(context) + .enqueueUniqueWork(osNotificationId + "_receive_receipt", ExistingWorkPolicy.KEEP, workRequest); + + } + + public static class ReceiveReceiptWorker extends Worker { + + public ReceiveReceiptWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { + super(context, workerParams); + } + + @NonNull + @Override + public Result doWork() { + Data inputData = getInputData(); + String notificationId = inputData.getString(OS_NOTIFICATION_ID); + + sendReceiveReceipt(notificationId); + + return Result.success(); } - final Integer finalDeviceType = deviceType; - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OSReceiveReceiptController: Device Type is: " + finalDeviceType); - - Runnable receiveReceiptRunnable = new Runnable() { - @Override - public void run() { - repository.sendReceiveReceipt(appId, playerId, finalDeviceType, notificationId, new OneSignalRestClient.ResponseHandler() { - @Override - void onSuccess(String response) { - OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Receive receipt sent for notificationID: " + notificationId); - } - - @Override - void onFailure(int statusCode, String response, Throwable throwable) { - OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Receive receipt failed with statusCode: " + statusCode + " response: " + response); - } - }); + void sendReceiveReceipt(@NonNull final String notificationId) { + final String appId = OneSignal.appId == null || OneSignal.appId.isEmpty() ? OneSignal.getSavedAppId() : OneSignal.appId; + final String playerId = OneSignal.getUserId(); + Integer deviceType = null; + + OSReceiveReceiptRepository repository = new OSReceiveReceiptRepository(); + + try { + deviceType = new OSUtils().getDeviceType(); + } catch (NullPointerException e) { + e.printStackTrace(); } - }; - taskController.delayTaskByRandom(receiveReceiptRunnable); + final Integer finalDeviceType = deviceType; + OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "ReceiveReceiptWorker: Device Type is: " + finalDeviceType); + + repository.sendReceiveReceipt(appId, playerId, finalDeviceType, notificationId, new OneSignalRestClient.ResponseHandler() { + @Override + void onSuccess(String response) { + OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "Receive receipt sent for notificationID: " + notificationId); + } + + @Override + void onFailure(int statusCode, String response, Throwable throwable) { + OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Receive receipt failed with statusCode: " + statusCode + " response: " + response); + } + }); + } } } diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java index 0c7bf75adc..932d4b777c 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java @@ -62,6 +62,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; +import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -649,4 +650,7 @@ static boolean shouldLogMissingAppIdError(@Nullable String appId) { return true; } + static int getRandomDelay(int minDelay, int maxDelay) { + return new Random().nextInt(maxDelay + 1 - minDelay) + minDelay; + } } \ No newline at end of file From 8b368861241c11757b07cff9f610ed5ae768f224 Mon Sep 17 00:00:00 2001 From: Nan Date: Tue, 9 Nov 2021 10:28:39 -0800 Subject: [PATCH 3/5] Remove OSDelayTaskController and related code - removed OSDelayTaskController.kt since no longer used now that we use Worker with a delay - removed MockDelayTaskController.java which is used in unit tests - removed other code related to these two classes --- .../com/onesignal/OSDelayTaskController.kt | 40 ------------------- .../main/java/com/onesignal/OneSignal.java | 9 ----- .../onesignal/MockDelayTaskController.java | 32 --------------- .../OneSignalPackagePrivateHelper.java | 5 --- .../java/com/onesignal/StaticResetHelper.java | 3 -- .../onesignal/MainOneSignalClassRunner.java | 2 - 6 files changed, 91 deletions(-) delete mode 100644 OneSignalSDK/onesignal/src/main/java/com/onesignal/OSDelayTaskController.kt delete mode 100644 OneSignalSDK/unittest/src/test/java/com/onesignal/MockDelayTaskController.java diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSDelayTaskController.kt b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSDelayTaskController.kt deleted file mode 100644 index 3dfe35c265..0000000000 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSDelayTaskController.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.onesignal - -import java.util.concurrent.ScheduledThreadPoolExecutor -import java.util.concurrent.ThreadFactory -import java.util.concurrent.TimeUnit -import kotlin.math.roundToInt - -open class OSDelayTaskController(private val logger: OSLogger) { - private val maxDelay = 25 - private val minDelay = 0 - - private var scheduledThreadPoolExecutor: ScheduledThreadPoolExecutor - - init { - scheduledThreadPoolExecutor = ScheduledThreadPoolExecutor(1, JobThreadFactory()) - } - - protected open fun getRandomDelay(): Int { - return (Math.random() * (maxDelay - minDelay + 1) + minDelay).roundToInt() - } - - open fun delayTaskByRandom(runnable: Runnable) { - val randomNum = getRandomDelay() - - logger.debug("OSDelayTaskController delaying task $randomNum second from thread: ${Thread.currentThread()}") - scheduledThreadPoolExecutor.schedule(runnable, randomNum.toLong(), TimeUnit.SECONDS) - } - - fun shutdownNow() { - scheduledThreadPoolExecutor.shutdownNow() - } - - private class JobThreadFactory : ThreadFactory { - private val delayThreadName = "ONE_SIGNAL_DELAY" - - override fun newThread(runnable: Runnable): Thread { - return Thread(runnable, delayThreadName) - } - } -} diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java index 2a0f94d5e7..e0de31cd2d 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java @@ -430,7 +430,6 @@ static OSInAppMessageController getInAppMessageController() { } private static OSTime time = new OSTimeImpl(); private static OSRemoteParamController remoteParamController = new OSRemoteParamController(); - private static OSDelayTaskController delayTaskController = new OSDelayTaskController(logger); private static OSTaskController taskController = new OSTaskController(logger); private static OSTaskRemoteController taskRemoteController = new OSTaskRemoteController(remoteParamController, logger); private static OneSignalAPIClient apiClient = new OneSignalRestClientWrapper(); @@ -3180,10 +3179,6 @@ static void setSharedPreferences(OSSharedPreferences preferences) { OneSignal.preferences = preferences; } - static void setDelayTaskController(OSDelayTaskController delayTaskController) { - OneSignal.delayTaskController = delayTaskController; - } - static OSSessionManager.SessionListener getSessionListener() { return sessionListener; } @@ -3208,10 +3203,6 @@ static OSTaskController getTaskController() { return taskController; } - static OSDelayTaskController getDelayTaskController() { - return delayTaskController; - } - static FocusTimeController getFocusTimeController() { if (focusTimeController == null) { focusTimeController = new FocusTimeController(new OSFocusTimeProcessorFactory(), logger); diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/MockDelayTaskController.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/MockDelayTaskController.java deleted file mode 100644 index f2ea5bc082..0000000000 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/MockDelayTaskController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.onesignal; - -import androidx.annotation.NonNull; - -public class MockDelayTaskController extends OSDelayTaskController { - private int mockedRandomValue = 0; - private boolean runOnSameThread = true; - - public MockDelayTaskController(OSLogger logger) { - super(logger); - } - - protected int getRandomDelay() { - return mockedRandomValue; - } - - public void delayTaskByRandom(@NonNull Runnable runnable) { - if (runOnSameThread) { - runnable.run(); - } else { - super.delayTaskByRandom(runnable); - } - } - - public void setMockedRandomValue(int mockedRandomValue) { - this.mockedRandomValue = mockedRandomValue; - } - - public void setRunOnSameThread(boolean runOnSameThread) { - this.runOnSameThread = runOnSameThread; - } -} diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java index 82b65b84cb..df4fd18b79 100644 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java +++ b/OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java @@ -125,10 +125,6 @@ public static void OneSignal_setTrackerFactory(OSTrackerFactory trackerFactory) OneSignal.setTrackerFactory(trackerFactory); } - public static void OneSignal_setDelayTaskController(OSDelayTaskController delayTaskController) { - OneSignal.setDelayTaskController(delayTaskController); - } - public static JSONObject bundleAsJSONObject(Bundle bundle) { return NotificationBundleProcessor.bundleAsJSONObject(bundle); } @@ -299,7 +295,6 @@ public static ConcurrentLinkedQueue OneSignal_taskQueueWaitingForInit( public static void OneSignal_OSTaskController_ShutdownNow() { OneSignal.getTaskRemoteController().shutdownNow(); OneSignal.getTaskController().shutdownNow(); - OneSignal.getDelayTaskController().shutdownNow(); } public static boolean OneSignal_requiresUserPrivacyConsent() { diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/StaticResetHelper.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/StaticResetHelper.java index dfabbbd55a..fd3549b693 100644 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/StaticResetHelper.java +++ b/OneSignalSDK/unittest/src/test/java/com/onesignal/StaticResetHelper.java @@ -31,9 +31,6 @@ public static void load() { } else if (field.getName().equals("taskRemoteController")) { field.set(null, new OSTaskRemoteController(OneSignal.getRemoteParamController(), logger)); return true; - } else if (field.getName().equals("delayTaskController")) { - field.set(null, new MockDelayTaskController(logger)); - return true; } else if (field.getName().equals("inAppMessageControllerFactory")) { field.set(null, new OSInAppMessageControllerFactory()); return true; diff --git a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java index 90c3e10a82..c69c2fbb15 100644 --- a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java +++ b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java @@ -45,7 +45,6 @@ import com.onesignal.FocusDelaySyncJobService; import com.onesignal.FocusDelaySyncService; -import com.onesignal.MockDelayTaskController; import com.onesignal.MockOSLog; import com.onesignal.MockOSSharedPreferences; import com.onesignal.MockOSTimeImpl; @@ -135,7 +134,6 @@ import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_getSessionListener; import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_handleNotificationOpen; import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_isInForeground; -import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_setDelayTaskController; import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_setSessionManager; import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_setTime; import static com.onesignal.OneSignalPackagePrivateHelper.OneSignal_setTrackerFactory; From d4458efd278191f6164a220a32075f7b0bc39574 Mon Sep 17 00:00:00 2001 From: Nan Date: Tue, 9 Nov 2021 16:01:22 -0800 Subject: [PATCH 4/5] Make ReceiveReceiptWorker run with no delay for unit tests - unit tests fail when ReceiveReceiptWorker runs with a delay so make no delay for unit tests - a few unit tests related to sending receive receipts were failing due to "Main looper has queued unexecuted runnables. This might be the cause of the test failure." even after awaiting a long time (flaky pass/fail) - removed test `testNotificationReceivedNoSendReceivedRequest_Delay` because no longer testing the delay in unit tests and other receive receipt tests are sufficient --- .../java/com/onesignal/ShadowOSUtils.java | 9 ++++- .../onesignal/MainOneSignalClassRunner.java | 34 ------------------- 2 files changed, 8 insertions(+), 35 deletions(-) diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowOSUtils.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowOSUtils.java index add1acca1a..cc2b64d69d 100644 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowOSUtils.java +++ b/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowOSUtils.java @@ -2,6 +2,7 @@ import android.content.Context; +import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @Implements(OSUtils.class) @@ -93,4 +94,10 @@ public String getCarrierName() { int initializationChecker(Context context, String oneSignalAppId) { return subscribableStatus; } -} \ No newline at end of file + + @Implementation + public static int getRandomDelay(int minDelay, int maxDelay) { + // unit tests fail when ReceiveReceiptWorker runs with a delay so make no delay for unit tests + return 0; + } +} diff --git a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java index c69c2fbb15..6fc9fb9787 100644 --- a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java +++ b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java @@ -1226,40 +1226,6 @@ public void testNotificationReceivedNoSendReceivedRequest_WhenNotificationNotDis assertNotEquals("notifications/UUID/report_received", ShadowOneSignalRestClient.lastUrl); } - @Test - @Config(shadows = { ShadowGenerateNotification.class }) - public void testNotificationReceivedNoSendReceivedRequest_Delay() throws Exception { - int delay = 2; - MockDelayTaskController mockDelayTaskController = new MockDelayTaskController(new MockOSLog()); - mockDelayTaskController.setMockedRandomValue(delay); - mockDelayTaskController.setRunOnSameThread(false); - OneSignal_setDelayTaskController(mockDelayTaskController); - - ShadowOneSignalRestClient.setRemoteParamsReceiveReceiptsEnable(true); - // First init run for appId to be saved - // At least OneSignal was init once for user to be subscribed - // If this doesn't' happen, notifications will not arrive - OneSignal.setAppId(ONESIGNAL_APP_ID); - OneSignal.initWithContext(blankActivity); - threadAndTaskWait(); - - long calledTime = System.currentTimeMillis(); - - // 1. Receive a notification in background - FCMBroadcastReceiver_processBundle(blankActivity, getBaseNotifBundle()); - threadAndTaskWait(); - - // 2. Check that report_received where sent - Awaitility.await() - .atMost(new Duration(3, TimeUnit.SECONDS)) - .pollInterval(new Duration(1, TimeUnit.SECONDS)) - .untilAsserted(() -> { - assertEquals(3, ShadowOneSignalRestClient.requests.size()); - assertEquals("notifications/UUID/report_received", ShadowOneSignalRestClient.lastUrl); - assertTrue(System.currentTimeMillis() - calledTime >= delay * 1000); - }); - } - /** * @see #testNotificationReceivedNoSendReceivedRequest_WhenNotificationNotDisplayed */ From d80b60bd40ce165091a0c5e02ea232ae2711d01d Mon Sep 17 00:00:00 2001 From: Nan Date: Fri, 12 Nov 2021 17:04:52 -0800 Subject: [PATCH 5/5] Don't have `NetworkType.CONNECTED` constraint for unit tests - unit tests sending receive receipts were failing when the ReceiveReceiptWorker has constraint of `setRequiredNetworkType(NetworkType.CONNECTED)` - they were failing even though a check to `NetworkInfo.isConnected()` returns `true` - so, refactor `buildConstraints` out of the method `beginEnqueueingWork` so it can be shadowed to return no constraints when building the work request for unit tests --- .../com/onesignal/OSReceiveReceiptController.java | 9 ++++++--- .../com/onesignal/ShadowReceiveReceiptController.java | 7 +++++-- .../test/onesignal/GenerateNotificationRunner.java | 3 ++- .../com/test/onesignal/MainOneSignalClassRunner.java | 11 ++++++----- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java index c50e92744a..a4fdbb1df1 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSReceiveReceiptController.java @@ -72,9 +72,7 @@ void beginEnqueueingWork(Context context, String osNotificationId) { .putString(OS_NOTIFICATION_ID, osNotificationId) .build(); - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); + Constraints constraints = buildConstraints(); OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(ReceiveReceiptWorker.class) .setConstraints(constraints) @@ -86,7 +84,12 @@ void beginEnqueueingWork(Context context, String osNotificationId) { WorkManager.getInstance(context) .enqueueUniqueWork(osNotificationId + "_receive_receipt", ExistingWorkPolicy.KEEP, workRequest); + } + Constraints buildConstraints() { + return new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); } public static class ReceiveReceiptWorker extends Worker { diff --git a/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowReceiveReceiptController.java b/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowReceiveReceiptController.java index 11b3fbbc72..edbde2bb1b 100644 --- a/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowReceiveReceiptController.java +++ b/OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowReceiveReceiptController.java @@ -1,13 +1,16 @@ package com.onesignal; +import androidx.work.Constraints; + import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @Implements(OSReceiveReceiptController.class) public class ShadowReceiveReceiptController { + // Removes the constraint `setRequiredNetworkType(NetworkType.CONNECTED)` which was causing unit tests to fail @Implementation - public boolean isReceiveReceiptEnabled() { - return true; + public Constraints buildConstraints() { + return Constraints.NONE; } } diff --git a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/GenerateNotificationRunner.java b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/GenerateNotificationRunner.java index 06fc897c93..6657dbd2bc 100644 --- a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/GenerateNotificationRunner.java +++ b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/GenerateNotificationRunner.java @@ -109,6 +109,7 @@ import com.onesignal.ShadowOSWebView; import com.onesignal.ShadowOneSignal; import com.onesignal.ShadowOneSignalRestClient; +import com.onesignal.ShadowReceiveReceiptController; import com.onesignal.ShadowResources; import com.onesignal.ShadowRoboNotificationManager; import com.onesignal.ShadowRoboNotificationManager.PostedNotification; @@ -1360,7 +1361,7 @@ public void shouldShowInAppPreviewWhenOpeningPreviewNotification() throws Except } @Test - @Config(shadows = { ShadowGenerateNotification.class }) + @Config(shadows = { ShadowGenerateNotification.class, ShadowReceiveReceiptController.class }) public void shouldSendReceivedReceiptWhenEnabled() throws Exception { ShadowOneSignalRestClient.setRemoteParamsReceiveReceiptsEnable(true); diff --git a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java index 6fc9fb9787..d75aecda49 100644 --- a/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java +++ b/OneSignalSDK/unittest/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java @@ -86,6 +86,7 @@ import com.onesignal.ShadowOneSignalRestClient; import com.onesignal.ShadowPushRegistratorADM; import com.onesignal.ShadowPushRegistratorFCM; +import com.onesignal.ShadowReceiveReceiptController; import com.onesignal.ShadowRoboNotificationManager; import com.onesignal.StaticResetHelper; import com.onesignal.SyncJobService; @@ -1109,7 +1110,7 @@ public void onBundleProcessed(OneSignalPackagePrivateHelper.ProcessedBundleResul // Start Received Request tests (report_received) @Test - @Config(shadows = { ShadowGenerateNotification.class }) + @Config(shadows = { ShadowGenerateNotification.class, ShadowReceiveReceiptController.class }) public void testNotificationReceivedSendReceivedRequest_WhenAppInBackground() throws Exception { // First init run for appId to be saved // At least OneSignal was init once for user to be subscribed @@ -1132,7 +1133,7 @@ public void testNotificationReceivedSendReceivedRequest_WhenAppInBackground() th } @Test - @Config(shadows = { ShadowGenerateNotification.class }) + @Config(shadows = { ShadowGenerateNotification.class, ShadowReceiveReceiptController.class }) public void testNotificationReceivedSendReceivedRequest_WhenAppInForeground() throws Exception { ShadowOneSignalRestClient.setRemoteParamsReceiveReceiptsEnable(true); // First init run for appId to be saved @@ -1152,7 +1153,7 @@ public void testNotificationReceivedSendReceivedRequest_WhenAppInForeground() th } @Test - @Config(shadows = { ShadowGenerateNotification.class }) + @Config(shadows = { ShadowGenerateNotification.class, ShadowReceiveReceiptController.class }) public void testNotificationReceivedNoSendReceivedRequest_WhenDisabled() throws Exception { ShadowOneSignalRestClient.setRemoteParamsReceiveReceiptsEnable(false); // First init run for appId to be saved @@ -1172,7 +1173,7 @@ public void testNotificationReceivedNoSendReceivedRequest_WhenDisabled() throws } @Test - @Config(shadows = { ShadowGenerateNotification.class }) + @Config(shadows = { ShadowGenerateNotification.class, ShadowReceiveReceiptController.class }) public void testNotificationReceivedNoSendReceivedRequest_WhenNotificationNotDisplayed() throws Exception { // 1. Setup correct notification extension service class startRemoteNotificationReceivedHandlerService("com.test.onesignal.MainOneSignalClassRunner$" + @@ -1199,7 +1200,7 @@ public void testNotificationReceivedNoSendReceivedRequest_WhenNotificationNotDis } @Test - @Config(sdk = 26, shadows = { ShadowGenerateNotification.class, ShadowOneSignalNotificationManager.class }) + @Config(sdk = 26, shadows = { ShadowGenerateNotification.class, ShadowOneSignalNotificationManager.class, ShadowReceiveReceiptController.class }) public void testNotificationReceivedNoSendReceivedRequest_WhenNotificationNotDisplayed_DisabledByChannel() throws Exception { // 1. Setup correct notification extension service class startRemoteNotificationReceivedHandlerService("com.test.onesignal.MainOneSignalClassRunner$" +