Merge "[Settings] Don't allow apps on external storage to be active admin" into nyc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 769fff4..1122e0f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3390,6 +3390,8 @@
     <string name="app_forward_locked">App is copy-protected.</string>
     <string name="invalid_location">Install location isn\u2019t valid.</string>
     <string name="system_package">System updates can\u2019t be installed on external media.</string>
+    <!-- Error message shown when trying to move device administrators to external disks, such as SD card [CHAR_LIMIT=none] -->
+    <string name="move_error_device_admin">Device Administrator can\u2019t be installed on external media.</string>
 
     <string name="force_stop_dlg_title">Force stop?</string>
     <!-- [CHAR LIMIT=200] Manage applications, text for dialog when killing persistent apps-->
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index 9791160..3adce15 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -359,6 +359,9 @@
                 DeviceAdminInfo deviceAdminInfo =  createDeviceAdminInfo(resolveInfo);
                 // add only visible ones (note: active admins are added regardless of visibility)
                 if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) {
+                    if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) {
+                        continue;
+                    }
                     DeviceAdminListItem item = new DeviceAdminListItem();
                     item.info = deviceAdminInfo;
                     item.name = deviceAdminInfo.loadLabel(pm).toString();
@@ -391,6 +394,8 @@
                     for (int j = 0; j < resolvedMax; ++j) {
                         DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolved.get(j));
                         if (deviceAdminInfo != null) {
+                            // Don't do the applicationInfo.isInternal() check here; if an active
+                            // admin is already on SD card, just show it.
                             DeviceAdminListItem item = new DeviceAdminListItem();
                             item.info = deviceAdminInfo;
                             item.name = deviceAdminInfo.loadLabel(packageManager).toString();
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
index fffdf74..69247f6 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java
@@ -86,6 +86,8 @@
         switch (returnCode) {
             case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE:
                 return getString(R.string.insufficient_storage);
+            case PackageManager.MOVE_FAILED_DEVICE_ADMIN:
+                return getString(R.string.move_error_device_admin);
             case PackageManager.MOVE_FAILED_DOESNT_EXIST:
                 return getString(R.string.does_not_exist);
             case PackageManager.MOVE_FAILED_FORWARD_LOCKED: