Merge "Updating the screen magnification description." into jb-mr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3353e38..201f4e2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2395,7 +2395,7 @@
  damage to your phone or loss of data that may result from using
  these apps.</string>
     <!-- Applications settings screen, setting check box title. If checked, the system will send package verification requests to package verifiers on the device who will ultimately allow or reject the installation of applications. [CHAR LIMIT=30] -->
-    <string name="verify_applications">App check</string>
+    <string name="verify_applications">Verify apps</string>
     <!-- Applications settings screen, setting check box summary. This is the summary for "App Check" checkbox. [CHAR LIMIT=none] -->
     <string name="verify_applications_summary">Disallow or warn before installation of apps that may cause harm</string>
     <!-- Applications settings screen, setting check box title. If checked, applications show more settings options. -->
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index 07b1776..c737c7d 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -25,6 +25,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.security.Credentials;
 import android.security.KeyChain.KeyChainConnection;
 import android.security.KeyChain;
@@ -104,17 +105,24 @@
      */
     private int mRetriesRemaining = -1;
 
-    @Override protected void onResume() {
+    @Override
+    protected void onResume() {
         super.onResume();
 
+        if (UserHandle.myUserId() != UserHandle.USER_OWNER) {
+            Log.i(TAG, "Cannot install to CredentialStorage as non-primary user");
+            finish();
+            return;
+        }
+
         Intent intent = getIntent();
         String action = intent.getAction();
 
         if (ACTION_RESET.equals(action)) {
             new ResetDialog();
         } else {
-            if (ACTION_INSTALL.equals(action) &&
-                    "com.android.certinstaller".equals(getCallingPackage())) {
+            if (ACTION_INSTALL.equals(action)
+                    && "com.android.certinstaller".equals(getCallingPackage())) {
                 mInstallBundle = intent.getExtras();
             }
             // ACTION_UNLOCK also handled here in addition to ACTION_INSTALL
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 9837193..7c1832f6 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -48,6 +48,7 @@
 import static com.android.settings.Utils.prepareCustomPreferencesList;
 
 import android.animation.LayoutTransition;
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
@@ -127,7 +128,6 @@
 import android.widget.TabWidget;
 import android.widget.TextView;
 
-import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.settings.drawable.InsetBoundsDrawable;
 import com.android.settings.net.ChartData;
@@ -447,20 +447,24 @@
     public void onPrepareOptionsMenu(Menu menu) {
         final Context context = getActivity();
         final boolean appDetailMode = isAppDetailMode();
+        final boolean isOwner = ActivityManager.getCurrentUser() == UserHandle.USER_OWNER;
 
         mMenuDataRoaming = menu.findItem(R.id.data_usage_menu_roaming);
         mMenuDataRoaming.setVisible(hasReadyMobileRadio(context) && !appDetailMode);
         mMenuDataRoaming.setChecked(getDataRoaming());
+        mMenuDataRoaming.setVisible(isOwner);
 
         mMenuRestrictBackground = menu.findItem(R.id.data_usage_menu_restrict_background);
         mMenuRestrictBackground.setVisible(hasReadyMobileRadio(context) && !appDetailMode);
         mMenuRestrictBackground.setChecked(mPolicyManager.getRestrictBackground());
+        mMenuRestrictBackground.setVisible(isOwner);
 
         mMenuAutoSync = menu.findItem(R.id.data_usage_menu_auto_sync);
         mMenuAutoSync.setChecked(ContentResolver.getMasterSyncAutomatically());
+        mMenuAutoSync.setVisible(isOwner && !appDetailMode);
 
         final MenuItem split4g = menu.findItem(R.id.data_usage_menu_split_4g);
-        split4g.setVisible(hasReadyMobile4gRadio(context) && !appDetailMode);
+        split4g.setVisible(hasReadyMobile4gRadio(context) && isOwner && !appDetailMode);
         split4g.setChecked(isMobilePolicySplit());
 
         final MenuItem showWifi = menu.findItem(R.id.data_usage_menu_show_wifi);
@@ -481,7 +485,7 @@
 
         final MenuItem metered = menu.findItem(R.id.data_usage_menu_metered);
         if (hasReadyMobileRadio(context) || hasWifiRadio(context)) {
-            metered.setVisible(!appDetailMode);
+            metered.setVisible(isOwner && !appDetailMode);
         } else {
             metered.setVisible(false);
         }
@@ -681,6 +685,7 @@
 
         final Context context = getActivity();
         final String currentTab = mTabHost.getCurrentTabTag();
+        final boolean isOwner = ActivityManager.getCurrentUser() == UserHandle.USER_OWNER;
 
         if (currentTab == null) {
             Log.w(TAG, "no tab selected; hiding body");
@@ -695,7 +700,7 @@
 
         if (LOGD) Log.d(TAG, "updateBody() with currentTab=" + currentTab);
 
-        mDataEnabledView.setVisibility(View.VISIBLE);
+        mDataEnabledView.setVisibility(isOwner ? View.VISIBLE : View.GONE);
 
         // TODO: remove mobile tabs when SIM isn't ready
         final TelephonyManager tele = TelephonyManager.from(context);
@@ -774,8 +779,8 @@
         mChart.bindNetworkPolicy(null);
 
         // show icon and all labels appearing under this app
-        final int appId = mCurrentApp.appId;
-        final UidDetail detail = mUidDetailProvider.getUidDetail(appId, true);
+        final int uid = mCurrentApp.key;
+        final UidDetail detail = mUidDetailProvider.getUidDetail(uid, true);
         mAppIcon.setImageDrawable(detail.icon);
 
         mAppTitles.removeAllViews();
@@ -788,14 +793,21 @@
         }
 
         // enable settings button when package provides it
-        // TODO: target torwards entire UID instead of just first package
-        final String[] packageNames = pm.getPackagesForUid(appId);
+        final String[] packageNames = pm.getPackagesForUid(uid);
         if (packageNames != null && packageNames.length > 0) {
             mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
-            mAppSettingsIntent.setPackage(packageNames[0]);
             mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT);
 
-            final boolean matchFound = pm.resolveActivity(mAppSettingsIntent, 0) != null;
+            // Search for match across all packages
+            boolean matchFound = false;
+            for (String packageName : packageNames) {
+                mAppSettingsIntent.setPackage(packageName);
+                if (pm.resolveActivity(mAppSettingsIntent, 0) != null) {
+                    matchFound = true;
+                    break;
+                }
+            }
+
             mAppSettings.setEnabled(matchFound);
             mAppSettings.setVisibility(View.VISIBLE);
 
@@ -806,7 +818,7 @@
 
         updateDetailData();
 
-        if (UserHandle.isApp(appId) && !mPolicyManager.getRestrictBackground()
+        if (UserHandle.isApp(uid) && !mPolicyManager.getRestrictBackground()
                 && isBandwidthControlEnabled() && hasReadyMobileRadio(context)) {
             setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background);
             setPreferenceSummary(mAppRestrictView,
@@ -855,7 +867,8 @@
     }
 
     private boolean isNetworkPolicyModifiable(NetworkPolicy policy) {
-        return policy != null && isBandwidthControlEnabled() && mDataEnabled.isChecked();
+        return policy != null && isBandwidthControlEnabled() && mDataEnabled.isChecked()
+                && ActivityManager.getCurrentUser() == UserHandle.USER_OWNER;
     }
 
     private boolean isBandwidthControlEnabled() {
@@ -886,16 +899,16 @@
     }
 
     private boolean getAppRestrictBackground() {
-        final int appId = mCurrentApp.appId;
-        final int uidPolicy = mPolicyManager.getAppPolicy(appId);
+        final int uid = mCurrentApp.key;
+        final int uidPolicy = mPolicyManager.getUidPolicy(uid);
         return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
     }
 
     private void setAppRestrictBackground(boolean restrictBackground) {
         if (LOGD) Log.d(TAG, "setAppRestrictBackground()");
-        final int appId = mCurrentApp.appId;
-        mPolicyManager.setAppPolicy(appId,
-                restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
+        final int uid = mCurrentApp.key;
+        mPolicyManager.setUidPolicy(
+                uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
         mAppRestrict.setChecked(restrictBackground);
     }
 
@@ -1080,7 +1093,7 @@
             // TODO: sigh, remove this hack once we understand 6450986
             if (mUidDetailProvider == null || app == null) return;
 
-            final UidDetail detail = mUidDetailProvider.getUidDetail(app.appId, true);
+            final UidDetail detail = mUidDetailProvider.getUidDetail(app.key, true);
             AppDetailsFragment.show(DataUsageSummary.this, app, detail.label);
         }
     };
@@ -1224,9 +1237,9 @@
 
         @Override
         public void onLoadFinished(Loader<NetworkStats> loader, NetworkStats data) {
-            final int[] restrictedAppIds = mPolicyManager.getAppsWithPolicy(
+            final int[] restrictedUids = mPolicyManager.getUidsWithPolicy(
                     POLICY_REJECT_METERED_BACKGROUND);
-            mAdapter.bindStats(data, restrictedAppIds);
+            mAdapter.bindStats(data, restrictedUids);
             updateEmptyVisible();
         }
 
@@ -1408,17 +1421,17 @@
     }
 
     public static class AppItem implements Comparable<AppItem>, Parcelable {
-        public final int appId;
+        public final int key;
         public boolean restricted;
         public SparseBooleanArray uids = new SparseBooleanArray();
         public long total;
 
-        public AppItem(int appId) {
-            this.appId = appId;
+        public AppItem(int key) {
+            this.key = key;
         }
 
         public AppItem(Parcel parcel) {
-            appId = parcel.readInt();
+            key = parcel.readInt();
             uids = parcel.readSparseBooleanArray();
             total = parcel.readLong();
         }
@@ -1429,7 +1442,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(appId);
+            dest.writeInt(key);
             dest.writeSparseBooleanArray(uids);
             dest.writeLong(total);
         }
@@ -1475,49 +1488,56 @@
         /**
          * Bind the given {@link NetworkStats}, or {@code null} to clear list.
          */
-        public void bindStats(NetworkStats stats, int[] restrictedAppIds) {
+        public void bindStats(NetworkStats stats, int[] restrictedUids) {
             mItems.clear();
 
-            final AppItem systemItem = new AppItem(android.os.Process.SYSTEM_UID);
-            final SparseArray<AppItem> knownUids = new SparseArray<AppItem>();
+            final int currentUserId = ActivityManager.getCurrentUser();
+            final SparseArray<AppItem> knownItems = new SparseArray<AppItem>();
 
             NetworkStats.Entry entry = null;
             final int size = stats != null ? stats.size() : 0;
             for (int i = 0; i < size; i++) {
                 entry = stats.getValues(i, entry);
 
-                final boolean isApp = UserHandle.isApp(entry.uid);
-                final int appId = isApp ? UserHandle.getAppId(entry.uid) : entry.uid;
-                if (isApp || appId == UID_REMOVED || appId == UID_TETHERING) {
-                    AppItem item = knownUids.get(appId);
-                    if (item == null) {
-                        item = new AppItem(appId);
-                        knownUids.put(appId, item);
-                        mItems.add(item);
+                // Decide how to collapse items together
+                final int uid = entry.uid;
+                final int collapseKey;
+                if (UserHandle.isApp(uid)) {
+                    if (UserHandle.getUserId(uid) == currentUserId) {
+                        collapseKey = uid;
+                    } else {
+                        collapseKey = UidDetailProvider.buildKeyForUser(UserHandle.getUserId(uid));
                     }
-
-                    item.total += entry.rxBytes + entry.txBytes;
-                    item.addUid(entry.uid);
+                } else if (uid == UID_REMOVED || uid == UID_TETHERING) {
+                    collapseKey = uid;
                 } else {
-                    systemItem.total += entry.rxBytes + entry.txBytes;
-                    systemItem.addUid(entry.uid);
+                    collapseKey = android.os.Process.SYSTEM_UID;
                 }
+
+                AppItem item = knownItems.get(collapseKey);
+                if (item == null) {
+                    item = new AppItem(collapseKey);
+                    mItems.add(item);
+                    knownItems.put(item.key, item);
+                }
+                item.addUid(uid);
+                item.total += entry.rxBytes + entry.txBytes;
             }
 
-            for (int appId : restrictedAppIds) {
-                AppItem item = knownUids.get(appId);
+            for (int uid : restrictedUids) {
+                // Only splice in restricted state for current user
+                if (UserHandle.getUserId(uid) != currentUserId) continue;
+
+                AppItem item = knownItems.get(uid);
                 if (item == null) {
-                    item = new AppItem(appId);
+                    item = new AppItem(uid);
                     item.total = -1;
                     mItems.add(item);
+                    knownItems.put(item.key, item);
                 }
                 item.restricted = true;
             }
 
-            if (systemItem.total > 0) {
-                mItems.add(systemItem);
-            }
-
             Collections.sort(mItems);
             mLargest = (mItems.size() > 0) ? mItems.get(0).total : 0;
             notifyDataSetChanged();
@@ -1535,7 +1555,7 @@
 
         @Override
         public long getItemId(int position) {
-            return mItems.get(position).appId;
+            return mItems.get(position).key;
         }
 
         @Override
@@ -2126,7 +2146,7 @@
                 existing.cancel(false);
             }
 
-            final UidDetail cachedDetail = provider.getUidDetail(item.appId, false);
+            final UidDetail cachedDetail = provider.getUidDetail(item.key, false);
             if (cachedDetail != null) {
                 bindView(cachedDetail, target);
             } else {
@@ -2155,7 +2175,7 @@
 
         @Override
         protected UidDetail doInBackground(Void... params) {
-            return mProvider.getUidDetail(mItem.appId, true);
+            return mProvider.getUidDetail(mItem.key, true);
         }
 
         @Override
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 88b3e87..bf31386 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -100,6 +100,7 @@
             R.id.wireless_section,
             R.id.wifi_settings,
             R.id.bluetooth_settings,
+            R.id.data_usage_settings,
             R.id.device_section,
             R.id.sound_settings,
             R.id.display_settings,
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 1240d43..0a73b02 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -20,6 +20,7 @@
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Fragment;
 import android.app.INotificationManager;
@@ -41,6 +42,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceFrameLayout;
 import android.provider.Settings;
@@ -1119,11 +1121,15 @@
                                 + prefActivities.get(i).getPackageName());
                         pm.clearPackagePreferredActivities(prefActivities.get(i).getPackageName());
                     }
-                    final int[] restrictedAppIds = npm.getAppsWithPolicy(
+                    final int[] restrictedUids = npm.getUidsWithPolicy(
                             POLICY_REJECT_METERED_BACKGROUND);
-                    for (int i : restrictedAppIds) {
-                        if (DEBUG) Log.v(TAG, "Clearing data policy: " + i);
-                        npm.setAppPolicy(i, POLICY_NONE);
+                    final int currentUserId = ActivityManager.getCurrentUser();
+                    for (int uid : restrictedUids) {
+                        // Only reset for current user
+                        if (UserHandle.getUserId(uid) == currentUserId) {
+                            if (DEBUG) Log.v(TAG, "Clearing data policy: " + uid);
+                            npm.setUidPolicy(uid, POLICY_NONE);
+                        }
                     }
                     handler.post(new Runnable() {
                         @Override public void run() {
diff --git a/src/com/android/settings/net/UidDetailProvider.java b/src/com/android/settings/net/UidDetailProvider.java
index dd2b8c0..37b99dd 100644
--- a/src/com/android/settings/net/UidDetailProvider.java
+++ b/src/com/android/settings/net/UidDetailProvider.java
@@ -21,20 +21,30 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.net.TrafficStats;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
 
+/**
+ * Return details about a specific UID, handling special cases like
+ * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}.
+ */
 public class UidDetailProvider {
     private final Context mContext;
     private final SparseArray<UidDetail> mUidDetailCache;
 
+    public static int buildKeyForUser(int userHandle) {
+        return -(2000 + userHandle);
+    }
+
     public UidDetailProvider(Context context) {
         mContext = context.getApplicationContext();
         mUidDetailCache = new SparseArray<UidDetail>();
@@ -101,10 +111,21 @@
                 return detail;
         }
 
+        // Handle keys that are actually user handles
+        if (uid <= -2000) {
+            final int userHandle = (-uid) - 2000;
+            final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+            final UserInfo info = um.getUserInfo(userHandle);
+            if (info != null) {
+                detail.label = res.getString(R.string.running_process_item_user_label, info.name);
+                detail.icon = Drawable.createFromPath(info.iconPath);
+                return detail;
+            }
+        }
+
         // otherwise fall back to using packagemanager labels
         final String[] packageNames = pm.getPackagesForUid(uid);
         final int length = packageNames != null ? packageNames.length : 0;
-
         try {
             if (length == 1) {
                 final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0);