From 5c2b48d4d52a2b6b3ae3c745e7016da390a4e1d7 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 16 Sep 2011 13:36:20 -0700 Subject: [PATCH] Fix issue #5320747: Disabling an app that is an active device administrator... ...can lead to an unsecure device Now you can't disable device admins. Or clear their data. Or force stop them. Or uninstall them (though the package manager also prevents uninstalling, might as well disable this button along with everything else). Change-Id: I69eefc2342e6f932908e9f5b87d3a601752810a4 --- .../applications/InstalledAppDetails.java | 24 ++++++++++++++----- .../settings/fuelgauge/PowerUsageDetail.java | 22 ++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index a84b8bb3248..faa531a7ac3 100644 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -25,6 +25,7 @@ import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.Fragment; +import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -86,6 +87,7 @@ public class InstalledAppDetails extends Fragment private PackageManager mPm; private IUsbManager mUsbManager; + private DevicePolicyManager mDpm; private ApplicationsState mState; private ApplicationsState.AppEntry mAppEntry; private PackageInfo mPackageInfo; @@ -206,7 +208,8 @@ public class InstalledAppDetails extends Fragment private void initDataButtons() { if ((mAppEntry.info.flags&(ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)) - == ApplicationInfo.FLAG_SYSTEM) { + == ApplicationInfo.FLAG_SYSTEM + || mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { mClearDataButton.setText(R.string.clear_user_data_text); mClearDataButton.setEnabled(false); mCanClearData = false; @@ -304,6 +307,11 @@ public class InstalledAppDetails extends Fragment mUninstallButton.setText(R.string.uninstall_text); } } + // If this is a device admin, it can't be uninstall or disabled. + // We do this here so the text of the button is still set correctly. + if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { + enabled = false; + } mUninstallButton.setEnabled(enabled); if (enabled) { // Register listener @@ -320,6 +328,7 @@ public class InstalledAppDetails extends Fragment mPm = getActivity().getPackageManager(); IBinder b = ServiceManager.getService(Context.USB_SERVICE); mUsbManager = IUsbManager.Stub.asInterface(b); + mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); mCanBeOnSdCardChecker = new CanBeOnSdCardChecker(); } @@ -809,15 +818,18 @@ public class InstalledAppDetails extends Fragment } private void checkForceStop() { - Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, - Uri.fromParts("package", mAppEntry.info.packageName, null)); - intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName }); - intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid); - if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) { + if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { + // User can't force stop device admin. + updateForceStopButton(false); + } else if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) { // If the app isn't explicitly stopped, then always show the // force stop button. updateForceStopButton(true); } else { + Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, + Uri.fromParts("package", mAppEntry.info.packageName, null)); + intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName }); + intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid); getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); } diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java index e6552ce1032..79cbac644ed 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ApplicationErrorReport; import android.app.Fragment; +import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -102,7 +103,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener public static final String EXTRA_NO_COVERAGE = "noCoverage"; public static final String EXTRA_ICON_ID = "iconId"; // Int - private static final boolean DEBUG = true; + private PackageManager mPm; + private DevicePolicyManager mDpm; private String mTitle; private int mUsageSince; private int[] mTypes; @@ -131,6 +133,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + mPm = getActivity().getPackageManager(); + mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); } @Override @@ -429,6 +433,22 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener mForceStopButton.setEnabled(false); return; } + for (int i = 0; i < mPackages.length; i++) { + if (mDpm.packageHasActiveAdmins(mPackages[i])) { + mForceStopButton.setEnabled(false); + return; + } + } + for (int i = 0; i < mPackages.length; i++) { + try { + ApplicationInfo info = mPm.getApplicationInfo(mPackages[i], 0); + if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) { + mForceStopButton.setEnabled(true); + break; + } + } catch (PackageManager.NameNotFoundException e) { + } + } Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, Uri.fromParts("package", mPackages[0], null)); intent.putExtra(Intent.EXTRA_PACKAGES, mPackages);