Home | History | Annotate | Download | only in volume
      1 package com.android.systemui.volume;
      2 
      3 import android.content.Context;
      4 import android.content.Intent;
      5 import android.content.res.Configuration;
      6 import android.database.ContentObserver;
      7 import android.media.AudioManager;
      8 import android.media.IRemoteVolumeController;
      9 import android.media.IVolumeController;
     10 import android.media.session.ISessionController;
     11 import android.media.session.MediaController;
     12 import android.media.session.MediaSessionManager;
     13 import android.net.Uri;
     14 import android.os.AsyncTask;
     15 import android.os.Handler;
     16 import android.os.RemoteException;
     17 import android.os.UserHandle;
     18 import android.provider.Settings;
     19 import android.util.Log;
     20 import android.view.WindowManagerGlobal;
     21 
     22 import com.android.systemui.R;
     23 import com.android.systemui.SystemUI;
     24 import com.android.systemui.keyguard.KeyguardViewMediator;
     25 import com.android.systemui.statusbar.phone.PhoneStatusBar;
     26 import com.android.systemui.statusbar.policy.ZenModeController;
     27 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
     28 
     29 import java.io.FileDescriptor;
     30 import java.io.PrintWriter;
     31 
     32 /*
     33  * Copyright (C) 2014 The Android Open Source Project
     34  *
     35  * Licensed under the Apache License, Version 2.0 (the "License");
     36  * you may not use this file except in compliance with the License.
     37  * You may obtain a copy of the License at
     38  *
     39  *      http://www.apache.org/licenses/LICENSE-2.0
     40  *
     41  * Unless required by applicable law or agreed to in writing, software
     42  * distributed under the License is distributed on an "AS IS" BASIS,
     43  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     44  * See the License for the specific language governing permissions and
     45  * limitations under the License.
     46  */
     47 
     48 public class VolumeUI extends SystemUI {
     49     private static final String TAG = "VolumeUI";
     50     private static final String SETTING = "systemui_volume_controller";  // for testing
     51     private static final Uri SETTING_URI = Settings.Global.getUriFor(SETTING);
     52     private static final int DEFAULT = 1;  // enabled by default
     53 
     54     private final Handler mHandler = new Handler();
     55 
     56     private AudioManager mAudioManager;
     57     private MediaSessionManager mMediaSessionManager;
     58     private VolumeController mVolumeController;
     59     private RemoteVolumeController mRemoteVolumeController;
     60 
     61     private VolumePanel mPanel;
     62     private int mDismissDelay;
     63 
     64     @Override
     65     public void start() {
     66         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
     67         mMediaSessionManager = (MediaSessionManager) mContext
     68                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
     69         initPanel();
     70         mVolumeController = new VolumeController();
     71         mRemoteVolumeController = new RemoteVolumeController();
     72         putComponent(VolumeComponent.class, mVolumeController);
     73         updateController();
     74         mContext.getContentResolver().registerContentObserver(SETTING_URI, false, mObserver);
     75     }
     76 
     77     @Override
     78     protected void onConfigurationChanged(Configuration newConfig) {
     79         super.onConfigurationChanged(newConfig);
     80         if (mPanel != null) {
     81             mPanel.onConfigurationChanged(newConfig);
     82         }
     83     }
     84 
     85     @Override
     86     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
     87         if (mPanel != null) {
     88             mPanel.dump(fd, pw, args);
     89         }
     90     }
     91 
     92     private void updateController() {
     93         if (Settings.Global.getInt(mContext.getContentResolver(), SETTING, DEFAULT) != 0) {
     94             Log.d(TAG, "Registering volume controller");
     95             mAudioManager.setVolumeController(mVolumeController);
     96             mMediaSessionManager.setRemoteVolumeController(mRemoteVolumeController);
     97         } else {
     98             Log.d(TAG, "Unregistering volume controller");
     99             mAudioManager.setVolumeController(null);
    100             mMediaSessionManager.setRemoteVolumeController(null);
    101         }
    102     }
    103 
    104     private void initPanel() {
    105         mDismissDelay = mContext.getResources().getInteger(R.integer.volume_panel_dismiss_delay);
    106         mPanel = new VolumePanel(mContext, new ZenModeControllerImpl(mContext, mHandler));
    107         mPanel.setCallback(new VolumePanel.Callback() {
    108             @Override
    109             public void onZenSettings() {
    110                 mHandler.removeCallbacks(mStartZenSettings);
    111                 mHandler.post(mStartZenSettings);
    112             }
    113 
    114             @Override
    115             public void onInteraction() {
    116                 final KeyguardViewMediator kvm = getComponent(KeyguardViewMediator.class);
    117                 if (kvm != null) {
    118                     kvm.userActivity();
    119                 }
    120             }
    121 
    122             @Override
    123             public void onVisible(boolean visible) {
    124                 if (mAudioManager != null && mVolumeController != null) {
    125                     mAudioManager.notifyVolumeControllerVisible(mVolumeController, visible);
    126                 }
    127             }
    128         });
    129     }
    130 
    131     private final ContentObserver mObserver = new ContentObserver(mHandler) {
    132         public void onChange(boolean selfChange, Uri uri) {
    133             if (SETTING_URI.equals(uri)) {
    134                 updateController();
    135             }
    136         }
    137     };
    138 
    139     private final Runnable mStartZenSettings = new Runnable() {
    140         @Override
    141         public void run() {
    142             getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard(
    143                     ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */);
    144             mPanel.postDismiss(mDismissDelay);
    145         }
    146     };
    147 
    148     /** For now, simply host an unmodified base volume panel in this process. */
    149     private final class VolumeController extends IVolumeController.Stub implements VolumeComponent {
    150 
    151         @Override
    152         public void displaySafeVolumeWarning(int flags) throws RemoteException {
    153             mPanel.postDisplaySafeVolumeWarning(flags);
    154         }
    155 
    156         @Override
    157         public void volumeChanged(int streamType, int flags)
    158                 throws RemoteException {
    159             mPanel.postVolumeChanged(streamType, flags);
    160         }
    161 
    162         @Override
    163         public void masterVolumeChanged(int flags) throws RemoteException {
    164             mPanel.postMasterVolumeChanged(flags);
    165         }
    166 
    167         @Override
    168         public void masterMuteChanged(int flags) throws RemoteException {
    169             mPanel.postMasterMuteChanged(flags);
    170         }
    171 
    172         @Override
    173         public void setLayoutDirection(int layoutDirection)
    174                 throws RemoteException {
    175             mPanel.postLayoutDirection(layoutDirection);
    176         }
    177 
    178         @Override
    179         public void dismiss() throws RemoteException {
    180             mPanel.postDismiss(0);
    181         }
    182 
    183         @Override
    184         public ZenModeController getZenController() {
    185             return mPanel.getZenController();
    186         }
    187     }
    188 
    189     private final class RemoteVolumeController extends IRemoteVolumeController.Stub {
    190 
    191         @Override
    192         public void remoteVolumeChanged(ISessionController binder, int flags)
    193                 throws RemoteException {
    194             MediaController controller = new MediaController(mContext, binder);
    195             mPanel.postRemoteVolumeChanged(controller, flags);
    196         }
    197 
    198         @Override
    199         public void updateRemoteController(ISessionController session) throws RemoteException {
    200             mPanel.postRemoteSliderVisibility(session != null);
    201             // TODO stash default session in case the slider can be opened other
    202             // than by remoteVolumeChanged.
    203         }
    204     }
    205 }
    206