Force screenshots to heads-up priority.

Test: updated ChannelsTest; manually verified heads up ss posted and old channel deleted.

Change-Id: Iafc1c65d3e8a5929ba922a2814848ce5bc036747
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 675aa8f..0132fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -185,7 +185,7 @@
 
         // The public notification will show similar info but with the actual screenshot omitted
         mPublicNotificationBuilder =
-                new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
+                new Notification.Builder(context, NotificationChannels.SCREENSHOTS_HEADSUP)
                         .setContentTitle(r.getString(R.string.screenshot_saving_title))
                         .setContentText(r.getString(R.string.screenshot_saving_text))
                         .setSmallIcon(R.drawable.stat_notify_image)
@@ -196,7 +196,8 @@
                                 com.android.internal.R.color.system_notification_accent_color));
         SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder);
 
-        mNotificationBuilder = new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
+        mNotificationBuilder = new Notification.Builder(context,
+                NotificationChannels.SCREENSHOTS_HEADSUP)
             .setTicker(r.getString(R.string.screenshot_saving_ticker)
                     + (mTickerAddSpace ? " " : ""))
             .setContentTitle(r.getString(R.string.screenshot_saving_title))
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 87bc0e6..14d5c6f5 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -31,7 +31,8 @@
 
 public class NotificationChannels extends SystemUI {
     public static String ALERTS      = "ALR";
-    public static String SCREENSHOTS = "SCN";
+    public static String SCREENSHOTS_LEGACY = "SCN";
+    public static String SCREENSHOTS_HEADSUP = "SCN_HEADSUP";
     public static String GENERAL     = "GEN";
     public static String STORAGE     = "DSK";
     public static String TVPIP       = "TPP";
@@ -56,10 +57,6 @@
                         context.getString(R.string.notification_channel_alerts),
                         NotificationManager.IMPORTANCE_HIGH),
                 new NotificationChannel(
-                        SCREENSHOTS,
-                        context.getString(R.string.notification_channel_screenshot),
-                        NotificationManager.IMPORTANCE_LOW),
-                new NotificationChannel(
                         GENERAL,
                         context.getString(R.string.notification_channel_general),
                         NotificationManager.IMPORTANCE_MIN),
@@ -69,9 +66,18 @@
                         isTv(context)
                                 ? NotificationManager.IMPORTANCE_DEFAULT
                                 : NotificationManager.IMPORTANCE_LOW),
+                createScreenshotChannel(
+                        context.getString(R.string.notification_channel_screenshot),
+                        nm.getNotificationChannel(SCREENSHOTS_LEGACY)),
                 batteryChannel
         ));
 
+        // Delete older SS channel if present.
+        // Screenshots promoted to heads-up in P, this cleans up the lower priority channel from O.
+        // This line can be deleted in Q.
+        nm.deleteNotificationChannel(SCREENSHOTS_LEGACY);
+
+
         if (isTv(context)) {
             // TV specific notification channel for TV PIP controls.
             // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest
@@ -83,6 +89,40 @@
         }
     }
 
+    /**
+     * Set up screenshot channel, respecting any previously committed user settings on legacy
+     * channel.
+     * @return
+     */
+    @VisibleForTesting static NotificationChannel createScreenshotChannel(
+            String name, NotificationChannel legacySS) {
+        NotificationChannel screenshotChannel = new NotificationChannel(SCREENSHOTS_HEADSUP,
+                name, NotificationManager.IMPORTANCE_HIGH); // pop on screen
+
+        screenshotChannel.setSound(Uri.parse(""), // silent
+                new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build());
+
+        if (legacySS != null) {
+            // Respect any user modified fields from the old channel.
+            int userlock = legacySS.getUserLockedFields();
+            if ((userlock & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0) {
+                screenshotChannel.setImportance(legacySS.getImportance());
+            }
+            if ((userlock & NotificationChannel.USER_LOCKED_SOUND) != 0)  {
+                screenshotChannel.setSound(legacySS.getSound(), legacySS.getAudioAttributes());
+            }
+            if ((userlock & NotificationChannel.USER_LOCKED_VIBRATION) != 0)  {
+                screenshotChannel.setVibrationPattern(legacySS.getVibrationPattern());
+            }
+            if ((userlock & NotificationChannel.USER_LOCKED_LIGHTS) != 0)  {
+                screenshotChannel.setLightColor(legacySS.getLightColor());
+            }
+            // skip show_badge, irrelevant for system channel
+        }
+
+        return screenshotChannel;
+    }
+
     @Override
     public void start() {
         createAll(mContext);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
index 04bdc04..80dc2c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
@@ -26,11 +26,14 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.content.Context;
+import android.net.Uri;
+import android.provider.Settings;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.NotificationChannels;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,7 +57,7 @@
     public void testChannelSetup() {
         Set<String> ALL_CHANNELS = new ArraySet<>(Arrays.asList(
                 NotificationChannels.ALERTS,
-                NotificationChannels.SCREENSHOTS,
+                NotificationChannels.SCREENSHOTS_HEADSUP,
                 NotificationChannels.STORAGE,
                 NotificationChannels.GENERAL,
                 NotificationChannels.BATTERY
@@ -66,4 +69,52 @@
         assertEquals(ALL_CHANNELS.size(), list.size());
         list.forEach((chan) -> assertTrue(ALL_CHANNELS.contains(chan.getId())));
     }
+
+    @Test
+    public void testChannelSetup_noLegacyScreenshot() {
+        // Assert old channel cleaned up.
+        // TODO: remove that code + this test after P.
+        NotificationChannels.createAll(mContext);
+        ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+        verify(mMockNotificationManager).deleteNotificationChannel(
+                NotificationChannels.SCREENSHOTS_LEGACY);
+    }
+
+    @Test
+    public void testInheritFromLegacy_keepsUserLockedLegacySettings() {
+        NotificationChannel legacyChannel = new NotificationChannel("id", "oldName",
+                NotificationManager.IMPORTANCE_MIN);
+        legacyChannel.setImportance(NotificationManager.IMPORTANCE_NONE);;
+        legacyChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
+                legacyChannel.getAudioAttributes());
+        legacyChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE |
+                NotificationChannel.USER_LOCKED_SOUND);
+        NotificationChannel newChannel =
+                NotificationChannels.createScreenshotChannel("newName", legacyChannel);
+        // NONE importance user locked, so don't use HIGH for new channel.
+        assertEquals(NotificationManager.IMPORTANCE_NONE, newChannel.getImportance());
+        assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, newChannel.getSound());
+    }
+
+    @Test
+    public void testInheritFromLegacy_dropsUnlockedLegacySettings() {
+        NotificationChannel legacyChannel = new NotificationChannel("id", "oldName",
+                NotificationManager.IMPORTANCE_MIN);
+        NotificationChannel newChannel =
+                NotificationChannels.createScreenshotChannel("newName", legacyChannel);
+        assertEquals(Uri.EMPTY, newChannel.getSound());
+        assertEquals("newName", newChannel.getName());
+        // MIN importance not user locked, so HIGH wins out.
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, newChannel.getImportance());
+    }
+
+    @Test
+    public void testInheritFromLegacy_noLegacyExists() {
+        NotificationChannel newChannel =
+                NotificationChannels.createScreenshotChannel("newName", null);
+        assertEquals(Uri.EMPTY, newChannel.getSound());
+        assertEquals("newName", newChannel.getName());
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, newChannel.getImportance());
+    }
+
 }