Let extra apps launch channel settings.

Test: manual
Change-Id: I689c0b35224dffc306ecbfa6f25ad3f072cd4dba
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a68b2a7..2ffc5db 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2700,6 +2700,22 @@
                 android:value="com.android.settings.notification.AppNotificationSettings" />
         </activity>
 
+        <!-- Show channel-level notification settings (channel passed in as extras) -->
+        <activity android:name="Settings$ChannelNotificationSettingsActivity"
+                  android:label="@string/app_notifications_title"
+                  android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.CHANNEL_NOTIFICATION_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.ChannelNotificationSettings" />
+        </activity>
+
         <!-- Show Manual (from settings item) -->
         <activity android:name="ManualDisplayActivity"
                   android:label="@string/manual"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 66e5b33..ab61fdd 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -124,6 +124,7 @@
     public static class ConfigureNotificationSettingsActivity extends SettingsActivity { /* empty */ }
     public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
     public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class ChannelNotificationSettingsActivity extends SettingsActivity { /* empty */ }
     public static class OtherSoundSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ManageDomainUrlsActivity extends SettingsActivity { /* empty */ }
     public static class AutomaticStorageManagerSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 76132ef..51a990e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -101,6 +101,7 @@
 import com.android.settings.nfc.AndroidBeam;
 import com.android.settings.nfc.PaymentSettings;
 import com.android.settings.notification.AppNotificationSettings;
+import com.android.settings.notification.ChannelNotificationSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
 import com.android.settings.notification.NotificationAccessSettings;
 import com.android.settings.notification.NotificationStation;
@@ -209,6 +210,7 @@
             InstalledAppDetails.class.getName(),
             BatterySaverSettings.class.getName(),
             AppNotificationSettings.class.getName(),
+            ChannelNotificationSettings.class.getName(),
             OtherSoundSettings.class.getName(),
             ApnSettings.class.getName(),
             ApnEditor.class.getName(),
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index d4cd6f8..45762c7 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -25,8 +25,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -84,6 +86,11 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo");
+            toastAndFinish();
+            return;
+        }
         final Activity activity = getActivity();
         mDashboardFeatureProvider =
                 FeatureFactory.getFactory(activity).getDashboardFeatureProvider(activity);
@@ -124,7 +131,7 @@
                         channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
                         channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
                         channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
-                        channelArgs.putString(ARG_CHANNEL, channel.getId());
+                        channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
                         Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
                                 ChannelNotificationSettings.class.getName(),
                                 channelArgs, null, 0, null, false);
@@ -154,8 +161,8 @@
     @Override
     public void onResume() {
         super.onResume();
-        if ((mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null)) {
-            // App isn't around anymore, must have been removed.
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo");
             finish();
             return;
         }
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index 2749e03..ecce79e 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -26,7 +26,6 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.net.Uri;
@@ -35,6 +34,8 @@
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
@@ -87,6 +88,11 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannel == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo or channel");
+            toastAndFinish();
+            return;
+        }
         final Activity activity = getActivity();
         mDashboardFeatureProvider =
                 FeatureFactory.getFactory(activity).getDashboardFeatureProvider(activity);
@@ -103,7 +109,7 @@
         mVibrate = (RestrictedSwitchPreference) findPreference(KEY_VIBRATE);
         mRingtone = (DefaultNotificationTonePreference) findPreference(KEY_RINGTONE);
 
-        if (mPkgInfo != null) {
+        if (mPkgInfo != null && mChannel != null) {
             setupPriorityPref(mChannel.canBypassDnd());
             setupVisOverridePref(mChannel.getLockscreenVisibility());
             setupLights();
@@ -131,8 +137,8 @@
     @Override
     public void onResume() {
         super.onResume();
-        if ((mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null)) {
-            // App isn't around anymore, must have been removed.
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannel == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo or channel");
             finish();
             return;
         }
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 1535269..f6c6591 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -18,6 +18,7 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
 import com.android.settings.applications.AppInfoBase;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedSwitchPreference;
@@ -44,8 +45,6 @@
     private static final String TAG = "NotifiSettingsBase";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    protected static final String ARG_CHANNEL = "channel";
-
     protected static final String KEY_BLOCK = "block";
     protected static final String KEY_BADGE = "badge";
 
@@ -99,26 +98,26 @@
         mUid = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_UID)
                 ? args.getInt(AppInfoBase.ARG_PACKAGE_UID)
                 : intent.getIntExtra(Settings.EXTRA_APP_UID, -1);
-        if (mUid == -1 || TextUtils.isEmpty(mPkg)) {
-            Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_PACKAGE + " was " + mPkg + ", "
-                    + Settings.EXTRA_APP_UID + " was " + mUid);
-            toastAndFinish();
-            return;
-        }
-        mUserId = UserHandle.getUserId(mUid);
 
-        if (DEBUG) Log.d(TAG, "Load details for pkg=" + mPkg + " uid=" + mUid);
+        if (mUid < 0) {
+            try {
+                mUid = mPm.getPackageUid(mPkg, 0);
+            } catch (NameNotFoundException e) {
+            }
+        }
+
         mPkgInfo = findPackageInfo(mPkg, mUid);
-        if (mPkgInfo == null) {
-            Log.w(TAG, "Failed to find package info: " + Settings.EXTRA_APP_PACKAGE + " was " + mPkg
-                    + ", " + Settings.EXTRA_APP_UID + " was " + mUid);
+
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo");
             toastAndFinish();
             return;
         }
 
+        mUserId = UserHandle.getUserId(mUid);
         mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);
-        mChannel = (args != null && args.containsKey(ARG_CHANNEL)) ?
-                mBackend.getChannel(mPkg, mUid, args.getString(ARG_CHANNEL)) : null;
+        mChannel = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_ID)) ?
+                mBackend.getChannel(mPkg, mUid, args.getString(Settings.EXTRA_CHANNEL_ID)) : null;
 
         mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
                 mContext, mPkg, mUserId);
@@ -130,8 +129,8 @@
     @Override
     public void onResume() {
         super.onResume();
-        if ((mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null)) {
-            // App isn't around anymore, must have been removed.
+        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
+            Log.w(TAG, "Missing package or uid or packageinfo");
             finish();
             return;
         }
@@ -157,6 +156,9 @@
     }
 
     private PackageInfo findPackageInfo(String pkg, int uid) {
+        if (pkg == null || uid < 0) {
+            return null;
+        }
         final String[] packages = mPm.getPackagesForUid(uid);
         if (packages != null && pkg != null) {
             final int N = packages.length;
@@ -173,4 +175,16 @@
         }
         return null;
     }
+
+    private PackageInfo findPackageInfo(String pkg) {
+        if (pkg == null) {
+            return null;
+        }
+        try {
+            return mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
+        } catch (NameNotFoundException e) {
+            Log.w(TAG, "Failed to load package " + pkg, e);
+        }
+        return null;
+    }
 }