Introduce new volume dialog.

 - New VolumeDialog (presentation) + VolumeDialogController (state)
   to implement a volume dialog that keeps track of multiple audio
   streams, including all remote streams.
 - The dialog starts out with a single stream, with more detail available
   behind an expand chevron.
 - Existing zen options reorganized under a master switch bar
   named "Block interruptions", with "None" renamed to "No interruptions"
   and "Priority" renamed to "Priority only".
 - Combined "Block interruptions" icon replaces the now-obsolete star/no-smoking
   icons in the status bar.
 - New icons for all sliders.
 - All sliders present a continuous facade, mapped to discrete integer units
   under the hood.
 - All interesting volume events and state changes piped through one central
   helper for future routing.
 - VolumePanel is obsolete, still accessible via a sysprop if needed.
   Complete removal / garbage collection deferred until all needed
   functionality is ported over.

Bug: 19260237
Change-Id: I6689de3e4d14ae666d3e8da302cc9da2d4d77b9b
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index ac08904..387aed0 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -29,25 +29,17 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.media.AudioManager;
-import android.media.IRemoteVolumeController;
-import android.media.IVolumeController;
-import android.media.VolumePolicy;
-import android.media.session.ISessionController;
-import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
-import android.os.Bundle;
 import android.os.Handler;
-import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
-import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.statusbar.ServiceMonitor;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
@@ -59,6 +51,8 @@
     private static final String TAG = "VolumeUI";
     private static boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
 
+    private static final boolean USE_OLD_VOLUME = SystemProperties.getBoolean("volume.old", false);
+
     private final Handler mHandler = new Handler();
     private final Receiver mReceiver = new Receiver();
     private final RestorationNotification mRestorationNotification = new RestorationNotification();
@@ -67,12 +61,10 @@
     private AudioManager mAudioManager;
     private NotificationManager mNotificationManager;
     private MediaSessionManager mMediaSessionManager;
-    private VolumeController mVolumeController;
-    private RemoteVolumeController mRemoteVolumeController;
     private ServiceMonitor mVolumeControllerService;
 
-    private VolumePanel mPanel;
-    private int mDismissDelay;
+    private VolumePanelComponent mOldVolume;
+    private VolumeDialogComponent mNewVolume;
 
     @Override
     public void start() {
@@ -83,10 +75,10 @@
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         mMediaSessionManager = (MediaSessionManager) mContext
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
-        initPanel();
-        mVolumeController = new VolumeController();
-        mRemoteVolumeController = new RemoteVolumeController();
-        putComponent(VolumeComponent.class, mVolumeController);
+        final ZenModeController zenController = new ZenModeControllerImpl(mContext, mHandler);
+        mOldVolume = new VolumePanelComponent(this, mContext, mHandler, zenController);
+        mNewVolume = new VolumeDialogComponent(this, mContext, null, zenController);
+        putComponent(VolumeComponent.class, getVolumeComponent());
         mReceiver.start();
         mVolumeControllerService = new ServiceMonitor(TAG, LOGD,
                 mContext, Settings.Secure.VOLUME_CONTROLLER_SERVICE_COMPONENT,
@@ -94,30 +86,30 @@
         mVolumeControllerService.start();
     }
 
+    private VolumeComponent getVolumeComponent() {
+        return USE_OLD_VOLUME ? mOldVolume : mNewVolume;
+    }
+
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        if (mPanel != null) {
-            mPanel.onConfigurationChanged(newConfig);
-        }
+        if (!mEnabled) return;
+        getVolumeComponent().onConfigurationChanged(newConfig);
     }
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("mEnabled="); pw.println(mEnabled);
+        if (!mEnabled) return;
         pw.print("mVolumeControllerService="); pw.println(mVolumeControllerService.getComponent());
-        if (mPanel != null) {
-            mPanel.dump(fd, pw, args);
-        }
+        getVolumeComponent().dump(fd, pw, args);
     }
 
-    private void setVolumeController(boolean register) {
+    private void setDefaultVolumeController(boolean register) {
         if (register) {
-            if (LOGD) Log.d(TAG, "Registering default volume controller");
-            mAudioManager.setVolumeController(mVolumeController);
-            mAudioManager.setVolumePolicy(VolumePolicy.DEFAULT);
-            mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
             DndTile.setVisible(mContext, false);
+            if (LOGD) Log.d(TAG, "Registering default volume controller");
+            getVolumeComponent().register();
         } else {
             if (LOGD) Log.d(TAG, "Unregistering default volume controller");
             mAudioManager.setVolumeController(null);
@@ -125,33 +117,6 @@
         }
     }
 
-    private void initPanel() {
-        mDismissDelay = mContext.getResources().getInteger(R.integer.volume_panel_dismiss_delay);
-        mPanel = new VolumePanel(mContext, new ZenModeControllerImpl(mContext, mHandler));
-        mPanel.setCallback(new VolumePanel.Callback() {
-            @Override
-            public void onZenSettings() {
-                mHandler.removeCallbacks(mStartZenSettings);
-                mHandler.post(mStartZenSettings);
-            }
-
-            @Override
-            public void onInteraction() {
-                final KeyguardViewMediator kvm = getComponent(KeyguardViewMediator.class);
-                if (kvm != null) {
-                    kvm.userActivity();
-                }
-            }
-
-            @Override
-            public void onVisible(boolean visible) {
-                if (mAudioManager != null && mVolumeController != null) {
-                    mAudioManager.notifyVolumeControllerVisible(mVolumeController, visible);
-                }
-            }
-        });
-    }
-
     private String getAppLabel(ComponentName component) {
         final String pkg = component.getPackageName();
         try {
@@ -179,83 +144,11 @@
         d.show();
     }
 
-    private final Runnable mStartZenSettings = new Runnable() {
-        @Override
-        public void run() {
-            getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard(
-                    ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */);
-            mPanel.postDismiss(mDismissDelay);
-        }
-    };
-
-    /** For now, simply host an unmodified base volume panel in this process. */
-    private final class VolumeController extends IVolumeController.Stub implements VolumeComponent {
-
-        @Override
-        public void displaySafeVolumeWarning(int flags) throws RemoteException {
-            mPanel.postDisplaySafeVolumeWarning(flags);
-        }
-
-        @Override
-        public void volumeChanged(int streamType, int flags)
-                throws RemoteException {
-            mPanel.postVolumeChanged(streamType, flags);
-        }
-
-        @Override
-        public void masterMuteChanged(int flags) throws RemoteException {
-            // no-op
-        }
-
-        @Override
-        public void setLayoutDirection(int layoutDirection)
-                throws RemoteException {
-            mPanel.postLayoutDirection(layoutDirection);
-        }
-
-        @Override
-        public void dismiss() throws RemoteException {
-            dismissNow();
-        }
-
-        @Override
-        public ZenModeController getZenController() {
-            return mPanel.getZenController();
-        }
-
-        @Override
-        public void dispatchDemoCommand(String command, Bundle args) {
-            mPanel.dispatchDemoCommand(command, args);
-        }
-
-        @Override
-        public void dismissNow() {
-            mPanel.postDismiss(0);
-        }
-    }
-
-    private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
-
-        @Override
-        public void remoteVolumeChanged(ISessionController binder, int flags)
-                throws RemoteException {
-            MediaController controller = new MediaController(mContext, binder);
-            mPanel.postRemoteVolumeChanged(controller, flags);
-        }
-
-        @Override
-        public void updateRemoteController(ISessionController session) throws RemoteException {
-            mPanel.postRemoteSliderVisibility(session != null);
-            // TODO stash default session in case the slider can be opened other
-            // than by remoteVolumeChanged.
-        }
-    }
-
     private final class ServiceMonitorCallbacks implements ServiceMonitor.Callbacks {
         @Override
         public void onNoService() {
             if (LOGD) Log.d(TAG, "onNoService");
-            setVolumeController(true);
+            setDefaultVolumeController(true);
             mRestorationNotification.hide();
             if (!mVolumeControllerService.isPackageAvailable()) {
                 mVolumeControllerService.setComponent(null);
@@ -267,8 +160,8 @@
             if (LOGD) Log.d(TAG, "onServiceStartAttempt");
             // poke the setting to update the uid
             mVolumeControllerService.setComponent(mVolumeControllerService.getComponent());
-            setVolumeController(false);
-            mVolumeController.dismissNow();
+            setDefaultVolumeController(false);
+            getVolumeComponent().dismissNow();
             mRestorationNotification.show();
             return 0;
         }