Merge "[LockScreenSetup] Fix "Choose Lock PIN" title" into mnc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 12551d0..500c0aa 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2251,7 +2251,24 @@
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.notification.NotificationAccessSettings" />
             <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
-                       android:resource="@id/security_settings" />
+                       android:resource="@id/notification_settings" />
+        </activity>
+
+        <activity android:name="Settings$ZenAccessSettingsActivity"
+                  android:label="@string/manage_zen_access_title"
+                  android:taskAffinity="">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.ZEN_ACCESS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.notification.ZenAccessSettings" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                       android:resource="@id/notification_settings" />
         </activity>
 
         <activity android:name="Settings$NotificationSettingsActivity"
diff --git a/res/drawable/ic_info.xml b/res/drawable/ic_info.xml
new file mode 100644
index 0000000..13d00a4
--- /dev/null
+++ b/res/drawable/ic_info.xml
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M11.0,17.0l2.0,0.0l0.0,-6.0l-2.0,0.0l0.0,6.0zm1.0,-15.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0zm0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0zM11.0,9.0l2.0,0.0L13.0,7.0l-2.0,0.0l0.0,2.0z"/>
+</vector>
diff --git a/res/layout/app_header.xml b/res/layout/app_header.xml
index d9453f4..ffc6829 100644
--- a/res/layout/app_header.xml
+++ b/res/layout/app_header.xml
@@ -50,7 +50,7 @@
         android:minWidth="0dp"
         android:contentDescription="@string/notification_app_settings_button"
         android:scaleType="center"
-        android:src="@drawable/ic_settings_32dp"
+        android:src="@drawable/ic_info"
         style="?android:attr/borderlessButtonStyle" />
 
     <View
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7467248..7aee58a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3561,6 +3561,8 @@
     <string name="wifi_allow_scan_with_traffic">Always allow Wi\u2011Fi Roam Scans</string>
     <!-- Setting Checkbox title whether to enable WiFi Scanning in the presence of traffic. [CHAR LIMIT=80] -->
     <string name="legacy_dhcp_client">Use legacy DHCP client</string>
+    <!-- Setting Checkbox title whether to always keep cellular data active. [CHAR LIMIT=80] -->
+    <string name="mobile_data_always_on">Cellular data always active</string>
 
     <!-- setting Checkbox summary whether to show options for wireless display certification  -->
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
@@ -3587,6 +3589,7 @@
     <!-- Title of warning dialog about the implications of enabling USB debugging -->
     <!-- Setting Checkbox summary whether to use DHCP client from Lollipop (Android 5.0) [CHAR LIMIT=130] -->
     <string name="legacy_dhcp_client_summary">Use the DHCP client from Lollipop instead of the new Android DHCP client.</string>
+    <string name="mobile_data_always_on_summary">Always keep mobile data active, even when Wi\u2011Fi is active (for fast network switching).</string>
     <string name="adb_warning_title">Allow USB debugging?</string>
     <!-- Warning text to user about the implications of enabling USB debugging -->
     <string name="adb_warning_message">USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification, and read log data.</string>
@@ -5931,6 +5934,9 @@
     <!-- Sound & notification: Notification section header [CHAR LIMIT=30] -->
     <string name="notification_section_header">Notification</string>
 
+    <!-- Sound & notification: Advanced section header [CHAR LIMIT=30] -->
+    <string name="advanced_section_header">Advanced</string>
+
     <!-- Sound & notification > Notification section: Title for the pulse notification light option. [CHAR LIMIT=30] -->
     <string name="notification_pulse_title">Pulse notification light</string>
 
@@ -5996,7 +6002,7 @@
     <!-- Sound & notification > Other sounds: Value for the emergency tone option with value 2: vibrate. [CHAR LIMIT=30] -->
     <string name="emergency_tone_vibrate">Vibrate</string>
 
-    <!-- Sound & notification > Notification section: Title for managing notification listeners option. [CHAR LIMIT=30] -->
+    <!-- Sound & notification > Advanced section: Title for managing notification listeners option. [CHAR LIMIT=30] -->
     <string name="manage_notification_access_title">Notification access</string>
 
     <!-- Summary of preference to manage notification listeners, when none are enabled -->
@@ -6025,6 +6031,12 @@
         to dismiss these notifications or touch action buttons within them.
     </string>
 
+    <!-- Sound & notification > Advanced section: Title for managing Do Not Disturb access option. [CHAR LIMIT=40] -->
+    <string name="manage_zen_access_title">Do Not Disturb access</string>
+
+    <!-- Sound & notification > Do Not Disturb access > Text to display when the list is empty. [CHAR LIMIT=NONE] -->
+    <string name="zen_access_empty_text">No installed apps have requested Do Not Disturb access</string>
+
     <!-- [CHAR LIMIT=NONE] Text when loading app list in notification settings -->
     <string name="loading_notification_apps">Loading apps...</string>
 
@@ -6651,4 +6663,7 @@
     <!-- Summary for app with no battery usage [CHAR LIMIT=NONE] -->
     <string name="no_battery_summary" translatable="false">No battery use since last full charge</string>
 
+    <!-- Link to an apps notification settings [CHAR LIMIT=50] -->
+    <string name="app_notification_preferences">App notification preferences</string>
+
 </resources>
diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml
index 9aebb39..b7557b2 100644
--- a/res/xml/app_notification_settings.xml
+++ b/res/xml/app_notification_settings.xml
@@ -50,4 +50,11 @@
             android:order="4"
             android:persistent="false" />
 
+    <!-- App notification preferences -->
+    <Preference
+            android:key="app_settings"
+            android:title="@string/app_notification_preferences"
+            android:order="5"
+            android:persistent="false" />
+
 </PreferenceScreen>
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 6911892..ecab700 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -137,9 +137,14 @@
 
        <SwitchPreference
             android:key="legacy_dhcp_client"
-            android:title="@string/legacy_dhcp_client" />
+            android:title="@string/legacy_dhcp_client"
             android:summary="@string/legacy_dhcp_client_summary"/>
 
+       <SwitchPreference
+            android:key="mobile_data_always_on"
+            android:title="@string/mobile_data_always_on"
+            android:summary="@string/mobile_data_always_on_summary"/>
+
         <ListPreference
             android:key="select_usb_configuration"
             android:title="@string/select_usb_configuration_title"
diff --git a/res/xml/device_info_phone_status.xml b/res/xml/device_info_phone_status.xml
index 21c5af1..ccda55f 100644
--- a/res/xml/device_info_phone_status.xml
+++ b/res/xml/device_info_phone_status.xml
@@ -20,28 +20,34 @@
     <!-- This menu item is only for CDMA phone -->
     <Preference android:key="min_number"
         android:title="@string/status_min_number"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
     <!-- This menu item is only for CDMA phone -->
     <Preference android:key="prl_version"
         android:title="@string/status_prl_version"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
     <!-- This menu item is only for CDMA phone -->
     <Preference android:key="meid_number"
         android:title="@string/status_meid_number"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
     <Preference android:key="imei"
         android:title="@string/status_imei"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
     <Preference android:key="imei_sv"
         android:title="@string/status_imei_sv"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
     <Preference android:key="icc_id"
         android:title="@string/status_icc_id"
-        android:summary="@string/device_info_not_available" />
+        android:summary="@string/device_info_not_available"
+        android:persistent="false"/>
 
 </PreferenceScreen>
diff --git a/res/xml/notification_settings.xml b/res/xml/notification_settings.xml
index 7956a6d..72a189d 100644
--- a/res/xml/notification_settings.xml
+++ b/res/xml/notification_settings.xml
@@ -120,6 +120,12 @@
                     android:value="com.android.settings.Settings$NotificationAppListActivity" />
         </PreferenceScreen>
 
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="advanced"
+        android:title="@string/advanced_section_header" >
+
         <!-- Notification access -->
         <Preference
                 android:key="manage_notification_access"
@@ -127,6 +133,13 @@
                 android:persistent="false"
                 android:fragment="com.android.settings.notification.NotificationAccessSettings" />
 
+        <!-- Do Not Disturb access -->
+        <Preference
+                android:key="manage_zen_access"
+                android:title="@string/manage_zen_access_title"
+                android:persistent="false"
+                android:fragment="com.android.settings.notification.ZenAccessSettings" />
+
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index 81e0a46..5415ccf 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -457,7 +457,7 @@
                 String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
                 if (!TextUtils.isEmpty(password)) {
                     // success
-                    mKeyStore.password(password);
+                    mKeyStore.unlock(password);
                     // return to onResume
                     return;
                 }
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 7005ece..653a781 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -765,7 +765,7 @@
             imeSwitcher.setOnClickListener(new OnClickListener() {
                     @Override
                 public void onClick(View v) {
-                    imm.showInputMethodPicker();
+                    imm.showInputMethodPicker(false /* showAuxiliarySubtypes */);
                 }
             });
         }
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index 6c2f135..3c964c9 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -155,6 +155,7 @@
     private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
     private static final String SELECT_USB_CONFIGURATION_PROPERTY = "sys.usb.config";
     private static final String WIFI_LEGACY_DHCP_CLIENT_KEY = "legacy_dhcp_client";
+    private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
     private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
 
@@ -208,6 +209,7 @@
     private SwitchPreference mWifiVerboseLogging;
     private SwitchPreference mWifiAggressiveHandover;
     private SwitchPreference mLegacyDhcpClient;
+    private SwitchPreference mMobileDataAlwaysOn;
 
     private SwitchPreference mWifiAllowScansWithTraffic;
     private SwitchPreference mStrictMode;
@@ -353,6 +355,7 @@
         mWifiAggressiveHandover = findAndInitSwitchPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
         mWifiAllowScansWithTraffic = findAndInitSwitchPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
         mLegacyDhcpClient = findAndInitSwitchPref(WIFI_LEGACY_DHCP_CLIENT_KEY);
+        mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON);
         mLogdSize = addListPreference(SELECT_LOGD_SIZE_KEY);
         mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
 
@@ -586,6 +589,7 @@
         updateWifiAggressiveHandoverOptions();
         updateWifiAllowScansWithTrafficOptions();
         updateLegacyDhcpClientOptions();
+        updateMobileDataAlwaysOnOptions();
         updateSimulateColorSpace();
         updateUseNuplayerOptions();
         updateUSBAudioOptions();
@@ -1152,6 +1156,18 @@
                 mLegacyDhcpClient.isChecked() ? 1 : 0);
     }
 
+    private void updateMobileDataAlwaysOnOptions() {
+        updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(
+                getActivity().getContentResolver(),
+                Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) != 0);
+    }
+
+    private void writeMobileDataAlwaysOnOptions() {
+        Settings.Global.putInt(getActivity().getContentResolver(),
+                Settings.Global.MOBILE_DATA_ALWAYS_ON,
+                mMobileDataAlwaysOn.isChecked() ? 1 : 0);
+    }
+
     private void updateLogdSizeValues() {
         if (mLogdSize != null) {
             String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
@@ -1592,6 +1608,8 @@
             writeWifiAllowScansWithTrafficOptions();
         } else if (preference == mLegacyDhcpClient) {
             writeLegacyDhcpClientOptions();
+        } else if (preference == mMobileDataAlwaysOn) {
+            writeMobileDataAlwaysOnOptions();
         } else if (preference == mUseAwesomePlayer) {
             writeUseAwesomePlayerOptions();
         } else if (preference == mUSBAudio) {
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index b91275a..5a6a2f0 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -91,6 +91,7 @@
     public static class NotificationStationActivity extends SettingsActivity { /* empty */ }
     public static class UserSettingsActivity extends SettingsActivity { /* empty */ }
     public static class NotificationAccessSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ConditionProviderSettingsActivity extends SettingsActivity { /* empty */ }
     public static class UsbSettingsActivity extends SettingsActivity { /* empty */ }
     public static class TrustedCredentialsSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 89dbc99..aa492f3 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -103,6 +103,7 @@
 import com.android.settings.notification.NotificationSettings;
 import com.android.settings.notification.NotificationStation;
 import com.android.settings.notification.OtherSoundSettings;
+import com.android.settings.notification.ZenAccessSettings;
 import com.android.settings.notification.ZenModeEventRuleSettings;
 import com.android.settings.notification.ZenModeExternalRuleSettings;
 import com.android.settings.notification.ZenModePrioritySettings;
@@ -328,6 +329,7 @@
             DreamSettings.class.getName(),
             UserSettings.class.getName(),
             NotificationAccessSettings.class.getName(),
+            ZenAccessSettings.class.getName(),
             PrintSettingsFragment.class.getName(),
             PrintJobSettingsFragment.class.getName(),
             TrustedCredentialsSettings.class.getName(),
diff --git a/src/com/android/settings/applications/AppInfoWithHeader.java b/src/com/android/settings/applications/AppInfoWithHeader.java
index f8feaf1..5bfd79a 100644
--- a/src/com/android/settings/applications/AppInfoWithHeader.java
+++ b/src/com/android/settings/applications/AppInfoWithHeader.java
@@ -16,13 +16,19 @@
 
 package com.android.settings.applications;
 
+import android.app.Fragment;
+import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
 
 import com.android.settings.AppHeader;
 
 public abstract class AppInfoWithHeader extends AppInfoBase {
 
+    public static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton";
+
     private boolean mCreated;
 
     @Override
@@ -35,6 +41,24 @@
         mCreated = true;
         if (mPackageInfo == null) return;
         AppHeader.createAppHeader(this, mPackageInfo.applicationInfo.loadIcon(mPm),
-                mPackageInfo.applicationInfo.loadLabel(mPm), null, 0);
+                mPackageInfo.applicationInfo.loadLabel(mPm), getInfoIntent(this, mPackageName), 0);
+    }
+
+    public static Intent getInfoIntent(Fragment fragment, String packageName) {
+        Bundle args = fragment.getArguments();
+        Intent intent = fragment.getActivity().getIntent();
+        boolean showInfo = true;
+        if (args != null && args.getBoolean(EXTRA_HIDE_INFO_BUTTON, false)) {
+            showInfo = false;
+        }
+        if (intent != null && intent.getBooleanExtra(EXTRA_HIDE_INFO_BUTTON, false)) {
+            showInfo = false;
+        }
+        Intent infoIntent = null;
+        if (showInfo) {
+            infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+            infoIntent.setData(Uri.fromParts("package", packageName, null));
+        }
+        return infoIntent;
     }
 }
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java
index c5124c6..01355d9 100644
--- a/src/com/android/settings/applications/ApplicationsState.java
+++ b/src/com/android/settings/applications/ApplicationsState.java
@@ -790,6 +790,10 @@
         mApplications = new ArrayList<ApplicationInfo>();
         for (UserHandle user : mUm.getUserProfiles()) {
             try {
+                // If this user is new, it needs a map created.
+                if (mEntriesMap.indexOfKey(user.getIdentifier()) < 0) {
+                    mEntriesMap.put(user.getIdentifier(), new HashMap<String, AppEntry>());
+                }
                 ParceledListSlice<ApplicationInfo> list =
                         mIpm.getInstalledApplications(
                                 user.isOwner() ? mOwnerRetrieveFlags : mRetrieveFlags,
@@ -802,10 +806,7 @@
         if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
             // If an interesting part of the configuration has changed, we
             // should completely reload the app entries.
-            for (int i = 0; i < mEntriesMap.size(); i++) {
-                mEntriesMap.valueAt(i).clear();
-            }
-            mAppEntries.clear();
+            clearEntries();
         } else {
             for (int i=0; i<mAppEntries.size(); i++) {
                 mAppEntries.get(i).sizeStale = true;
@@ -831,12 +832,23 @@
                 entry.info = info;
             }
         }
+        if (mAppEntries.size() > mApplications.size()) {
+            // There are less apps now, some must have been uninstalled.
+            clearEntries();
+        }
         mCurComputingSizePkg = null;
         if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
             mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
         }
     }
 
+    private void clearEntries() {
+        for (int i = 0; i < mEntriesMap.size(); i++) {
+            mEntriesMap.valueAt(i).clear();
+        }
+        mAppEntries.clear();
+    }
+
     public boolean haveDisabledApps() {
         return mHaveDisabledApps;
     }
@@ -1179,7 +1191,7 @@
                     int numDone = 0;
                     synchronized (mEntriesMap) {
                         if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_ENTRIES acquired lock");
-                        for (int i=0; i<mApplications.size() && numDone<6; i++) {
+                        for (int i = 0; i < mApplications.size() && numDone < 6; i++) {
                             if (!mRunning) {
                                 mRunning = true;
                                 Message m = mMainHandler.obtainMessage(
diff --git a/src/com/android/settings/applications/DefaultBrowserPreference.java b/src/com/android/settings/applications/DefaultBrowserPreference.java
index 4479789..32f77ba 100644
--- a/src/com/android/settings/applications/DefaultBrowserPreference.java
+++ b/src/com/android/settings/applications/DefaultBrowserPreference.java
@@ -37,10 +37,10 @@
         super(context, attrs);
 
         mPm = context.getPackageManager();
-        loadBrowserApps();
+        refreshBrowserApps();
     }
 
-    private void loadBrowserApps() {
+    public void refreshBrowserApps() {
         List<String> browsers = resolveBrowserApps();
 
         setPackageNames(browsers.toArray(new String[browsers.size()]), null);
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index a6fee90..99d0172 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -246,9 +246,11 @@
         AppItem app = new AppItem(mAppEntry.info.uid);
         app.addUid(mAppEntry.info.uid);
         getLoaderManager().restartLoader(LOADER_CHART_DATA,
-                ChartDataLoader.buildArgs(NetworkTemplate.buildTemplateMobileWildcard(), app),
+                ChartDataLoader.buildArgs(getTemplate(getContext()), app),
                 mDataCallbacks);
-        new BatteryUpdater().execute();
+        if (mPackageInfo != null) {
+            new BatteryUpdater().execute();
+        }
     }
 
     @Override
@@ -616,6 +618,7 @@
         // start new activity to manage app permissions
         Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);
         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
+        intent.putExtra(AppInfoWithHeader.EXTRA_HIDE_INFO_BUTTON, true);
         try {
             startActivity(intent);
         } catch (ActivityNotFoundException e) {
@@ -627,6 +630,7 @@
         // start new fragment to display extended information
         Bundle args = new Bundle();
         args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mAppEntry.info.packageName);
+        args.putBoolean(AppInfoWithHeader.EXTRA_HIDE_INFO_BUTTON, true);
 
         SettingsActivity sa = (SettingsActivity) getActivity();
         sa.startPreferencePanel(fragment.getName(), args, -1, title, this, SUB_INFO_FRAGMENT);
@@ -636,6 +640,7 @@
         // start new fragment to display extended information
         getActivity().startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                .putExtra(AppInfoWithHeader.EXTRA_HIDE_INFO_BUTTON, true)
                 .putExtra(Settings.EXTRA_APP_PACKAGE, mAppEntry.info.packageName)
                 .putExtra(Settings.EXTRA_APP_UID, mAppEntry.info.uid));
     }
@@ -698,6 +703,16 @@
         return true;
     }
 
+    private static NetworkTemplate getTemplate(Context context) {
+        if (DataUsageSummary.hasReadyMobileRadio(context)) {
+            return NetworkTemplate.buildTemplateMobileWildcard();
+        }
+        if (DataUsageSummary.hasWifiRadio(context)) {
+            return NetworkTemplate.buildTemplateWifiWildcard();
+        }
+        return NetworkTemplate.buildTemplateEthernet();
+    }
+
     public static CharSequence getNotificationSummary(AppEntry appEntry, Context context) {
         return getNotificationSummary(appEntry, context, new NotificationBackend());
     }
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index aaec5cf..14ab541 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -162,7 +162,6 @@
 
     // whether showing system apps.
     private boolean mShowSystem;
-    private boolean mHasDisabledApps;
 
     private ApplicationsState mApplicationsState;
 
@@ -429,10 +428,11 @@
         Activity activity = getActivity();
         switch (mListType) {
             case LIST_TYPE_NOTIFICATION:
-                activity.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
+                activity.startActivityAsUser(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
                         .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                         .putExtra(Settings.EXTRA_APP_PACKAGE, mCurrentPkgName)
-                        .putExtra(Settings.EXTRA_APP_UID, mCurrentUid));
+                        .putExtra(Settings.EXTRA_APP_UID, mCurrentUid),
+                        new UserHandle(UserHandle.getUserId(mCurrentUid)));
                 break;
             case LIST_TYPE_DOMAINS_URLS:
                 startAppInfoFragment(AppLaunchSettings.class, R.string.auto_launch_label);
@@ -559,7 +559,6 @@
     }
 
     public void setHasDisabled(boolean hasDisabledApps) {
-        mHasDisabledApps = hasDisabledApps;
         mFilterAdapter.setFilterEnabled(FILTER_APPS_ENABLED, hasDisabledApps);
         mFilterAdapter.setFilterEnabled(FILTER_APPS_DISABLED, hasDisabledApps);
     }
@@ -817,7 +816,7 @@
                 return;
             }
 
-            mManageApplications.setHasDisabled(hasDisabledApps());
+            mManageApplications.setHasDisabled(mState.haveDisabledApps());
         }
 
         private void updateLoading() {
diff --git a/src/com/android/settings/applications/ManageDefaultApps.java b/src/com/android/settings/applications/ManageDefaultApps.java
index 4437654..bca4b30 100644
--- a/src/com/android/settings/applications/ManageDefaultApps.java
+++ b/src/com/android/settings/applications/ManageDefaultApps.java
@@ -23,6 +23,7 @@
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.Preference;
@@ -32,6 +33,7 @@
 import android.util.Log;
 import android.view.View;
 
+import com.android.internal.content.PackageMonitor;
 import com.android.settings.InstrumentedFragment;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
@@ -57,6 +59,71 @@
     private PackageManager mPm;
     private int myUserId;
 
+    private static final long DELAY_UPDATE_BROWSER_MILLIS = 500;
+
+    private final Handler mHandler = new Handler();
+
+    private final Runnable mUpdateRunnable = new Runnable() {
+        @Override
+        public void run() {
+            updateDefaultBrowserPreference();
+        }
+    };
+
+    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageAppeared(String packageName, int reason) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageDisappeared(String packageName, int reason) {
+            sendUpdate();
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            sendUpdate();
+        }
+
+        private void sendUpdate() {
+            mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_BROWSER_MILLIS);
+        }
+    };
+
+    private void updateDefaultBrowserPreference() {
+        mDefaultBrowserPreference.refreshBrowserApps();
+
+        final PackageManager pm = getPackageManager();
+
+        String packageName = pm.getDefaultBrowserPackageName(UserHandle.myUserId());
+        if (!TextUtils.isEmpty(packageName)) {
+            // Check if the default Browser package is still there
+            Intent intent = new Intent();
+            intent.setPackage(packageName);
+            intent.setAction(Intent.ACTION_VIEW);
+            intent.addCategory(Intent.CATEGORY_BROWSABLE);
+            intent.setData(Uri.parse("http:"));
+
+            ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, myUserId);
+            if (info != null) {
+                mDefaultBrowserPreference.setValue(packageName);
+                CharSequence label = info.loadLabel(pm);
+                mDefaultBrowserPreference.setSummary(label);
+            } else {
+                mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none);
+            }
+        } else {
+            mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none);
+            Log.d(TAG, "Cannot set empty default Browser value!");
+        }
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -112,37 +179,17 @@
     }
 
     @Override
-    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
+    public void onResume() {
+        super.onResume();
+        updateDefaultBrowserPreference();
+        mPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
+    }
 
-        final PackageManager pm = getPackageManager();
+    @Override
+    public void onPause() {
+        super.onPause();
 
-        String packageName = pm.getDefaultBrowserPackageName(UserHandle.myUserId());
-        if (!TextUtils.isEmpty(packageName)) {
-            // Check if the default Browser package is still there
-            Intent intent = new Intent();
-            intent.setPackage(packageName);
-            intent.setAction(Intent.ACTION_VIEW);
-            intent.addCategory(Intent.CATEGORY_BROWSABLE);
-            intent.setData(Uri.parse("http:"));
-
-            ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, myUserId);
-            if (info != null) {
-                mDefaultBrowserPreference.setValue(packageName);
-                CharSequence label = info.loadLabel(pm);
-                mDefaultBrowserPreference.setSummary(label);
-            } else {
-                CharSequence[] values = mDefaultBrowserPreference.getEntryValues();
-                if (values.length > 0) {
-                    // Otherwise select the first one if we can
-                    mDefaultBrowserPreference.setValueIndex(0);
-                } else {
-                    // Do nothing, we cannot select any value
-                }
-            }
-        } else {
-            Log.d(TAG, "Cannot set empty default Browser value!");
-        }
+        mPackageMonitor.unregister();
     }
 
     @Override
diff --git a/src/com/android/settings/applications/ProcStatsPackageEntry.java b/src/com/android/settings/applications/ProcStatsPackageEntry.java
index feb11d8..e056b06 100644
--- a/src/com/android/settings/applications/ProcStatsPackageEntry.java
+++ b/src/com/android/settings/applications/ProcStatsPackageEntry.java
@@ -90,10 +90,10 @@
         for (int i=0; i < N; i++) {
             ProcStatsEntry entry = mEntries.get(i);
             mBgDuration += entry.mBgDuration;
-            mAvgBgMem += entry.mAvgBgMem * entry.mBgDuration;
+            mAvgBgMem += entry.mAvgBgMem;
             mBgWeight += entry.mBgWeight;
             mRunDuration += entry.mRunDuration;
-            mAvgRunMem += entry.mAvgRunMem * entry.mRunDuration;
+            mAvgRunMem += entry.mAvgRunMem;
             mRunWeight += entry.mRunWeight;
 
             // Each entry is generally a process or something similar.  Since it is extremely
@@ -103,12 +103,8 @@
             mMaxBgMem += entry.mMaxBgMem;
             mMaxRunMem += entry.mMaxRunMem;
         }
-        if (mBgDuration != 0) {
-            mAvgBgMem = mAvgBgMem * N / mBgDuration;
-        }
-        if (mRunDuration != 0) {
-            mAvgRunMem = mAvgRunMem * N / mRunDuration;
-        }
+        mAvgBgMem /= N;
+        mAvgRunMem /= N;
     }
 
     public void retrieveUiData(Context context, PackageManager pm) {
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
index 7035bf0..b29b2fe 100644
--- a/src/com/android/settings/applications/ProcessStatsDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -86,7 +86,7 @@
 
     private LinearColorBar mColorBar;
 
-    private float mMaxMemoryUsage;
+    private double mMaxMemoryUsage;
 
     private double mTotalScale;
 
@@ -101,7 +101,7 @@
         mUseUss = args.getBoolean(EXTRA_USE_USS);
         mWeightToRam = args.getDouble(EXTRA_WEIGHT_TO_RAM);
         mTotalTime = args.getLong(EXTRA_TOTAL_TIME);
-        mMaxMemoryUsage = args.getFloat(EXTRA_MAX_MEMORY_USAGE);
+        mMaxMemoryUsage = args.getDouble(EXTRA_MAX_MEMORY_USAGE);
         mTotalScale = args.getDouble(EXTRA_TOTAL_SCALE);
         mOnePercentTime = mTotalTime/100;
 
@@ -115,7 +115,7 @@
 
         AppHeader.createAppHeader(this,
                 mApp.mUiTargetApp != null ? mApp.mUiTargetApp.loadIcon(mPm) : new ColorDrawable(0),
-                mApp.mUiLabel, null);
+                mApp.mUiLabel, AppInfoWithHeader.getInfoIntent(this, mApp.mPackage));
     }
 
     @Override
@@ -199,16 +199,17 @@
 
         // TODO: Find way to share this code with ProcessStatsPreference.
         boolean statsForeground = mApp.mRunWeight > mApp.mBgWeight;
-        float mAvgRatio = (statsForeground ? mApp.mAvgRunMem : mApp.mAvgBgMem) / mMaxMemoryUsage;
-        float mMaxRatio = (statsForeground ? mApp.mMaxRunMem : mApp.mMaxBgMem) / mMaxMemoryUsage
-                - mAvgRatio;
-        float mRemainingRatio = 1 - mAvgRatio - mMaxRatio;
+        float avgRatio = (float) ((statsForeground ? mApp.mRunWeight : mApp.mBgWeight)
+                * mWeightToRam / mMaxMemoryUsage);
+        float maxRatio = (float) ((statsForeground ? mApp.mMaxRunMem : mApp.mMaxBgMem)
+                * mTotalScale * 1024 / mMaxMemoryUsage - avgRatio);
+        float remainingRatio = 1 - avgRatio - maxRatio;
         mColorBar = (LinearColorBar) headerLayout.findViewById(R.id.color_bar);
         Context context = getActivity();
         mColorBar.setColors(context.getColor(R.color.memory_avg_use),
                 context.getColor(R.color.memory_max_use),
                 context.getColor(R.color.memory_remaining));
-        mColorBar.setRatios(mAvgRatio, mMaxRatio, mRemainingRatio);
+        mColorBar.setRatios(avgRatio, maxRatio, remainingRatio);
     }
 
     public void onClick(View v) {
diff --git a/src/com/android/settings/applications/ProcessStatsPreference.java b/src/com/android/settings/applications/ProcessStatsPreference.java
index 239e0d3..ffbc560 100644
--- a/src/com/android/settings/applications/ProcessStatsPreference.java
+++ b/src/com/android/settings/applications/ProcessStatsPreference.java
@@ -58,7 +58,8 @@
         mRemainingColor = context.getColor(R.color.memory_remaining);
     }
 
-    public void init(ProcStatsPackageEntry entry, PackageManager pm, float maxMemory) {
+    public void init(ProcStatsPackageEntry entry, PackageManager pm, double maxMemory,
+            double weightToRam, double totalScale) {
         mEntry = entry;
         setTitle(TextUtils.isEmpty(entry.mUiLabel) ? entry.mPackage : entry.mUiLabel);
         if (entry.mUiTargetApp != null) {
@@ -69,8 +70,10 @@
         boolean statsForeground = entry.mRunWeight > entry.mBgWeight;
         setSummary(entry.mRunDuration > entry.mBgDuration ? entry.getRunningFrequency(getContext())
                 : entry.getBackgroundFrequency(getContext()));
-        mAvgRatio = (statsForeground ? entry.mAvgRunMem : entry.mAvgBgMem) / maxMemory;
-        mMaxRatio = (statsForeground ? entry.mMaxRunMem : entry.mMaxBgMem) / maxMemory - mAvgRatio;
+        mAvgRatio = (float) ((statsForeground ? entry.mRunWeight : entry.mBgWeight)
+                * weightToRam / maxMemory);
+        mMaxRatio = (float) ((statsForeground ? entry.mMaxRunMem : entry.mMaxBgMem)
+                * totalScale * 1024 / maxMemory - mAvgRatio);
         mRemainingRatio = 1 - mAvgRatio - mMaxRatio;
     }
 
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index fee167a..3dc0661 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -74,16 +74,12 @@
             = new Comparator<ProcStatsPackageEntry>() {
         @Override
         public int compare(ProcStatsPackageEntry lhs, ProcStatsPackageEntry rhs) {
-            if (lhs.mRunWeight < rhs.mRunWeight) {
-                return 1;
-            } else if (lhs.mRunWeight > rhs.mRunWeight) {
-                return -1;
-            } else if (lhs.mRunDuration < rhs.mRunDuration) {
-                return 1;
-            } else if (lhs.mRunDuration > rhs.mRunDuration) {
-                return -1;
+            double rhsWeight = Math.max(rhs.mRunWeight, rhs.mBgWeight);
+            double lhsWeight = Math.max(lhs.mRunWeight, lhs.mBgWeight);
+            if (lhsWeight == rhsWeight) {
+                return 0;
             }
-            return 0;
+            return lhsWeight < rhsWeight ? 1 : -1;
         }
     };
 
@@ -128,7 +124,7 @@
     };
 
     private ProcStatsData mStatsManager;
-    private float mMaxMemoryUsage;
+    private double mMaxMemoryUsage;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -200,7 +196,7 @@
         args.putDouble(ProcessStatsDetail.EXTRA_WEIGHT_TO_RAM,
                 mStatsManager.getMemInfo().weightToRam);
         args.putLong(ProcessStatsDetail.EXTRA_TOTAL_TIME, memTotalTime);
-        args.putFloat(ProcessStatsDetail.EXTRA_MAX_MEMORY_USAGE, mMaxMemoryUsage);
+        args.putDouble(ProcessStatsDetail.EXTRA_MAX_MEMORY_USAGE, mMaxMemoryUsage);
         args.putDouble(ProcessStatsDetail.EXTRA_TOTAL_SCALE, mStatsManager.getMemInfo().totalScale);
         ((SettingsActivity) getActivity()).startPreferencePanel(
                 ProcessStatsDetail.class.getName(), args, R.string.details_title, null, null, 0);
@@ -422,7 +418,7 @@
         for (int i=0, N=pkgEntries.size(); i<N; i++) {
             ProcStatsPackageEntry pkg = pkgEntries.get(i);
             pkg.updateMetrics();
-            float maxMem = Math.max(pkg.mMaxBgMem, pkg.mMaxRunMem);
+            double maxMem = Math.max(pkg.mMaxBgMem, pkg.mMaxRunMem) * 1024 * memInfo.totalScale;
             if (maxMem > mMaxMemoryUsage) {
                 mMaxMemoryUsage = maxMem;
             }
@@ -452,7 +448,7 @@
             ProcStatsPackageEntry pkg = pkgEntries.get(i);
             ProcessStatsPreference pref = new ProcessStatsPreference(context);
             pkg.retrieveUiData(context, mPm);
-            pref.init(pkg, mPm, mMaxMemoryUsage);
+            pref.init(pkg, mPm, mMaxMemoryUsage, memInfo.weightToRam, memInfo.totalScale);
             pref.setOrder(i);
             mAppListGroup.addPreference(pref);
             if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) {
diff --git a/src/com/android/settings/deviceinfo/SimStatus.java b/src/com/android/settings/deviceinfo/SimStatus.java
index ea4c3e1..d6a3bf5 100644
--- a/src/com/android/settings/deviceinfo/SimStatus.java
+++ b/src/com/android/settings/deviceinfo/SimStatus.java
@@ -282,11 +282,17 @@
                 display = mRes.getString(R.string.radioInfo_service_in);
                 break;
             case ServiceState.STATE_OUT_OF_SERVICE:
+                // Set signal strength to 0 when service state is STATE_OUT_OF_SERVICE
+                mSignalStrength.setSummary("0");
             case ServiceState.STATE_EMERGENCY_ONLY:
+                // Set summary string of service state to radioInfo_service_out when
+                // service state is both STATE_OUT_OF_SERVICE & STATE_EMERGENCY_ONLY
                 display = mRes.getString(R.string.radioInfo_service_out);
                 break;
             case ServiceState.STATE_POWER_OFF:
                 display = mRes.getString(R.string.radioInfo_service_off);
+                // Also set signal strength to 0
+                mSignalStrength.setSummary("0");
                 break;
         }
 
@@ -314,6 +320,7 @@
             if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
                     (ServiceState.STATE_POWER_OFF == state)) {
                 mSignalStrength.setSummary("0");
+                return;
             }
 
             int signalDbm = signalStrength.getDbm();
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index bac8202..63ca1a4 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -54,6 +54,7 @@
 import com.android.settings.Utils;
 import com.android.settings.WirelessSettings;
 import com.android.settings.applications.AppInfoBase;
+import com.android.settings.applications.AppInfoWithHeader;
 import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.bluetooth.BluetoothSettings;
@@ -464,7 +465,8 @@
             appIcon = getActivity().getPackageManager().getDefaultActivityIcon();
         }
 
-        AppHeader.createAppHeader(this, appIcon, title, null,
+        AppHeader.createAppHeader(this, appIcon, title,
+                AppInfoWithHeader.getInfoIntent(this, iconPackage),
                 mDrainType != DrainType.APP ? android.R.color.white : 0);
     }
 
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 1b2f567..8f23ce9 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -325,7 +325,7 @@
             } else if (KEY_CURRENT_INPUT_METHOD.equals(preference.getKey())) {
                 final InputMethodManager imm = (InputMethodManager)
                         getSystemService(Context.INPUT_METHOD_SERVICE);
-                imm.showInputMethodPicker();
+                imm.showInputMethodPicker(false /* showAuxiliarySubtypes */);
             }
         } else if (preference instanceof SwitchPreference) {
             final SwitchPreference pref = (SwitchPreference) preference;
diff --git a/src/com/android/settings/inputmethod/InputMethodDialogReceiver.java b/src/com/android/settings/inputmethod/InputMethodDialogReceiver.java
index 46be132..e442e88 100644
--- a/src/com/android/settings/inputmethod/InputMethodDialogReceiver.java
+++ b/src/com/android/settings/inputmethod/InputMethodDialogReceiver.java
@@ -26,7 +26,7 @@
     public void onReceive(Context context, Intent intent) {
         if (Settings.ACTION_SHOW_INPUT_METHOD_PICKER.equals(intent.getAction())) {
             ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
-                    .showInputMethodPicker();
+                    .showInputMethodPicker(true /* showAuxiliarySubtypes */);
         }
     }
 }
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 28245c8..52c011c 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.SwitchPreference;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -42,6 +43,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
+import com.android.settings.applications.AppInfoWithHeader;
 import com.android.settings.notification.NotificationBackend.AppRow;
 
 import java.util.List;
@@ -55,6 +57,7 @@
     private static final String KEY_PRIORITY = "priority";
     private static final String KEY_PEEKABLE = "peekable";
     private static final String KEY_SENSITIVE = "sensitive";
+    private static final String KEY_APP_SETTINGS = "app_settings";
 
     static final String EXTRA_HAS_SETTINGS_INTENT = "has_settings_intent";
     static final String EXTRA_SETTINGS_INTENT = "settings_intent";
@@ -85,7 +88,7 @@
         mCreated = true;
         if (mAppRow == null) return;
         AppHeader.createAppHeader(this, mAppRow.icon, mAppRow.label,
-                mAppRow.settingsIntent);
+                AppInfoWithHeader.getInfoIntent(this, mAppRow.pkg));
     }
 
     @Override
@@ -189,6 +192,19 @@
                 return mBackend.setSensitive(pkg, uid, sensitive);
             }
         });
+
+        if (mAppRow.settingsIntent != null) {
+            findPreference(KEY_APP_SETTINGS).setOnPreferenceClickListener(
+                    new OnPreferenceClickListener() {
+                @Override
+                public boolean onPreferenceClick(Preference preference) {
+                    mContext.startActivity(mAppRow.settingsIntent);
+                    return true;
+                }
+            });
+        } else {
+            removePreference(KEY_APP_SETTINGS);
+        }
     }
 
     private void updateDependents(boolean banned) {
diff --git a/src/com/android/settings/notification/NotificationSettings.java b/src/com/android/settings/notification/NotificationSettings.java
index cdff32f..00f5497 100644
--- a/src/com/android/settings/notification/NotificationSettings.java
+++ b/src/com/android/settings/notification/NotificationSettings.java
@@ -79,6 +79,7 @@
     private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
     private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications";
     private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
+    private static final String KEY_ZEN_ACCESS = "manage_zen_access";
 
     private static final int SAMPLE_CUTOFF = 2000;  // manually cap sample playback at 2 seconds
 
@@ -101,6 +102,7 @@
     private TwoStatePreference mNotificationPulse;
     private DropDownPreference mLockscreen;
     private Preference mNotificationAccess;
+    private Preference mZenAccess;
     private boolean mSecure;
     private int mLockscreenSelectedValue;
     private ComponentName mSuppressor;
@@ -153,6 +155,8 @@
 
         mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS);
         refreshNotificationListeners();
+        mZenAccess = findPreference(KEY_ZEN_ACCESS);
+        refreshZenAccess();
         updateRingerMode();
         updateEffectsSuppressor();
     }
@@ -161,6 +165,7 @@
     public void onResume() {
         super.onResume();
         refreshNotificationListeners();
+        refreshZenAccess();
         lookupRingtoneNames();
         mSettingsObserver.register(true);
         mReceiver.register(true);
@@ -471,23 +476,24 @@
 
     private void refreshNotificationListeners() {
         if (mNotificationAccess != null) {
-            final int total = NotificationAccessSettings.getListenersCount(mPM);
-            if (total == 0) {
-                getPreferenceScreen().removePreference(mNotificationAccess);
+            final int n = NotificationAccessSettings.getEnabledListenersCount(mContext);
+            if (n == 0) {
+                mNotificationAccess.setSummary(getResources().getString(
+                        R.string.manage_notification_access_summary_zero));
             } else {
-                final int n = NotificationAccessSettings.getEnabledListenersCount(mContext);
-                if (n == 0) {
-                    mNotificationAccess.setSummary(getResources().getString(
-                            R.string.manage_notification_access_summary_zero));
-                } else {
-                    mNotificationAccess.setSummary(String.format(getResources().getQuantityString(
-                            R.plurals.manage_notification_access_summary_nonzero,
-                            n, n)));
-                }
+                mNotificationAccess.setSummary(String.format(getResources().getQuantityString(
+                        R.plurals.manage_notification_access_summary_nonzero,
+                        n, n)));
             }
         }
     }
 
+    // === Zen access ===
+
+    private void refreshZenAccess() {
+        // noop for now
+    }
+
     // === Callbacks ===
 
     private final class SettingsObserver extends ContentObserver {
diff --git a/src/com/android/settings/notification/ZenAccessSettings.java b/src/com/android/settings/notification/ZenAccessSettings.java
new file mode 100644
index 0000000..a9f02a9
--- /dev/null
+++ b/src/com/android/settings/notification/ZenAccessSettings.java
@@ -0,0 +1,169 @@
+/*
+ * 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.notification;
+
+import android.app.ListFragment;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+public class ZenAccessSettings extends ListFragment {
+    private static final boolean SHOW_PACKAGE_NAME = false;
+
+    private Context mContext;
+    private PackageManager mPkgMan;
+    private NotificationManager mNoMan;
+    private Adapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mContext = getActivity();
+        mPkgMan = mContext.getPackageManager();
+        mNoMan = mContext.getSystemService(NotificationManager.class);
+        mAdapter = new Adapter(mContext);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        final View v =  inflater.inflate(R.layout.managed_service_settings, container, false);
+        final TextView empty = (TextView) v.findViewById(android.R.id.empty);
+        empty.setText(R.string.zen_access_empty_text);
+        return v;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        reloadList();
+    }
+
+    private void reloadList() {
+        mAdapter.clear();
+        final ArraySet<String> requesting = mNoMan.getPackagesRequestingNotificationPolicyAccess();
+        if (requesting != null && !requesting.isEmpty()) {
+            final List<ApplicationInfo> apps = mPkgMan.getInstalledApplications(0);
+            if (apps != null) {
+                for (ApplicationInfo app : apps) {
+                    if (requesting.contains(app.packageName)) {
+                        mAdapter.add(app);
+                    }
+                }
+            }
+        }
+        mAdapter.sort(new PackageItemInfo.DisplayNameComparator(mPkgMan));
+        getListView().setAdapter(mAdapter);
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        final ApplicationInfo info = mAdapter.getItem(position);
+        final boolean hasAccess = hasAccess(info.packageName);
+        setAccess(info.packageName, !hasAccess);
+        mAdapter.notifyDataSetChanged();
+    }
+
+    private boolean hasAccess(String pkg) {
+        return mNoMan.isNotificationPolicyAccessGrantedForPackage(pkg);
+    }
+
+    private void setAccess(String pkg, boolean access) {
+        mNoMan.setNotificationPolicyAccessGranted(pkg, access);
+    }
+
+    private static class ViewHolder {
+        ImageView icon;
+        TextView name;
+        CheckBox checkbox;
+        TextView description;
+    }
+
+    private final class Adapter extends ArrayAdapter<ApplicationInfo> {
+        final LayoutInflater mInflater;
+
+        Adapter(Context context) {
+            super(context, 0, 0);
+            mInflater = (LayoutInflater)
+                    getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v;
+            if (convertView == null) {
+                v = newView(parent);
+            } else {
+                v = convertView;
+            }
+            bindView(v, position);
+            return v;
+        }
+
+        public View newView(ViewGroup parent) {
+            View v = mInflater.inflate(R.layout.managed_service_item, parent, false);
+            ViewHolder h = new ViewHolder();
+            h.icon = (ImageView) v.findViewById(R.id.icon);
+            h.name = (TextView) v.findViewById(R.id.name);
+            h.checkbox = (CheckBox) v.findViewById(R.id.checkbox);
+            h.description = (TextView) v.findViewById(R.id.description);
+            v.setTag(h);
+            return v;
+        }
+
+        public void bindView(View view, int position) {
+            ViewHolder vh = (ViewHolder) view.getTag();
+            ApplicationInfo info = getItem(position);
+
+            vh.icon.setImageDrawable(info.loadIcon(mPkgMan));
+            vh.name.setText(info.loadLabel(mPkgMan));
+            if (SHOW_PACKAGE_NAME) {
+                vh.description.setText(info.packageName);
+                vh.description.setVisibility(View.VISIBLE);
+            } else {
+                vh.description.setVisibility(View.GONE);
+            }
+            vh.checkbox.setChecked(hasAccess(info.packageName));
+        }
+
+    }
+
+}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 5b62844..09af07a 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -211,7 +211,7 @@
     }
 
     private String computeCalendarName(EventInfo event) {
-        if (event.calendar != 0) {
+        if (event.calendar != EventInfo.ANY_CALENDAR) {
             final CalendarInfo[] calendars = ZenModeEventRuleSettings.getCalendars(mContext);
             for (int i = 0; i < calendars.length; i++) {
                 final CalendarInfo calendar = calendars[i];
diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java
index 847007c..9842419 100644
--- a/src/com/android/settings/notification/ZenRuleNameDialog.java
+++ b/src/com/android/settings/notification/ZenRuleNameDialog.java
@@ -165,7 +165,7 @@
 
     private static RuleInfo defaultNewEvent() {
         final EventInfo event = new EventInfo();
-        event.calendar = 0; // any
+        event.calendar = EventInfo.ANY_CALENDAR;
         event.reply = EventInfo.REPLY_ANY_EXCEPT_NO;
         final RuleInfo rt = new RuleInfo();
         rt.settingsAction = ZenModeEventRuleSettings.ACTION;
diff --git a/tests/src/com/android/settings/vpn2/CertInstallerHelper.java b/tests/src/com/android/settings/vpn2/CertInstallerHelper.java
index f95893f..fa2638f 100644
--- a/tests/src/com/android/settings/vpn2/CertInstallerHelper.java
+++ b/tests/src/com/android/settings/vpn2/CertInstallerHelper.java
@@ -71,7 +71,7 @@
      */
     public CertInstallerHelper() {
         mKeyStore.reset();
-        mKeyStore.password(CERT_STORE_PASSWORD);
+        mKeyStore.onUserPasswordChanged(CERT_STORE_PASSWORD);
     }
 
     private void extractCertificate(String certFile, String password) {