Skip to content

Commit 3ad1b97

Browse files
authored
Merge pull request #1739 from OneSignal/user-model/permission-fallback-detection
[User Model] Update logic for detecting when to show fallback settings
2 parents 9f7171e + 018a330 commit 3ad1b97

File tree

8 files changed

+68
-10
lines changed

8 files changed

+68
-10
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ import com.onesignal.OneSignal
1010
import com.onesignal.common.AndroidSupportV4Compat
1111
import com.onesignal.core.R
1212
import com.onesignal.core.internal.permissions.impl.RequestPermissionService
13+
import com.onesignal.core.internal.preferences.IPreferencesService
14+
import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys
15+
import com.onesignal.core.internal.preferences.PreferenceStores
1316

1417
class PermissionsActivity : Activity() {
1518
private var _requestPermissionService: RequestPermissionService? = null
19+
private var _preferenceService: IPreferencesService? = null
1620
private var permissionRequestType: String? = null
1721
private var androidPermissionString: String? = null
1822

@@ -21,6 +25,7 @@ class PermissionsActivity : Activity() {
2125
OneSignal.initWithContext(this)
2226

2327
_requestPermissionService = OneSignal.getService()
28+
_preferenceService = OneSignal.getService()
2429

2530
handleBundleParams(intent.extras)
2631
}
@@ -62,8 +67,8 @@ class PermissionsActivity : Activity() {
6267
private fun requestPermission(androidPermissionString: String?) {
6368
if (!_requestPermissionService!!.waiting) {
6469
_requestPermissionService!!.waiting = true
65-
_requestPermissionService!!.neverAskAgainClicked =
66-
!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
70+
_requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest =
71+
AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
6772
this@PermissionsActivity,
6873
androidPermissionString
6974
)
@@ -107,14 +112,34 @@ class PermissionsActivity : Activity() {
107112
}
108113

109114
private fun shouldShowSettings(): Boolean {
110-
return (
111-
_requestPermissionService!!.fallbackToSettings &&
112-
_requestPermissionService!!.neverAskAgainClicked &&
113-
!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
115+
if (!_requestPermissionService!!.fallbackToSettings)
116+
return false;
117+
118+
// We want to show settings after the user has clicked "Don't Allow" 2 times.
119+
// After the first time shouldShowRequestPermissionRationale becomes true, after
120+
// the second time shouldShowRequestPermissionRationale becomes false again. We
121+
// look for the change from `true` -> `false`. When this happens we remember this
122+
// rejection, as the user will never be prompted again.
123+
if (_requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest) {
124+
if (!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
114125
this@PermissionsActivity,
115126
androidPermissionString
116127
)
117-
)
128+
) {
129+
_preferenceService!!.saveBool(
130+
PreferenceStores.ONESIGNAL,
131+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}${androidPermissionString}",
132+
true
133+
)
134+
return false;
135+
}
136+
}
137+
138+
return _preferenceService!!.getBool(
139+
PreferenceStores.ONESIGNAL,
140+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}$androidPermissionString",
141+
false
142+
)!!
118143
}
119144

120145
companion object {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/permissions/impl/RequestPermissionService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import com.onesignal.core.internal.application.IApplicationService
99
import com.onesignal.core.internal.permissions.IRequestPermissionService
1010

1111
internal class RequestPermissionService(
12-
private val _application: IApplicationService
12+
private val _application: IApplicationService,
1313
) : Activity(), IRequestPermissionService {
1414

1515
var waiting = false
1616
var fallbackToSettings = false
17-
var neverAskAgainClicked = false
17+
var shouldShowRequestPermissionRationaleBeforeRequest = false
1818
private val callbackMap = HashMap<String?, IRequestPermissionService.PermissionCallback>()
1919

2020
override fun registerAsCallback(

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/IPreferencesService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ object PreferenceOneSignalKeys {
151151
*/
152152
const val PREFS_OS_LAST_LOCATION_TIME = "OS_LAST_LOCATION_TIME"
153153

154+
// Permissions
155+
/**
156+
* (Boolean) A prefix key for the permission state. When true, the user has rejected this
157+
* permission too many times and will not be prompted again.
158+
*/
159+
const val PREFS_OS_USER_REJECTED_PERMISSION_PREFIX = "USER_REJECTED_PERMISSION_"
160+
154161
// HTTP
155162
/**
156163
* (String) A prefix key for retrieving the ETAG for a given HTTP GET cache key. The cache

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/INotificationsManager.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ interface INotificationsManager {
99
*/
1010
val permission: Boolean
1111

12+
/**
13+
* Whether this app can request push notification permission.
14+
*/
15+
val canRequestPermission: Boolean
16+
1217
/**
1318
* Prompt the user for permission to push notifications. This will display the native
1419
* OS prompt to request push notification permission. If the user enables, a push

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/internal/MisconfiguredNotificationsManager.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import com.onesignal.notifications.IPermissionChangedHandler
1212
internal class MisconfiguredNotificationsManager : INotificationsManager {
1313
override val permission: Boolean
1414
get() = throw EXCEPTION
15+
override val canRequestPermission: Boolean
16+
get() = throw EXCEPTION
1517

1618
override suspend fun requestPermission(fallbackToSettings: Boolean): Boolean = throw EXCEPTION
1719
override fun removeNotification(id: Int) = throw EXCEPTION

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/NotificationsManager.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ internal class NotificationsManager(
4545

4646
override var permission: Boolean = NotificationHelper.areNotificationsEnabled(_applicationService.appContext)
4747

48+
override val canRequestPermission: Boolean
49+
get() = _notificationPermissionController.canRequestPermission
50+
4851
private val _permissionChangedNotifier = EventProducer<IPermissionChangedHandler>()
4952

5053
init {

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/permissions/INotificationPermissionController.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ import com.onesignal.common.events.IEventNotifier
3131

3232
internal interface INotificationPermissionController :
3333
IEventNotifier<INotificationPermissionChangedHandler> {
34+
/**
35+
* Whether this app can request push notification permission.
36+
*/
37+
val canRequestPermission: Boolean
38+
3439
/**
3540
* Prompt the user for notification permission. Note it is possible the application
3641
* will be killed while the permission prompt is being displayed to the user. When the

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/permissions/impl/NotificationPermissionController.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import com.onesignal.core.internal.application.ApplicationLifecycleHandlerBase
3636
import com.onesignal.core.internal.application.IApplicationService
3737
import com.onesignal.core.internal.permissions.AlertDialogPrepromptForAndroidSettings
3838
import com.onesignal.core.internal.permissions.IRequestPermissionService
39+
import com.onesignal.core.internal.preferences.IPreferencesService
40+
import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys
41+
import com.onesignal.core.internal.preferences.PreferenceStores
3942
import com.onesignal.notifications.R
4043
import com.onesignal.notifications.internal.common.NotificationHelper
4144
import com.onesignal.notifications.internal.permissions.INotificationPermissionChangedHandler
@@ -44,13 +47,21 @@ import com.onesignal.notifications.internal.permissions.INotificationPermissionC
4447
internal class NotificationPermissionController(
4548
private val _application: IApplicationService,
4649
private val _requestPermission: IRequestPermissionService,
47-
private val _applicationService: IApplicationService
50+
private val _applicationService: IApplicationService,
51+
private val _preferenceService: IPreferencesService
4852
) : IRequestPermissionService.PermissionCallback,
4953
INotificationPermissionController {
5054

5155
private val _waiter = WaiterWithValue<Boolean>()
5256
private val _events = EventProducer<INotificationPermissionChangedHandler>()
5357

58+
override val canRequestPermission: Boolean
59+
get() = !_preferenceService.getBool(
60+
PreferenceStores.ONESIGNAL,
61+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}${ANDROID_PERMISSION_STRING}",
62+
false
63+
)!!
64+
5465
init {
5566
_requestPermission.registerAsCallback(PERMISSION_TYPE, this)
5667
}

0 commit comments

Comments
 (0)