Loading res/values/strings.xml +0 −3 Original line number Diff line number Diff line Loading @@ -12227,9 +12227,6 @@ Data usage charges may apply.</string> <!-- Help URI, action disabled by restricted settings [DO NOT TRANSLATE] --> <string name="help_url_action_disabled_by_restricted_settings" translatable="false"></string> <!-- Help URI, action disabled by advanced protection [DO NOT TRANSLATE] --> <string name="help_url_action_disabled_by_advanced_protection" translatable="false"></string> <!-- Title label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] --> <string name="zen_suggestion_title">Update Do Not Disturb</string> src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialog.kt +9 −5 Original line number Diff line number Diff line Loading @@ -14,21 +14,23 @@ * limitations under the License. */ package com.android.settings.security; package com.android.settings.security import android.content.Intent import android.content.pm.PackageManager import android.security.advancedprotection.AdvancedProtectionManager import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP import android.content.pm.PackageManager import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN import android.util.Log import android.view.WindowManager import androidx.annotation.VisibleForTesting import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable Loading @@ -38,7 +40,6 @@ import com.android.settingslib.spa.SpaDialogWindowTypeActivity import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogContent import com.android.settingslib.wifi.WifiUtils.Companion.DIALOG_WINDOW_TYPE import android.security.advancedprotection.AdvancedProtectionManager class ActionDisabledByAdvancedProtectionDialog : SpaDialogWindowTypeActivity() { Loading Loading @@ -85,9 +86,12 @@ class ActionDisabledByAdvancedProtectionDialog : SpaDialogWindowTypeActivity() { return getString(messageId) } private fun getSupportButtonIfExists(): AlertDialogButton? { @VisibleForTesting fun getSupportButtonIfExists(): AlertDialogButton? { try { val helpIntentUri = getString(R.string.help_url_action_disabled_by_advanced_protection) val helpIntentUri = getString( com.android.internal.R.string.config_help_url_action_disabled_by_advanced_protection ) val helpIntent = Intent.parseUri(helpIntentUri, Intent.URI_INTENT_SCHEME) if (helpIntent == null) return null val helpActivityInfo = packageManager.resolveActivity(helpIntent, /* flags */ 0) Loading tests/spa_unit/AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,14 @@ <provider android:name="com.android.settings.slices.SettingsSliceProvider" android:authorities="${applicationId}.slices" tools:replace="android:authorities"/> <activity android:name="com.android.settings.security.ActionDisabledByAdvancedProtectionDialogTest$HelpTestActivity" android:exported="true"> <intent-filter> <action android:name="com.android.settings.tests.spa_unit.HELP_ACTION" /> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> <instrumentation Loading tests/spa_unit/src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialogTest.kt +112 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,14 @@ package com.android.settings.security import android.app.Activity import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.content.pm.ResolveInfo import android.os.Bundle import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.CheckFlagsRule import android.platform.test.flag.junit.DeviceFlagsValueProvider Loading @@ -36,9 +41,21 @@ import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @RequiresFlagsEnabled(Flags.FLAG_AAPM_API) @RunWith(AndroidJUnit4::class) Loading @@ -49,7 +66,9 @@ class ActionDisabledByAdvancedProtectionDialogTest { @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() val context: Context = ApplicationProvider.getApplicationContext() private val mockPackageManager = mock<PackageManager>() private val context: Context = ApplicationProvider.getApplicationContext() @Test fun blockedInteractionDialog_showsCorrectTitleAndMessage() { Loading Loading @@ -159,6 +178,85 @@ class ActionDisabledByAdvancedProtectionDialogTest { } } @Test fun helpIntentDoesNotExist_getSupportButtonIfExists_returnsNull() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, /* uriToReturn */ null) val button = spyActivity.getSupportButtonIfExists() assertNull(button) } } } @Test fun helpIntentExistsAndDoesNotResolveToActivity_getSupportButtonIfExists_returnsNull() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, helpIntentUri) mockResolveActivity(spyActivity, /* resolveInfoToReturn */ null) val button = spyActivity.getSupportButtonIfExists() assertNull(button) } } } @Test fun helpIntentExistsAndResolvesToActivity_getSupportButtonIfExists_returnsButton() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, helpIntentUri) val resolveInfoToReturn = ResolveInfo().apply { activityInfo = ActivityInfo().apply { packageName = HELP_INTENT_PKG_NAME } } mockResolveActivity(spyActivity, resolveInfoToReturn) // 1. Check the button is returned. val button = spyActivity.getSupportButtonIfExists() assertNotNull(button) // 2. Check the button has correct text. assertEquals(context.getString( R.string.disabled_by_advanced_protection_help_button_title), button!!.text ) // 3. Check the button's onClick launches the help activity and finishes the dialog. button.onClick() val intentCaptor = ArgumentCaptor.forClass(Intent::class.java) verify(spyActivity).startActivity(intentCaptor.capture()) val launchedIntent = intentCaptor.value assertEquals(HELP_INTENT_ACTION, launchedIntent.action) assertEquals(HELP_INTENT_PKG_NAME, launchedIntent.`package`) assertTrue(spyActivity.isFinishing) } } } private fun spyOnActivityHelpIntentUri( activity: ActionDisabledByAdvancedProtectionDialog, uriToReturn: String? ): ActionDisabledByAdvancedProtectionDialog { val spyActivity = spy(activity) val spyResources = spy(spyActivity.resources) doReturn(spyResources).whenever(spyActivity).resources doReturn(uriToReturn).whenever(spyResources).getString(helpUriResourceId) return spyActivity } private fun mockResolveActivity( spyActivity: ActionDisabledByAdvancedProtectionDialog, resolveInfoToReturn: ResolveInfo? ) { doReturn(mockPackageManager).whenever(spyActivity).packageManager doReturn(resolveInfoToReturn).whenever(mockPackageManager).resolveActivity(any(), anyInt()) } private fun launchDialogActivity( intent: Intent, onScenario: (ActivityScenario<ActionDisabledByAdvancedProtectionDialog>) -> Unit Loading @@ -172,10 +270,23 @@ class ActionDisabledByAdvancedProtectionDialogTest { launch<ActionDisabledByAdvancedProtectionDialog>(intent).use(onScenario) } class HelpTestActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) finish() } } private companion object { val defaultIntent = AdvancedProtectionManager.createSupportIntent( FEATURE_ID_DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION ) const val HELP_INTENT_PKG_NAME = "com.android.settings.tests.spa_unit" const val HELP_INTENT_ACTION = "$HELP_INTENT_PKG_NAME.HELP_ACTION" val helpIntent = Intent(HELP_INTENT_ACTION).setPackage(HELP_INTENT_PKG_NAME) val helpIntentUri = helpIntent.toUri(Intent.URI_INTENT_SCHEME) val helpUriResourceId = com.android.internal.R.string.config_help_url_action_disabled_by_advanced_protection } } Loading
res/values/strings.xml +0 −3 Original line number Diff line number Diff line Loading @@ -12227,9 +12227,6 @@ Data usage charges may apply.</string> <!-- Help URI, action disabled by restricted settings [DO NOT TRANSLATE] --> <string name="help_url_action_disabled_by_restricted_settings" translatable="false"></string> <!-- Help URI, action disabled by advanced protection [DO NOT TRANSLATE] --> <string name="help_url_action_disabled_by_advanced_protection" translatable="false"></string> <!-- Title label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] --> <string name="zen_suggestion_title">Update Do Not Disturb</string>
src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialog.kt +9 −5 Original line number Diff line number Diff line Loading @@ -14,21 +14,23 @@ * limitations under the License. */ package com.android.settings.security; package com.android.settings.security import android.content.Intent import android.content.pm.PackageManager import android.security.advancedprotection.AdvancedProtectionManager import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE import android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP import android.content.pm.PackageManager import android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING import android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN import android.util.Log import android.view.WindowManager import androidx.annotation.VisibleForTesting import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable Loading @@ -38,7 +40,6 @@ import com.android.settingslib.spa.SpaDialogWindowTypeActivity import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogContent import com.android.settingslib.wifi.WifiUtils.Companion.DIALOG_WINDOW_TYPE import android.security.advancedprotection.AdvancedProtectionManager class ActionDisabledByAdvancedProtectionDialog : SpaDialogWindowTypeActivity() { Loading Loading @@ -85,9 +86,12 @@ class ActionDisabledByAdvancedProtectionDialog : SpaDialogWindowTypeActivity() { return getString(messageId) } private fun getSupportButtonIfExists(): AlertDialogButton? { @VisibleForTesting fun getSupportButtonIfExists(): AlertDialogButton? { try { val helpIntentUri = getString(R.string.help_url_action_disabled_by_advanced_protection) val helpIntentUri = getString( com.android.internal.R.string.config_help_url_action_disabled_by_advanced_protection ) val helpIntent = Intent.parseUri(helpIntentUri, Intent.URI_INTENT_SCHEME) if (helpIntent == null) return null val helpActivityInfo = packageManager.resolveActivity(helpIntent, /* flags */ 0) Loading
tests/spa_unit/AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,14 @@ <provider android:name="com.android.settings.slices.SettingsSliceProvider" android:authorities="${applicationId}.slices" tools:replace="android:authorities"/> <activity android:name="com.android.settings.security.ActionDisabledByAdvancedProtectionDialogTest$HelpTestActivity" android:exported="true"> <intent-filter> <action android:name="com.android.settings.tests.spa_unit.HELP_ACTION" /> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> <instrumentation Loading
tests/spa_unit/src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialogTest.kt +112 −1 Original line number Diff line number Diff line Loading @@ -16,9 +16,14 @@ package com.android.settings.security import android.app.Activity import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.content.pm.ResolveInfo import android.os.Bundle import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.CheckFlagsRule import android.platform.test.flag.junit.DeviceFlagsValueProvider Loading @@ -36,9 +41,21 @@ import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @RequiresFlagsEnabled(Flags.FLAG_AAPM_API) @RunWith(AndroidJUnit4::class) Loading @@ -49,7 +66,9 @@ class ActionDisabledByAdvancedProtectionDialogTest { @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() val context: Context = ApplicationProvider.getApplicationContext() private val mockPackageManager = mock<PackageManager>() private val context: Context = ApplicationProvider.getApplicationContext() @Test fun blockedInteractionDialog_showsCorrectTitleAndMessage() { Loading Loading @@ -159,6 +178,85 @@ class ActionDisabledByAdvancedProtectionDialogTest { } } @Test fun helpIntentDoesNotExist_getSupportButtonIfExists_returnsNull() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, /* uriToReturn */ null) val button = spyActivity.getSupportButtonIfExists() assertNull(button) } } } @Test fun helpIntentExistsAndDoesNotResolveToActivity_getSupportButtonIfExists_returnsNull() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, helpIntentUri) mockResolveActivity(spyActivity, /* resolveInfoToReturn */ null) val button = spyActivity.getSupportButtonIfExists() assertNull(button) } } } @Test fun helpIntentExistsAndResolvesToActivity_getSupportButtonIfExists_returnsButton() { launchDialogActivity(defaultIntent) { scenario -> scenario.onActivity { activity -> val spyActivity = spyOnActivityHelpIntentUri(activity, helpIntentUri) val resolveInfoToReturn = ResolveInfo().apply { activityInfo = ActivityInfo().apply { packageName = HELP_INTENT_PKG_NAME } } mockResolveActivity(spyActivity, resolveInfoToReturn) // 1. Check the button is returned. val button = spyActivity.getSupportButtonIfExists() assertNotNull(button) // 2. Check the button has correct text. assertEquals(context.getString( R.string.disabled_by_advanced_protection_help_button_title), button!!.text ) // 3. Check the button's onClick launches the help activity and finishes the dialog. button.onClick() val intentCaptor = ArgumentCaptor.forClass(Intent::class.java) verify(spyActivity).startActivity(intentCaptor.capture()) val launchedIntent = intentCaptor.value assertEquals(HELP_INTENT_ACTION, launchedIntent.action) assertEquals(HELP_INTENT_PKG_NAME, launchedIntent.`package`) assertTrue(spyActivity.isFinishing) } } } private fun spyOnActivityHelpIntentUri( activity: ActionDisabledByAdvancedProtectionDialog, uriToReturn: String? ): ActionDisabledByAdvancedProtectionDialog { val spyActivity = spy(activity) val spyResources = spy(spyActivity.resources) doReturn(spyResources).whenever(spyActivity).resources doReturn(uriToReturn).whenever(spyResources).getString(helpUriResourceId) return spyActivity } private fun mockResolveActivity( spyActivity: ActionDisabledByAdvancedProtectionDialog, resolveInfoToReturn: ResolveInfo? ) { doReturn(mockPackageManager).whenever(spyActivity).packageManager doReturn(resolveInfoToReturn).whenever(mockPackageManager).resolveActivity(any(), anyInt()) } private fun launchDialogActivity( intent: Intent, onScenario: (ActivityScenario<ActionDisabledByAdvancedProtectionDialog>) -> Unit Loading @@ -172,10 +270,23 @@ class ActionDisabledByAdvancedProtectionDialogTest { launch<ActionDisabledByAdvancedProtectionDialog>(intent).use(onScenario) } class HelpTestActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) finish() } } private companion object { val defaultIntent = AdvancedProtectionManager.createSupportIntent( FEATURE_ID_DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION ) const val HELP_INTENT_PKG_NAME = "com.android.settings.tests.spa_unit" const val HELP_INTENT_ACTION = "$HELP_INTENT_PKG_NAME.HELP_ACTION" val helpIntent = Intent(HELP_INTENT_ACTION).setPackage(HELP_INTENT_PKG_NAME) val helpIntentUri = helpIntent.toUri(Intent.URI_INTENT_SCHEME) val helpUriResourceId = com.android.internal.R.string.config_help_url_action_disabled_by_advanced_protection } }