Zen: New behavior for built-in downtime + nextalarm conditions.

 - Downtime: Allow user to enter downtime early, offer as an end
   condition four hours before downtime starts.  Available in
   either none or priority, regardless of settings configuration.
 - Downtime: Always exit before next alarm if zen=none.
 - Downtime: Make more like any other condition provider, remove
   special status (mostly).
 - Downtime: New auto-triggering rules, allow triggering after a
   manual condition ends, once.
 - Decouple NextAlarm + Downtime providers, allow them to offer
   their conditions at the same time.
 - Downtime/NextAlarm: Update conditions if they change while being
   requested, even if unsubscribed.
 - Make all three built-in condition providers optional, via config.
 - New internal helper for runtime config.
 - Don't follow changes to next alarm, consider the condition false.
 - Isolate downtime calendar logic into separate class (for testing).
 - Allow a:bb -> a:bb as a valid downtime range (all day).
 - Volume dialog: configuration establishes maximum number of visible
   conditions, including built-ins.
 - Zen mode panel: avoid widget updates during layout transition.
 - Zen mode panel: move controller callers to background thread.
 - Zen mode panel: hide/show/rebind rows instead of adding/removing.
 - ZenLog: Add downtime autotrigger results.
 - Volume panel: Smarter refresh on ringer/zen changes.

Bug: 16373455

Change-Id: I4f801018ddb0beb6eb9fa03a81c79f7949888a3f
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index d3a8fc0..acdcfc1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -124,8 +124,7 @@
     private static final int MSG_ZEN_MODE_AVAILABLE_CHANGED = 13;
     private static final int MSG_USER_ACTIVITY = 14;
     private static final int MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED = 15;
-    private static final int MSG_ZEN_MODE_CHANGED = 16;
-    private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 17;
+    private static final int MSG_INTERNAL_RINGER_MODE_CHANGED = 16;
 
     // Pseudo stream type for master volume
     private static final int STREAM_MASTER = -100;
@@ -511,6 +510,9 @@
                 pw.println();
             }
         }
+        if (mZenPanel != null) {
+            mZenPanel.dump(fd, pw, args);
+        }
     }
 
     private void initZenModePanel() {
@@ -723,7 +725,7 @@
             mSliderPanel.addView(active.group);
             mActiveStreamType = activeStreamType;
             active.group.setVisibility(View.VISIBLE);
-            updateSlider(active);
+            updateSlider(active, true /*forceReloadIcon*/);
             updateTimeoutDelay();
             updateZenPanelVisible();
         }
@@ -799,11 +801,12 @@
     }
 
     /** Update the mute and progress state of a slider */
-    private void updateSlider(StreamControl sc) {
+    private void updateSlider(StreamControl sc, boolean forceReloadIcon) {
         updateSliderProgress(sc, -1);
         final boolean muted = isMuted(sc.streamType);
-        // Force reloading the image resource
-        sc.icon.setImageDrawable(null);
+        if (forceReloadIcon) {
+            sc.icon.setImageDrawable(null);
+        }
         updateSliderIcon(sc, muted);
         updateSliderEnabled(sc, muted, false);
         updateSliderSuppressor(sc);
@@ -907,11 +910,18 @@
         }
     }
 
-    public void updateStates() {
+    private void updateStates() {
         final int count = mSliderPanel.getChildCount();
         for (int i = 0; i < count; i++) {
             StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag();
-            updateSlider(sc);
+            updateSlider(sc, true /*forceReloadIcon*/);
+        }
+    }
+
+    private void updateActiveSlider() {
+        final StreamControl active = mStreamControls.get(mActiveStreamType);
+        if (active != null) {
+            updateSlider(active, false /*forceReloadIcon*/);
         }
     }
 
@@ -1449,12 +1459,11 @@
                 break;
             }
 
-            case MSG_ZEN_MODE_CHANGED:
             case MSG_RINGER_MODE_CHANGED:
             case MSG_INTERNAL_RINGER_MODE_CHANGED:
             case MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED: {
                 if (isShowing()) {
-                    updateStates();
+                    updateActiveSlider();
                 }
                 break;
             }
@@ -1563,10 +1572,6 @@
             mNotificationEffectsSuppressor = mZenController.getEffectsSuppressor();
             sendEmptyMessage(MSG_NOTIFICATION_EFFECTS_SUPPRESSOR_CHANGED);
         }
-
-        public void onZenChanged(int zen) {
-            sendEmptyMessage(MSG_ZEN_MODE_CHANGED);
-        }
     };
 
     private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
@@ -1591,6 +1596,7 @@
 
         public void start(StreamControl sc) {
             if (sc == null) throw new IllegalArgumentException();
+            if (LOGD) Log.d(mTag, "Secondary icon animation start");
             if (mTarget != null) {
                 cancel();
             }
@@ -1643,6 +1649,7 @@
         @Override
         public void run() {
             if (mTarget == null) return;
+            if (LOGD) Log.d(mTag, "Secondary icon animation complete, show notification slider");
             mAudioManager.forceVolumeControlStream(StreamResources.NotificationStream.streamType);
             mAudioManager.adjustStreamVolume(StreamResources.NotificationStream.streamType,
                     AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);