Merge "Import translations. DO NOT MERGE" into jb-mr2-dev
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index 27e7a54..6234038 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -116,34 +116,38 @@
             return;
         }
 
-        // Make sure the given component name is actually a valid device admin.
-        List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
-                new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
-                PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
-        int count = avail == null ? 0 : avail.size();
-        boolean found = false;
-        for (int i=0; i<count; i++) {
-            ResolveInfo ri = avail.get(i);
-            if (ai.packageName.equals(ri.activityInfo.packageName)
-                    && ai.name.equals(ri.activityInfo.name)) {
-                try {
-                    // We didn't retrieve the meta data for all possible matches, so
-                    // need to use the activity info of this specific one that was retrieved.
-                    ri.activityInfo = ai;
-                    DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri);
-                    found = true;
-                } catch (XmlPullParserException e) {
-                    Log.w(TAG, "Bad " + ri.activityInfo, e);
-                } catch (IOException e) {
-                    Log.w(TAG, "Bad " + ri.activityInfo, e);
+        // When activating, make sure the given component name is actually a valid device admin.
+        // No need to check this when deactivating, because it is safe to deactivate an active
+        // invalid device admin.
+        if (!mDPM.isAdminActive(cn)) {
+            List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
+                    new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
+                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+            int count = avail == null ? 0 : avail.size();
+            boolean found = false;
+            for (int i=0; i<count; i++) {
+                ResolveInfo ri = avail.get(i);
+                if (ai.packageName.equals(ri.activityInfo.packageName)
+                        && ai.name.equals(ri.activityInfo.name)) {
+                    try {
+                        // We didn't retrieve the meta data for all possible matches, so
+                        // need to use the activity info of this specific one that was retrieved.
+                        ri.activityInfo = ai;
+                        DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri);
+                        found = true;
+                    } catch (XmlPullParserException e) {
+                        Log.w(TAG, "Bad " + ri.activityInfo, e);
+                    } catch (IOException e) {
+                        Log.w(TAG, "Bad " + ri.activityInfo, e);
+                    }
+                    break;
                 }
-                break;
             }
-        }
-        if (!found) {
-            Log.w(TAG, "Request to add invalid device admin: " + cn);
-            finish();
-            return;
+            if (!found) {
+                Log.w(TAG, "Request to add invalid device admin: " + cn);
+                finish();
+                return;
+            }
         }
 
         ResolveInfo ri = new ResolveInfo();
diff --git a/src/com/android/settings/applications/RunningState.java b/src/com/android/settings/applications/RunningState.java
index 5797dfa..d373fdd 100644
--- a/src/com/android/settings/applications/RunningState.java
+++ b/src/com/android/settings/applications/RunningState.java
@@ -462,6 +462,12 @@
                     si.mServiceInfo = ActivityThread.getPackageManager().getServiceInfo(
                             service.service, PackageManager.GET_UNINSTALLED_PACKAGES,
                             UserHandle.getUserId(service.uid));
+
+                    if (si.mServiceInfo == null) {
+                        Log.d("RunningService", "getServiceInfo returned null for: "
+                                + service.service);
+                        return false;
+                    }
                 } catch (RemoteException e) {
                 }
                 si.mDisplayLabel = makeLabel(pm,
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index 3d68024..95d3496 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -513,6 +513,17 @@
                 info.activityName = info.appName;
                 info.icon = app.loadIcon(pm);
                 mVisibleApps.add(info);
+            } else {
+                try {
+                    PackageInfo pi = pm.getPackageInfo(app.packageName, 0);
+                    // If it's a system app that requires an account and doesn't see restricted
+                    // accounts, mark for removal. It might get shown in the UI if it has an icon
+                    // but will still be marked as false and immutable.
+                    if (pi.requiredAccountType != null && pi.restrictedAccountType == null) {
+                        mSelectedPackages.put(app.packageName, false);
+                    }
+                } catch (NameNotFoundException re) {
+                }
             }
         }