Skip to content

Commit 96fb6c4

Browse files
committed
[User Model] Session Manager
* Move outcome calls over to new ISessionManager (OneSignal.session) * Add OneSignal.disableGMSMissingPrompt
1 parent 86af18f commit 96fb6c4

File tree

10 files changed

+157
-74
lines changed

10 files changed

+157
-74
lines changed

Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,18 +650,18 @@ private void setupOutcomeLayout() {
650650
public boolean onSuccess(OutcomeEvent outcomeEvent, String name, String value) {
651651
switch (outcomeEvent) {
652652
case OUTCOME:
653-
OneSignal.getUser().sendOutcome(name);
653+
OneSignal.getSession().sendOutcome(name);
654654
break;
655655
case UNIQUE_OUTCOME:
656-
OneSignal.getUser().sendUniqueOutcome(name);
656+
OneSignal.getSession().sendUniqueOutcome(name);
657657
break;
658658
case OUTCOME_WITH_VALUE:
659659
if (value.isEmpty()) {
660660
toaster.makeCustomViewToast("Please enter an outcome value!", ToastType.ERROR);
661661
return false;
662662
}
663663

664-
OneSignal.getUser().sendOutcomeWithValue(name, Float.parseFloat(value));
664+
OneSignal.getSession().sendOutcomeWithValue(name, Float.parseFloat(value));
665665
break;
666666
}
667667

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/Continue.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.onesignal.core
22

3+
import android.os.Build
4+
import androidx.annotation.RequiresApi
35
import kotlinx.coroutines.Dispatchers
46
import java.util.function.Consumer
57
import kotlin.coroutines.Continuation
@@ -57,6 +59,7 @@ object Continue {
5759
* @return The [Continuation] which should be provided to the Kotlin coroutine, and will be executed
5860
* once that coroutine has completed.
5961
*/
62+
@RequiresApi(Build.VERSION_CODES.N)
6063
@JvmOverloads
6164
@JvmStatic
6265
fun <R> with(onFinished: Consumer<ContinueResult<R>>, context: CoroutineContext = Dispatchers.Main): Continuation<R> {

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/IOneSignal.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Context
44
import com.onesignal.core.OneSignal.login
55
import com.onesignal.core.OneSignal.user
66
import com.onesignal.core.debug.IDebugManager
7+
import com.onesignal.core.session.ISessionManager
78
import com.onesignal.core.user.IUserManager
89
import com.onesignal.iam.IIAMManager
910
import com.onesignal.location.ILocationManager
@@ -26,6 +27,11 @@ interface IOneSignal {
2627
*/
2728
val user: IUserManager
2829

30+
/**
31+
* The session manager for accessing session-scoped management.
32+
*/
33+
val session: ISessionManager
34+
2935
/**
3036
* The notification manager for accessing device-scoped
3137
* notification management.
@@ -66,6 +72,11 @@ interface IOneSignal {
6672
*/
6773
var privacyConsent: Boolean
6874

75+
/**
76+
* Whether to disable the "GMS is missing" prompt to the user.
77+
*/
78+
var disableGMSMissingPrompt: Boolean
79+
6980
/**
7081
* Initialize the OneSignal SDK. This should be called during startup of the application.
7182
*

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/OneSignal.kt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Context
44
import com.onesignal.core.debug.IDebugManager
55
import com.onesignal.core.internal.OneSignalImp
66
import com.onesignal.core.internal.service.IServiceProvider
7+
import com.onesignal.core.session.ISessionManager
78
import com.onesignal.core.user.IUserManager
89
import com.onesignal.iam.IIAMManager
910
import com.onesignal.location.ILocationManager
@@ -44,6 +45,14 @@ object OneSignal {
4445
val user: IUserManager
4546
get() = oneSignal.user
4647

48+
/**
49+
* The session manager for accessing session-scoped management. Initialized only after [initWithContext]
50+
* has been called.
51+
*/
52+
@JvmStatic
53+
val session: ISessionManager
54+
get() = oneSignal.session
55+
4756
/**
4857
* The notification manager for accessing device-scoped notification management. Initialized
4958
* only after [initWithContext] has been called.
@@ -98,6 +107,14 @@ object OneSignal {
98107
get() = oneSignal.privacyConsent
99108
set(value) { oneSignal.privacyConsent = value }
100109

110+
/**
111+
* Whether to disable the "GMS is missing" prompt to the user.
112+
*/
113+
@JvmStatic
114+
var disableGMSMissingPrompt: Boolean
115+
get() = oneSignal.disableGMSMissingPrompt
116+
set(value) { oneSignal.disableGMSMissingPrompt = value }
117+
101118
/**
102119
* Initialize the OneSignal SDK. This should be called during startup of the application.
103120
*
@@ -126,13 +143,31 @@ object OneSignal {
126143
* because both Push and IAM are owned by the device.
127144
*
128145
* @param externalId The external ID of the user that is to be logged in.
129-
* @param jwtBearerToken The optional JWT bearer token generated by your backend to establish
130-
* trust for the login operation. Required when identity verification has been enabled. See
131-
* [Identity Verification | OneSignal](https://documentation.onesignal.com/docs/identity-verification)
132146
*/
133147
@JvmStatic
134148
suspend fun login(externalId: String) = oneSignal.login(externalId)
135149

150+
/**
151+
* Login to OneSignal under the user identified by the [externalId] provided. The act of
152+
* logging a user into the OneSignal SDK will switch the [user] context to that specific user.
153+
*
154+
* * If the [externalId] exists the user will be retrieved and the context set from that
155+
* user information. If operations have already been performed under a guest user, they
156+
* *will not* be applied to the now logged in user (they will be lost).
157+
* * If the [externalId] does not exist the user will be created and the context set from
158+
* the current local state. If operations have already been performed under a guest user
159+
* those operations *will* be applied to the newly created user.
160+
*
161+
* *Push Notifications and In App Messaging*
162+
* Logging in a new user will automatically transfer push notification and in app messaging
163+
* subscriptions from the current user (if there is one) to the newly logged in user. This is
164+
* because both Push and IAM are owned by the device.
165+
*
166+
* @param externalId The external ID of the user that is to be logged in.
167+
* @param jwtBearerToken The optional JWT bearer token generated by your backend to establish
168+
* trust for the login operation. Required when identity verification has been enabled. See
169+
* [Identity Verification | OneSignal](https://documentation.onesignal.com/docs/identity-verification)
170+
*/
136171
@JvmStatic
137172
suspend fun login(externalId: String, jwtBearerToken: String? = null) = oneSignal.login(externalId, jwtBearerToken)
138173

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/internal/CoreModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import com.onesignal.core.internal.purchases.TrackAmazonPurchase
5959
import com.onesignal.core.internal.purchases.TrackGooglePurchase
6060
import com.onesignal.core.internal.service.ServiceBuilder
6161
import com.onesignal.core.internal.session.ISessionService
62+
import com.onesignal.core.internal.session.SessionManager
6263
import com.onesignal.core.internal.session.impl.SessionService
6364
import com.onesignal.core.internal.startup.IBootstrapService
6465
import com.onesignal.core.internal.startup.IStartableService
@@ -68,6 +69,7 @@ import com.onesignal.core.internal.time.Time
6869
import com.onesignal.core.internal.user.ISubscriptionManager
6970
import com.onesignal.core.internal.user.SubscriptionManager
7071
import com.onesignal.core.internal.user.UserManager
72+
import com.onesignal.core.session.ISessionManager
7173
import com.onesignal.core.user.IUserManager
7274

7375
internal object CoreModule {
@@ -121,6 +123,7 @@ internal object CoreModule {
121123
.provides<IStartableService>()
122124
.provides<IBackgroundService>()
123125
builder.register<SessionListener>().provides<IStartableService>()
126+
builder.register<SessionManager>().provides<ISessionManager>()
124127

125128
// Background
126129
builder.register<BackgroundManager>()

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/internal/OneSignalImp.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.onesignal.core.internal.service.IServiceProvider
2929
import com.onesignal.core.internal.service.ServiceBuilder
3030
import com.onesignal.core.internal.service.ServiceProvider
3131
import com.onesignal.core.internal.startup.StartupService
32+
import com.onesignal.core.session.ISessionManager
3233
import com.onesignal.core.user.IUserManager
3334
import com.onesignal.iam.IIAMManager
3435
import com.onesignal.iam.internal.IAMModule
@@ -55,7 +56,15 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
5556
_configModel?.givenPrivacyConsent = value
5657
}
5758

59+
override var disableGMSMissingPrompt: Boolean
60+
get() = _configModel?.disableGMSMissingPrompt ?: (_disableGMSMissingPrompt == true)
61+
set(value) {
62+
_disableGMSMissingPrompt = value
63+
_configModel?.disableGMSMissingPrompt = value
64+
}
65+
5866
override val debug: IDebugManager = DebugManager()
67+
override val session: ISessionManager get() = if (isInitialized) _session!! else throw Exception("Must call 'initWithContext' before use")
5968
override val notifications: INotificationsManager get() = if (isInitialized) _notifications!! else throw Exception("Must call 'initWithContext' before use")
6069
override val location: ILocationManager get() = if (isInitialized) _location!! else throw Exception("Must call 'initWithContext' before use")
6170
override val iam: IIAMManager get() = if (isInitialized) _iam!! else throw Exception("Must call 'initWithContext' before use")
@@ -82,6 +91,7 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
8291
// Services required by this class
8392
private var _user: IUserManager? = null
8493
private var _hasCreatedBackendUser: Boolean = false
94+
private var _session: ISessionManager? = null
8595
private var _iam: IIAMManager? = null
8696
private var _location: ILocationManager? = null
8797
private var _notifications: INotificationsManager? = null
@@ -97,6 +107,7 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
97107
private var _sessionModel: SessionModel? = null
98108
private var _requiresPrivacyConsent: Boolean? = null
99109
private var _givenPrivacyConsent: Boolean? = null
110+
private var _disableGMSMissingPrompt: Boolean? = null
100111

101112
init {
102113
var serviceBuilder = ServiceBuilder()
@@ -141,9 +152,14 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
141152
_configModel!!.givenPrivacyConsent = _givenPrivacyConsent!!
142153
}
143154

155+
if (_disableGMSMissingPrompt != null) {
156+
_configModel!!.disableGMSMissingPrompt = _disableGMSMissingPrompt!!
157+
}
158+
144159
// "Inject" the services required by this main class
145160
_location = _services.getService()
146161
_user = _services.getService()
162+
_session = _services.getService()
147163
_iam = _services.getService()
148164
_notifications = _services.getService()
149165
_operationRepo = _services.getService()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.onesignal.core.internal.session
2+
3+
import com.onesignal.core.debug.LogLevel
4+
import com.onesignal.core.internal.common.suspendifyOnThread
5+
import com.onesignal.core.internal.logging.Logging
6+
import com.onesignal.core.internal.outcomes.IOutcomeEventsController
7+
import com.onesignal.core.session.ISessionManager
8+
9+
internal open class SessionManager(
10+
private val _outcomeController: IOutcomeEventsController
11+
) : ISessionManager {
12+
13+
override fun sendOutcome(name: String): ISessionManager {
14+
Logging.log(LogLevel.DEBUG, "sendOutcome(name: $name)")
15+
16+
suspendifyOnThread {
17+
_outcomeController.sendOutcomeEvent(name)
18+
}
19+
20+
return this
21+
}
22+
23+
override fun sendUniqueOutcome(name: String): ISessionManager {
24+
Logging.log(LogLevel.DEBUG, "sendUniqueOutcome(name: $name)")
25+
26+
suspendifyOnThread {
27+
_outcomeController.sendUniqueOutcomeEvent(name)
28+
}
29+
30+
return this
31+
}
32+
33+
override fun sendOutcomeWithValue(name: String, value: Float): ISessionManager {
34+
Logging.log(LogLevel.DEBUG, "sendOutcomeWithValue(name: $name, value: $value)")
35+
36+
suspendifyOnThread {
37+
_outcomeController.sendOutcomeEventWithValue(name, value)
38+
}
39+
40+
return this
41+
}
42+
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/core/internal/user/UserManager.kt

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.onesignal.core.internal.user
22

33
import com.onesignal.core.debug.LogLevel
44
import com.onesignal.core.internal.backend.IdentityConstants
5-
import com.onesignal.core.internal.common.suspendifyOnThread
65
import com.onesignal.core.internal.language.ILanguageContext
76
import com.onesignal.core.internal.logging.Logging
87
import com.onesignal.core.internal.models.IdentityModel
@@ -11,7 +10,6 @@ import com.onesignal.core.internal.models.PropertiesModel
1110
import com.onesignal.core.internal.models.PropertiesModelStore
1211
import com.onesignal.core.internal.models.TriggerModel
1312
import com.onesignal.core.internal.models.TriggerModelStore
14-
import com.onesignal.core.internal.outcomes.IOutcomeEventsController
1513
import com.onesignal.core.user.IUserManager
1614
import com.onesignal.core.user.subscriptions.SubscriptionList
1715

@@ -20,8 +18,7 @@ internal open class UserManager(
2018
private val _identityModelStore: IdentityModelStore,
2119
private val _propertiesModelStore: PropertiesModelStore,
2220
private val _triggerModelStore: TriggerModelStore,
23-
private val _languageContext: ILanguageContext,
24-
private val _outcomeController: IOutcomeEventsController
21+
private val _languageContext: ILanguageContext
2522
) : IUserManager {
2623

2724
override val externalId: String?
@@ -184,34 +181,4 @@ internal open class UserManager(
184181
_triggerModelStore.clear()
185182
return this
186183
}
187-
188-
override fun sendOutcome(name: String): IUserManager {
189-
Logging.log(LogLevel.DEBUG, "sendOutcome(name: $name)")
190-
191-
suspendifyOnThread {
192-
_outcomeController.sendOutcomeEvent(name)
193-
}
194-
195-
return this
196-
}
197-
198-
override fun sendUniqueOutcome(name: String): IUserManager {
199-
Logging.log(LogLevel.DEBUG, "sendUniqueOutcome(name: $name)")
200-
201-
suspendifyOnThread {
202-
_outcomeController.sendUniqueOutcomeEvent(name)
203-
}
204-
205-
return this
206-
}
207-
208-
override fun sendOutcomeWithValue(name: String, value: Float): IUserManager {
209-
Logging.log(LogLevel.DEBUG, "sendOutcomeWithValue(name: $name, value: $value)")
210-
211-
suspendifyOnThread {
212-
_outcomeController.sendOutcomeEventWithValue(name, value)
213-
}
214-
215-
return this
216-
}
217184
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.onesignal.core.session
2+
3+
/**
4+
* The OneSignal session manager is responsible for managing the current session state.
5+
*/
6+
interface ISessionManager {
7+
/**
8+
* Send an outcome with the provided name, captured against the current session.
9+
* See [Outcomes | OneSignal] (https://documentation.onesignal.com/docs/outcomes)
10+
*
11+
* @param name The name of the outcome that has occurred.
12+
*
13+
* @return this user manager to allow for chaining of calls.
14+
*/
15+
fun sendOutcome(name: String): ISessionManager
16+
17+
/**
18+
* Send a unique outcome with the provided name, captured against the current session.
19+
* See [Outcomes | OneSignal] (https://documentation.onesignal.com/docs/outcomes)
20+
*
21+
* @param name The name of the unique outcome that has occurred.
22+
*
23+
* @return this user manager to allow for chaining of calls.
24+
*/
25+
fun sendUniqueOutcome(name: String): ISessionManager
26+
27+
/**
28+
* Send an outcome with the provided name and value, captured against the current session.
29+
* See [Outcomes | OneSignal] (https://documentation.onesignal.com/docs/outcomes)
30+
*
31+
* @param name The name of the outcome that has occurred.
32+
* @param value The value tied to the outcome.
33+
*
34+
* @return this user manager to allow for chaining of calls.
35+
*/
36+
fun sendOutcomeWithValue(name: String, value: Float): ISessionManager
37+
}

0 commit comments

Comments
 (0)