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) {