From 02a06eff4269e8b7958a5719a3733147086f8424 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Wed, 27 Jan 2016 13:00:10 -0800 Subject: [PATCH] Adding an easy uninstall for active device admin Currently the uninstall button is disabled for a package with an active device admin. This change enables the button, which when clicked gives the user an option to deactivate all the DAs in the package and then uninstall the package. Bug: b/22359208 cherry pick of I8b955305927751185a4c982dadb5b1b6b07efe5e Change-Id: Ib2ab0e35b74fc8dba7168174b2bc8fd383fe94fe --- res/values/strings.xml | 2 ++ src/com/android/settings/DeviceAdminAdd.java | 35 ++++++++++++++++--- .../applications/InstalledAppDetails.java | 23 +++++++++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 5d093f16e9a..65f522ea557 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4557,6 +4557,8 @@ Deactivate Uninstall + + Deactivate and Uninstall Device administrators diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java index 1ce72f98b18..0c928f6cfb0 100644 --- a/src/com/android/settings/DeviceAdminAdd.java +++ b/src/com/android/settings/DeviceAdminAdd.java @@ -77,6 +77,13 @@ public class DeviceAdminAdd extends Activity { private static final int REQUEST_CODE_UNINSTALL = 1; + /** + * Optional key to map to the package name of the Device Admin. + * Currently only used when uninstalling an active device admin. + */ + public static final String EXTRA_DEVICE_ADMIN_PACKAGE_NAME = + "android.app.extra.DEVICE_ADMIN_PACKAGE_NAME"; + Handler mHandler; DevicePolicyManager mDPM; @@ -99,6 +106,7 @@ public class DeviceAdminAdd extends Activity { Button mUninstallButton; Button mCancelButton; + boolean mUninstalling = false; boolean mAdding; boolean mRefreshing; boolean mWaitingForRemoveMsg; @@ -123,13 +131,24 @@ public class DeviceAdminAdd extends Activity { return; } + String action = getIntent().getAction(); ComponentName who = (ComponentName)getIntent().getParcelableExtra( DevicePolicyManager.EXTRA_DEVICE_ADMIN); if (who == null) { - Log.w(TAG, "No component specified in " + action); - finish(); - return; + String packageName = getIntent().getStringExtra(EXTRA_DEVICE_ADMIN_PACKAGE_NAME); + for (ComponentName component : mDPM.getActiveAdmins()) { + if (component.getPackageName().equals(packageName)) { + who = component; + mUninstalling = true; + break; + } + } + if (who == null) { + Log.w(TAG, "No component specified in " + action); + finish(); + return; + } } if (action != null && action.equals(DevicePolicyManager.ACTION_SET_PROFILE_OWNER)) { @@ -329,6 +348,9 @@ public class DeviceAdminAdd extends Activity { } } ).show(); + } else if (mUninstalling) { + mDPM.uninstallPackageWithActiveAdmins(mDeviceAdmin.getPackageName()); + finish(); } else if (!mWaitingForRemoveMsg) { try { // Don't allow the admin to put a dialog up in front @@ -524,7 +546,11 @@ public class DeviceAdminAdd extends Activity { mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel( getPackageManager()))); setTitle(R.string.active_device_admin_msg); - mActionButton.setText(R.string.remove_device_admin); + if (mUninstalling) { + mActionButton.setText(R.string.remove_and_uninstall_device_admin); + } else { + mActionButton.setText(R.string.remove_device_admin); + } } String supportMessage = mDPM.getLongSupportMessageForUser( mDeviceAdmin.getComponent(), UserHandle.myUserId()); @@ -606,7 +632,6 @@ public class DeviceAdminAdd extends Activity { final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); uninstallIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); - startActivityForResult(uninstallIntent, REQUEST_CODE_UNINSTALL); } } diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 83159e326d1..a8e8eae4c22 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -68,6 +68,7 @@ import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.AppHeader; +import com.android.settings.DeviceAdminAdd; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; @@ -116,6 +117,8 @@ public class InstalledAppDetails extends AppInfoBase // Result code identifiers public static final int REQUEST_UNINSTALL = 0; + private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; + private static final int SUB_INFO_FRAGMENT = 1; private static final int LOADER_CHART_DATA = 2; @@ -207,7 +210,7 @@ public class InstalledAppDetails extends AppInfoBase } // If this is a device admin, it can't be uninstalled or disabled. // We do this here so the text of the button is still set correctly. - if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { + if (isBundled && mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { enabled = false; } @@ -218,6 +221,11 @@ public class InstalledAppDetails extends AppInfoBase enabled = false; } + // If the uninstall intent is already queued, disable the uninstall button + if (mDpm.isUninstallInQueue(mPackageName)) { + enabled = false; + } + // Home apps need special handling. Bundled ones we don't risk downgrading // because that can interfere with home-key resolution. Furthermore, we // can't allow uninstallation of the only home app, and we don't want to @@ -447,6 +455,11 @@ public class InstalledAppDetails extends AppInfoBase setIntentAndFinish(true, true); } } + if (requestCode == REQUEST_REMOVE_DEVICE_ADMIN) { + if (!refreshUi()) { + setIntentAndFinish(true, true); + } + } } // Utility method to set application label and icon. @@ -717,6 +730,14 @@ public class InstalledAppDetails extends AppInfoBase } String packageName = mAppEntry.info.packageName; if(v == mUninstallButton) { + if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { + Activity activity = getActivity(); + Intent uninstallDAIntent = new Intent(activity, DeviceAdminAdd.class); + uninstallDAIntent.putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME, + mPackageName); + activity.startActivityForResult(uninstallDAIntent, REQUEST_REMOVE_DEVICE_ADMIN); + return; + } EnforcedAdmin admin = RestrictedLockUtils.checkIfUninstallBlocked(getActivity(), packageName, mUserId); if (admin != null) {