Merge "Settings: New DND access settings page." into mnc-dev
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 253638a..7aee58a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6663,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/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/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 6d8f867..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,
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 415fff1..14ab541 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -428,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);
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
index 3c4fc02..b29b2fe 100644
--- a/src/com/android/settings/applications/ProcessStatsDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -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
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/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/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) {