FocusRequester.java revision 270f1c9d8ff38be25b8972f7d158ca178da82eb7
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 176156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockpackage com.android.server.audio; 1883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 190212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Triviimport android.annotation.NonNull; 2099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Triviimport android.annotation.Nullable; 216156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockimport android.media.AudioAttributes; 226156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockimport android.media.AudioFocusInfo; 236156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockimport android.media.AudioManager; 246156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockimport android.media.IAudioFocusDispatcher; 2583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport android.os.IBinder; 2683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport android.util.Log; 2783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 286156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockimport com.android.server.audio.MediaFocusControl.AudioFocusDeathHandler; 296156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlock 3083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Triviimport java.io.PrintWriter; 3183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 3283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi/** 3383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * @hide 3483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * Class to handle all the information about a user of audio focus. The lifecycle of each 3583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * instance is managed by android.media.MediaFocusControl, from its addition to the audio focus 36126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi * stack, or the map of focus owners for an external focus policy, to its release. 3783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */ 386156017c2217d0fbbbb03434986250ec6bbd69d8John Spurlockpublic class FocusRequester { 3983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 4083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi // on purpose not using this classe's name, as it will only be used from MediaFocusControl 4183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private static final String TAG = "MediaFocusControl"; 42cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi private static final boolean DEBUG = false; 4383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 44e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi private AudioFocusDeathHandler mDeathHandler; // may be null 45e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi private IAudioFocusDispatcher mFocusDispatcher; // may be null 46e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi private final IBinder mSourceRef; // may be null 4783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private final String mClientId; 4883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private final String mPackageName; 4983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private final int mCallingUid; 500212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi private final MediaFocusControl mFocusController; // never null 51461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi private final int mSdkTarget; 5299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 5383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi /** 5483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * the audio focus gain request that caused the addition of this object in the focus stack. 5583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */ 5683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private final int mFocusGainRequest; 5783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi /** 58fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi * the flags associated with the gain request that qualify the type of grant (e.g. accepting 59fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi * delay vs grant must be immediate) 60fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi */ 61fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi private final int mGrantFlags; 62fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi /** 632380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi * the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if 6483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * it never lost focus. 6583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */ 6683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private int mFocusLossReceived; 6783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi /** 6899489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi * whether this focus owner listener was notified when it lost focus 6999489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi */ 7099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi private boolean mFocusLossWasNotified; 7199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi /** 72fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi * the audio attributes associated with the focus request 7383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */ 74fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi private final AudioAttributes mAttributes; 7583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 760212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi /** 770212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * Class constructor 780212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param aa 790212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param focusRequest 800212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param grantFlags 810212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param afl 820212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param source 830212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param id 840212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param hdlr 850212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param pn 860212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param uid 870212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * @param ctlr cannot be null 880212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi */ 89fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags, 9083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr, 91461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi String pn, int uid, @NonNull MediaFocusControl ctlr, int sdk) { 92fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi mAttributes = aa; 9383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mFocusDispatcher = afl; 9483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mSourceRef = source; 9583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mClientId = id; 9683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mDeathHandler = hdlr; 9783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mPackageName = pn; 9883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mCallingUid = uid; 9983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mFocusGainRequest = focusRequest; 100fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi mGrantFlags = grantFlags; 1012380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; 1020212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusController = ctlr; 103461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi mSdkTarget = sdk; 10483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 10583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 106126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi FocusRequester(AudioFocusInfo afi, IAudioFocusDispatcher afl, 107126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi IBinder source, AudioFocusDeathHandler hdlr, @NonNull MediaFocusControl ctlr) { 108126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mAttributes = afi.getAttributes(); 109126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mClientId = afi.getClientId(); 110126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mPackageName = afi.getPackageName(); 111126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mCallingUid = afi.getClientUid(); 112126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusGainRequest = afi.getGainRequest(); 113126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; 114126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mGrantFlags = afi.getFlags(); 115461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi mSdkTarget = afi.getSdkTarget(); 116126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi 117126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusDispatcher = afl; 118126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mSourceRef = source; 119126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mDeathHandler = hdlr; 120126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusController = ctlr; 121126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 12283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 12383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi boolean hasSameClient(String otherClient) { 12483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi try { 12583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return mClientId.compareTo(otherClient) == 0; 12683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } catch (NullPointerException e) { 12783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return false; 12883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 12983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 13083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 131958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi boolean isLockedFocusOwner() { 132958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi return ((mGrantFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0); 133958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi } 134958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi 13583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi boolean hasSameBinder(IBinder ib) { 13683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return (mSourceRef != null) && mSourceRef.equals(ib); 13783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 13883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 139126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi boolean hasSameDispatcher(IAudioFocusDispatcher fd) { 140126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi return (mFocusDispatcher != null) && mFocusDispatcher.equals(fd); 141126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 142126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi 14383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi boolean hasSamePackage(String pack) { 14483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi try { 14583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return mPackageName.compareTo(pack) == 0; 14683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } catch (NullPointerException e) { 14783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return false; 14883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 14983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 15083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 15183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi boolean hasSameUid(int uid) { 15283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return mCallingUid == uid; 15383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 15483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 15599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi int getClientUid() { 15699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return mCallingUid; 15799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 15899489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 159958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi String getClientId() { 160958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi return mClientId; 161958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi } 16283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 16383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi int getGainRequest() { 16483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return mFocusGainRequest; 16583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 16683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 167fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi int getGrantFlags() { 168fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi return mGrantFlags; 169fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi } 170fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi 171fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi AudioAttributes getAudioAttributes() { 172fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi return mAttributes; 17383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 17483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 175461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi int getSdkTarget() { 176461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi return mSdkTarget; 177461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi } 17883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 17983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private static String focusChangeToString(int focus) { 18083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi switch(focus) { 1812380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_NONE: 18283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "none"; 18383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN: 18483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "GAIN"; 18583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: 18683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "GAIN_TRANSIENT"; 18783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: 18883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "GAIN_TRANSIENT_MAY_DUCK"; 1892380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 1902380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi return "GAIN_TRANSIENT_EXCLUSIVE"; 19183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS: 19283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "LOSS"; 19383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 19483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "LOSS_TRANSIENT"; 19583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 19683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "LOSS_TRANSIENT_CAN_DUCK"; 19783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi default: 19883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return "[invalid focus change" + focus + "]"; 19983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 20083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 20183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 20283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private String focusGainToString() { 20383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return focusChangeToString(mFocusGainRequest); 20483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 20583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 20683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private String focusLossToString() { 20783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi return focusChangeToString(mFocusLossReceived); 20883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 20983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 210958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi private static String flagsToString(int flags) { 211958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi String msg = new String(); 2120212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if ((flags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK) != 0) { 2130212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi msg += "DELAY_OK"; 2140212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 2150212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0) { 2160212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if (!msg.isEmpty()) { msg += "|"; } 2170212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi msg += "LOCK"; 2180212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 2190212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if ((flags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0) { 2200212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if (!msg.isEmpty()) { msg += "|"; } 2210212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi msg += "PAUSES_ON_DUCKABLE_LOSS"; 2220212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 223958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi return msg; 224958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi } 225958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi 22683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi void dump(PrintWriter pw) { 22783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi pw.println(" source:" + mSourceRef 22883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi + " -- pack: " + mPackageName 22983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi + " -- client: " + mClientId 23083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi + " -- gain: " + focusGainToString() 231958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi + " -- flags: " + flagsToString(mGrantFlags) 23283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi + " -- loss: " + focusLossToString() 23399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi + " -- notified: " + mFocusLossWasNotified 23483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi + " -- uid: " + mCallingUid 235461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi + " -- attr: " + mAttributes 236461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi + " -- sdk:" + mSdkTarget); 23783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 23883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 23983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 24083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi void release() { 24183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi try { 24283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi if (mSourceRef != null && mDeathHandler != null) { 24383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mSourceRef.unlinkToDeath(mDeathHandler, 0); 24483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi mDeathHandler = null; 245e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi mFocusDispatcher = null; 24683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 24783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } catch (java.util.NoSuchElementException e) { 24883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi Log.e(TAG, "FocusRequester.release() hit ", e); 24983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 25083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 25183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 25283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi @Override 25383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi protected void finalize() throws Throwable { 25483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi release(); 25583283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi super.finalize(); 25683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 25783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 25883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi /** 25983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * For a given audio focus gain request, return the audio focus loss type that will result 26053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi * from it, taking into account any previous focus loss. 26183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * @param gainRequest 26283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi * @return the audio focus loss type that matches the gain request 26383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi */ 26483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi private int focusLossForGainRequest(int gainRequest) { 26553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi switch(gainRequest) { 26653e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN: 26753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi switch(mFocusLossReceived) { 26853e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 26953e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 27053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS: 2712380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_NONE: 27253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS; 27353e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi } 2742380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 27553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: 27653e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi switch(mFocusLossReceived) { 27753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 27853e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 2792380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_NONE: 28053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT; 28153e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS: 28253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS; 28353e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi } 28453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: 28553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi switch(mFocusLossReceived) { 2862380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi case AudioManager.AUDIOFOCUS_NONE: 28753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 288cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK; 28953e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 29053e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT; 29153e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi case AudioManager.AUDIOFOCUS_LOSS: 29253e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi return AudioManager.AUDIOFOCUS_LOSS; 29353e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi } 29453e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi default: 29553e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest); 2962380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi return AudioManager.AUDIOFOCUS_NONE; 29753e6e287ffe924b6d26237e167a1a8996054e17eJean-Michel Trivi } 29883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 29983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 3000212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi /** 3010212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * Called synchronized on MediaFocusControl.mAudioFocusLock 3020212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi */ 30399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi void handleExternalFocusGain(int focusGain, final FocusRequester fr) { 304cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi int focusLoss = focusLossForGainRequest(focusGain); 30599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi handleFocusLoss(focusLoss, fr); 30683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 30783283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 3080212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi /** 3090212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * Called synchronized on MediaFocusControl.mAudioFocusLock 3100212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi */ 31183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi void handleFocusGain(int focusGain) { 31283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi try { 3130212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE; 3140212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusController.notifyExtPolicyFocusGrant_syncAf(toAudioFocusInfo(), 3150212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi AudioManager.AUDIOFOCUS_REQUEST_GRANTED); 316e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi final IAudioFocusDispatcher fd = mFocusDispatcher; 317e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi if (fd != null) { 318cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi if (DEBUG) { 319cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to " 320cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi + mClientId); 321cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi } 32299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (mFocusLossWasNotified) { 32399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi fd.dispatchAudioFocusChange(focusGain, mClientId); 32499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 325cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi } 326270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi mFocusController.unduckPlayers(this); 32799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi mFocusLossWasNotified = false; 32883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } catch (android.os.RemoteException e) { 32983283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi Log.e(TAG, "Failure to signal gain of audio focus due to: ", e); 33083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 33183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 33283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 3330212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi /** 3340212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi * Called synchronized on MediaFocusControl.mAudioFocusLock 3350212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi */ 336270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi void handleFocusGainFromRequest(int focusRequestResult) { 337270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi if (focusRequestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 338270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi mFocusController.unduckPlayers(this); 339270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi } 340270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi } 341270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi 342270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi /** 343270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi * Called synchronized on MediaFocusControl.mAudioFocusLock 344270f1c9d8ff38be25b8972f7d158ca178da82eb7Jean-Michel Trivi */ 34599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi void handleFocusLoss(int focusLoss, @Nullable final FocusRequester fr) { 34683283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi try { 347cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi if (focusLoss != mFocusLossReceived) { 3480212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusLossReceived = focusLoss; 34999489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi mFocusLossWasNotified = false; 3500212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi // before dispatching a focus loss, check if the following conditions are met: 3510212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi // 1/ the framework is not supposed to notify the focus loser on a DUCK loss 3527b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi // (i.e. it has a focus controller that implements a ducking policy) 3530212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi // 2/ it is a DUCK loss 3540212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi // 3/ the focus loser isn't flagged as pausing in a DUCK loss 3550212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi // if they are, do not notify the focus loser 3560212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if (!mFocusController.mustNotifyFocusOwnerOnDuck() 3570212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi && mFocusLossReceived == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 3580212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi && (mGrantFlags 3590212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) == 0) { 3600212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi if (DEBUG) { 3610212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived) 3620212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi + " to " + mClientId + ", to be handled externally"); 3630212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 3640212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusController.notifyExtPolicyFocusLoss_syncAf( 3650212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi toAudioFocusInfo(), false /* wasDispatched */); 3660212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi return; 3670212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 36899489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 36999489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // check enforcement by the framework 37099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi boolean handled = false; 37199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (focusLoss == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 37299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi && MediaFocusControl.ENFORCE_DUCKING 37399489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi && fr != null) { 37499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // candidate for enforcement by the framework 37599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (fr.mCallingUid != this.mCallingUid) { 3767b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi if ((mGrantFlags 3777b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0) { 3787b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi // the focus loser declared it would pause instead of duck, let it 3797b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi // handle it (the framework doesn't pause for apps) 3807b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi handled = false; 3817b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi } else { 3827b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi handled = mFocusController.duckPlayers(fr, this); 3837b8da92d49caf965e8616ceeba828275574f09c0Jean-Michel Trivi } 38499489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } // else: the focus change is within the same app, so let the dispatching 38599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi // happen as if the framework was not involved. 38699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 38799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 38899489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (handled) { 38999489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi if (DEBUG) { 39099489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived) 39199489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi + " to " + mClientId + ", ducking implemented by framework"); 39299489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 393081249282005640682da315d6f0e0e3697fe4b37Jean-Michel Trivi mFocusController.notifyExtPolicyFocusLoss_syncAf( 394081249282005640682da315d6f0e0e3697fe4b37Jean-Michel Trivi toAudioFocusInfo(), false /* wasDispatched */); 39599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return; // with mFocusLossWasNotified = false 39699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi } 39799489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi 398e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi final IAudioFocusDispatcher fd = mFocusDispatcher; 399e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi if (fd != null) { 400cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi if (DEBUG) { 4010212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi Log.v(TAG, "dispatching " + focusChangeToString(mFocusLossReceived) + " to " 402cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi + mClientId); 403cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi } 4040212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi mFocusController.notifyExtPolicyFocusLoss_syncAf( 4050212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi toAudioFocusInfo(), true /* wasDispatched */); 40699489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi mFocusLossWasNotified = true; 407e89877245fc6dd359e435b5202901f9042819c51Jean-Michel Trivi fd.dispatchAudioFocusChange(mFocusLossReceived, mClientId); 408cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi } 409cbb212ff6f06b004ae19dfb6958ee3852716bbdcJean-Michel Trivi } 41083283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } catch (android.os.RemoteException e) { 41183283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi Log.e(TAG, "Failure to signal loss of audio focus due to:", e); 41283283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 41383283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi } 41483283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi 415126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi int dispatchFocusChange(int focusChange) { 416126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi if (mFocusDispatcher == null) { 417126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi if (MediaFocusControl.DEBUG) { Log.v(TAG, "dispatchFocusChange: no focus dispatcher"); } 418126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 419126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 420126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi if (focusChange == AudioManager.AUDIOFOCUS_NONE) { 421126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi if (MediaFocusControl.DEBUG) { Log.v(TAG, "dispatchFocusChange: AUDIOFOCUS_NONE"); } 422126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 423126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } else if ((focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 424126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi || focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 425126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi || focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT 426126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi || focusChange == AudioManager.AUDIOFOCUS_GAIN) 427126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi && (mFocusGainRequest != focusChange)){ 428126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi Log.w(TAG, "focus gain was requested with " + mFocusGainRequest 429126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi + ", dispatching " + focusChange); 430126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 431126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT 432126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi || focusChange == AudioManager.AUDIOFOCUS_LOSS) { 433126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusLossReceived = focusChange; 434126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 435126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi try { 436126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi mFocusDispatcher.dispatchAudioFocusChange(focusChange, mClientId); 437126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } catch (android.os.RemoteException e) { 438126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi Log.v(TAG, "dispatchFocusChange: error talking to focus listener", e); 439126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 440126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 441126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi return AudioManager.AUDIOFOCUS_REQUEST_GRANTED; 442126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi } 443126cf03f7c8e825a23e47dd133e77eb1b3b7633dJean-Michel Trivi 4440212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi AudioFocusInfo toAudioFocusInfo() { 44599489ccf740d369193a8ffc7eeb4bbde6919bd65Jean-Michel Trivi return new AudioFocusInfo(mAttributes, mCallingUid, mClientId, mPackageName, 446461922fcfc8572415aa39c43c06afce685bd998dJean-Michel Trivi mFocusGainRequest, mFocusLossReceived, mGrantFlags, mSdkTarget); 4470212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi } 44883283f23eb1b7c1576e253c644b8aade6f657d0aJean-Michel Trivi} 449