From 148c1a30c1e7b45542e79672cbd6b37969cfd9e1 Mon Sep 17 00:00:00 2001 From: jinliu9508 <jinliu9508@gmail.com> Date: Tue, 14 Nov 2023 02:25:31 -0500 Subject: [PATCH] Add UserStateObserver following the structure of pushSubscriptionObserver Assumption: 1. we want to store the change notifier in UserManager Still Need: 1 implementation on where user state is updated 2 better comments in some places 3. testing units --- .../java/com/onesignal/user/IUserManager.kt | 12 +++++++++ .../onesignal/user/internal/UserManager.kt | 8 ++++++ .../user/internal/state/IUserStateObserver.kt | 16 +++++++++++ .../user/internal/state/UserChangedState.kt | 16 +++++++++++ .../user/internal/state/UserState.kt | 27 +++++++++++++++++++ .../notifications/consumer-rules.pro | 4 +++ 6 files changed, 83 insertions(+) create mode 100644 OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/IUserStateObserver.kt create mode 100644 OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserChangedState.kt create mode 100644 OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserState.kt diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/IUserManager.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/IUserManager.kt index e9de656d0d..1f783f9771 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/IUserManager.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/IUserManager.kt @@ -1,6 +1,7 @@ package com.onesignal.user import com.onesignal.OneSignal +import com.onesignal.user.internal.state.IUserStateObserver import com.onesignal.user.subscriptions.IPushSubscription /** @@ -133,4 +134,15 @@ interface IUserManager { * @param keys The collection of keys, all of which will be removed from the current user. */ fun removeTags(keys: Collection<String>) + + /** + * Add an observer to the user state, allowing the provider to be + * notified whenever the user state has changed. + */ + fun addObserver(observer: IUserStateObserver) + + /** + * Remove an observer from the user state. + */ + fun removeObserver(observer: IUserStateObserver) } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/UserManager.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/UserManager.kt index dbb8add277..71f849ebc0 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/UserManager.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/UserManager.kt @@ -1,6 +1,7 @@ package com.onesignal.user.internal import com.onesignal.common.OneSignalUtils +import com.onesignal.common.events.EventProducer import com.onesignal.core.internal.language.ILanguageContext import com.onesignal.debug.LogLevel import com.onesignal.debug.internal.logging.Logging @@ -10,6 +11,7 @@ import com.onesignal.user.internal.identity.IdentityModel import com.onesignal.user.internal.identity.IdentityModelStore import com.onesignal.user.internal.properties.PropertiesModel import com.onesignal.user.internal.properties.PropertiesModelStore +import com.onesignal.user.internal.state.IUserStateObserver import com.onesignal.user.internal.subscriptions.ISubscriptionManager import com.onesignal.user.internal.subscriptions.SubscriptionList import com.onesignal.user.subscriptions.IPushSubscription @@ -32,6 +34,8 @@ internal open class UserManager( val subscriptions: SubscriptionList get() = _subscriptionManager.subscriptions + val changeHandlersNotifier = EventProducer<IUserStateObserver>() + override val pushSubscription: IPushSubscription get() = _subscriptionManager.subscriptions.push @@ -218,4 +222,8 @@ internal open class UserManager( _propertiesModel.tags.remove(it) } } + + override fun addObserver(observer: IUserStateObserver) = changeHandlersNotifier.subscribe(observer) + + override fun removeObserver(observer: IUserStateObserver) = changeHandlersNotifier.unsubscribe(observer) } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/IUserStateObserver.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/IUserStateObserver.kt new file mode 100644 index 0000000000..5cc77c33ba --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/IUserStateObserver.kt @@ -0,0 +1,16 @@ +package com.onesignal.user.internal.state + + +/** + * A user state changed handler. Implement this interface and provide the implementation + * to be notified when the user has changed. + */ +interface IUserStateObserver { + /** + * Called when the user state this change handler was added to, has changed. A + * user state can change when user has logged in or out + * + * @param state The user changed state. + */ + fun onUserStateChange(state: UserChangedState) +} \ No newline at end of file diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserChangedState.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserChangedState.kt new file mode 100644 index 0000000000..0a6db62a78 --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserChangedState.kt @@ -0,0 +1,16 @@ +package com.onesignal.user.internal.state + +import org.json.JSONObject + +class UserChangedState( + val previous: UserState, + val current: UserState, + val switchedUsers: Boolean, +) { + fun toJSONObject(): JSONObject { + return JSONObject() + .put("previous", previous.toJSONObject()) + .put("current", current.toJSONObject()) + .put("switchedUsers", switchedUsers) + } +} \ No newline at end of file diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserState.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserState.kt new file mode 100644 index 0000000000..57567ebcc5 --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/state/UserState.kt @@ -0,0 +1,27 @@ +package com.onesignal.user.internal.state + +import org.json.JSONObject + +/** + * A user state. + */ +class UserState ( + /** + * The unique identifier for OneSignal account. This will be an empty string + * until the user has been successfully logged in on the backend and + * assigned an ID. Use [addObserver] to be notified when the [onesignalId] has + * been successfully assigned. + */ + val onesignalId: String?, + + /** + * ????? What should be a good comment here ????? + */ + val externalId: String?, +) { + fun toJSONObject(): JSONObject { + return JSONObject() + .put("onesignalId", onesignalId) + .put("externalId", externalId) + } +} \ No newline at end of file diff --git a/OneSignalSDK/onesignal/notifications/consumer-rules.pro b/OneSignalSDK/onesignal/notifications/consumer-rules.pro index d9fc948356..fa6eae266f 100644 --- a/OneSignalSDK/onesignal/notifications/consumer-rules.pro +++ b/OneSignalSDK/onesignal/notifications/consumer-rules.pro @@ -20,6 +20,10 @@ void onPushSubscriptionChange(com.onesignal.user.subscriptions.PushSubscriptionChangedState); } +-keep class ** implements com.onesignal.user.internal.state.IUserStateObserver { + void onUserChange(com.onesignal.user.internal.state.UserChangedState); +} + -keep class ** implements com.onesignal.notifications.INotificationServiceExtension{ void onNotificationReceived(com.onesignal.notifications.INotificationReceivedEvent); }