Merge "Update Setup Wizard redaction interstitial styles" into mnc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 674dfc9..8728ab4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1737,6 +1737,7 @@
         <activity android:name=".bluetooth.BluetoothPairingDialog"
                   android:label="@string/bluetooth_pairing_request"
                   android:excludeFromRecents="true"
+                  android:windowSoftInputMode="stateVisible|adjustResize"
                   android:theme="@*android:style/Theme.Material.Light.Dialog.Alert">
             <intent-filter android:priority="1">
                 <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
diff --git a/res/drawable/ic_menu_delete.xml b/res/drawable/ic_menu_delete.xml
index 1f211c5..74f63c3 100644
--- a/res/drawable/ic_menu_delete.xml
+++ b/res/drawable/ic_menu_delete.xml
@@ -17,8 +17,9 @@
         android:width="24.0dp"
         android:height="24.0dp"
         android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportHeight="48.0"
+        android:tint="?android:attr/colorAccent">
     <path
-        android:fillColor="?android:attr/colorAccent"
+        android:fillColor="@android:color/white"
         android:pathData="M12.0,38.0c0.0,2.21 1.79,4.0 4.0,4.0l16.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L36.0,14.0L12.0,14.0l0.0,24.0zM38.0,8.0l-7.0,0.0l-2.0,-2.0L19.0,6.0l-2.0,2.0l-7.0,0.0l0.0,4.0l28.0,0.0L38.0,8.0z"/>
 </vector>
diff --git a/res/layout/apps_filter_spinner.xml b/res/layout/apps_filter_spinner.xml
index f72d7ee..45e64c4 100644
--- a/res/layout/apps_filter_spinner.xml
+++ b/res/layout/apps_filter_spinner.xml
@@ -26,7 +26,7 @@
         android:id="@+id/filter_spinner"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
-        android:layout_marginStart="@dimen/switchbar_subsettings_margin_start"
+        android:layout_marginStart="64dp"
         android:layout_alignWithParentIfMissing="true"
         android:layout_centerVertical="true"
         android:textAlignment="viewStart" />
diff --git a/res/layout/dashboard.xml b/res/layout/dashboard.xml
index c9be94d..0563fc0 100644
--- a/res/layout/dashboard.xml
+++ b/res/layout/dashboard.xml
@@ -30,6 +30,7 @@
                 android:paddingEnd="@dimen/dashboard_padding_end"
                 android:paddingTop="@dimen/dashboard_padding_top"
                 android:paddingBottom="@dimen/dashboard_padding_bottom"
+                android:clipToPadding="false"
                 android:orientation="vertical"
                 />
 
diff --git a/res/layout/manage_applications_item.xml b/res/layout/manage_applications_item.xml
index 90555c8..6d24114 100755
--- a/res/layout/manage_applications_item.xml
+++ b/res/layout/manage_applications_item.xml
@@ -20,19 +20,19 @@
 <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:minHeight="72dp"
     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:paddingTop="8dip"
-    android:paddingBottom="8dip"
+    android:paddingTop="16dip"
+    android:paddingBottom="16dip"
     android:columnCount="4">
 
     <ImageView
         android:id="@+id/app_icon"
-        android:layout_width="@android:dimen/app_icon_size"
-        android:layout_height="@android:dimen/app_icon_size"
+        android:layout_width="@dimen/app_icon_size"
+        android:layout_height="@dimen/app_icon_size"
         android:layout_rowSpan="2"
-        android:layout_marginEnd="8dip"
+        android:layout_marginEnd="16dip"
         android:scaleType="centerInside"
         android:contentDescription="@null"
         android:duplicateParentState="true" />
diff --git a/res/layout/zen_rule_name.xml b/res/layout/zen_rule_name.xml
index 31a5df8..39262ab 100755
--- a/res/layout/zen_rule_name.xml
+++ b/res/layout/zen_rule_name.xml
@@ -32,13 +32,23 @@
 
     </EditText>
 
+    <TextView
+        android:id="@+id/rule_name_warning"
+        android:visibility="invisible"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:layout_marginLeft="26dp"
+        android:layout_marginRight="26dp"
+        android:textColor="@color/zen_rule_name_warning"
+        android:text="@string/zen_mode_rule_name_warning" />
+
     <RadioGroup
         android:id="@+id/rule_types"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginLeft="22dp"
         android:layout_marginRight="22dp"
-        android:layout_marginTop="16dp"
         android:orientation="vertical"
         android:checkedButton="@+id/rule_type_schedule" >
 
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 81d7347..dba17bd 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <color name="card_background">#ff424242</color>
-</resources>
\ No newline at end of file
+    <color name="lock_pattern_view_regular_color">@*android:color/secondary_text_default_material_dark</color>
+
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 3508893..d0ef652 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -50,6 +50,8 @@
     <color name="setup_wizard_wifi_color_dark">#89ffffff</color>
     <color name="setup_wizard_wifi_color_light">#89000000</color>
 
+    <color name="system_warning_color">#fff4511e</color><!-- deep orange 600 -->
+
     <color name="lock_pattern_background">#00000000</color>
     <color name="lock_pattern_view_regular_color">#ff37474f</color>
     <color name="lock_pattern_view_error_color">@color/warning</color>
@@ -57,14 +59,13 @@
     <color name="lock_pattern_view_regular_color_dark">#ffffff</color>
 
     <color name="unlock_pattern_view_regular_color">@android:color/white</color>
-    <color name="unlock_pattern_view_error_color">#fff4511e</color>
+    <color name="unlock_pattern_view_error_color">@color/system_warning_color</color>
 
     <color name="fingerprint_title_area_bg">?android:attr/colorAccent</color>
     <color name="fingerprint_title_color">#ffffffff</color>
     <color name="fingerprint_message_color">#de000000</color>
     <color name="fingerprint_progress_ring">?android:attr/colorAccent</color>
     <color name="fingerprint_progress_ring_bg">#20000000</color>
-    <color name="fingerprint_dot_color">?android:attr/colorAccent</color>
 
     <color name="running_processes_system_ram">#ff384248</color>
     <color name="running_processes_apps_ram">#ff009587</color>
@@ -95,4 +96,6 @@
     <color name="memory_max_use">#ff009587</color>
     <color name="memory_remaining">#ffced7db</color>
 
+    <color name="zen_rule_name_warning">@color/system_warning_color</color>
+
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d2eb0ab..5891438 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -19,7 +19,7 @@
     <dimen name="device_memory_usage_button_height">32dip</dimen>
     <dimen name="action_bar_switch_padding">16dip</dimen>
 
-    <dimen name="app_icon_size">56dip</dimen>
+    <dimen name="app_icon_size">40dip</dimen>
     <dimen name="screen_margin_sides">64dip</dimen>
     <dimen name="screen_margin_top">72dip</dimen>
     <dimen name="screen_margin_bottom">48dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4babac7..fc61b89 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4582,6 +4582,8 @@
     <string name="auto_restore_summary">When reinstalling an app, restore backed up settings and data</string>
     <!-- Title of the preference informing the user about the backup service being inactive [CHAR LIMIT=50]-->
     <string name="backup_inactive_title">Backup service is inactive.</string>
+    <!-- Default summary text of the "Configure backup account" setting [CHAR LIMIT=80]-->
+    <string name="backup_configure_account_default_summary">No account is currently storing backed up data</string>
 
     <!-- Local (desktop) backup password menu title [CHAR LIMIT=25] -->
     <string name="local_backup_password_title">Desktop backup password</string>
@@ -6102,6 +6104,9 @@
     <!-- [CHAR LIMIT=40] Zen mode settings: Rule name hint text -->
     <string name="zen_mode_rule_name_hint">Enter rule name</string>
 
+    <!-- [CHAR LIMIT=100] Zen mode settings: Warning text for invalid zen rule names -->
+    <string name="zen_mode_rule_name_warning">Rule name already in use</string>
+
     <!-- [CHAR LIMIT=40] Zen mode settings: Add rule menu option name -->
     <string name="zen_mode_add_rule">Add rule</string>
 
diff --git a/res/xml/security_settings_lockscreen.xml b/res/xml/security_settings_lockscreen.xml
index 480d6ee..fde0446 100644
--- a/res/xml/security_settings_lockscreen.xml
+++ b/res/xml/security_settings_lockscreen.xml
@@ -31,6 +31,7 @@
 
         <com.android.settings.SingleLineSummaryPreference
             android:key="owner_info_settings"
+            android:enabled="false"
             android:title="@string/owner_info_settings_title"
             android:summary="@string/owner_info_settings_summary"/>
 
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index ad76bfd..baee599 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -463,8 +463,6 @@
                 mLockPatternView.clearPattern();
                 updateStage(Stage.Introduction);
             } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
-                // They are canceling the entire wizard
-                getActivity().setResult(RESULT_FINISHED);
                 getActivity().finish();
             } else {
                 throw new IllegalStateException("left footer button pressed, but stage of " +
@@ -639,21 +637,18 @@
                 utils.setVisiblePatternEnabled(true, UserHandle.myUserId());
             }
 
-            if (!wasSecureBefore) {
-                startActivity(getRedactionInterstitialIntent(getActivity()));
-            }
-
             if (mHasChallenge) {
-                startVerifyPattern(utils);
-                return;
+                startVerifyPattern(utils, wasSecureBefore);
             } else {
+                if (!wasSecureBefore) {
+                    startActivity(getRedactionInterstitialIntent(getActivity()));
+                }
                 getActivity().setResult(RESULT_FINISHED);
+                doFinish();
             }
-
-            doFinish();
         }
 
-        private void startVerifyPattern(LockPatternUtils utils) {
+        private void startVerifyPattern(LockPatternUtils utils, final boolean wasSecureBefore) {
             mLockPatternView.disableInput();
             if (mPendingLockCheck != null) {
                 mPendingLockCheck.cancel(false);
@@ -674,6 +669,10 @@
                             mLockPatternView.enableInput();
                             mPendingLockCheck = null;
 
+                            if (!wasSecureBefore) {
+                                startActivity(getRedactionInterstitialIntent(getActivity()));
+                            }
+
                             Intent intent = new Intent();
                             intent.putExtra(
                                     ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index a295759..3a8ce90 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -170,7 +170,7 @@
         if (summary != null) {
             mConfigure.setSummary(summary);
         } else {
-            //mConfigure.setSummary(R.string.backup_configure_account_default_summary);
+            mConfigure.setSummary(R.string.backup_configure_account_default_summary);
         }
     }
 
diff --git a/src/com/android/settings/SmsDefaultDialog.java b/src/com/android/settings/SmsDefaultDialog.java
index e2a3faf..a1af021 100644
--- a/src/com/android/settings/SmsDefaultDialog.java
+++ b/src/com/android/settings/SmsDefaultDialog.java
@@ -20,19 +20,30 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.internal.telephony.SmsApplication;
 import com.android.internal.telephony.SmsApplication.SmsApplicationData;
-import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
 
 public final class SmsDefaultDialog extends AlertActivity implements
         DialogInterface.OnClickListener {
-    private ComponentName mNewDefault;
     private SmsApplicationData mNewSmsApplicationData;
 
     @Override
@@ -57,6 +68,18 @@
                 break;
             case BUTTON_NEGATIVE:
                 break;
+            default:
+                if (which >= 0) {
+                    AppListAdapter adapter = (AppListAdapter) mAlertParams.mAdapter;
+                    if (!adapter.isSelected(which)) {
+                        String packageName = adapter.getPackageName(which);
+                        if (!TextUtils.isEmpty(packageName)) {
+                            SmsApplication.setDefaultApplication(packageName, this);
+                            setResult(RESULT_OK);
+                        }
+                    }
+                }
+                break;
         }
     }
 
@@ -66,39 +89,177 @@
             // No phone, no SMS
             return false;
         }
-
-        mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this);
-        if (mNewSmsApplicationData == null) {
-            return false;
-        }
-
-        SmsApplicationData oldSmsApplicationData = null;
-        ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true);
-        if (oldSmsComponent != null) {
-            oldSmsApplicationData =
-                    SmsApplication.getSmsApplicationData(oldSmsComponent.getPackageName(), this);
-            if (oldSmsApplicationData.mPackageName.equals(mNewSmsApplicationData.mPackageName)) {
-                return false;
-            }
-        }
-
-        // Compose dialog; get
         final AlertController.AlertParams p = mAlertParams;
         p.mTitle = getString(R.string.sms_change_default_dialog_title);
-        if (oldSmsApplicationData != null) {
-            p.mMessage = getString(R.string.sms_change_default_dialog_text,
-                    mNewSmsApplicationData.mApplicationName,
-                    oldSmsApplicationData.mApplicationName);
+        mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this);
+        if (mNewSmsApplicationData != null) {
+            // New default SMS app specified, change to that directly after the confirmation
+            // dialog.
+            SmsApplicationData oldSmsApplicationData = null;
+            ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true);
+            if (oldSmsComponent != null) {
+                oldSmsApplicationData = SmsApplication.getSmsApplicationData(
+                        oldSmsComponent.getPackageName(), this);
+                if (oldSmsApplicationData.mPackageName.equals(
+                        mNewSmsApplicationData.mPackageName)) {
+                    return false;
+                }
+            }
+
+            // Compose dialog; get
+            if (oldSmsApplicationData != null) {
+                p.mMessage = getString(R.string.sms_change_default_dialog_text,
+                        mNewSmsApplicationData.mApplicationName,
+                        oldSmsApplicationData.mApplicationName);
+            } else {
+                p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text,
+                        mNewSmsApplicationData.mApplicationName);
+            }
+            p.mPositiveButtonText = getString(R.string.yes);
+            p.mNegativeButtonText = getString(R.string.no);
+            p.mPositiveButtonListener = this;
+            p.mNegativeButtonListener = this;
         } else {
-            p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text,
-                    mNewSmsApplicationData.mApplicationName);
+            // No new default SMS app specified, show a list of all SMS apps and let user to pick
+            p.mAdapter = new AppListAdapter();
+            p.mOnClickListener = this;
+            p.mNegativeButtonText = getString(R.string.cancel);
+            p.mNegativeButtonListener = this;
         }
-        p.mPositiveButtonText = getString(R.string.yes);
-        p.mNegativeButtonText = getString(R.string.no);
-        p.mPositiveButtonListener = this;
-        p.mNegativeButtonListener = this;
         setupAlert();
 
         return true;
     }
-}
\ No newline at end of file
+
+    /**
+     * The list of SMS apps with label, icon. Current default SMS app is marked as "default".
+     */
+    private class AppListAdapter extends BaseAdapter {
+        /**
+         * SMS app item in the list
+         */
+        private class Item {
+            final String label;         // app label
+            final Drawable icon;        // app icon
+            final String packgeName;    // full app package name
+
+            public Item(String label, Drawable icon, String packageName) {
+                this.label = label;
+                this.icon = icon;
+                this.packgeName = packageName;
+            }
+        }
+
+        // The list
+        private final List<Item> mItems;
+        // The index of selected
+        private final int mSelectedIndex;
+
+        public AppListAdapter() {
+            mItems = getItems();
+            int selected = getSelectedIndex();
+            // Move selected up to the top so it is easy to find
+            if (selected > 0) {
+                Item item = mItems.remove(selected);
+                mItems.add(0, item);
+                selected = 0;
+            }
+            mSelectedIndex = selected;
+        }
+
+        @Override
+        public int getCount() {
+            return mItems != null ? mItems.size() : 0;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return mItems != null && position < mItems.size() ? mItems.get(position) : null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            Item item = ((Item) getItem(position));
+            LayoutInflater inflater = getLayoutInflater();
+            View view = inflater.inflate(R.layout.app_preference_item, parent, false);
+            TextView textView = (TextView) view.findViewById(R.id.app_label);
+            textView.setText(item.label);
+            if (position == mSelectedIndex) {
+                view.findViewById(R.id.default_label).setVisibility(View.VISIBLE);
+            } else {
+                view.findViewById(R.id.default_label).setVisibility(View.GONE);
+            }
+            ImageView imageView = (ImageView)view.findViewById(R.id.app_image);
+            imageView.setImageDrawable(item.icon);
+            return view;
+        }
+
+        /**
+         * Get the selected package name by
+         *
+         * @param position the index of the item in the list
+         * @return the package name of selected item
+         */
+        public String getPackageName(int position) {
+            Item item = (Item) getItem(position);
+            if (item != null) {
+                return item.packgeName;
+            }
+            return null;
+        }
+
+        /**
+         * Check if an item at a position is already selected
+         *
+         * @param position the index of the item in the list
+         * @return true if the item at the position is already selected, false otherwise
+         */
+        public boolean isSelected(int position) {
+            return position == mSelectedIndex;
+        }
+
+        // Get the list items by looking for SMS apps
+        private List<Item> getItems() {
+            PackageManager pm = getPackageManager();
+            List<Item> items = new ArrayList<>();
+            for (SmsApplication.SmsApplicationData app :
+                    SmsApplication.getApplicationCollection(SmsDefaultDialog.this)) {
+                try {
+                    String packageName = app.mPackageName;
+                    ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0/*flags*/);
+                    if (appInfo != null) {
+                        items.add(new Item(
+                                appInfo.loadLabel(pm).toString(),
+                                appInfo.loadIcon(pm),
+                                packageName));
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    // Ignore package can't be found
+                }
+            }
+            return items;
+        }
+
+        // Get the selected item index by looking for the current default SMS app
+        private int getSelectedIndex() {
+            ComponentName appName = SmsApplication.getDefaultSmsApplication(
+                    SmsDefaultDialog.this, true);
+            if (appName != null) {
+                String defaultSmsAppPackageName = appName.getPackageName();
+                if (!TextUtils.isEmpty(defaultSmsAppPackageName)) {
+                    for (int i = 0; i < mItems.size(); i++) {
+                        if (TextUtils.equals(mItems.get(i).packgeName, defaultSmsAppPackageName)) {
+                            return i;
+                        }
+                    }
+                }
+            }
+            return -1;
+        }
+    }
+}
diff --git a/src/com/android/settings/TintablePreference.java b/src/com/android/settings/TintablePreference.java
index 3c56b1e..58794b9 100644
--- a/src/com/android/settings/TintablePreference.java
+++ b/src/com/android/settings/TintablePreference.java
@@ -40,7 +40,7 @@
         super.onBindView(view);
 
         if (mTintColor != 0) {
-            ((ImageView) view.findViewById(R.id.icon)).setImageTintList(
+            ((ImageView) view.findViewById(android.R.id.icon)).setImageTintList(
                     ColorStateList.valueOf(mTintColor));
         }
     }
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index 5e0f4eb..6dbeefd 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -54,6 +54,7 @@
     protected boolean mAppControlRestricted = false;
 
     protected ApplicationsState mState;
+    protected ApplicationsState.Session mSession;
     protected ApplicationsState.AppEntry mAppEntry;
     protected PackageInfo mPackageInfo;
     protected int mUserId;
@@ -75,6 +76,7 @@
         mFinishing = false;
 
         mState = ApplicationsState.getInstance(getActivity().getApplication());
+        mSession = mState.newSession(this);
         Context context = getActivity();
         mDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -88,6 +90,7 @@
     @Override
     public void onResume() {
         super.onResume();
+        mSession.resume();
         mAppControlRestricted = mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL);
 
         if (!refreshUi()) {
@@ -95,6 +98,12 @@
         }
     }
 
+    @Override
+    public void onPause() {
+        mSession.pause();
+        super.onPause();
+    }
+
     protected String retrieveAppEntry() {
         final Bundle args = getArguments();
         mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 4bd74b0..26e3d49 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications;
 
+import android.app.admin.DevicePolicyManager;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
@@ -32,6 +33,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkTemplate;
@@ -188,6 +190,10 @@
             enabled = false;
         }
 
+        if (isProfileOrDeviceOwner(mPackageInfo.packageName)) {
+            enabled = false;
+        }
+
         // Home apps need special handling.  Bundled ones we don't risk downgrading
         // because that can interfere with home-key resolution.  Furthermore, we
         // can't allow uninstallation of the only home app, and we don't want to
@@ -223,6 +229,23 @@
         }
     }
 
+    /** Returns if the supplied package is device owner or profile owner of at least one user */
+    private boolean isProfileOrDeviceOwner(String packageName) {
+        List<UserInfo> userInfos = mUserManager.getUsers();
+        DevicePolicyManager dpm = (DevicePolicyManager)
+                getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (packageName.equals(dpm.getDeviceOwner())) {
+            return true;
+        }
+        for (UserInfo userInfo : userInfos) {
+            ComponentName cn = dpm.getProfileOwnerAsUser(userInfo.id);
+            if (cn != null && cn.getPackageName().equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle icicle) {
diff --git a/src/com/android/settings/applications/RunningProcessesView.java b/src/com/android/settings/applications/RunningProcessesView.java
index d33acd9..ea9b6da 100644
--- a/src/com/android/settings/applications/RunningProcessesView.java
+++ b/src/com/android/settings/applications/RunningProcessesView.java
@@ -406,7 +406,7 @@
 
     // utility method used to start sub activity
     private void startServiceDetailsActivity(RunningState.MergedItem mi) {
-        if (mOwner != null) {
+        if (mOwner != null && mi != null) {
             // start new fragment to display extended information
             Bundle args = new Bundle();
             if (mi.mProcess != null) {
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
index a0a5003..886cdb2 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
@@ -17,14 +17,15 @@
 package com.android.settings.fingerprint;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.view.MotionEvent;
 import android.view.View;
@@ -82,7 +83,7 @@
         mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar);
         mFingerprintAnimator = (ImageView) findViewById(R.id.fingerprint_animator);
         mIconAnimationDrawable = (AnimatedVectorDrawable) mFingerprintAnimator.getDrawable();
-        mIconAnimationDrawable.addListener(mIconAnimationListener);
+        mIconAnimationDrawable.registerAnimationCallback(mIconAnimationCallback);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
                 this, android.R.interpolator.fast_out_slow_in);
         mFingerprintAnimator.setOnTouchListener(new View.OnTouchListener() {
@@ -248,9 +249,10 @@
         }
     };
 
-    private final Animator.AnimatorListener mIconAnimationListener = new AnimatorListenerAdapter() {
+    private final Animatable2.AnimationCallback mIconAnimationCallback =
+            new Animatable2.AnimationCallback() {
         @Override
-        public void onAnimationEnd(Animator animation) {
+        public void onAnimationEnd(Drawable d) {
             if (mAnimationCancelled) {
                 return;
             }
diff --git a/src/com/android/settings/fingerprint/FingerprintLocationAnimationView.java b/src/com/android/settings/fingerprint/FingerprintLocationAnimationView.java
index b52fed3..65f38bd 100644
--- a/src/com/android/settings/fingerprint/FingerprintLocationAnimationView.java
+++ b/src/com/android/settings/fingerprint/FingerprintLocationAnimationView.java
@@ -24,6 +24,7 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
@@ -59,7 +60,9 @@
                 R.fraction.fingerprint_sensor_location_fraction_x, 1, 1);
         mFractionCenterY = getResources().getFraction(
                 R.fraction.fingerprint_sensor_location_fraction_y, 1, 1);
-        int color = getResources().getColor(R.color.fingerprint_dot_color, null);
+        TypedValue typedValue = new TypedValue();
+        context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+        int color = getResources().getColor(typedValue.resourceId, null);
         mDotPaint.setAntiAlias(true);
         mPulsePaint.setAntiAlias(true);
         mDotPaint.setColor(color);
diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java
new file mode 100644
index 0000000..25ed8ae
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/FakeUid.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.os.BatteryStats.Timer;
+import android.os.BatteryStats.Uid;
+import android.os.Process;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+/**
+ * Fake UID for testing power usage screen.
+ */
+public class FakeUid extends Uid {
+
+    @Override
+    public int getUid() {
+        return Process.FIRST_APPLICATION_UID;
+    }
+
+    @Override
+    public ArrayMap<String, ? extends Wakelock> getWakelockStats() {
+        return null;
+    }
+
+    @Override
+    public ArrayMap<String, ? extends Timer> getSyncStats() {
+        return null;
+    }
+
+    @Override
+    public ArrayMap<String, ? extends Timer> getJobStats() {
+        return null;
+    }
+
+    @Override
+    public SparseArray<? extends Sensor> getSensorStats() {
+        return null;
+    }
+
+    @Override
+    public SparseArray<? extends Pid> getPidStats() {
+        return null;
+    }
+
+    @Override
+    public ArrayMap<String, ? extends Proc> getProcessStats() {
+        return null;
+    }
+
+    @Override
+    public ArrayMap<String, ? extends Pkg> getPackageStats() {
+        return null;
+    }
+
+    @Override
+    public long getWifiControllerActivity(int type, int which) {
+        return 0;
+    }
+
+    @Override
+    public void noteWifiRunningLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiStoppedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteFullWifiLockAcquiredLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteFullWifiLockReleasedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiScanStartedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiScanStoppedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiBatchedScanStoppedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiMulticastEnabledLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteWifiMulticastDisabledLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteActivityResumedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public void noteActivityPausedLocked(long elapsedRealtime) {
+    }
+
+    @Override
+    public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public long getWifiScanTime(long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public int getWifiScanCount(int which) {
+        return 0;
+    }
+
+    @Override
+    public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public int getWifiBatchedScanCount(int csphBin, int which) {
+        return 0;
+    }
+
+    @Override
+    public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public Timer getAudioTurnedOnTimer() {
+        return null;
+    }
+
+    @Override
+    public Timer getVideoTurnedOnTimer() {
+        return null;
+    }
+
+    @Override
+    public Timer getFlashlightTurnedOnTimer() {
+        return null;
+    }
+
+    @Override
+    public Timer getCameraTurnedOnTimer() {
+        return null;
+    }
+
+    @Override
+    public Timer getForegroundActivityTimer() {
+        return null;
+    }
+
+    @Override
+    public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
+        return 0;
+    }
+
+    @Override
+    public Timer getVibratorOnTimer() {
+        return null;
+    }
+
+    @Override
+    public void noteUserActivityLocked(int type) {
+    }
+
+    @Override
+    public boolean hasUserActivity() {
+        return false;
+    }
+
+    @Override
+    public int getUserActivityCount(int type, int which) {
+        return 0;
+    }
+
+    @Override
+    public boolean hasNetworkActivity() {
+        return false;
+    }
+
+    @Override
+    public long getNetworkActivityBytes(int type, int which) {
+        return 0;
+    }
+
+    @Override
+    public long getNetworkActivityPackets(int type, int which) {
+        return 0;
+    }
+
+    @Override
+    public long getMobileRadioActiveTime(int which) {
+        return 0;
+    }
+
+    @Override
+    public int getMobileRadioActiveCount(int which) {
+        return 0;
+    }
+
+    @Override
+    public long getUserCpuTimeUs(int which) {
+        return 0;
+    }
+
+    @Override
+    public long getSystemCpuTimeUs(int which) {
+        return 0;
+    }
+
+    @Override
+    public long getTimeAtCpuSpeed(int step, int which) {
+        return 0;
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 1fe59e9..d5e7bf7 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -35,8 +35,8 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BatterySipper;
-import com.android.internal.os.PowerProfile;
 import com.android.internal.os.BatterySipper.DrainType;
+import com.android.internal.os.PowerProfile;
 import com.android.settings.HelpUtils;
 import com.android.settings.R;
 import com.android.settings.Settings.HighPowerApplicationsActivity;
@@ -282,6 +282,8 @@
             stats.add(new BatterySipper(type, null, use));
             use += 5;
         }
+        BatterySipper sipper = new BatterySipper(DrainType.APP, new FakeUid(), use);
+        stats.add(sipper);
         return stats;
     }
 
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
index 937940a..c06038e 100644
--- a/src/com/android/settings/notification/ZenRuleNameDialog.java
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -22,6 +22,7 @@
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnDismissListener;
 import android.content.pm.ServiceInfo;
+import android.content.res.ColorStateList;
 import android.net.Uri;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.EventInfo;
@@ -31,6 +32,7 @@
 import android.text.TextWatcher;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.EditText;
@@ -47,7 +49,11 @@
 
     private final AlertDialog mDialog;
     private final EditText mEditText;
+    private final View mWarning;
     private final RadioGroup mTypes;
+    private final ColorStateList mWarningTint;
+    private final ColorStateList mOriginalTint;
+    private final String mOriginalRuleName;
     private final ArraySet<String> mExistingNames;
     private final ServiceListing mServiceListing;
     private final RuleInfo[] mExternalRules = new RuleInfo[3];
@@ -57,11 +63,17 @@
             ArraySet<String> existingNames) {
         mServiceListing = serviceListing;
         mIsNew = ruleName == null;
+        mOriginalRuleName = ruleName;
+        mWarningTint = ColorStateList.valueOf(context.getColor(R.color.zen_rule_name_warning));
         final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null, false);
         mEditText = (EditText) v.findViewById(R.id.rule_name);
+        mWarning = v.findViewById(R.id.rule_name_warning);
         if (!mIsNew) {
             mEditText.setText(ruleName);
         }
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(android.R.attr.colorAccent, outValue, true);
+        mOriginalTint = ColorStateList.valueOf(outValue.data);
         mEditText.setSelectAllOnFocus(true);
         mTypes = (RadioGroup) v.findViewById(R.id.rule_types);
         if (mServiceListing != null) {
@@ -79,7 +91,12 @@
                 .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
-                        onOk(trimmedText(), selectedRuleInfo());
+                        final String newName = trimmedText();
+                        if (!mIsNew && mOriginalRuleName != null
+                                && mOriginalRuleName.equalsIgnoreCase(newName)) {
+                            return;  // no change to an existing rule, just dismiss
+                        }
+                        onOk(newName, selectedRuleInfo());
                     }
                 })
                 .setOnDismissListener(new OnDismissListener() {
@@ -105,7 +122,7 @@
 
             @Override
             public void afterTextChanged(Editable s) {
-                updatePositiveButton();
+                updatePositiveButtonAndWarning();
             }
         });
         mExistingNames = new ArraySet<String>(existingNames.size());
@@ -118,7 +135,7 @@
 
     public void show() {
         mDialog.show();
-        updatePositiveButton();
+        updatePositiveButtonAndWarning();
     }
 
     private void bindType(int id, RuleInfo ri) {
@@ -145,11 +162,15 @@
         return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
     }
 
-    private void updatePositiveButton() {
+    private void updatePositiveButtonAndWarning() {
         final String name = trimmedText();
         final boolean validName = !TextUtils.isEmpty(name)
-                && !mExistingNames.contains(name.toLowerCase());
+                && (name.equalsIgnoreCase(mOriginalRuleName)
+                        || !mExistingNames.contains(name.toLowerCase()));
         mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validName);
+        final boolean showWarning = !TextUtils.isEmpty(name) && !validName;
+        mWarning.setVisibility(showWarning ? View.VISIBLE : View.INVISIBLE);
+        mEditText.setBackgroundTintList(showWarning ? mWarningTint : mOriginalTint);
     }
 
     private static RuleInfo defaultNewSchedule() {
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 0dee191..6b9fc2f 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -816,7 +816,8 @@
     /* package */ void forget() {
         MetricsLogger.action(getActivity(), MetricsLogger.ACTION_WIFI_FORGET);
         if (!mSelectedAccessPoint.isSaved()) {
-            if (mSelectedAccessPoint.getNetworkInfo().getState() != State.DISCONNECTED) {
+            if (mSelectedAccessPoint.getNetworkInfo() != null &&
+                    mSelectedAccessPoint.getNetworkInfo().getState() != State.DISCONNECTED) {
                 // Network is active but has no network ID - must be ephemeral.
                 mWifiManager.disableEphemeralNetwork(
                         AccessPoint.convertToQuotedString(mSelectedAccessPoint.getSsid()));