Loading api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -22842,6 +22842,7 @@ package android.media { method public void adjustStreamVolume(int, int, int); method public void adjustSuggestedStreamVolume(int, int, int); method public void adjustVolume(int, int); method public int dispatchAudioFocusChange(android.media.AudioFocusInfo, int, android.media.audiopolicy.AudioPolicy); method public void dispatchMediaKeyEvent(android.view.KeyEvent); method public int generateAudioSessionId(); method public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations(); Loading Loading @@ -25844,8 +25845,10 @@ package android.media.audiopolicy { public static abstract class AudioPolicy.AudioPolicyFocusListener { ctor public AudioPolicy.AudioPolicyFocusListener(); method public void onAudioFocusAbandon(android.media.AudioFocusInfo); method public void onAudioFocusGrant(android.media.AudioFocusInfo, int); method public void onAudioFocusLoss(android.media.AudioFocusInfo, boolean); method public void onAudioFocusRequest(android.media.AudioFocusInfo, int); } public static abstract class AudioPolicy.AudioPolicyStatusListener { Loading @@ -25860,6 +25863,7 @@ package android.media.audiopolicy { method public android.media.audiopolicy.AudioPolicy build(); method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener); method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener); method public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); method public android.media.audiopolicy.AudioPolicy.Builder setLooper(android.os.Looper) throws java.lang.IllegalArgumentException; } media/java/android/media/AudioManager.java +41 −3 Original line number Diff line number Diff line Loading @@ -2538,6 +2538,44 @@ public class AudioManager { } } /** * @hide * Notifies an application with a focus listener of gain or loss of audio focus. * This method can only be used by owners of an {@link AudioPolicy} configured with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to true. * @param afi the recipient of the focus change, that has previously requested audio focus, and * that was received by the {@code AudioPolicy} through * {@link AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(AudioFocusInfo, int)}. * @param focusChange one of focus gain types ({@link #AUDIOFOCUS_GAIN}, * {@link #AUDIOFOCUS_GAIN_TRANSIENT}, {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} or * {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}) * or one of the focus loss types ({@link AudioManager#AUDIOFOCUS_LOSS}, * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}, * or {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}). * <br>For the focus gain, the change type should be the same as the app requested. * @param ap a valid registered {@link AudioPolicy} configured as a focus policy. * @return {@link #AUDIOFOCUS_REQUEST_GRANTED} if the dispatch was successfully sent, or * {@link #AUDIOFOCUS_REQUEST_FAILED} if the focus client didn't have a listener, or * if there was an error sending the request. * @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null. */ @SystemApi public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange, @NonNull AudioPolicy ap) { if (afi == null) { throw new NullPointerException("Illegal null AudioFocusInfo"); } if (ap == null) { throw new NullPointerException("Illegal null AudioPolicy"); } final IAudioService service = getService(); try { return service.dispatchFocusChange(afi, focusChange, ap.cb()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @hide * Used internally by telephony package to abandon audio focus, typically after a call or Loading @@ -2548,7 +2586,7 @@ public class AudioManager { final IAudioService service = getService(); try { service.abandonAudioFocus(null, AudioSystem.IN_VOICE_COMM_FOCUS_ID, null /*AudioAttributes, legacy behavior*/); null /*AudioAttributes, legacy behavior*/, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2579,7 +2617,7 @@ public class AudioManager { final IAudioService service = getService(); try { status = service.abandonAudioFocus(mAudioFocusDispatcher, getIdForAudioFocusListener(l), aa); getIdForAudioFocusListener(l), aa, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2787,7 +2825,7 @@ public class AudioManager { final IAudioService service = getService(); try { String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(), policy.hasFocusListener()); policy.hasFocusListener(), policy.isFocusPolicy()); if (regId == null) { return ERROR; } else { Loading media/java/android/media/IAudioService.aidl +7 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioFocusInfo; import android.media.AudioPlaybackConfiguration; import android.media.AudioRecordingConfiguration; import android.media.AudioRoutesInfo; Loading Loading @@ -122,7 +123,8 @@ interface IAudioService { IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb); int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa); int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa, in String callingPackageName); void unregisterAudioFocusClient(String clientId); Loading Loading @@ -164,7 +166,7 @@ interface IAudioService { boolean isHdmiSystemAudioSupported(); String registerAudioPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb, boolean hasFocusListener); in IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy); oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); Loading Loading @@ -196,5 +198,8 @@ interface IAudioService { int getFocusRampTimeMs(in int focusGain, in AudioAttributes attr); int dispatchFocusChange(in AudioFocusInfo afi, in int focusChange, in IAudioPolicyCallback pcb); // WARNING: read warning at top of file, it is recommended to add new methods at the end } media/java/android/media/audiopolicy/AudioPolicy.java +86 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ public class AudioPolicy { private int mStatus; private String mRegistrationId; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; /** * The behavior of a policy with regards to audio focus where it relies on the application Loading Loading @@ -96,12 +97,14 @@ public class AudioPolicy { public AudioPolicyConfig getConfig() { return mConfig; } /** @hide */ public boolean hasFocusListener() { return mFocusListener != null; } /** @hide */ public boolean isFocusPolicy() { return mIsFocusPolicy; } /** * The parameter is guaranteed non-null through the Builder */ private AudioPolicy(AudioPolicyConfig config, Context context, Looper looper, AudioPolicyFocusListener fl, AudioPolicyStatusListener sl) { AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, boolean isFocusPolicy) { mConfig = config; mStatus = POLICY_STATUS_UNREGISTERED; mContext = context; Loading @@ -116,10 +119,12 @@ public class AudioPolicy { } mFocusListener = fl; mStatusListener = sl; mIsFocusPolicy = isFocusPolicy; } /** * Builder class for {@link AudioPolicy} objects * Builder class for {@link AudioPolicy} objects. * By default the policy to be created doesn't govern audio focus decisions. */ @SystemApi public static class Builder { Loading @@ -128,6 +133,7 @@ public class AudioPolicy { private Looper mLooper; private AudioPolicyFocusListener mFocusListener; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy = false; /** * Constructs a new Builder with no audio mixes. Loading Loading @@ -178,6 +184,21 @@ public class AudioPolicy { mFocusListener = l; } /** * Declares whether this policy will grant and deny audio focus through * the {@link AudioPolicy.AudioPolicyStatusListener}. * If set to {@code true}, it is mandatory to set an * {@link AudioPolicy.AudioPolicyStatusListener} in order to successfully build * an {@code AudioPolicy} instance. * @param enforce true if the policy will govern audio focus decisions. * @return the same Builder instance. */ @SystemApi public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) { mIsFocusPolicy = isFocusPolicy; return this; } /** * Sets the audio policy status listener. * @param l a {@link AudioPolicy.AudioPolicyStatusListener} Loading @@ -187,6 +208,14 @@ public class AudioPolicy { mStatusListener = l; } /** * Combines all of the attributes that have been set on this {@code Builder} and returns a * new {@link AudioPolicy} object. * @return a new {@code AudioPolicy} object. * @throws IllegalStateException if there is no * {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured * as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}. */ @SystemApi public AudioPolicy build() { if (mStatusListener != null) { Loading @@ -195,8 +224,12 @@ public class AudioPolicy { mix.mCallbackFlags |= AudioMix.CALLBACK_FLAG_NOTIFY_ACTIVITY; } } if (mIsFocusPolicy && mFocusListener == null) { throw new IllegalStateException("Cannot be a focus policy without " + "an AudioPolicyFocusListener"); } return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper, mFocusListener, mStatusListener); mFocusListener, mStatusListener, mIsFocusPolicy); } } Loading Loading @@ -402,6 +435,24 @@ public class AudioPolicy { public static abstract class AudioPolicyFocusListener { public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {} public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {} /** * Called whenever an application requests audio focus. * Only ever called if the {@link AudioPolicy} was built with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}. * @param afi information about the focus request and the requester * @param requestResult the result that was returned synchronously by the framework to the * application, {@link #AUDIOFOCUS_REQUEST_FAILED},or * {@link #AUDIOFOCUS_REQUEST_DELAYED}. */ public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {} /** * Called whenever an application abandons audio focus. * Only ever called if the {@link AudioPolicy} was built with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}. * @param afi information about the focus request being abandoned and the original * requester. */ public void onAudioFocusAbandon(AudioFocusInfo afi) {} } private void onPolicyStatusChange() { Loading Loading @@ -439,6 +490,22 @@ public class AudioPolicy { } } public void notifyAudioFocusRequest(AudioFocusInfo afi, int requestResult) { sendMsg(MSG_FOCUS_REQUEST, afi, requestResult); if (DEBUG) { Log.v(TAG, "notifyAudioFocusRequest: pack=" + afi.getPackageName() + " client=" + afi.getClientId() + "reqRes=" + requestResult); } } public void notifyAudioFocusAbandon(AudioFocusInfo afi) { sendMsg(MSG_FOCUS_ABANDON, afi, 0 /* ignored */); if (DEBUG) { Log.v(TAG, "notifyAudioFocusAbandon: pack=" + afi.getPackageName() + " client=" + afi.getClientId()); } } public void notifyMixStateUpdate(String regId, int state) { for (AudioMix mix : mConfig.getMixes()) { if (mix.getRegistration().equals(regId)) { Loading @@ -459,6 +526,8 @@ public class AudioPolicy { private final static int MSG_FOCUS_GRANT = 1; private final static int MSG_FOCUS_LOSS = 2; private final static int MSG_MIX_STATE_UPDATE = 3; private final static int MSG_FOCUS_REQUEST = 4; private final static int MSG_FOCUS_ABANDON = 5; private class EventHandler extends Handler { public EventHandler(AudioPolicy ap, Looper looper) { Loading Loading @@ -488,6 +557,20 @@ public class AudioPolicy { mStatusListener.onMixStateUpdate((AudioMix) msg.obj); } break; case MSG_FOCUS_REQUEST: if (mFocusListener != null) { mFocusListener.onAudioFocusRequest((AudioFocusInfo) msg.obj, msg.arg1); } else { // should never be null, but don't crash Log.e(TAG, "Invalid null focus listener for focus request event"); } break; case MSG_FOCUS_ABANDON: if (mFocusListener != null) { // should never be null mFocusListener.onAudioFocusAbandon((AudioFocusInfo) msg.obj); } else { // should never be null, but don't crash Log.e(TAG, "Invalid null focus listener for focus abandon event"); } break; default: Log.e(TAG, "Unknown event " + msg.what); } Loading media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -22,9 +22,12 @@ import android.media.AudioFocusInfo; */ oneway interface IAudioPolicyCallback { // callbacks for audio focus // callbacks for audio focus listening void notifyAudioFocusGrant(in AudioFocusInfo afi, int requestResult); void notifyAudioFocusLoss(in AudioFocusInfo afi, boolean wasNotified); // callback for audio focus policy void notifyAudioFocusRequest(in AudioFocusInfo afi, int requestResult); void notifyAudioFocusAbandon(in AudioFocusInfo afi); // callback for mix activity status update void notifyMixStateUpdate(in String regId, int state); Loading Loading
api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -22842,6 +22842,7 @@ package android.media { method public void adjustStreamVolume(int, int, int); method public void adjustSuggestedStreamVolume(int, int, int); method public void adjustVolume(int, int); method public int dispatchAudioFocusChange(android.media.AudioFocusInfo, int, android.media.audiopolicy.AudioPolicy); method public void dispatchMediaKeyEvent(android.view.KeyEvent); method public int generateAudioSessionId(); method public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations(); Loading Loading @@ -25844,8 +25845,10 @@ package android.media.audiopolicy { public static abstract class AudioPolicy.AudioPolicyFocusListener { ctor public AudioPolicy.AudioPolicyFocusListener(); method public void onAudioFocusAbandon(android.media.AudioFocusInfo); method public void onAudioFocusGrant(android.media.AudioFocusInfo, int); method public void onAudioFocusLoss(android.media.AudioFocusInfo, boolean); method public void onAudioFocusRequest(android.media.AudioFocusInfo, int); } public static abstract class AudioPolicy.AudioPolicyStatusListener { Loading @@ -25860,6 +25863,7 @@ package android.media.audiopolicy { method public android.media.audiopolicy.AudioPolicy build(); method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener); method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener); method public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); method public android.media.audiopolicy.AudioPolicy.Builder setLooper(android.os.Looper) throws java.lang.IllegalArgumentException; }
media/java/android/media/AudioManager.java +41 −3 Original line number Diff line number Diff line Loading @@ -2538,6 +2538,44 @@ public class AudioManager { } } /** * @hide * Notifies an application with a focus listener of gain or loss of audio focus. * This method can only be used by owners of an {@link AudioPolicy} configured with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to true. * @param afi the recipient of the focus change, that has previously requested audio focus, and * that was received by the {@code AudioPolicy} through * {@link AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(AudioFocusInfo, int)}. * @param focusChange one of focus gain types ({@link #AUDIOFOCUS_GAIN}, * {@link #AUDIOFOCUS_GAIN_TRANSIENT}, {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} or * {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}) * or one of the focus loss types ({@link AudioManager#AUDIOFOCUS_LOSS}, * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}, * or {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}). * <br>For the focus gain, the change type should be the same as the app requested. * @param ap a valid registered {@link AudioPolicy} configured as a focus policy. * @return {@link #AUDIOFOCUS_REQUEST_GRANTED} if the dispatch was successfully sent, or * {@link #AUDIOFOCUS_REQUEST_FAILED} if the focus client didn't have a listener, or * if there was an error sending the request. * @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null. */ @SystemApi public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange, @NonNull AudioPolicy ap) { if (afi == null) { throw new NullPointerException("Illegal null AudioFocusInfo"); } if (ap == null) { throw new NullPointerException("Illegal null AudioPolicy"); } final IAudioService service = getService(); try { return service.dispatchFocusChange(afi, focusChange, ap.cb()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @hide * Used internally by telephony package to abandon audio focus, typically after a call or Loading @@ -2548,7 +2586,7 @@ public class AudioManager { final IAudioService service = getService(); try { service.abandonAudioFocus(null, AudioSystem.IN_VOICE_COMM_FOCUS_ID, null /*AudioAttributes, legacy behavior*/); null /*AudioAttributes, legacy behavior*/, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2579,7 +2617,7 @@ public class AudioManager { final IAudioService service = getService(); try { status = service.abandonAudioFocus(mAudioFocusDispatcher, getIdForAudioFocusListener(l), aa); getIdForAudioFocusListener(l), aa, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2787,7 +2825,7 @@ public class AudioManager { final IAudioService service = getService(); try { String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(), policy.hasFocusListener()); policy.hasFocusListener(), policy.isFocusPolicy()); if (regId == null) { return ERROR; } else { Loading
media/java/android/media/IAudioService.aidl +7 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioFocusInfo; import android.media.AudioPlaybackConfiguration; import android.media.AudioRecordingConfiguration; import android.media.AudioRoutesInfo; Loading Loading @@ -122,7 +123,8 @@ interface IAudioService { IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb); int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa); int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa, in String callingPackageName); void unregisterAudioFocusClient(String clientId); Loading Loading @@ -164,7 +166,7 @@ interface IAudioService { boolean isHdmiSystemAudioSupported(); String registerAudioPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb, boolean hasFocusListener); in IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy); oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); Loading Loading @@ -196,5 +198,8 @@ interface IAudioService { int getFocusRampTimeMs(in int focusGain, in AudioAttributes attr); int dispatchFocusChange(in AudioFocusInfo afi, in int focusChange, in IAudioPolicyCallback pcb); // WARNING: read warning at top of file, it is recommended to add new methods at the end }
media/java/android/media/audiopolicy/AudioPolicy.java +86 −3 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ public class AudioPolicy { private int mStatus; private String mRegistrationId; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; /** * The behavior of a policy with regards to audio focus where it relies on the application Loading Loading @@ -96,12 +97,14 @@ public class AudioPolicy { public AudioPolicyConfig getConfig() { return mConfig; } /** @hide */ public boolean hasFocusListener() { return mFocusListener != null; } /** @hide */ public boolean isFocusPolicy() { return mIsFocusPolicy; } /** * The parameter is guaranteed non-null through the Builder */ private AudioPolicy(AudioPolicyConfig config, Context context, Looper looper, AudioPolicyFocusListener fl, AudioPolicyStatusListener sl) { AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, boolean isFocusPolicy) { mConfig = config; mStatus = POLICY_STATUS_UNREGISTERED; mContext = context; Loading @@ -116,10 +119,12 @@ public class AudioPolicy { } mFocusListener = fl; mStatusListener = sl; mIsFocusPolicy = isFocusPolicy; } /** * Builder class for {@link AudioPolicy} objects * Builder class for {@link AudioPolicy} objects. * By default the policy to be created doesn't govern audio focus decisions. */ @SystemApi public static class Builder { Loading @@ -128,6 +133,7 @@ public class AudioPolicy { private Looper mLooper; private AudioPolicyFocusListener mFocusListener; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy = false; /** * Constructs a new Builder with no audio mixes. Loading Loading @@ -178,6 +184,21 @@ public class AudioPolicy { mFocusListener = l; } /** * Declares whether this policy will grant and deny audio focus through * the {@link AudioPolicy.AudioPolicyStatusListener}. * If set to {@code true}, it is mandatory to set an * {@link AudioPolicy.AudioPolicyStatusListener} in order to successfully build * an {@code AudioPolicy} instance. * @param enforce true if the policy will govern audio focus decisions. * @return the same Builder instance. */ @SystemApi public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) { mIsFocusPolicy = isFocusPolicy; return this; } /** * Sets the audio policy status listener. * @param l a {@link AudioPolicy.AudioPolicyStatusListener} Loading @@ -187,6 +208,14 @@ public class AudioPolicy { mStatusListener = l; } /** * Combines all of the attributes that have been set on this {@code Builder} and returns a * new {@link AudioPolicy} object. * @return a new {@code AudioPolicy} object. * @throws IllegalStateException if there is no * {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured * as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}. */ @SystemApi public AudioPolicy build() { if (mStatusListener != null) { Loading @@ -195,8 +224,12 @@ public class AudioPolicy { mix.mCallbackFlags |= AudioMix.CALLBACK_FLAG_NOTIFY_ACTIVITY; } } if (mIsFocusPolicy && mFocusListener == null) { throw new IllegalStateException("Cannot be a focus policy without " + "an AudioPolicyFocusListener"); } return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper, mFocusListener, mStatusListener); mFocusListener, mStatusListener, mIsFocusPolicy); } } Loading Loading @@ -402,6 +435,24 @@ public class AudioPolicy { public static abstract class AudioPolicyFocusListener { public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {} public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {} /** * Called whenever an application requests audio focus. * Only ever called if the {@link AudioPolicy} was built with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}. * @param afi information about the focus request and the requester * @param requestResult the result that was returned synchronously by the framework to the * application, {@link #AUDIOFOCUS_REQUEST_FAILED},or * {@link #AUDIOFOCUS_REQUEST_DELAYED}. */ public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {} /** * Called whenever an application abandons audio focus. * Only ever called if the {@link AudioPolicy} was built with * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}. * @param afi information about the focus request being abandoned and the original * requester. */ public void onAudioFocusAbandon(AudioFocusInfo afi) {} } private void onPolicyStatusChange() { Loading Loading @@ -439,6 +490,22 @@ public class AudioPolicy { } } public void notifyAudioFocusRequest(AudioFocusInfo afi, int requestResult) { sendMsg(MSG_FOCUS_REQUEST, afi, requestResult); if (DEBUG) { Log.v(TAG, "notifyAudioFocusRequest: pack=" + afi.getPackageName() + " client=" + afi.getClientId() + "reqRes=" + requestResult); } } public void notifyAudioFocusAbandon(AudioFocusInfo afi) { sendMsg(MSG_FOCUS_ABANDON, afi, 0 /* ignored */); if (DEBUG) { Log.v(TAG, "notifyAudioFocusAbandon: pack=" + afi.getPackageName() + " client=" + afi.getClientId()); } } public void notifyMixStateUpdate(String regId, int state) { for (AudioMix mix : mConfig.getMixes()) { if (mix.getRegistration().equals(regId)) { Loading @@ -459,6 +526,8 @@ public class AudioPolicy { private final static int MSG_FOCUS_GRANT = 1; private final static int MSG_FOCUS_LOSS = 2; private final static int MSG_MIX_STATE_UPDATE = 3; private final static int MSG_FOCUS_REQUEST = 4; private final static int MSG_FOCUS_ABANDON = 5; private class EventHandler extends Handler { public EventHandler(AudioPolicy ap, Looper looper) { Loading Loading @@ -488,6 +557,20 @@ public class AudioPolicy { mStatusListener.onMixStateUpdate((AudioMix) msg.obj); } break; case MSG_FOCUS_REQUEST: if (mFocusListener != null) { mFocusListener.onAudioFocusRequest((AudioFocusInfo) msg.obj, msg.arg1); } else { // should never be null, but don't crash Log.e(TAG, "Invalid null focus listener for focus request event"); } break; case MSG_FOCUS_ABANDON: if (mFocusListener != null) { // should never be null mFocusListener.onAudioFocusAbandon((AudioFocusInfo) msg.obj); } else { // should never be null, but don't crash Log.e(TAG, "Invalid null focus listener for focus abandon event"); } break; default: Log.e(TAG, "Unknown event " + msg.what); } Loading
media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -22,9 +22,12 @@ import android.media.AudioFocusInfo; */ oneway interface IAudioPolicyCallback { // callbacks for audio focus // callbacks for audio focus listening void notifyAudioFocusGrant(in AudioFocusInfo afi, int requestResult); void notifyAudioFocusLoss(in AudioFocusInfo afi, boolean wasNotified); // callback for audio focus policy void notifyAudioFocusRequest(in AudioFocusInfo afi, int requestResult); void notifyAudioFocusAbandon(in AudioFocusInfo afi); // callback for mix activity status update void notifyMixStateUpdate(in String regId, int state); Loading