Skip to content

Commit c1fdf95

Browse files
authored
ADFA-4322: Paper-cut: Guide users to enable Display over other apps when blocked by Android restricted settings during onboarding (#1391)
1 parent eabb240 commit c1fdf95

3 files changed

Lines changed: 73 additions & 6 deletions

File tree

‎app/src/main/java/com/itsaky/androidide/fragments/onboarding/PermissionsFragment.kt‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.core.net.toUri
3232
import androidx.fragment.app.viewModels
3333
import androidx.lifecycle.Lifecycle
3434
import androidx.lifecycle.repeatOnLifecycle
35+
import androidx.lifecycle.withResumed
3536
import androidx.recyclerview.widget.RecyclerView
3637
import com.github.appintro.SlidePolicy
3738
import com.github.appintro.SlideSelectionListener
@@ -45,6 +46,7 @@ import com.itsaky.androidide.databinding.LayoutOnboardingPermissionsBinding
4546
import com.itsaky.androidide.events.InstallationEvent
4647
import com.itsaky.androidide.preferences.internal.prefManager
4748
import com.itsaky.androidide.tasks.doAsyncWithProgress
49+
import com.itsaky.androidide.utils.OverlayPermissionGuide
4850
import com.itsaky.androidide.utils.PermissionsHelper
4951
import com.itsaky.androidide.utils.flashError
5052
import com.itsaky.androidide.utils.isTestMode
@@ -73,7 +75,6 @@ class PermissionsFragment :
7375
private var recyclerView: RecyclerView? = null
7476
private var finishButton: MaterialButton? = null
7577
private lateinit var pulseAnimation: Animation
76-
private var awaitingOverlayGrantResult = false
7778

7879
private val storagePermissionRequestLauncher =
7980
registerForActivityResult(
@@ -97,6 +98,8 @@ class PermissionsFragment :
9798
private val logger = LoggerFactory.getLogger(PermissionsFragment::class.java)
9899
private const val KEY_PRIVACY_DISCLOSURE_SHOWN = "privacy.disclosure.shown"
99100

101+
private var awaitingOverlayGrantResult = false
102+
100103
@JvmStatic
101104
fun newInstance(context: Context): PermissionsFragment =
102105
PermissionsFragment().apply {
@@ -231,12 +234,13 @@ class PermissionsFragment :
231234
}
232235
awaitingOverlayGrantResult = false
233236

234-
if (PermissionsHelper.canDrawOverlays(requireContext())) {
235-
return
237+
viewLifecycleScope.launch {
238+
viewLifecycleOwner.withResumed {
239+
if (!PermissionsHelper.canDrawOverlays(requireContext())) {
240+
OverlayPermissionGuide.showRestrictedSettingsDialog(requireContext())
241+
}
242+
}
236243
}
237-
238-
flashError(getString(R.string.permission_overlay_restricted_settings_hint))
239-
requestSettingsTogglePermission(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
240244
}
241245

242246
private fun startIdeSetup() {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.itsaky.androidide.utils
2+
3+
import android.app.Activity
4+
import android.content.ActivityNotFoundException
5+
import android.content.Context
6+
import android.content.Intent
7+
import android.net.Uri
8+
import android.provider.Settings
9+
import android.text.SpannableStringBuilder
10+
import com.itsaky.androidide.resources.R
11+
import org.slf4j.LoggerFactory
12+
13+
object OverlayPermissionGuide {
14+
15+
private val log = LoggerFactory.getLogger(OverlayPermissionGuide::class.java)
16+
17+
fun showRestrictedSettingsDialog(context: Context) {
18+
val message = SpannableStringBuilder()
19+
message.append(context.getString(R.string.permission_overlay_restricted_dialog_message))
20+
message.append("\n\n")
21+
message.appendOrderedList(*context.resources.getStringArray(R.array.overlay_restricted_settings_steps))
22+
23+
DialogUtils
24+
.newMaterialDialogBuilder(context)
25+
.setTitle(R.string.permission_overlay_restricted_dialog_title)
26+
.setMessage(message)
27+
.setPositiveButton(R.string.permission_overlay_open_app_info) { dialog, _ ->
28+
dialog.dismiss()
29+
openAppInfo(context)
30+
}
31+
.setNegativeButton(android.R.string.cancel, null)
32+
.show()
33+
}
34+
35+
private fun openAppInfo(context: Context) {
36+
val intent = Intent(
37+
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
38+
Uri.fromParts("package", context.packageName, null),
39+
)
40+
if (context !is Activity) {
41+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
42+
}
43+
try {
44+
context.startActivity(intent)
45+
} catch (e: ActivityNotFoundException) {
46+
log.error("Failed to open App info settings", e)
47+
flashError(
48+
context.getString(
49+
R.string.err_no_activity_to_handle_action,
50+
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
51+
),
52+
)
53+
}
54+
}
55+
}

‎resources/src/main/res/values/strings.xml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,9 @@
722722
<string name="permission_desc_overlay_window">Allow Code on the Go to display floating debugger controls to inspect your code while it runs.</string>
723723
<string name="permission_overlay_unsupported_hint">Floating debugger is not available on this device.</string>
724724
<string name="permission_overlay_restricted_settings_hint">If you can\'t enable this permission, display App info for Code on the Go, tap the three-dot menu, and enable restricted settings.</string>
725+
<string name="permission_overlay_restricted_dialog_title">Enable restricted settings</string>
726+
<string name="permission_overlay_restricted_dialog_message">Android turned off the “Display over other apps” switch because Code on the Go was installed from outside an app store. To turn it on:</string>
727+
<string name="permission_overlay_open_app_info">Open App info</string>
725728
<string name="permission_title_notifications">Notifications</string>
726729
<string name="permission_desc_notifications">Allow Code on the Go to display notifications.</string>
727730
<string name="permission_title_accessibility">Accessibility</string>
@@ -1136,6 +1139,11 @@
11361139
To use the debugger, you must enable developer options. When you’re ready to pair with the debugger:]]></string>
11371140

11381141
<!-- Steps shown to the user in an ordered list in the ADB pairing dialog -->
1142+
<string-array name="overlay_restricted_settings_steps">
1143+
<item><![CDATA[On the <b>App info</b> screen, tap the three-dot menu (⋮) in the top corner.]]></item>
1144+
<item><![CDATA[Tap <b>Allow restricted settings</b>.]]></item>
1145+
<item><![CDATA[Open <b>Display over other apps</b> and turn it on for Code on the Go.]]></item>
1146+
</string-array>
11391147
<string-array name="debugger_setup_pairing_steps">
11401148
<item><![CDATA[Tap <b>Start pairing</b>. Developer options are displayed.]]></item>
11411149
<item><![CDATA[Enable <b>Wireless debugging</b>.]]></item>

0 commit comments

Comments
 (0)