summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShraddha Basantwani <basantwani@google.com>2024-12-02 09:36:05 +0000
committeraoleary <seanm187@gmail.com>2025-07-09 07:12:13 +0000
commit9424ce747547ff1dfb0fc291e8bb340514542dd9 (patch)
tree9472b41ca6f480da4d1859b74c3d6622bf6c29a7
parent0b2daaea305442e6f5fe57d88c9de5a16b52c992 (diff)
Add biometric authentication for package modification
Add an extra step of Lock Screen for disabling, force-stopping or uninstalling updates for protected packages Bug: 352504490, 344865740 Test: atest AppButtonsPreferenceControllerTest Flag: EXEMPT High Security Bug DISABLE_TOPIC_PROTECTOR (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:32e388ad3199de3c062bb2e2db5d3239f934d0eb) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:dbe975ff3111692da8ec0086ef74ed97e7d54ca9) Merged-In: I0c494e307b02229d751de118abcc89e4e61a6861 Change-Id: I0c494e307b02229d751de118abcc89e4e61a6861 Change-Id: If1eaa6c88eb2111b6a51f2e89d5356f64b0049b3
-rw-r--r--src/com/android/settings/Utils.java16
-rw-r--r--src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java66
-rwxr-xr-xsrc/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java3
-rw-r--r--tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java2
-rw-r--r--tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java11
5 files changed, 78 insertions, 20 deletions
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index bee6c48a3f6..da5b49fc0c6 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -114,6 +114,7 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.widget.ActionBarShadowController;
import com.android.settingslib.widget.AdaptiveIcon;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -1271,4 +1272,19 @@ public final class Utils extends com.android.settingslib.Utils {
Log.d("savePINPasswordLength", "saveLong error: " + e.getMessage());
}
}
+
+ /**
+ * Returns {@code true} if the supplied package is a protected package. Otherwise, returns
+ * {@code false}.
+ *
+ * @param context the context
+ * @param packageName the package name
+ */
+ public static boolean isProtectedPackage(
+ @NonNull Context context, @NonNull String packageName) {
+ final List<String> protectedPackageNames = Arrays.asList(context.getResources()
+ .getStringArray(com.android.internal.R.array
+ .config_biometric_protected_package_names));
+ return protectedPackageNames != null && protectedPackageNames.contains(packageName);
+ }
}
diff --git a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
index 1b270d63b4d..69f23fe5648 100644
--- a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java
@@ -52,6 +52,7 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.applications.ApplicationFeatureProvider;
+import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
@@ -249,13 +250,21 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
} else {
showDialogInner(ButtonActionDialogFragment.DialogType.DISABLE);
}
+ } else if (mAppEntry.info.enabled) {
+ requireAuthAndExecute(() -> {
+ mMetricsFeatureProvider.action(
+ mActivity,
+ SettingsEnums.ACTION_SETTINGS_DISABLE_APP,
+ getPackageNameForMetric());
+ AsyncTask.execute(new DisableChangerRunnable(mPm,
+ mAppEntry.info.packageName,
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT));
+ });
} else {
mMetricsFeatureProvider.action(
mActivity,
- mAppEntry.info.enabled
- ? SettingsEnums.ACTION_SETTINGS_DISABLE_APP
- : SettingsEnums.ACTION_SETTINGS_ENABLE_APP,
- getPackageNameForMetric());
+ SettingsEnums.ACTION_SETTINGS_ENABLE_APP,
+ getPackageNameForMetric());
AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT));
}
@@ -303,13 +312,28 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
}
}
+ /**
+ * Runs the given action with restricted lock authentication if it is a protected package.
+ *
+ * @param action The action to run.
+ */
+ private void requireAuthAndExecute(Runnable action) {
+ if (Utils.isProtectedPackage(mContext, mAppEntry.info.packageName)) {
+ AppInfoDashboardFragment.showLockScreen(mContext, () -> action.run());
+ } else {
+ action.run();
+ }
+ }
+
public void handleDialogClick(int id) {
switch (id) {
case ButtonActionDialogFragment.DialogType.DISABLE:
- mMetricsFeatureProvider.action(mActivity,
- SettingsEnums.ACTION_SETTINGS_DISABLE_APP);
- AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER));
+ requireAuthAndExecute(() -> {
+ mMetricsFeatureProvider.action(mActivity,
+ SettingsEnums.ACTION_SETTINGS_DISABLE_APP);
+ AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER));
+ });
break;
case ButtonActionDialogFragment.DialogType.SPECIAL_DISABLE:
mMetricsFeatureProvider.action(mActivity,
@@ -317,7 +341,9 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
uninstallPkg(mAppEntry.info.packageName, false, true);
break;
case ButtonActionDialogFragment.DialogType.FORCE_STOP:
- forceStopPackage(mAppEntry.info.packageName);
+ requireAuthAndExecute(() -> {
+ forceStopPackage(mAppEntry.info.packageName);
+ });
break;
}
}
@@ -547,16 +573,18 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
@VisibleForTesting
void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
- stopListeningToPackageRemove();
- // Create new intent to launch Uninstaller activity
- Uri packageUri = Uri.parse("package:" + packageName);
- Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
- uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
-
- mMetricsFeatureProvider.action(
- mActivity, SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP);
- mFragment.startActivityForResult(uninstallIntent, mRequestUninstall);
- mDisableAfterUninstall = andDisable;
+ requireAuthAndExecute(() -> {
+ stopListeningToPackageRemove();
+ // Create new intent to launch Uninstaller activity
+ Uri packageUri = Uri.parse("package:" + packageName);
+ Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
+ uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
+
+ mMetricsFeatureProvider.action(
+ mActivity, SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP);
+ mFragment.startActivityForResult(uninstallIntent, mRequestUninstall);
+ mDisableAfterUninstall = andDisable;
+ });
}
@VisibleForTesting
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 6e15ade393b..875a2a3db3a 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -441,7 +441,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
&& !isAospOrStore(mAppEntry.info.packageName));
}
- private static void showLockScreen(Context context, Runnable successRunnable) {
+ /** Shows the lock screen if the keyguard is secured. */
+ public static void showLockScreen(Context context, Runnable successRunnable) {
final KeyguardManager keyguardManager = context.getSystemService(
KeyguardManager.class);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java
index 9a65dc8829c..91c5e7bf0fd 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java
@@ -81,6 +81,7 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.Set;
+@Config(shadows = {ShadowUtils.class})
@RunWith(RobolectricTestRunner.class)
public class AppButtonsPreferenceControllerTest {
@@ -166,6 +167,7 @@ public class AppButtonsPreferenceControllerTest {
@After
public void tearDown() {
ShadowAppUtils.reset();
+ ShadowUtils.reset();
}
@Test
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index 5f8c434fc9f..1dd381f3570 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -50,6 +50,7 @@ public class ShadowUtils {
private static ArraySet<String> sResultLinks = new ArraySet<>();
private static boolean sIsBatteryPresent;
private static boolean sIsMultipleBiometricsSupported;
+ private static boolean sIsProtectedPackage;
@Implementation
protected static int enforceSameOwner(Context context, int userId) {
@@ -82,6 +83,7 @@ public class ShadowUtils {
sResultLinks = new ArraySet<>();
sIsBatteryPresent = true;
sIsMultipleBiometricsSupported = false;
+ sIsProtectedPackage = false;
}
public static void setIsDemoUser(boolean isDemoUser) {
@@ -188,4 +190,13 @@ public class ShadowUtils {
public static void setIsMultipleBiometricsSupported(boolean isMultipleBiometricsSupported) {
sIsMultipleBiometricsSupported = isMultipleBiometricsSupported;
}
+
+ @Implementation
+ protected static boolean isProtectedPackage(Context context, String packageName) {
+ return sIsProtectedPackage;
+ }
+
+ public static void setIsProtectedPackage(boolean isProtectedPackage) {
+ sIsProtectedPackage = isProtectedPackage;
+ }
}