Loading Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -306,6 +306,7 @@ LOCAL_SRC_FILES += \ media/java/android/media/IRemoteDisplayProvider.aidl \ media/java/android/media/IRemoteDisplayProvider.aidl \ media/java/android/media/IRemoteVolumeObserver.aidl \ media/java/android/media/IRemoteVolumeObserver.aidl \ media/java/android/media/IRingtonePlayer.aidl \ media/java/android/media/IRingtonePlayer.aidl \ media/java/android/media/IVolumeController.aidl \ media/java/android/media/routeprovider/IRouteConnection.aidl \ media/java/android/media/routeprovider/IRouteConnection.aidl \ media/java/android/media/routeprovider/IRouteProvider.aidl \ media/java/android/media/routeprovider/IRouteProvider.aidl \ media/java/android/media/routeprovider/IRouteProviderCallback.aidl \ media/java/android/media/routeprovider/IRouteProviderCallback.aidl \ Loading media/java/android/media/AudioManager.java +76 −2 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.os.ServiceManager; import android.provider.Settings; import android.provider.Settings; import android.util.Log; import android.util.Log; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.VolumePanel; import java.util.HashMap; import java.util.HashMap; Loading Loading @@ -498,7 +497,7 @@ public class AudioManager { int keyCode = event.getKeyCode(); int keyCode = event.getKeyCode(); if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE && mVolumeKeyUpTime + VolumePanel.PLAY_SOUND_DELAY && mVolumeKeyUpTime + AudioService.PLAY_SOUND_DELAY > SystemClock.uptimeMillis()) { > SystemClock.uptimeMillis()) { /* /* * The user has hit another key during the delay (e.g., 300ms) * The user has hit another key during the delay (e.g., 300ms) Loading Loading @@ -2892,4 +2891,79 @@ public class AudioManager { return AudioSystem.getOutputLatency(streamType); return AudioSystem.getOutputLatency(streamType); } } /** * Registers a global volume controller interface. Currently limited to SystemUI. * * @hide */ public void setVolumeController(IVolumeController controller) { try { getService().setVolumeController(controller); } catch (RemoteException e) { Log.w(TAG, "Error setting volume controller", e); } } /** * Only useful for volume controllers. * @hide */ public int getRemoteStreamVolume() { try { return getService().getRemoteStreamVolume(); } catch (RemoteException e) { Log.w(TAG, "Error getting remote stream volume", e); return 0; } } /** * Only useful for volume controllers. * @hide */ public int getRemoteStreamMaxVolume() { try { return getService().getRemoteStreamMaxVolume(); } catch (RemoteException e) { Log.w(TAG, "Error getting remote stream max volume", e); return 0; } } /** * Only useful for volume controllers. * @hide */ public void setRemoteStreamVolume(int index) { try { getService().setRemoteStreamVolume(index); } catch (RemoteException e) { Log.w(TAG, "Error setting remote stream volume", e); } } /** * Only useful for volume controllers. * @hide */ public boolean isStreamAffectedByRingerMode(int streamType) { try { return getService().isStreamAffectedByRingerMode(streamType); } catch (RemoteException e) { Log.w(TAG, "Error calling isStreamAffectedByRingerMode", e); return false; } } /** * Only useful for volume controllers. * @hide */ public void disableSafeMediaVolume() { try { getService().disableSafeMediaVolume(); } catch (RemoteException e) { Log.w(TAG, "Error disabling safe media volume", e); } } } } media/java/android/media/AudioService.java +60 −11 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.Surface; import android.view.Surface; import android.view.VolumePanel; import android.view.WindowManager; import android.view.WindowManager; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.ITelephony; Loading Loading @@ -116,13 +115,21 @@ public class AudioService extends IAudioService.Stub { /** How long to delay before persisting a change in volume/ringer mode. */ /** How long to delay before persisting a change in volume/ringer mode. */ private static final int PERSIST_DELAY = 500; private static final int PERSIST_DELAY = 500; /** * The delay before playing a sound. This small period exists so the user * can press another key (non-volume keys, too) to have it NOT be audible. * <p> * PhoneWindow will implement this part. */ public static final int PLAY_SOUND_DELAY = 300; private final Context mContext; private final Context mContext; private final ContentResolver mContentResolver; private final ContentResolver mContentResolver; private final AppOpsManager mAppOps; private final AppOpsManager mAppOps; private final boolean mVoiceCapable; private final boolean mVoiceCapable; /** The UI */ /** The controller for the volume UI. */ private VolumePanel mVolumePanel; private final VolumeController mVolumeController = new VolumeController(); // sendMsg() flags // sendMsg() flags /** If the msg is already queued, replace it with this one. */ /** If the msg is already queued, replace it with this one. */ Loading Loading @@ -477,13 +484,12 @@ public class AudioService extends IAudioService.Stub { sSoundEffectVolumeDb = context.getResources().getInteger( sSoundEffectVolumeDb = context.getResources().getInteger( com.android.internal.R.integer.config_soundEffectVolumeDb); com.android.internal.R.integer.config_soundEffectVolumeDb); mVolumePanel = new VolumePanel(context, this); mForcedUseForComm = AudioSystem.FORCE_NONE; mForcedUseForComm = AudioSystem.FORCE_NONE; createAudioSystemThread(); createAudioSystemThread(); mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(), mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(), mContext, /*VolumeController*/ mVolumePanel, this); mContext, mVolumeController, this); AudioSystem.setErrorCallback(mAudioSystemCallback); AudioSystem.setErrorCallback(mAudioSystemCallback); Loading Loading @@ -953,7 +959,7 @@ public class AudioService extends IAudioService.Stub { if ((direction == AudioManager.ADJUST_RAISE) && if ((direction == AudioManager.ADJUST_RAISE) && !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex); Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex); mVolumePanel.postDisplaySafeVolumeWarning(flags); mVolumeController.postDisplaySafeVolumeWarning(flags); } else if (streamState.adjustIndex(direction * step, device)) { } else if (streamState.adjustIndex(direction * step, device)) { // Post message to set system volume (it in turn will post a message // Post message to set system volume (it in turn will post a message // to persist). Do not change volume if stream is muted. // to persist). Do not change volume if stream is muted. Loading Loading @@ -1081,7 +1087,7 @@ public class AudioService extends IAudioService.Stub { } } if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { mVolumePanel.postDisplaySafeVolumeWarning(flags); mVolumeController.postDisplaySafeVolumeWarning(flags); mPendingVolumeCommand = new StreamVolumeCommand( mPendingVolumeCommand = new StreamVolumeCommand( streamType, index, flags, device); streamType, index, flags, device); } else { } else { Loading Loading @@ -1202,7 +1208,7 @@ public class AudioService extends IAudioService.Stub { streamType = AudioSystem.STREAM_NOTIFICATION; streamType = AudioSystem.STREAM_NOTIFICATION; } } mVolumePanel.postVolumeChanged(streamType, flags); mVolumeController.postVolumeChanged(streamType, flags); if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) { if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) { oldIndex = (oldIndex + 5) / 10; oldIndex = (oldIndex + 5) / 10; Loading @@ -1217,7 +1223,7 @@ public class AudioService extends IAudioService.Stub { // UI update and Broadcast Intent // UI update and Broadcast Intent private void sendMasterVolumeUpdate(int flags, int oldVolume, int newVolume) { private void sendMasterVolumeUpdate(int flags, int oldVolume, int newVolume) { mVolumePanel.postMasterVolumeChanged(flags); mVolumeController.postMasterVolumeChanged(flags); Intent intent = new Intent(AudioManager.MASTER_VOLUME_CHANGED_ACTION); Intent intent = new Intent(AudioManager.MASTER_VOLUME_CHANGED_ACTION); intent.putExtra(AudioManager.EXTRA_PREV_MASTER_VOLUME_VALUE, oldVolume); intent.putExtra(AudioManager.EXTRA_PREV_MASTER_VOLUME_VALUE, oldVolume); Loading @@ -1227,7 +1233,7 @@ public class AudioService extends IAudioService.Stub { // UI update and Broadcast Intent // UI update and Broadcast Intent private void sendMasterMuteUpdate(boolean muted, int flags) { private void sendMasterMuteUpdate(boolean muted, int flags) { mVolumePanel.postMasterMuteChanged(flags); mVolumeController.postMasterMuteChanged(flags); broadcastMasterMuteStatus(muted); broadcastMasterMuteStatus(muted); } } Loading Loading @@ -2589,6 +2595,7 @@ public class AudioService extends IAudioService.Stub { return adjustVolumeIndex; return adjustVolumeIndex; } } @Override public boolean isStreamAffectedByRingerMode(int streamType) { public boolean isStreamAffectedByRingerMode(int streamType) { return (mRingerModeAffectedStreams & (1 << streamType)) != 0; return (mRingerModeAffectedStreams & (1 << streamType)) != 0; } } Loading Loading @@ -4309,15 +4316,19 @@ public class AudioService extends IAudioService.Stub { mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo); mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo); } } @Override public int getRemoteStreamVolume() { public int getRemoteStreamVolume() { return mMediaFocusControl.getRemoteStreamVolume(); return mMediaFocusControl.getRemoteStreamVolume(); } } @Override public int getRemoteStreamMaxVolume() { public int getRemoteStreamMaxVolume() { return mMediaFocusControl.getRemoteStreamMaxVolume(); return mMediaFocusControl.getRemoteStreamMaxVolume(); } } @Override public void setRemoteStreamVolume(int index) { public void setRemoteStreamVolume(int index) { enforceSelfOrSystemUI("set the remote stream volume"); mMediaFocusControl.setRemoteStreamVolume(index); mMediaFocusControl.setRemoteStreamVolume(index); } } Loading Loading @@ -4450,7 +4461,7 @@ public class AudioService extends IAudioService.Stub { } } } } } } mVolumePanel.setLayoutDirection(config.getLayoutDirection()); mVolumeController.setLayoutDirection(config.getLayoutDirection()); } catch (Exception e) { } catch (Exception e) { Log.e(TAG, "Error handling configuration change: ", e); Log.e(TAG, "Error handling configuration change: ", e); } } Loading Loading @@ -4625,7 +4636,9 @@ public class AudioService extends IAudioService.Stub { } } } } @Override public void disableSafeMediaVolume() { public void disableSafeMediaVolume() { enforceSelfOrSystemUI("disable the safe media volume"); synchronized (mSafeMediaVolumeState) { synchronized (mSafeMediaVolumeState) { setSafeMediaVolumeEnabled(false); setSafeMediaVolumeEnabled(false); if (mPendingVolumeCommand != null) { if (mPendingVolumeCommand != null) { Loading Loading @@ -4681,6 +4694,7 @@ public class AudioService extends IAudioService.Stub { pw.println("\nAudio routes:"); pw.println("\nAudio routes:"); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); pw.print(" mVolumeController="); pw.println(mVolumeController); } } // Inform AudioFlinger of our device's low RAM attribute // Inform AudioFlinger of our device's low RAM attribute Loading @@ -4691,4 +4705,39 @@ public class AudioService extends IAudioService.Stub { Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); } } } } private void enforceSelfOrSystemUI(String action) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, "Only SystemUI can " + action); } @Override public void setVolumeController(final IVolumeController controller) { enforceSelfOrSystemUI("set the volume controller"); // return early if things are not actually changing if (mVolumeController.isSameBinder(controller)) { return; } // dismiss the old volume controller mVolumeController.postDismiss(); if (controller != null) { // we are about to register a new controller, listen for its death try { controller.asBinder().linkToDeath(new DeathRecipient() { @Override public void binderDied() { if (mVolumeController.isSameBinder(controller)) { Log.w(TAG, "Current remote volume controller died, unregistering"); setVolumeController(null); } } }, 0); } catch (RemoteException e) { // noop } } mVolumeController.setController(controller); } } } media/java/android/media/IAudioService.aidl +7 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.media.IRemoteControlClient; import android.media.IRemoteControlDisplay; import android.media.IRemoteControlDisplay; import android.media.IRemoteVolumeObserver; import android.media.IRemoteVolumeObserver; import android.media.IRingtonePlayer; import android.media.IRingtonePlayer; import android.media.IVolumeController; import android.media.Rating; import android.media.Rating; import android.net.Uri; import android.net.Uri; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -236,4 +237,10 @@ interface IAudioService { AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer); AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer); boolean isCameraSoundForced(); boolean isCameraSoundForced(); void setVolumeController(in IVolumeController controller); boolean isStreamAffectedByRingerMode(int streamType); void disableSafeMediaVolume(); } } media/java/android/media/IVolumeController.aidl 0 → 100644 +42 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; /** * AIDL for the AudioService to report interesting events to a remote volume control dialog. * @hide */ oneway interface IVolumeController { void hasNewRemotePlaybackInfo(); void remoteVolumeChanged(int streamType, int flags); void remoteSliderVisibility(boolean visible); void displaySafeVolumeWarning(int flags); void volumeChanged(int streamType, int flags); void masterVolumeChanged(int flags); void masterMuteChanged(int flags); void setLayoutDirection(int layoutDirection); void dismiss(); } Loading
Android.mk +1 −0 Original line number Original line Diff line number Diff line Loading @@ -306,6 +306,7 @@ LOCAL_SRC_FILES += \ media/java/android/media/IRemoteDisplayProvider.aidl \ media/java/android/media/IRemoteDisplayProvider.aidl \ media/java/android/media/IRemoteVolumeObserver.aidl \ media/java/android/media/IRemoteVolumeObserver.aidl \ media/java/android/media/IRingtonePlayer.aidl \ media/java/android/media/IRingtonePlayer.aidl \ media/java/android/media/IVolumeController.aidl \ media/java/android/media/routeprovider/IRouteConnection.aidl \ media/java/android/media/routeprovider/IRouteConnection.aidl \ media/java/android/media/routeprovider/IRouteProvider.aidl \ media/java/android/media/routeprovider/IRouteProvider.aidl \ media/java/android/media/routeprovider/IRouteProviderCallback.aidl \ media/java/android/media/routeprovider/IRouteProviderCallback.aidl \ Loading
media/java/android/media/AudioManager.java +76 −2 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.os.ServiceManager; import android.provider.Settings; import android.provider.Settings; import android.util.Log; import android.util.Log; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.VolumePanel; import java.util.HashMap; import java.util.HashMap; Loading Loading @@ -498,7 +497,7 @@ public class AudioManager { int keyCode = event.getKeyCode(); int keyCode = event.getKeyCode(); if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE && mVolumeKeyUpTime + VolumePanel.PLAY_SOUND_DELAY && mVolumeKeyUpTime + AudioService.PLAY_SOUND_DELAY > SystemClock.uptimeMillis()) { > SystemClock.uptimeMillis()) { /* /* * The user has hit another key during the delay (e.g., 300ms) * The user has hit another key during the delay (e.g., 300ms) Loading Loading @@ -2892,4 +2891,79 @@ public class AudioManager { return AudioSystem.getOutputLatency(streamType); return AudioSystem.getOutputLatency(streamType); } } /** * Registers a global volume controller interface. Currently limited to SystemUI. * * @hide */ public void setVolumeController(IVolumeController controller) { try { getService().setVolumeController(controller); } catch (RemoteException e) { Log.w(TAG, "Error setting volume controller", e); } } /** * Only useful for volume controllers. * @hide */ public int getRemoteStreamVolume() { try { return getService().getRemoteStreamVolume(); } catch (RemoteException e) { Log.w(TAG, "Error getting remote stream volume", e); return 0; } } /** * Only useful for volume controllers. * @hide */ public int getRemoteStreamMaxVolume() { try { return getService().getRemoteStreamMaxVolume(); } catch (RemoteException e) { Log.w(TAG, "Error getting remote stream max volume", e); return 0; } } /** * Only useful for volume controllers. * @hide */ public void setRemoteStreamVolume(int index) { try { getService().setRemoteStreamVolume(index); } catch (RemoteException e) { Log.w(TAG, "Error setting remote stream volume", e); } } /** * Only useful for volume controllers. * @hide */ public boolean isStreamAffectedByRingerMode(int streamType) { try { return getService().isStreamAffectedByRingerMode(streamType); } catch (RemoteException e) { Log.w(TAG, "Error calling isStreamAffectedByRingerMode", e); return false; } } /** * Only useful for volume controllers. * @hide */ public void disableSafeMediaVolume() { try { getService().disableSafeMediaVolume(); } catch (RemoteException e) { Log.w(TAG, "Error disabling safe media volume", e); } } } }
media/java/android/media/AudioService.java +60 −11 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.view.KeyEvent; import android.view.KeyEvent; import android.view.Surface; import android.view.Surface; import android.view.VolumePanel; import android.view.WindowManager; import android.view.WindowManager; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.ITelephony; Loading Loading @@ -116,13 +115,21 @@ public class AudioService extends IAudioService.Stub { /** How long to delay before persisting a change in volume/ringer mode. */ /** How long to delay before persisting a change in volume/ringer mode. */ private static final int PERSIST_DELAY = 500; private static final int PERSIST_DELAY = 500; /** * The delay before playing a sound. This small period exists so the user * can press another key (non-volume keys, too) to have it NOT be audible. * <p> * PhoneWindow will implement this part. */ public static final int PLAY_SOUND_DELAY = 300; private final Context mContext; private final Context mContext; private final ContentResolver mContentResolver; private final ContentResolver mContentResolver; private final AppOpsManager mAppOps; private final AppOpsManager mAppOps; private final boolean mVoiceCapable; private final boolean mVoiceCapable; /** The UI */ /** The controller for the volume UI. */ private VolumePanel mVolumePanel; private final VolumeController mVolumeController = new VolumeController(); // sendMsg() flags // sendMsg() flags /** If the msg is already queued, replace it with this one. */ /** If the msg is already queued, replace it with this one. */ Loading Loading @@ -477,13 +484,12 @@ public class AudioService extends IAudioService.Stub { sSoundEffectVolumeDb = context.getResources().getInteger( sSoundEffectVolumeDb = context.getResources().getInteger( com.android.internal.R.integer.config_soundEffectVolumeDb); com.android.internal.R.integer.config_soundEffectVolumeDb); mVolumePanel = new VolumePanel(context, this); mForcedUseForComm = AudioSystem.FORCE_NONE; mForcedUseForComm = AudioSystem.FORCE_NONE; createAudioSystemThread(); createAudioSystemThread(); mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(), mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(), mContext, /*VolumeController*/ mVolumePanel, this); mContext, mVolumeController, this); AudioSystem.setErrorCallback(mAudioSystemCallback); AudioSystem.setErrorCallback(mAudioSystemCallback); Loading Loading @@ -953,7 +959,7 @@ public class AudioService extends IAudioService.Stub { if ((direction == AudioManager.ADJUST_RAISE) && if ((direction == AudioManager.ADJUST_RAISE) && !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex); Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex); mVolumePanel.postDisplaySafeVolumeWarning(flags); mVolumeController.postDisplaySafeVolumeWarning(flags); } else if (streamState.adjustIndex(direction * step, device)) { } else if (streamState.adjustIndex(direction * step, device)) { // Post message to set system volume (it in turn will post a message // Post message to set system volume (it in turn will post a message // to persist). Do not change volume if stream is muted. // to persist). Do not change volume if stream is muted. Loading Loading @@ -1081,7 +1087,7 @@ public class AudioService extends IAudioService.Stub { } } if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { mVolumePanel.postDisplaySafeVolumeWarning(flags); mVolumeController.postDisplaySafeVolumeWarning(flags); mPendingVolumeCommand = new StreamVolumeCommand( mPendingVolumeCommand = new StreamVolumeCommand( streamType, index, flags, device); streamType, index, flags, device); } else { } else { Loading Loading @@ -1202,7 +1208,7 @@ public class AudioService extends IAudioService.Stub { streamType = AudioSystem.STREAM_NOTIFICATION; streamType = AudioSystem.STREAM_NOTIFICATION; } } mVolumePanel.postVolumeChanged(streamType, flags); mVolumeController.postVolumeChanged(streamType, flags); if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) { if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) { oldIndex = (oldIndex + 5) / 10; oldIndex = (oldIndex + 5) / 10; Loading @@ -1217,7 +1223,7 @@ public class AudioService extends IAudioService.Stub { // UI update and Broadcast Intent // UI update and Broadcast Intent private void sendMasterVolumeUpdate(int flags, int oldVolume, int newVolume) { private void sendMasterVolumeUpdate(int flags, int oldVolume, int newVolume) { mVolumePanel.postMasterVolumeChanged(flags); mVolumeController.postMasterVolumeChanged(flags); Intent intent = new Intent(AudioManager.MASTER_VOLUME_CHANGED_ACTION); Intent intent = new Intent(AudioManager.MASTER_VOLUME_CHANGED_ACTION); intent.putExtra(AudioManager.EXTRA_PREV_MASTER_VOLUME_VALUE, oldVolume); intent.putExtra(AudioManager.EXTRA_PREV_MASTER_VOLUME_VALUE, oldVolume); Loading @@ -1227,7 +1233,7 @@ public class AudioService extends IAudioService.Stub { // UI update and Broadcast Intent // UI update and Broadcast Intent private void sendMasterMuteUpdate(boolean muted, int flags) { private void sendMasterMuteUpdate(boolean muted, int flags) { mVolumePanel.postMasterMuteChanged(flags); mVolumeController.postMasterMuteChanged(flags); broadcastMasterMuteStatus(muted); broadcastMasterMuteStatus(muted); } } Loading Loading @@ -2589,6 +2595,7 @@ public class AudioService extends IAudioService.Stub { return adjustVolumeIndex; return adjustVolumeIndex; } } @Override public boolean isStreamAffectedByRingerMode(int streamType) { public boolean isStreamAffectedByRingerMode(int streamType) { return (mRingerModeAffectedStreams & (1 << streamType)) != 0; return (mRingerModeAffectedStreams & (1 << streamType)) != 0; } } Loading Loading @@ -4309,15 +4316,19 @@ public class AudioService extends IAudioService.Stub { mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo); mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo); } } @Override public int getRemoteStreamVolume() { public int getRemoteStreamVolume() { return mMediaFocusControl.getRemoteStreamVolume(); return mMediaFocusControl.getRemoteStreamVolume(); } } @Override public int getRemoteStreamMaxVolume() { public int getRemoteStreamMaxVolume() { return mMediaFocusControl.getRemoteStreamMaxVolume(); return mMediaFocusControl.getRemoteStreamMaxVolume(); } } @Override public void setRemoteStreamVolume(int index) { public void setRemoteStreamVolume(int index) { enforceSelfOrSystemUI("set the remote stream volume"); mMediaFocusControl.setRemoteStreamVolume(index); mMediaFocusControl.setRemoteStreamVolume(index); } } Loading Loading @@ -4450,7 +4461,7 @@ public class AudioService extends IAudioService.Stub { } } } } } } mVolumePanel.setLayoutDirection(config.getLayoutDirection()); mVolumeController.setLayoutDirection(config.getLayoutDirection()); } catch (Exception e) { } catch (Exception e) { Log.e(TAG, "Error handling configuration change: ", e); Log.e(TAG, "Error handling configuration change: ", e); } } Loading Loading @@ -4625,7 +4636,9 @@ public class AudioService extends IAudioService.Stub { } } } } @Override public void disableSafeMediaVolume() { public void disableSafeMediaVolume() { enforceSelfOrSystemUI("disable the safe media volume"); synchronized (mSafeMediaVolumeState) { synchronized (mSafeMediaVolumeState) { setSafeMediaVolumeEnabled(false); setSafeMediaVolumeEnabled(false); if (mPendingVolumeCommand != null) { if (mPendingVolumeCommand != null) { Loading Loading @@ -4681,6 +4694,7 @@ public class AudioService extends IAudioService.Stub { pw.println("\nAudio routes:"); pw.println("\nAudio routes:"); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); pw.print(" mVolumeController="); pw.println(mVolumeController); } } // Inform AudioFlinger of our device's low RAM attribute // Inform AudioFlinger of our device's low RAM attribute Loading @@ -4691,4 +4705,39 @@ public class AudioService extends IAudioService.Stub { Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); } } } } private void enforceSelfOrSystemUI(String action) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, "Only SystemUI can " + action); } @Override public void setVolumeController(final IVolumeController controller) { enforceSelfOrSystemUI("set the volume controller"); // return early if things are not actually changing if (mVolumeController.isSameBinder(controller)) { return; } // dismiss the old volume controller mVolumeController.postDismiss(); if (controller != null) { // we are about to register a new controller, listen for its death try { controller.asBinder().linkToDeath(new DeathRecipient() { @Override public void binderDied() { if (mVolumeController.isSameBinder(controller)) { Log.w(TAG, "Current remote volume controller died, unregistering"); setVolumeController(null); } } }, 0); } catch (RemoteException e) { // noop } } mVolumeController.setController(controller); } } }
media/java/android/media/IAudioService.aidl +7 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.media.IRemoteControlClient; import android.media.IRemoteControlDisplay; import android.media.IRemoteControlDisplay; import android.media.IRemoteVolumeObserver; import android.media.IRemoteVolumeObserver; import android.media.IRingtonePlayer; import android.media.IRingtonePlayer; import android.media.IVolumeController; import android.media.Rating; import android.media.Rating; import android.net.Uri; import android.net.Uri; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -236,4 +237,10 @@ interface IAudioService { AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer); AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer); boolean isCameraSoundForced(); boolean isCameraSoundForced(); void setVolumeController(in IVolumeController controller); boolean isStreamAffectedByRingerMode(int streamType); void disableSafeMediaVolume(); } }
media/java/android/media/IVolumeController.aidl 0 → 100644 +42 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; /** * AIDL for the AudioService to report interesting events to a remote volume control dialog. * @hide */ oneway interface IVolumeController { void hasNewRemotePlaybackInfo(); void remoteVolumeChanged(int streamType, int flags); void remoteSliderVisibility(boolean visible); void displaySafeVolumeWarning(int flags); void volumeChanged(int streamType, int flags); void masterVolumeChanged(int flags); void masterMuteChanged(int flags); void setLayoutDirection(int layoutDirection); void dismiss(); }