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