183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi/*
283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * Copyright (C) 2013 The Android Open Source Project
383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi *
483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * you may not use this file except in compliance with the License.
683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * You may obtain a copy of the License at
783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi *
883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi *
1083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * See the License for the specific language governing permissions and
1483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * limitations under the License.
1583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */
1683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
1783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivipackage android.media;
1883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
1983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport android.media.MediaFocusControl.AudioFocusDeathHandler;
2083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport android.os.IBinder;
2183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport android.util.Log;
2283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
2383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport java.io.PrintWriter;
2483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
2583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi/**
2683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * @hide
2783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * Class to handle all the information about a user of audio focus. The lifecycle of each
2883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * instance is managed by android.media.MediaFocusControl, from its addition to the audio focus
2983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * stack to its release.
3083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */
3183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviclass FocusRequester {
3283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
3383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    // on purpose not using this classe's name, as it will only be used from MediaFocusControl
3483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private static final String TAG = "MediaFocusControl";
35cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi    private static final boolean DEBUG = false;
3683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
3783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private AudioFocusDeathHandler mDeathHandler;
38cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi    private final IAudioFocusDispatcher mFocusDispatcher; // may be null
3983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final IBinder mSourceRef;
4083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final String mClientId;
4183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final String mPackageName;
4283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final int mCallingUid;
4383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    /**
4483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     * the audio focus gain request that caused the addition of this object in the focus stack.
4583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     */
4683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final int mFocusGainRequest;
4783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    /**
482380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if
4983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     *  it never lost focus.
5083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     */
5183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private int mFocusLossReceived;
5283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    /**
5383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     * the stream type associated with the focus request
5483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     */
5583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private final int mStreamType;
5683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
5783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    FocusRequester(int streamType, int focusRequest,
5883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
5983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            String pn, int uid) {
6083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mStreamType = streamType;
6183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mFocusDispatcher = afl;
6283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mSourceRef = source;
6383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mClientId = id;
6483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mDeathHandler = hdlr;
6583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mPackageName = pn;
6683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mCallingUid = uid;
6783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        mFocusGainRequest = focusRequest;
682380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
6983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
7083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
7183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
7283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    boolean hasSameClient(String otherClient) {
7383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        try {
7483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            return mClientId.compareTo(otherClient) == 0;
7583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        } catch (NullPointerException e) {
7683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            return false;
7783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
7883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
7983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
8083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    boolean hasSameBinder(IBinder ib) {
8183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return (mSourceRef != null) && mSourceRef.equals(ib);
8283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
8383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
8483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    boolean hasSamePackage(String pack) {
8583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        try {
8683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            return mPackageName.compareTo(pack) == 0;
8783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        } catch (NullPointerException e) {
8883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            return false;
8983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
9083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
9183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
9283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    boolean hasSameUid(int uid) {
9383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return mCallingUid == uid;
9483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
9583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
9683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
9783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    int getGainRequest() {
9883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return mFocusGainRequest;
9983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
10083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
10183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    int getStreamType() {
10283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return mStreamType;
10383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
10483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
10583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
10683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private static String focusChangeToString(int focus) {
10783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        switch(focus) {
1082380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            case AudioManager.AUDIOFOCUS_NONE:
10983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "none";
11083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN:
11183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "GAIN";
11283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
11383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "GAIN_TRANSIENT";
11483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
11583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "GAIN_TRANSIENT_MAY_DUCK";
1162380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
1172380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                return "GAIN_TRANSIENT_EXCLUSIVE";
11883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_LOSS:
11983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "LOSS";
12083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
12183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "LOSS_TRANSIENT";
12283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
12383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "LOSS_TRANSIENT_CAN_DUCK";
12483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            default:
12583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                return "[invalid focus change" + focus + "]";
12683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
12783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
12883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
12983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private String focusGainToString() {
13083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return focusChangeToString(mFocusGainRequest);
13183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
13283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
13383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private String focusLossToString() {
13483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        return focusChangeToString(mFocusLossReceived);
13583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
13683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
13783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    void dump(PrintWriter pw) {
13883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        pw.println("  source:" + mSourceRef
13983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- pack: " + mPackageName
14083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- client: " + mClientId
14183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- gain: " + focusGainToString()
14283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- loss: " + focusLossToString()
14383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- uid: " + mCallingUid
14483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                + " -- stream: " + mStreamType);
14583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
14683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
14783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
14883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    void release() {
14983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        try {
15083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            if (mSourceRef != null && mDeathHandler != null) {
15183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                mSourceRef.unlinkToDeath(mDeathHandler, 0);
15283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi                mDeathHandler = null;
15383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            }
15483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        } catch (java.util.NoSuchElementException e) {
15583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            Log.e(TAG, "FocusRequester.release() hit ", e);
15683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
15783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
15883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
15983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    @Override
16083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    protected void finalize() throws Throwable {
16183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        release();
16283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        super.finalize();
16383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
16483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
16583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    /**
16683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     * For a given audio focus gain request, return the audio focus loss type that will result
16753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi     * from it, taking into account any previous focus loss.
16883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     * @param gainRequest
16983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     * @return the audio focus loss type that matches the gain request
17083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi     */
17183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    private int focusLossForGainRequest(int gainRequest) {
17253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi        switch(gainRequest) {
17353e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN:
17453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                switch(mFocusLossReceived) {
17553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
17653e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
17753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS:
1782380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                    case AudioManager.AUDIOFOCUS_NONE:
17953e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS;
18053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                }
1812380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
18253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
18353e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                switch(mFocusLossReceived) {
18453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
18553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
1862380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                    case AudioManager.AUDIOFOCUS_NONE:
18753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
18853e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS:
18953e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS;
19053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                }
19153e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
19253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                switch(mFocusLossReceived) {
1932380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                    case AudioManager.AUDIOFOCUS_NONE:
19453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
195cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
19653e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
19753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
19853e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                    case AudioManager.AUDIOFOCUS_LOSS:
19953e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                        return AudioManager.AUDIOFOCUS_LOSS;
20053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                }
20153e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi            default:
20253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi                Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest);
2032380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                        return AudioManager.AUDIOFOCUS_NONE;
20453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi        }
20583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
20683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
20783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    void handleExternalFocusGain(int focusGain) {
208cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi        int focusLoss = focusLossForGainRequest(focusGain);
209cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi        handleFocusLoss(focusLoss);
21083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
21183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
21283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    void handleFocusGain(int focusGain) {
21383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        try {
214cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi            if (mFocusDispatcher != null) {
215cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                if (DEBUG) {
216cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                    Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to "
217cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                        + mClientId);
218cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                }
219cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
220cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi            }
2212380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
22283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        } catch (android.os.RemoteException e) {
22383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
22483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
22583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
22683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
22783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    void handleFocusLoss(int focusLoss) {
22883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        try {
229cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi            if (focusLoss != mFocusLossReceived) {
230cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                if (mFocusDispatcher != null) {
231cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                    if (DEBUG) {
232cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                        Log.v(TAG, "dispatching " + focusChangeToString(focusLoss) + " to "
233cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                            + mClientId);
234cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                    }
235cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                    mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
236cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                }
237cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi                mFocusLossReceived = focusLoss;
238cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi            }
23983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        } catch (android.os.RemoteException e) {
24083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi            Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
24183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi        }
24283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi    }
24383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi
24483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi}
245