Merge "Update strings for clarity about restricted profiles" into jb-mr2-dev
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index b2145b0..27e7a54 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -50,6 +50,8 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 
 public class DeviceAdminAdd extends Activity {
     static final String TAG = "DeviceAdminAdd";
@@ -104,7 +106,7 @@
             finish();
             return;
         }
-        
+
         ActivityInfo ai;
         try {
             ai = getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA);
@@ -113,7 +115,37 @@
             finish();
             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);
+                }
+                break;
+            }
+        }
+        if (!found) {
+            Log.w(TAG, "Request to add invalid device admin: " + cn);
+            finish();
+            return;
+        }
+
         ResolveInfo ri = new ResolveInfo();
         ri.activityInfo = ai;
         try {
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index 9cfb44d..fa1c7f4 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -43,8 +43,10 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 public class DeviceAdminSettings extends ListFragment {
     static final String TAG = "DeviceAdminSettings";
@@ -91,8 +93,33 @@
         List<ResolveInfo> avail = getActivity().getPackageManager().queryBroadcastReceivers(
                 new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
-        int count = avail == null ? 0 : avail.size();
-        for (int i=0; i<count; i++) {
+        if (avail == null) {
+            avail = Collections.emptyList();
+        }
+
+        // Some admins listed in mActiveAdmins may not have been found by the above query.
+        // We thus add them separately.
+        Set<ComponentName> activeAdminsNotInAvail = new HashSet<ComponentName>(mActiveAdmins);
+        for (ResolveInfo ri : avail) {
+            ComponentName riComponentName =
+                    new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
+            activeAdminsNotInAvail.remove(riComponentName);
+        }
+        if (!activeAdminsNotInAvail.isEmpty()) {
+            avail = new ArrayList<ResolveInfo>(avail);
+            PackageManager packageManager = getActivity().getPackageManager();
+            for (ComponentName unlistedActiveAdmin : activeAdminsNotInAvail) {
+                List<ResolveInfo> resolved = packageManager.queryBroadcastReceivers(
+                        new Intent().setComponent(unlistedActiveAdmin),
+                        PackageManager.GET_META_DATA
+                                | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+                if (resolved != null) {
+                    avail.addAll(resolved);
+                }
+            }
+        }
+
+        for (int i = 0, count = avail.size(); i < count; i++) {
             ResolveInfo ri = avail.get(i);
             try {
                 DeviceAdminInfo dpi = new DeviceAdminInfo(getActivity(), ri);
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index bfcc677..3d68024 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -607,6 +607,11 @@
                     p.setImmutable(true);
                     // If the app is required and has no restrictions, skip showing it
                     if (!hasSettings && !isSettingsApp) continue;
+                    // Get and populate the defaults, since the user is not going to be
+                    // able to toggle this app ON (it's ON by default and immutable).
+                    if (hasSettings) {
+                        requestRestrictionsForApp(packageName, p);
+                    }
                 } else if (!mNewUser && appInfoListHasPackage(mUserApps, packageName)) {
                     p.setChecked(true);
                 }
@@ -896,6 +901,12 @@
             }
         }
         preference.setRestrictions(restrictions);
+        if (count == 1 // No visible restrictions
+                && preference.isImmutable()
+                && preference.isChecked()) {
+            // Special case of required app with no visible restrictions. Remove it
+            mAppList.removePreference(preference);
+        }
     }
 
     /**
@@ -1001,7 +1012,7 @@
                     mSavedPhoto, drawable);
 
             mEditUserInfoDialog = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.user_info_settings_title)
+                .setTitle(R.string.profile_info_settings_title)
                 .setIconAttribute(R.drawable.ic_settings_multiuser)
                 .setView(content)
                 .setCancelable(true)