Skip to content

Commit 20806c4

Browse files
committed
Refactor for background thread to work with manager instance
1 parent e59d578 commit 20806c4

File tree

4 files changed

+52
-55
lines changed

4 files changed

+52
-55
lines changed

com.unity.mobile.notifications/Runtime/Android/Plugins/com/unity/androidnotifications/UnityNotificationBackgroundThread.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import static com.unity.androidnotifications.UnityNotificationManager.TAG_UNITY;
55

66
import android.app.Notification;
7-
import android.content.Context;
87
import android.util.Log;
98

109
import java.util.concurrent.ConcurrentHashMap;
@@ -17,7 +16,7 @@
1716
public class UnityNotificationBackgroundThread extends Thread {
1817
private static abstract class Task {
1918
// returns true if notificationIds was modified (needs to be saved)
20-
public abstract boolean run(Context context, ConcurrentHashMap<Integer, Notification.Builder> notifications);
19+
public abstract boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications);
2120
}
2221

2322
private static class ScheduleNotificationTask extends Task {
@@ -32,7 +31,7 @@ public ScheduleNotificationTask(int id, Notification.Builder builder, boolean ad
3231
}
3332

3433
@Override
35-
public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
34+
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
3635
String id = String.valueOf(notificationId);
3736
Integer ID = Integer.valueOf(notificationId);
3837
boolean didSchedule = false;
@@ -43,8 +42,8 @@ public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Buil
4342
// if failed to schedule or replace, remove
4443
if (!didSchedule) {
4544
notifications.remove(notificationId);
46-
UnityNotificationManager.cancelPendingNotificationIntent(context, notificationId);
47-
UnityNotificationManager.deleteExpiredNotificationIntent(context, id);
45+
manager.cancelPendingNotificationIntent(notificationId);
46+
manager.deleteExpiredNotificationIntent(id);
4847
}
4948
}
5049

@@ -60,10 +59,10 @@ public CancelNotificationTask(int id) {
6059
}
6160

6261
@Override
63-
public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
64-
UnityNotificationManager.cancelPendingNotificationIntent(context, notificationId);
62+
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
63+
manager.cancelPendingNotificationIntent(notificationId);
6564
if (notifications.remove(notificationId) != null) {
66-
UnityNotificationManager.deleteExpiredNotificationIntent(context, String.valueOf(notificationId));
65+
manager.deleteExpiredNotificationIntent(String.valueOf(notificationId));
6766
return true;
6867
}
6968

@@ -73,15 +72,15 @@ public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Buil
7372

7473
private static class CancelAllNotificationsTask extends Task {
7574
@Override
76-
public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
75+
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
7776
if (notifications.isEmpty())
7877
return false;
7978

8079
Enumeration<Integer> ids = notifications.keys();
8180
while (ids.hasMoreElements()) {
8281
Integer notificationId = ids.nextElement();
83-
UnityNotificationManager.cancelPendingNotificationIntent(context, notificationId);
84-
UnityNotificationManager.deleteExpiredNotificationIntent(context, String.valueOf(notificationId));
82+
manager.cancelPendingNotificationIntent(notificationId);
83+
manager.deleteExpiredNotificationIntent(String.valueOf(notificationId));
8584
}
8685

8786
notifications.clear();
@@ -97,25 +96,25 @@ public HousekeepingTask(UnityNotificationBackgroundThread th) {
9796
}
9897

9998
@Override
100-
public boolean run(Context context, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
99+
public boolean run(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
101100
HashSet<String> notificationIds = new HashSet<>();
102101
Enumeration<Integer> ids = notifications.keys();
103102
while (ids.hasMoreElements()) {
104103
notificationIds.add(String.valueOf(ids.nextElement()));
105104
}
106-
thread.performHousekeeping(context, notificationIds);
105+
thread.performHousekeeping(notificationIds);
107106
return false;
108107
}
109108
}
110109

111110
private static final int TASKS_FOR_HOUSEKEEPING = 50;
112111
private LinkedTransferQueue<Task> mTasks = new LinkedTransferQueue();
113112
private ConcurrentHashMap<Integer, Notification.Builder> mScheduledNotifications;
114-
private static Context mContext;
113+
private UnityNotificationManager mManager;
115114
private int mTasksSinceHousekeeping = TASKS_FOR_HOUSEKEEPING; // we want hoursekeeping at the start
116115

117-
public UnityNotificationBackgroundThread(Context context, ConcurrentHashMap<Integer, Notification.Builder> scheduledNotifications) {
118-
mContext = context;
116+
public UnityNotificationBackgroundThread(UnityNotificationManager manager, ConcurrentHashMap<Integer, Notification.Builder> scheduledNotifications) {
117+
mManager = manager;
119118
mScheduledNotifications = scheduledNotifications;
120119
// rescheduling after reboot may have loaded, otherwise load here
121120
if (mScheduledNotifications.size() == 0)
@@ -144,7 +143,7 @@ public void run() {
144143
while (true) {
145144
try {
146145
Task task = mTasks.take();
147-
haveChanges |= executeTask(mContext, task, mScheduledNotifications);
146+
haveChanges |= executeTask(mManager, task, mScheduledNotifications);
148147
if (!(task instanceof HousekeepingTask))
149148
++mTasksSinceHousekeeping;
150149
if (mTasks.size() == 0 && haveChanges) {
@@ -158,26 +157,26 @@ public void run() {
158157
}
159158
}
160159

161-
private boolean executeTask(Context context, Task task, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
160+
private boolean executeTask(UnityNotificationManager manager, Task task, ConcurrentHashMap<Integer, Notification.Builder> notifications) {
162161
try {
163-
return task.run(context, notifications);
162+
return task.run(manager, notifications);
164163
} catch (Exception e) {
165164
Log.e(TAG_UNITY, "Exception executing notification task", e);
166165
return false;
167166
}
168167
}
169168

170-
private void performHousekeeping(Context context, Set<String> notificationIds) {
169+
private void performHousekeeping(Set<String> notificationIds) {
171170
// don't do housekeeping if last task we did was housekeeping (other=1)
172171
boolean performHousekeeping = mTasksSinceHousekeeping >= TASKS_FOR_HOUSEKEEPING;
173172
mTasksSinceHousekeeping = 0;
174173
if (performHousekeeping)
175-
UnityNotificationManager.performNotificationHousekeeping(context, notificationIds);
176-
UnityNotificationManager.saveScheduledNotificationIDs(context, notificationIds);
174+
mManager.performNotificationHousekeeping(notificationIds);
175+
mManager.saveScheduledNotificationIDs(notificationIds);
177176
}
178177

179178
private void loadNotifications() {
180-
List<Notification.Builder> notifications = UnityNotificationManager.loadSavedNotifications(mContext);
179+
List<Notification.Builder> notifications = mManager.loadSavedNotifications();
181180
for (Notification.Builder builder : notifications) {
182181
int id = builder.getExtras().getInt(KEY_ID, -1);
183182
mScheduledNotifications.put(id, builder);

com.unity.mobile.notifications/Runtime/Android/Plugins/com/unity/androidnotifications/UnityNotificationManager.java

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private void initialize(Activity activity, NotificationCallback notificationCall
7575
mContext = activity.getApplicationContext();
7676
mActivity = activity;
7777
if (mBackgroundThread == null)
78-
mBackgroundThread = new UnityNotificationBackgroundThread(mContext, mScheduledNotifications);
78+
mBackgroundThread = new UnityNotificationBackgroundThread(this, mScheduledNotifications);
7979
if (mRandom == null)
8080
mRandom = new Random();
8181
mNotificationCallback = notificationCallback;
@@ -348,7 +348,7 @@ protected void performNotificationScheduling(int id, Notification.Builder notifi
348348

349349
if (fireNow) {
350350
Notification notification = buildNotificationForSending(mContext, mOpenActivity, notificationBuilder);
351-
notify(mContext, id, notification);
351+
notify(id, notification);
352352
}
353353
}
354354

@@ -413,10 +413,10 @@ protected static Intent buildOpenAppIntent(Context context, Class className) {
413413
return openAppIntent;
414414
}
415415

416-
protected static void performNotificationHousekeeping(Context context, Set<String> ids) {
416+
void performNotificationHousekeeping(Set<String> ids) {
417417
Log.d(TAG_UNITY, "Checking for invalid notification IDs still hanging around");
418418

419-
Set<String> invalid = findInvalidNotificationIds(context, ids);
419+
Set<String> invalid = findInvalidNotificationIds(mContext, ids);
420420
synchronized (UnityNotificationManager.class) {
421421
Set<String> currentIds = new HashSet<>(ids);
422422
for (String id : invalid) {
@@ -427,7 +427,7 @@ protected static void performNotificationHousekeeping(Context context, Set<Strin
427427

428428
// in case we have saved intents, clear them
429429
for (String id : invalid)
430-
deleteExpiredNotificationIntent(context, id);
430+
deleteExpiredNotificationIntent(id);
431431
}
432432

433433
private static Set<String> findInvalidNotificationIds(Context context, Set<String> ids) {
@@ -503,21 +503,21 @@ protected static String getSharedPrefsNameByNotificationId(String id)
503503
}
504504

505505
// Load all the notification intents from SharedPreferences.
506-
protected static synchronized List<Notification.Builder> loadSavedNotifications(Context context) {
507-
Set<String> ids = getScheduledNotificationIDs(context);
506+
synchronized List<Notification.Builder> loadSavedNotifications() {
507+
Set<String> ids = getScheduledNotificationIDs(mContext);
508508

509509
List<Notification.Builder> intent_data_list = new ArrayList();
510510
Set<String> idsMarkedForRemoval = new HashSet<String>();
511511

512512
for (String id : ids) {
513-
SharedPreferences prefs = context.getSharedPreferences(getSharedPrefsNameByNotificationId(id), Context.MODE_PRIVATE);
513+
SharedPreferences prefs = mContext.getSharedPreferences(getSharedPrefsNameByNotificationId(id), Context.MODE_PRIVATE);
514514
Notification.Builder builder = null;
515-
Object notification = UnityNotificationUtilities.deserializeNotification(context, prefs);
515+
Object notification = UnityNotificationUtilities.deserializeNotification(mContext, prefs);
516516
if (notification != null) {
517517
if (notification instanceof Notification.Builder)
518518
builder = (Notification.Builder)notification;
519519
else
520-
builder = UnityNotificationUtilities.recoverBuilder(context, (Notification)notification);
520+
builder = UnityNotificationUtilities.recoverBuilder(mContext, (Notification)notification);
521521
}
522522

523523
if (builder != null)
@@ -530,9 +530,9 @@ protected static synchronized List<Notification.Builder> loadSavedNotifications(
530530
ids = new HashSet<>(ids);
531531
for (String id : idsMarkedForRemoval) {
532532
ids.remove(id);
533-
deleteExpiredNotificationIntent(context, id);
533+
deleteExpiredNotificationIntent(id);
534534
}
535-
saveScheduledNotificationIDs(context, ids);
535+
saveScheduledNotificationIDs(ids);
536536
}
537537

538538
return intent_data_list;
@@ -603,8 +603,8 @@ protected static synchronized Set<String> getScheduledNotificationIDs(Context co
603603
return ids;
604604
}
605605

606-
protected static synchronized void saveScheduledNotificationIDs(Context context, Set<String> ids) {
607-
SharedPreferences.Editor editor = context.getSharedPreferences(NOTIFICATION_IDS_SHARED_PREFS, Context.MODE_PRIVATE).edit().clear();
606+
synchronized void saveScheduledNotificationIDs(Set<String> ids) {
607+
SharedPreferences.Editor editor = mContext.getSharedPreferences(NOTIFICATION_IDS_SHARED_PREFS, Context.MODE_PRIVATE).edit().clear();
608608
editor.putStringSet(NOTIFICATION_IDS_SHARED_PREFS_KEY, ids);
609609
editor.apply();
610610
}
@@ -615,22 +615,20 @@ public void cancelPendingNotification(int id) {
615615
}
616616

617617
// Cancel a pending notification by id.
618-
protected static void cancelPendingNotificationIntent(Context context, int id) {
619-
Intent intent = new Intent(context, UnityNotificationManager.class);
620-
PendingIntent broadcast = getBroadcastPendingIntent(context, id, intent, PendingIntent.FLAG_NO_CREATE);
618+
void cancelPendingNotificationIntent(int id) {
619+
Intent intent = new Intent(mContext, UnityNotificationManager.class);
620+
PendingIntent broadcast = getBroadcastPendingIntent(mContext, id, intent, PendingIntent.FLAG_NO_CREATE);
621621

622622
if (broadcast != null) {
623-
if (context != null) {
624-
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
625-
alarmManager.cancel(broadcast);
626-
}
623+
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
624+
alarmManager.cancel(broadcast);
627625
broadcast.cancel();
628626
}
629627
}
630628

631629
// Delete the notification intent from SharedPreferences by id.
632-
protected static synchronized void deleteExpiredNotificationIntent(Context context, String id) {
633-
SharedPreferences notificationPrefs = context.getSharedPreferences(getSharedPrefsNameByNotificationId(id), Context.MODE_PRIVATE);
630+
synchronized void deleteExpiredNotificationIntent(String id) {
631+
SharedPreferences notificationPrefs = mContext.getSharedPreferences(getSharedPrefsNameByNotificationId(id), Context.MODE_PRIVATE);
634632
notificationPrefs.edit().clear().apply();
635633
}
636634

@@ -688,16 +686,16 @@ public void onReceive(Intent intent) {
688686
}
689687

690688
if (notif != null) {
691-
UnityNotificationManager.notify(mContext, id, notif);
689+
notify(id, notif);
692690
}
693691
}
694692
}
695693

696694
// Call the system notification service to notify the notification.
697-
protected static void notify(Context context, int id, Notification notification) {
695+
private void notify(int id, Notification notification) {
698696
boolean showInForeground = notification.extras.getBoolean(KEY_SHOW_IN_FOREGROUND, true);
699697
if (!isInForeground() || showInForeground) {
700-
getNotificationManager(context).notify(id, notification);
698+
getNotificationManager().notify(id, notification);
701699
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) synchronized (UnityNotificationManager.class) {
702700
mVisibleNotifications.add(Integer.valueOf(id));
703701
}
@@ -706,7 +704,7 @@ protected static void notify(Context context, int id, Notification notification)
706704
long repeatInterval = notification.extras.getLong(KEY_REPEAT_INTERVAL, -1);
707705
if (repeatInterval <= 0) {
708706
mScheduledNotifications.remove(id);
709-
cancelPendingNotificationIntent(context, id);
707+
cancelPendingNotificationIntent(id);
710708
}
711709

712710
try {
@@ -752,7 +750,7 @@ public Notification.Builder createNotificationBuilder(String channelID) {
752750
}
753751

754752
@SuppressWarnings("deprecation")
755-
protected static Notification.Builder createNotificationBuilder(Context context, String channelID) {
753+
static Notification.Builder createNotificationBuilder(Context context, String channelID) {
756754
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
757755
Notification.Builder notificationBuilder = new Notification.Builder(context);
758756

com.unity.mobile.notifications/Runtime/Android/Plugins/com/unity/androidnotifications/UnityNotificationRestartOnBootReceiver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void onReceive(Context context, Intent received_intent) {
2323
}
2424

2525
private static void rescheduleSavedNotifications(Context context) {
26-
List<Notification.Builder> saved_notifications = UnityNotificationManager.loadSavedNotifications(context);
26+
List<Notification.Builder> saved_notifications = UnityNotificationManager.getNotificationManagerImpl(context).loadSavedNotifications();
2727

2828
for (Notification.Builder notificationBuilder : saved_notifications) {
2929
Bundle extras = notificationBuilder.getExtras();

com.unity.mobile.notifications/Tests/Runtime/Android/AndroidNotificationSendingTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,14 @@ public IEnumerator SendNotification_CanReschedule()
346346
int id = AndroidNotificationCenter.SendNotification(n, kDefaultTestChannel);
347347
yield return new WaitForSeconds(0.2f);
348348

349-
// temporary null the manager, cause that's what we have in reality
350349
var manager = managerClass.GetStatic<AndroidJavaObject>("mUnityNotificationManager");
350+
// simulate reboot by directly cancelling scheduled alarms preserving saves
351+
manager.Call("cancelPendingNotificationIntent", id);
352+
// temporary null the manager, cause that's what we have in reality
351353
managerClass.SetStatic<AndroidJavaObject>("mUnityNotificationManager", null);
352354
// also clear cached notifications, since they don't exist after reboot
353355
managerClass.GetStatic<AndroidJavaObject>("mScheduledNotifications").Call("clear");
354356

355-
// simulate reboot by directly cancelling scheduled alarms preserving saves
356-
managerClass.CallStatic("cancelPendingNotificationIntent", context, id);
357357
yield return new WaitForSeconds(0.2f);
358358
// simulate reboot by calling reschedule method, that is called after reboot
359359
rebootClass.CallStatic("rescheduleSavedNotifications", context);

0 commit comments

Comments
 (0)