Add QS tile for Night Display when first used

Bug: 30994985
Test: runtest systemui, and manual - verify that the quick settings
panel does not have a Night Display quick settings tile, then turn
Night Display on and verify that the tile has appeared. Multiuser
does NOT work and is tracked separately.

Change-Id: I997b4ca7952016fc703a6bb777e500f4eccce189
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 8f9358f..bb7e19d 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -23,6 +23,7 @@
 import android.util.ArrayMap;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.NightDisplayController;
 import com.android.internal.util.Preconditions;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.fragments.FragmentService;
@@ -180,6 +181,9 @@
         mProviders.put(BatteryController.class, () ->
                 new BatteryControllerImpl(mContext));
 
+        mProviders.put(NightDisplayController.class, () ->
+                new NightDisplayController(mContext));
+
         mProviders.put(ManagedProfileController.class, () ->
                 new ManagedProfileControllerImpl(mContext));
 
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index b9ae585..e1aaaa3 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -47,6 +47,7 @@
         Key.QS_DATA_SAVER_DIALOG_SHOWN,
         Key.QS_INVERT_COLORS_ADDED,
         Key.QS_WORK_ADDED,
+        Key.QS_NIGHTDISPLAY_ADDED,
     })
     public @interface Key {
         @Deprecated
@@ -67,6 +68,7 @@
         String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown";
         String QS_INVERT_COLORS_ADDED = "QsInvertColorsAdded";
         String QS_WORK_ADDED = "QsWorkAdded";
+        String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 31cfa66..cd9a49d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -19,6 +19,8 @@
 import android.os.Looper;
 import android.provider.Settings.Secure;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.NightDisplayController;
 import com.android.systemui.Dependency;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
@@ -64,6 +66,11 @@
         if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) {
             Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
         }
+
+        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false)
+                && NightDisplayController.isAvailable(mContext)) {
+            Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);
+        }
     }
 
     public void destroy() {
@@ -71,6 +78,7 @@
         Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
+        Dependency.get(NightDisplayController.class).setListener(null);
     }
 
     private final ManagedProfileController.Callback mProfileCallback =
@@ -115,4 +123,30 @@
             }
         }
     };
+
+    @VisibleForTesting
+    final NightDisplayController.Callback mNightDisplayCallback =
+            new NightDisplayController.Callback() {
+        @Override
+        public void onActivated(boolean activated) {
+            if (activated) {
+                addNightTile();
+            }
+        }
+
+        @Override
+        public void onAutoModeChanged(int autoMode) {
+            if (autoMode == NightDisplayController.AUTO_MODE_CUSTOM
+                    || autoMode == NightDisplayController.AUTO_MODE_TWILIGHT) {
+                addNightTile();
+            }
+        }
+
+        private void addNightTile() {
+            mHost.addTile("night");
+            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true);
+            mHandler.post(() -> Dependency.get(NightDisplayController.class)
+                    .setListener(null));
+        }
+    };
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
new file mode 100644
index 0000000..9a477d2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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.systemui.statusbar.phone;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import com.android.internal.app.NightDisplayController;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+import com.android.systemui.SysUIRunner;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@RunWith(SysUIRunner.class)
+public class AutoTileManagerTest extends SysuiTestCase {
+
+    private QSTileHost mQsTileHost;
+    private AutoTileManager mAutoTileManager;
+
+    @Before
+    public void setUp() throws Exception {
+        Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, false);
+        mQsTileHost = Mockito.mock(QSTileHost.class);
+        mAutoTileManager = new AutoTileManager(mContext, mQsTileHost);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mAutoTileManager = null;
+    }
+
+    @Test
+    public void nightTileAdded_whenActivated() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onActivated(true);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileNotAdded_whenDeactivated() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onActivated(false);
+        verify(mQsTileHost, never()).addTile("night");
+    }
+
+    @Test
+    public void nightTileAdded_whenNightModeTwilight() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_TWILIGHT);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileAdded_whenNightModeCustom() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_CUSTOM);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileNotAdded_whenNightModeDisabled() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_DISABLED);
+        verify(mQsTileHost, never()).addTile("night");
+    }
+}