FileDocCategorySizeDatePackage
FocusRequester.javaAPI DocAndroid 5.1 API12058Thu Mar 12 22:22:30 GMT 2015android.media

FocusRequester

public class FocusRequester extends Object
hide
Class to handle all the information about a user of audio focus. The lifecycle of each instance is managed by android.media.MediaFocusControl, from its addition to the audio focus stack to its release.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private android.media.MediaFocusControl.AudioFocusDeathHandler
mDeathHandler
private final IAudioFocusDispatcher
mFocusDispatcher
private final android.os.IBinder
mSourceRef
private final String
mClientId
private final String
mPackageName
private final int
mCallingUid
private final MediaFocusControl
mFocusController
private final int
mFocusGainRequest
the audio focus gain request that caused the addition of this object in the focus stack.
private final int
mGrantFlags
the flags associated with the gain request that qualify the type of grant (e.g. accepting delay vs grant must be immediate)
private int
mFocusLossReceived
the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if it never lost focus.
private final AudioAttributes
mAttributes
the audio attributes associated with the focus request
Constructors Summary
FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags, IAudioFocusDispatcher afl, android.os.IBinder source, String id, android.media.MediaFocusControl.AudioFocusDeathHandler hdlr, String pn, int uid, MediaFocusControl ctlr)
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


                                  
         
                   
                   
        mAttributes = aa;
        mFocusDispatcher = afl;
        mSourceRef = source;
        mClientId = id;
        mDeathHandler = hdlr;
        mPackageName = pn;
        mCallingUid = uid;
        mFocusGainRequest = focusRequest;
        mGrantFlags = grantFlags;
        mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
        mFocusController = ctlr;
    
Methods Summary
voiddump(java.io.PrintWriter pw)

        pw.println("  source:" + mSourceRef
                + " -- pack: " + mPackageName
                + " -- client: " + mClientId
                + " -- gain: " + focusGainToString()
                + " -- flags: " + flagsToString(mGrantFlags)
                + " -- loss: " + focusLossToString()
                + " -- uid: " + mCallingUid
                + " -- attr: " + mAttributes);
    
protected voidfinalize()

        release();
        super.finalize();
    
private static java.lang.StringflagsToString(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;
    
private static java.lang.StringfocusChangeToString(int focus)

        switch(focus) {
            case AudioManager.AUDIOFOCUS_NONE:
                return "none";
            case AudioManager.AUDIOFOCUS_GAIN:
                return "GAIN";
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                return "GAIN_TRANSIENT";
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
                return "GAIN_TRANSIENT_MAY_DUCK";
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
                return "GAIN_TRANSIENT_EXCLUSIVE";
            case AudioManager.AUDIOFOCUS_LOSS:
                return "LOSS";
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                return "LOSS_TRANSIENT";
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                return "LOSS_TRANSIENT_CAN_DUCK";
            default:
                return "[invalid focus change" + focus + "]";
        }
    
private java.lang.StringfocusGainToString()

        return focusChangeToString(mFocusGainRequest);
    
private intfocusLossForGainRequest(int gainRequest)
For a given audio focus gain request, return the audio focus loss type that will result from it, taking into account any previous focus loss.

param
gainRequest
return
the audio focus loss type that matches the gain request

        switch(gainRequest) {
            case AudioManager.AUDIOFOCUS_GAIN:
                switch(mFocusLossReceived) {
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    case AudioManager.AUDIOFOCUS_LOSS:
                    case AudioManager.AUDIOFOCUS_NONE:
                        return AudioManager.AUDIOFOCUS_LOSS;
                }
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                switch(mFocusLossReceived) {
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    case AudioManager.AUDIOFOCUS_NONE:
                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
                    case AudioManager.AUDIOFOCUS_LOSS:
                        return AudioManager.AUDIOFOCUS_LOSS;
                }
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
                switch(mFocusLossReceived) {
                    case AudioManager.AUDIOFOCUS_NONE:
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
                    case AudioManager.AUDIOFOCUS_LOSS:
                        return AudioManager.AUDIOFOCUS_LOSS;
                }
            default:
                Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest);
                        return AudioManager.AUDIOFOCUS_NONE;
        }
    
private java.lang.StringfocusLossToString()

        return focusChangeToString(mFocusLossReceived);
    
AudioAttributesgetAudioAttributes()

        return mAttributes;
    
java.lang.StringgetClientId()

        return mClientId;
    
intgetGainRequest()

        return mFocusGainRequest;
    
intgetGrantFlags()

        return mGrantFlags;
    
voidhandleExternalFocusGain(int focusGain)
Called synchronized on MediaFocusControl.mAudioFocusLock

        int focusLoss = focusLossForGainRequest(focusGain);
        handleFocusLoss(focusLoss);
    
voidhandleFocusGain(int focusGain)
Called synchronized on MediaFocusControl.mAudioFocusLock

        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 "
                        + mClientId);
                }
                mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
            }
        } catch (android.os.RemoteException e) {
            Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
        }
    
voidhandleFocusLoss(int focusLoss)
Called synchronized on MediaFocusControl.mAudioFocusLock

        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(mFocusLossReceived) + " to "
                            + mClientId);
                    }
                    mFocusController.notifyExtPolicyFocusLoss_syncAf(
                            toAudioFocusInfo(), true /* wasDispatched */);
                    mFocusDispatcher.dispatchAudioFocusChange(mFocusLossReceived, mClientId);
                }
            }
        } catch (android.os.RemoteException e) {
            Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
        }
    
booleanhasSameBinder(android.os.IBinder ib)

        return (mSourceRef != null) && mSourceRef.equals(ib);
    
booleanhasSameClient(java.lang.String otherClient)

        try {
            return mClientId.compareTo(otherClient) == 0;
        } catch (NullPointerException e) {
            return false;
        }
    
booleanhasSamePackage(java.lang.String pack)

        try {
            return mPackageName.compareTo(pack) == 0;
        } catch (NullPointerException e) {
            return false;
        }
    
booleanhasSameUid(int uid)

        return mCallingUid == uid;
    
booleanisLockedFocusOwner()

        return ((mGrantFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0);
    
voidrelease()

        try {
            if (mSourceRef != null && mDeathHandler != null) {
                mSourceRef.unlinkToDeath(mDeathHandler, 0);
                mDeathHandler = null;
            }
        } catch (java.util.NoSuchElementException e) {
            Log.e(TAG, "FocusRequester.release() hit ", e);
        }
    
AudioFocusInfotoAudioFocusInfo()

        return new AudioFocusInfo(mAttributes, mClientId, mPackageName,
                mFocusGainRequest, mFocusLossReceived, mGrantFlags);