Loading core/java/android/hardware/hdmi/HdmiTvClient.java +28 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,34 @@ public final class HdmiTvClient { } } /** * Set system audio volume * * @param oldIndex current volume index * @param newIndex volume index to be set * @param maxIndex maximum volume index */ public void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex) { try { mService.setSystemAudioVolume(oldIndex, newIndex, maxIndex); } catch (RemoteException e) { Log.e(TAG, "failed to set volume: ", e); } } /** * Set system audio mute status * * @param mute {@code true} if muted; otherwise, {@code false} */ public void setSystemAudioMute(boolean mute) { try { mService.setSystemAudioMute(mute); } catch (RemoteException e) { Log.e(TAG, "failed to set mute: ", e); } } private static IHdmiControlCallback getCallbackWrapper(final SelectCallback callback) { return new IHdmiControlCallback.Stub() { @Override Loading core/java/android/hardware/hdmi/IHdmiControlService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -51,4 +51,6 @@ interface IHdmiControlService { void setControlEnabled(boolean enabled); void setArcMode(boolean enabled); void setOption(int option, int value); oneway void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex); oneway void setSystemAudioMute(boolean mute); } media/java/android/media/AudioManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,12 @@ public class AudioManager { */ public static final int FLAG_SHOW_SILENT_HINT = 1 << 7; /** * Indicates the volume call is for Hdmi Cec system audio volume * @hide */ public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8; /** * Ringer mode that will be silent and will not vibrate. (This overrides the * vibrate setting.) Loading Loading @@ -2872,6 +2878,23 @@ public class AudioManager { } } /** * Set Hdmi Cec system audio mode. * * @param on whether to be on system audio mode * @param device out device type to be used for system audio mode. * Ignored if {@code on} is {@code false} * @param name name of system audio device * @hide */ public void setHdmiSystemAudioSupported(boolean on, int device, String name) { try { getService().setHdmiSystemAudioSupported(on, device, name); } catch (RemoteException e) { Log.w(TAG, "Error setting system audio mode", e); } } /** * Return codes for listAudioPorts(), createAudioPatch() ... */ Loading media/java/android/media/AudioService.java +100 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.database.ContentObserver; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiTvClient; import android.hardware.usb.UsbManager; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; Loading Loading @@ -572,6 +574,11 @@ public class AudioService extends IAudioService.Stub { setRotationForAudioSystem(); } HdmiControlManager hdmiManager = (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE); // Null if device is not Tv. mHdmiTvClient = hdmiManager.getTvClient(); context.registerReceiver(mReceiver, intentFilter); mUseMasterVolume = context.getResources().getBoolean( Loading Loading @@ -969,6 +976,21 @@ public class AudioService extends IAudioService.Stub { streamState, 0); } // Check if volume update should be send to Hdmi system audio. int newIndex = mStreamStates[streamType].getIndex(device); if (mHdmiTvClient != null && streamTypeAlias == AudioSystem.STREAM_MUSIC && (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0 && oldIndex != newIndex) { int maxIndex = getStreamMaxVolume(streamType); synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioVolume( (oldIndex + 5) / 10, (newIndex + 5) / 10, maxIndex); } } } } int index = mStreamStates[streamType].getIndex(device); sendVolumeUpdate(streamType, oldIndex, index, flags); Loading Loading @@ -1069,6 +1091,19 @@ public class AudioService extends IAudioService.Stub { } } if (mHdmiTvClient != null && streamTypeAlias == AudioSystem.STREAM_MUSIC && (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0 && oldIndex != index) { int maxIndex = getStreamMaxVolume(streamType); synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioVolume( (oldIndex + 5) / 10, (index + 5) / 10, maxIndex); } } } flags &= ~AudioManager.FLAG_FIXED_VOLUME; if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && ((device & mFixedVolumeDevices) != 0)) { Loading Loading @@ -1292,6 +1327,13 @@ public class AudioService extends IAudioService.Stub { } if (isStreamAffectedByMute(streamType)) { if (streamType == AudioSystem.STREAM_MUSIC && mHdmiTvClient != null) { synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioMute(state); } } } mStreamStates[streamType].mute(cb, state); } } Loading Loading @@ -4701,6 +4743,64 @@ public class AudioService extends IAudioService.Stub { } } //========================================================================================== // Hdmi Cec system audio mode. // If Hdmi Cec's system audio mode is on, audio service should notify volume change // to HdmiControlService so that audio recevier can handle volume change. //========================================================================================== // If HDMI-CEC system audio is supported private boolean mHdmiSystemAudioSupported = false; // Set only when device is tv. private HdmiTvClient mHdmiTvClient; @Override public void setHdmiSystemAudioSupported(boolean on, int device, String name) { if (mHdmiTvClient == null) { Log.w(TAG, "Only Hdmi-Cec enabled TV device supports system audio mode."); return; } if ((device & AudioSystem.DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO) == 0) { Log.w(TAG, "Unsupported Hdmi-Cec system audio output:" + device); return; } VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; int oldStreamDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC); int oldIndex = streamState.getIndex(oldStreamDevice); synchronized (mHdmiTvClient) { mHdmiSystemAudioSupported = on; // TODO: call AudioSystem.setForceUse(FORCE_FOR_MEDIA, // on ? AudioSystem.FORCE_SYSTEM_AUDIO_XXX : AudioSystem.FORCE_NONE; } int newStreamDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC); boolean updateSpeakerVolume = false; if (on) { if ((oldStreamDevice & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { // Mute tv speaker. Note that set volume 0 instead of call mute() method because // it's not possible to mute for a specific device. streamState.setIndex(0, AudioSystem.DEVICE_OUT_SPEAKER); updateSpeakerVolume = true; } } else { if ((newStreamDevice & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { // Restore speaker volume if exists. As there is no way to mute a device here, // load system audio's volume and set it to speaker. streamState.setIndex(oldIndex, AudioSystem.DEVICE_OUT_SPEAKER); updateSpeakerVolume = true; } } if (updateSpeakerVolume) { sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, AudioSystem.DEVICE_OUT_SPEAKER, 0, streamState, 0); } } //========================================================================================== // Camera shutter sound policy. Loading media/java/android/media/AudioSystem.java +3 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,9 @@ public class AudioSystem DEVICE_OUT_BLUETOOTH_SCO_CARKIT); public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY | DEVICE_OUT_USB_DEVICE); public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_LINE | DEVICE_OUT_HDMI_ARC | DEVICE_OUT_SPDIF); // input devices public static final int DEVICE_IN_COMMUNICATION = DEVICE_BIT_IN | 0x1; Loading Loading
core/java/android/hardware/hdmi/HdmiTvClient.java +28 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,34 @@ public final class HdmiTvClient { } } /** * Set system audio volume * * @param oldIndex current volume index * @param newIndex volume index to be set * @param maxIndex maximum volume index */ public void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex) { try { mService.setSystemAudioVolume(oldIndex, newIndex, maxIndex); } catch (RemoteException e) { Log.e(TAG, "failed to set volume: ", e); } } /** * Set system audio mute status * * @param mute {@code true} if muted; otherwise, {@code false} */ public void setSystemAudioMute(boolean mute) { try { mService.setSystemAudioMute(mute); } catch (RemoteException e) { Log.e(TAG, "failed to set mute: ", e); } } private static IHdmiControlCallback getCallbackWrapper(final SelectCallback callback) { return new IHdmiControlCallback.Stub() { @Override Loading
core/java/android/hardware/hdmi/IHdmiControlService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -51,4 +51,6 @@ interface IHdmiControlService { void setControlEnabled(boolean enabled); void setArcMode(boolean enabled); void setOption(int option, int value); oneway void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex); oneway void setSystemAudioMute(boolean mute); }
media/java/android/media/AudioManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,12 @@ public class AudioManager { */ public static final int FLAG_SHOW_SILENT_HINT = 1 << 7; /** * Indicates the volume call is for Hdmi Cec system audio volume * @hide */ public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8; /** * Ringer mode that will be silent and will not vibrate. (This overrides the * vibrate setting.) Loading Loading @@ -2872,6 +2878,23 @@ public class AudioManager { } } /** * Set Hdmi Cec system audio mode. * * @param on whether to be on system audio mode * @param device out device type to be used for system audio mode. * Ignored if {@code on} is {@code false} * @param name name of system audio device * @hide */ public void setHdmiSystemAudioSupported(boolean on, int device, String name) { try { getService().setHdmiSystemAudioSupported(on, device, name); } catch (RemoteException e) { Log.w(TAG, "Error setting system audio mode", e); } } /** * Return codes for listAudioPorts(), createAudioPatch() ... */ Loading
media/java/android/media/AudioService.java +100 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.database.ContentObserver; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiTvClient; import android.hardware.usb.UsbManager; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; Loading Loading @@ -572,6 +574,11 @@ public class AudioService extends IAudioService.Stub { setRotationForAudioSystem(); } HdmiControlManager hdmiManager = (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE); // Null if device is not Tv. mHdmiTvClient = hdmiManager.getTvClient(); context.registerReceiver(mReceiver, intentFilter); mUseMasterVolume = context.getResources().getBoolean( Loading Loading @@ -969,6 +976,21 @@ public class AudioService extends IAudioService.Stub { streamState, 0); } // Check if volume update should be send to Hdmi system audio. int newIndex = mStreamStates[streamType].getIndex(device); if (mHdmiTvClient != null && streamTypeAlias == AudioSystem.STREAM_MUSIC && (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0 && oldIndex != newIndex) { int maxIndex = getStreamMaxVolume(streamType); synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioVolume( (oldIndex + 5) / 10, (newIndex + 5) / 10, maxIndex); } } } } int index = mStreamStates[streamType].getIndex(device); sendVolumeUpdate(streamType, oldIndex, index, flags); Loading Loading @@ -1069,6 +1091,19 @@ public class AudioService extends IAudioService.Stub { } } if (mHdmiTvClient != null && streamTypeAlias == AudioSystem.STREAM_MUSIC && (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0 && oldIndex != index) { int maxIndex = getStreamMaxVolume(streamType); synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioVolume( (oldIndex + 5) / 10, (index + 5) / 10, maxIndex); } } } flags &= ~AudioManager.FLAG_FIXED_VOLUME; if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && ((device & mFixedVolumeDevices) != 0)) { Loading Loading @@ -1292,6 +1327,13 @@ public class AudioService extends IAudioService.Stub { } if (isStreamAffectedByMute(streamType)) { if (streamType == AudioSystem.STREAM_MUSIC && mHdmiTvClient != null) { synchronized (mHdmiTvClient) { if (mHdmiSystemAudioSupported) { mHdmiTvClient.setSystemAudioMute(state); } } } mStreamStates[streamType].mute(cb, state); } } Loading Loading @@ -4701,6 +4743,64 @@ public class AudioService extends IAudioService.Stub { } } //========================================================================================== // Hdmi Cec system audio mode. // If Hdmi Cec's system audio mode is on, audio service should notify volume change // to HdmiControlService so that audio recevier can handle volume change. //========================================================================================== // If HDMI-CEC system audio is supported private boolean mHdmiSystemAudioSupported = false; // Set only when device is tv. private HdmiTvClient mHdmiTvClient; @Override public void setHdmiSystemAudioSupported(boolean on, int device, String name) { if (mHdmiTvClient == null) { Log.w(TAG, "Only Hdmi-Cec enabled TV device supports system audio mode."); return; } if ((device & AudioSystem.DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO) == 0) { Log.w(TAG, "Unsupported Hdmi-Cec system audio output:" + device); return; } VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; int oldStreamDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC); int oldIndex = streamState.getIndex(oldStreamDevice); synchronized (mHdmiTvClient) { mHdmiSystemAudioSupported = on; // TODO: call AudioSystem.setForceUse(FORCE_FOR_MEDIA, // on ? AudioSystem.FORCE_SYSTEM_AUDIO_XXX : AudioSystem.FORCE_NONE; } int newStreamDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC); boolean updateSpeakerVolume = false; if (on) { if ((oldStreamDevice & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { // Mute tv speaker. Note that set volume 0 instead of call mute() method because // it's not possible to mute for a specific device. streamState.setIndex(0, AudioSystem.DEVICE_OUT_SPEAKER); updateSpeakerVolume = true; } } else { if ((newStreamDevice & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { // Restore speaker volume if exists. As there is no way to mute a device here, // load system audio's volume and set it to speaker. streamState.setIndex(oldIndex, AudioSystem.DEVICE_OUT_SPEAKER); updateSpeakerVolume = true; } } if (updateSpeakerVolume) { sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, AudioSystem.DEVICE_OUT_SPEAKER, 0, streamState, 0); } } //========================================================================================== // Camera shutter sound policy. Loading
media/java/android/media/AudioSystem.java +3 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,9 @@ public class AudioSystem DEVICE_OUT_BLUETOOTH_SCO_CARKIT); public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY | DEVICE_OUT_USB_DEVICE); public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_LINE | DEVICE_OUT_HDMI_ARC | DEVICE_OUT_SPDIF); // input devices public static final int DEVICE_IN_COMMUNICATION = DEVICE_BIT_IN | 0x1; Loading