RESTRICT AUTOMERGE Add biometric authentication for package modification am: 6179d4fdf3

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/30686223

Change-Id: If2b7208f85717859c7b38f826f674021cb098c5b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Shraddha Basantwani
2025-02-13 21:37:16 -08:00
committed by Automerger Merge Worker
5 changed files with 78 additions and 19 deletions

View File

@@ -114,6 +114,7 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.widget.ActionBarShadowController; import com.android.settingslib.widget.ActionBarShadowController;
import com.android.settingslib.widget.AdaptiveIcon; import com.android.settingslib.widget.AdaptiveIcon;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -1229,4 +1230,19 @@ public final class Utils extends com.android.settingslib.Utils {
public static int getHomepageIconColorHighlight(Context context) { public static int getHomepageIconColorHighlight(Context context) {
return context.getColor(R.color.accent_select_primary_text); return context.getColor(R.color.accent_select_primary_text);
} }
/**
* 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);
}
} }

View File

@@ -52,6 +52,7 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.applications.ApplicationFeatureProvider; 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.applications.specialaccess.deviceadmin.DeviceAdminAdd;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.InstrumentedPreferenceFragment;
@@ -249,13 +250,21 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
} else { } else {
showDialogInner(ButtonActionDialogFragment.DialogType.DISABLE); 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 { } else {
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mActivity, mActivity,
mAppEntry.info.enabled SettingsEnums.ACTION_SETTINGS_ENABLE_APP,
? SettingsEnums.ACTION_SETTINGS_DISABLE_APP getPackageNameForMetric());
: SettingsEnums.ACTION_SETTINGS_ENABLE_APP,
getPackageNameForMetric());
AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName, AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)); 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) { public void handleDialogClick(int id) {
switch (id) { switch (id) {
case ButtonActionDialogFragment.DialogType.DISABLE: case ButtonActionDialogFragment.DialogType.DISABLE:
mMetricsFeatureProvider.action(mActivity, requireAuthAndExecute(() -> {
SettingsEnums.ACTION_SETTINGS_DISABLE_APP); mMetricsFeatureProvider.action(mActivity,
AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName, SettingsEnums.ACTION_SETTINGS_DISABLE_APP);
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)); AsyncTask.execute(new DisableChangerRunnable(mPm, mAppEntry.info.packageName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER));
});
break; break;
case ButtonActionDialogFragment.DialogType.SPECIAL_DISABLE: case ButtonActionDialogFragment.DialogType.SPECIAL_DISABLE:
mMetricsFeatureProvider.action(mActivity, mMetricsFeatureProvider.action(mActivity,
@@ -317,7 +341,9 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
uninstallPkg(mAppEntry.info.packageName, false, true); uninstallPkg(mAppEntry.info.packageName, false, true);
break; break;
case ButtonActionDialogFragment.DialogType.FORCE_STOP: case ButtonActionDialogFragment.DialogType.FORCE_STOP:
forceStopPackage(mAppEntry.info.packageName); requireAuthAndExecute(() -> {
forceStopPackage(mAppEntry.info.packageName);
});
break; break;
} }
} }
@@ -547,16 +573,18 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
@VisibleForTesting @VisibleForTesting
void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) { void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
stopListeningToPackageRemove(); requireAuthAndExecute(() -> {
// Create new intent to launch Uninstaller activity stopListeningToPackageRemove();
Uri packageUri = Uri.parse("package:" + packageName); // Create new intent to launch Uninstaller activity
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri); Uri packageUri = Uri.parse("package:" + packageName);
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers); Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mActivity, SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP); mActivity, SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP);
mFragment.startActivityForResult(uninstallIntent, mRequestUninstall); mFragment.startActivityForResult(uninstallIntent, mRequestUninstall);
mDisableAfterUninstall = andDisable; mDisableAfterUninstall = andDisable;
});
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -430,7 +430,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
} }
} }
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( final KeyguardManager keyguardManager = context.getSystemService(
KeyguardManager.class); KeyguardManager.class);

View File

@@ -56,6 +56,7 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
@@ -81,6 +82,7 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.Set; import java.util.Set;
@Config(shadows = {ShadowUtils.class})
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class AppButtonsPreferenceControllerTest { public class AppButtonsPreferenceControllerTest {
@@ -166,6 +168,7 @@ public class AppButtonsPreferenceControllerTest {
@After @After
public void tearDown() { public void tearDown() {
ShadowAppUtils.reset(); ShadowAppUtils.reset();
ShadowUtils.reset();
} }
@Test @Test

View File

@@ -48,6 +48,7 @@ public class ShadowUtils {
private static ArraySet<String> sResultLinks = new ArraySet<>(); private static ArraySet<String> sResultLinks = new ArraySet<>();
private static boolean sIsBatteryPresent; private static boolean sIsBatteryPresent;
private static boolean sIsMultipleBiometricsSupported; private static boolean sIsMultipleBiometricsSupported;
private static boolean sIsProtectedPackage;
@Implementation @Implementation
protected static int enforceSameOwner(Context context, int userId) { protected static int enforceSameOwner(Context context, int userId) {
@@ -71,6 +72,7 @@ public class ShadowUtils {
sResultLinks = new ArraySet<>(); sResultLinks = new ArraySet<>();
sIsBatteryPresent = true; sIsBatteryPresent = true;
sIsMultipleBiometricsSupported = false; sIsMultipleBiometricsSupported = false;
sIsProtectedPackage = false;
} }
public static void setIsDemoUser(boolean isDemoUser) { public static void setIsDemoUser(boolean isDemoUser) {
@@ -177,4 +179,13 @@ public class ShadowUtils {
public static void setIsMultipleBiometricsSupported(boolean isMultipleBiometricsSupported) { public static void setIsMultipleBiometricsSupported(boolean isMultipleBiometricsSupported) {
sIsMultipleBiometricsSupported = isMultipleBiometricsSupported; sIsMultipleBiometricsSupported = isMultipleBiometricsSupported;
} }
@Implementation
protected static boolean isProtectedPackage(Context context, String packageName) {
return sIsProtectedPackage;
}
public static void setIsProtectedPackage(boolean isProtectedPackage) {
sIsProtectedPackage = isProtectedPackage;
}
} }