Add alarm tile to QS.

- Add an alarm tile to QS
- Add the tile to QS the first time the user creates an alarm
- Tapping on the tile navigates to alarm settings
- Added unit tests for alarm tile
- Updated AutoAddTracker to remove deprecated shared preferences values
so the keys can be removed in a later release

Bug: 70799533
Test: manual testing the alarm QS tile behavior
Change-Id: I2b10468c41b4720b66c9e7bb32e22eb958c199f7
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 36f9f6b..b220686 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -14,16 +14,13 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.AlarmManager.AlarmClockInfo;
 import android.content.Context;
 import android.os.Handler;
-import android.os.Looper;
 import android.provider.Settings.Secure;
-
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ColorDisplayController;
 import com.android.systemui.Dependency;
-import com.android.systemui.Prefs;
-import com.android.systemui.Prefs.Key;
 import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.SecureSetting;
@@ -31,27 +28,37 @@
 import com.android.systemui.statusbar.policy.DataSaverController.Listener;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.HotspotController.Callback;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
 
 /**
  * Manages which tiles should be automatically added to QS.
  */
 public class AutoTileManager {
-
     public static final String HOTSPOT = "hotspot";
     public static final String SAVER = "saver";
     public static final String INVERSION = "inversion";
     public static final String WORK = "work";
     public static final String NIGHT = "night";
+    public static final String ALARM = "alarm";
+
     private final Context mContext;
     private final QSTileHost mHost;
     private final Handler mHandler;
     private final AutoAddTracker mAutoTracker;
 
     public AutoTileManager(Context context, QSTileHost host) {
-        mAutoTracker = new AutoAddTracker(context);
+        this(context, new AutoAddTracker(context), host,
+            new Handler(Dependency.get(Dependency.BG_LOOPER)));
+    }
+
+    @VisibleForTesting
+    AutoTileManager(Context context, AutoAddTracker autoAddTracker, QSTileHost host,
+            Handler handler) {
+        mAutoTracker = autoAddTracker;
         mContext = context;
         mHost = host;
-        mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
+        mHandler = handler;
         if (!mAutoTracker.isAdded(HOTSPOT)) {
             Dependency.get(HotspotController.class).addCallback(mHotspotCallback);
         }
@@ -76,20 +83,25 @@
         if (!mAutoTracker.isAdded(WORK)) {
             Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
         }
-
         if (!mAutoTracker.isAdded(NIGHT)
-                && ColorDisplayController.isAvailable(mContext)) {
+            && ColorDisplayController.isAvailable(mContext)) {
             Dependency.get(ColorDisplayController.class).setListener(mColorDisplayCallback);
         }
+        if (!mAutoTracker.isAdded(ALARM)) {
+            Dependency.get(NextAlarmController.class).addCallback(mNextAlarmChangeCallback);
+        }
     }
 
     public void destroy() {
-        mColorsSetting.setListening(false);
+        if (mColorsSetting != null) {
+            mColorsSetting.setListening(false);
+        }
         mAutoTracker.destroy();
         Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
         Dependency.get(ColorDisplayController.class).setListener(null);
+        Dependency.get(NextAlarmController.class).removeCallback(mNextAlarmChangeCallback);
     }
 
     private final ManagedProfileController.Callback mProfileCallback =
@@ -138,6 +150,19 @@
         }
     };
 
+    private final NextAlarmChangeCallback mNextAlarmChangeCallback = new NextAlarmChangeCallback() {
+        @Override
+        public void onNextAlarmChanged(AlarmClockInfo nextAlarm) {
+            if (mAutoTracker.isAdded(ALARM)) return;
+            if (nextAlarm != null) {
+                mHost.addTile(ALARM);
+                mAutoTracker.setTileAdded(ALARM);
+                mHandler.post(() -> Dependency.get(NextAlarmController.class)
+                    .removeCallback(mNextAlarmChangeCallback));
+            }
+        }
+    };
+
     @VisibleForTesting
     final ColorDisplayController.Callback mColorDisplayCallback =
             new ColorDisplayController.Callback() {