diff options
Diffstat (limited to 'media/java/android/media/FocusRequester.java')
| -rw-r--r-- | media/java/android/media/FocusRequester.java | 108 |
1 files changed, 96 insertions, 12 deletions
diff --git a/media/java/android/media/FocusRequester.java b/media/java/android/media/FocusRequester.java index 9a39994..bbe5fd2 100644 --- a/media/java/android/media/FocusRequester.java +++ b/media/java/android/media/FocusRequester.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.NonNull; import android.media.MediaFocusControl.AudioFocusDeathHandler; import android.os.IBinder; import android.util.Log; @@ -40,24 +41,43 @@ class FocusRequester { private final String mClientId; private final String mPackageName; private final int mCallingUid; + private final MediaFocusControl mFocusController; // never null /** * the audio focus gain request that caused the addition of this object in the focus stack. */ private final int mFocusGainRequest; /** + * the flags associated with the gain request that qualify the type of grant (e.g. accepting + * delay vs grant must be immediate) + */ + private final int mGrantFlags; + /** * the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if * it never lost focus. */ private int mFocusLossReceived; /** - * the stream type associated with the focus request + * the audio attributes associated with the focus request */ - private final int mStreamType; + private final AudioAttributes mAttributes; - FocusRequester(int streamType, int focusRequest, + /** + * Class constructor + * @param aa + * @param focusRequest + * @param grantFlags + * @param afl + * @param source + * @param id + * @param hdlr + * @param pn + * @param uid + * @param ctlr cannot be null + */ + FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags, IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr, - String pn, int uid) { - mStreamType = streamType; + String pn, int uid, @NonNull MediaFocusControl ctlr) { + mAttributes = aa; mFocusDispatcher = afl; mSourceRef = source; mClientId = id; @@ -65,7 +85,9 @@ class FocusRequester { mPackageName = pn; mCallingUid = uid; mFocusGainRequest = focusRequest; + mGrantFlags = grantFlags; mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; + mFocusController = ctlr; } @@ -77,6 +99,10 @@ class FocusRequester { } } + boolean isLockedFocusOwner() { + return ((mGrantFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0); + } + boolean hasSameBinder(IBinder ib) { return (mSourceRef != null) && mSourceRef.equals(ib); } @@ -93,13 +119,20 @@ class FocusRequester { return mCallingUid == uid; } + String getClientId() { + return mClientId; + } int getGainRequest() { return mFocusGainRequest; } - int getStreamType() { - return mStreamType; + int getGrantFlags() { + return mGrantFlags; + } + + AudioAttributes getAudioAttributes() { + return mAttributes; } @@ -134,14 +167,31 @@ class FocusRequester { return focusChangeToString(mFocusLossReceived); } + private static String flagsToString(int flags) { + String msg = new String(); + if ((flags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK) != 0) { + msg += "DELAY_OK"; + } + if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0) { + if (!msg.isEmpty()) { msg += "|"; } + msg += "LOCK"; + } + if ((flags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0) { + if (!msg.isEmpty()) { msg += "|"; } + msg += "PAUSES_ON_DUCKABLE_LOSS"; + } + return msg; + } + void dump(PrintWriter pw) { pw.println(" source:" + mSourceRef + " -- pack: " + mPackageName + " -- client: " + mClientId + " -- gain: " + focusGainToString() + + " -- flags: " + flagsToString(mGrantFlags) + " -- loss: " + focusLossToString() + " -- uid: " + mCallingUid - + " -- stream: " + mStreamType); + + " -- attr: " + mAttributes); } @@ -204,13 +254,22 @@ class FocusRequester { } } + /** + * Called synchronized on MediaFocusControl.mAudioFocusLock + */ void handleExternalFocusGain(int focusGain) { int focusLoss = focusLossForGainRequest(focusGain); handleFocusLoss(focusLoss); } + /** + * Called synchronized on MediaFocusControl.mAudioFocusLock + */ void handleFocusGain(int focusGain) { try { + mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; + mFocusController.notifyExtPolicyFocusGrant_syncAf(toAudioFocusInfo(), + AudioManager.AUDIOFOCUS_REQUEST_GRANTED); if (mFocusDispatcher != null) { if (DEBUG) { Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to " @@ -218,27 +277,52 @@ class FocusRequester { } mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId); } - mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; } catch (android.os.RemoteException e) { Log.e(TAG, "Failure to signal gain of audio focus due to: ", e); } } + /** + * Called synchronized on MediaFocusControl.mAudioFocusLock + */ void handleFocusLoss(int focusLoss) { try { if (focusLoss != mFocusLossReceived) { + mFocusLossReceived = focusLoss; + // before dispatching a focus loss, check if the following conditions are met: + // 1/ the framework is not supposed to notify the focus loser on a DUCK loss + // 2/ it is a DUCK loss + // 3/ the focus loser isn't flagged as pausing in a DUCK loss + // if they are, do not notify the focus loser + if (!mFocusController.mustNotifyFocusOwnerOnDuck() + && mFocusLossReceived == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK + && (mGrantFlags + & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) == 0) { + if (DEBUG) { + Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived) + + " to " + mClientId + ", to be handled externally"); + } + mFocusController.notifyExtPolicyFocusLoss_syncAf( + toAudioFocusInfo(), false /* wasDispatched */); + return; + } if (mFocusDispatcher != null) { if (DEBUG) { - Log.v(TAG, "dispatching " + focusChangeToString(focusLoss) + " to " + Log.v(TAG, "dispatching " + focusChangeToString(mFocusLossReceived) + " to " + mClientId); } - mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId); + mFocusController.notifyExtPolicyFocusLoss_syncAf( + toAudioFocusInfo(), true /* wasDispatched */); + mFocusDispatcher.dispatchAudioFocusChange(mFocusLossReceived, mClientId); } - mFocusLossReceived = focusLoss; } } catch (android.os.RemoteException e) { Log.e(TAG, "Failure to signal loss of audio focus due to:", e); } } + AudioFocusInfo toAudioFocusInfo() { + return new AudioFocusInfo(mAttributes, mClientId, mPackageName, + mFocusGainRequest, mFocusLossReceived, mGrantFlags); + } } |
