[AAPM] Add advanced protection dialog according to API feedback
This change also updates ActionDisabledByAdminDialog because the
AdvancedProtectionManager#createSupportIntent method is now static.
Bug: 378968840
Bug: 352420507
Test: ActionDisabledByAdminDialogTest
Test: WepNetworksPreferenceControllerTest
Test: manual
Flag: android.security.aapm_api
Change-Id: I8443742aadead45091fee757cbdf715d28eee495
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2295ee3..37a2340 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -4443,6 +4443,19 @@
</intent-filter>
</activity>
+ <activity android:name=".security.ActionDisabledByAdvancedProtectionDialog"
+ android:theme="@style/Theme.AlertDialog"
+ android:taskAffinity="com.android.settings.security"
+ android:excludeFromRecents="true"
+ android:exported="false"
+ android:launchMode="singleTop"
+ android:featureFlag="android.security.aapm_api">
+ <intent-filter android:priority="1">
+ <action android:name="android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity
android:name="Settings$ManageExternalStorageActivity"
android:knownActivityEmbeddingCerts="@array/config_known_host_certs"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6fc9fb1..f9a0532 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10631,6 +10631,11 @@
<string name="admin_financed_message">Your device administrator may be able to access data
associated with this device, manage apps, and change this device\’s settings.</string>
+ <!-- Title for dialog displayed when user taps a setting on their phone that's blocked by Advanced Protection. [CHAR LIMIT=50] -->
+ <string name="disabled_by_advanced_protection_title">Prevented by Advanced Protection</string>
+ <!-- Short summary for dialog displayed when user taps a setting on their phone that's blocked by Advanced Protection. [CHAR LIMIT=NONE] -->
+ <string name="disabled_by_advanced_protection_message">This action is not allowed because Advanced Protection is on for your device.</string>
+
<!-- Turn off a conditional state of the device (e.g. airplane mode, or hotspot) [CHAR LIMIT=30] -->
<string name="condition_turn_off">Turn off</string>
diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java
index e05ae71..b0d0af1 100644
--- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java
+++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialog.java
@@ -109,12 +109,9 @@
}
if (enforcingAdmin.getAuthority() instanceof UnknownAuthority authority
&& ADVANCED_PROTECTION_SYSTEM_ENTITY.equals(authority.getName())) {
- AdvancedProtectionManager apm = getSystemService(AdvancedProtectionManager.class);
- if (apm == null) {
- return;
- }
- Intent apmSupportIntent = apm.createSupportIntentForPolicyIdentifierOrRestriction(
- restriction, /* type */ null);
+ Intent apmSupportIntent = AdvancedProtectionManager
+ .createSupportIntentForPolicyIdentifierOrRestriction(restriction,
+ AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN);
startActivityAsUser(apmSupportIntent, UserHandle.of(userId));
finish();
} else {
diff --git a/src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialog.kt b/src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialog.kt
new file mode 100644
index 0000000..d56f895
--- /dev/null
+++ b/src/com/android/settings/security/ActionDisabledByAdvancedProtectionDialog.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import android.app.Activity
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import com.android.settings.R
+
+import androidx.appcompat.app.AlertDialog;
+
+class ActionDisabledByAdvancedProtectionDialog : Activity(), DialogInterface.OnDismissListener {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val dialogView = layoutInflater.inflate(R.layout.support_details_dialog, null) as ViewGroup
+ val builder = AlertDialog.Builder(this)
+ .setPositiveButton(R.string.okay, null)
+ .setView(dialogView)
+ .setOnDismissListener(this)
+ initializeDialogView(dialogView)
+ builder.show()
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ finish()
+ }
+
+ private fun initializeDialogView(dialogView: View) {
+ setSupportTitle(dialogView)
+ setSupportDetails(dialogView)
+ }
+
+ private fun setSupportTitle(root: View) {
+ val titleView: TextView = root.findViewById(R.id.admin_support_dialog_title) ?: return
+ titleView.setText(R.string.disabled_by_advanced_protection_title)
+ }
+
+ private fun setSupportDetails(root: View) {
+ val textView: TextView = root.findViewById(R.id.admin_support_msg)
+ textView.setText(R.string.disabled_by_advanced_protection_message)
+ }
+}
diff --git a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
index 92716be..59c67ee 100644
--- a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
+++ b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
@@ -162,10 +162,10 @@
emit(aapmManager?.isAdvancedProtectionEnabled ?: false) }.flowOn(Dispatchers.Default)
private fun startSupportIntent() {
- aapmManager?.createSupportIntent(
+ AdvancedProtectionManager.createSupportIntent(
AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING
- )?.let { mContext.startActivity(it) }
+ ).let { mContext.startActivity(it) }
}
val wepAllowedFlow =
diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java
index 4b7abec..37e0424 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogTest.java
@@ -20,9 +20,14 @@
import static android.security.advancedprotection.AdvancedProtectionManager.ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG;
import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE;
+import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -40,7 +45,6 @@
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.security.advancedprotection.AdvancedProtectionManager;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -48,6 +52,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -59,8 +64,6 @@
@Mock
private DevicePolicyManager mDevicePolicyManager;
- @Mock
- private AdvancedProtectionManager mAdvancedProtectionManager;
private ActionDisabledByAdminDialog mDialog;
private final ComponentName mAdminComponent = new ComponentName("admin", "adminclass");
@@ -70,8 +73,6 @@
MockitoAnnotations.initMocks(this);
mDialog = spy(new ActionDisabledByAdminDialog());
doReturn(mDevicePolicyManager).when(mDialog).getSystemService(DevicePolicyManager.class);
- doReturn(mAdvancedProtectionManager).when(mDialog).getSystemService(
- AdvancedProtectionManager.class);
}
@Test
@@ -118,24 +119,28 @@
advancedProtectionAuthority, UserHandle.of(userId), mAdminComponent);
final String userRestriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
- final Intent apmIntent = new Intent(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG);
- apmIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- apmIntent.putExtra(EXTRA_SUPPORT_DIALOG_FEATURE, "featureId");
-
final Intent dialogIntent = new Intent();
dialogIntent.putExtra(Intent.EXTRA_USER_ID, userId);
dialogIntent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, userRestriction);
when(mDevicePolicyManager.getEnforcingAdmin(userId, userRestriction))
.thenReturn(advancedProtectionEnforcingAdmin);
- when(mAdvancedProtectionManager.createSupportIntentForPolicyIdentifierOrRestriction(
- userRestriction, /* type */ null)).thenReturn(apmIntent);
- doNothing().when(mDialog).startActivityAsUser(apmIntent, UserHandle.of(userId));
+ doNothing().when(mDialog).startActivityAsUser(any(), eq(UserHandle.of(userId)));
mDialog.getAdminDetailsFromIntent(dialogIntent);
- verify(mDialog).startActivityAsUser(apmIntent, UserHandle.of(userId));
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mDialog).startActivityAsUser(intentCaptor.capture(), eq(UserHandle.of(userId)));
assertTrue(mDialog.isFinishing());
+
+ Intent launchedIntent = intentCaptor.getValue();
+ assertEquals("Intent action is incorrect", ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG,
+ launchedIntent.getAction());
+ assertEquals("Feature ID extra is incorrect", FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES,
+ launchedIntent.getIntExtra(EXTRA_SUPPORT_DIALOG_FEATURE, -1));
+ assertEquals("Type is incorrect", SUPPORT_DIALOG_TYPE_UNKNOWN,
+ launchedIntent.getIntExtra(EXTRA_SUPPORT_DIALOG_TYPE, -1));
+ assertEquals(FLAG_ACTIVITY_NEW_TASK, launchedIntent.getFlags());
}
@RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
diff --git a/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
index 1f0a491..7410757 100644
--- a/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
@@ -200,7 +200,6 @@
fun whenClick_aapmEnabled_openDialog() {
mockAapmManager.stub {
on { isAdvancedProtectionEnabled } doReturn true
- on { createSupportIntent(any(), any()) } doReturn Intent()
}
doNothing().whenever(context).startActivity(any())
composeTestRule.setContent { controller.Content() }