blob: 99f08405a375c2f109d11ccd956548222a724113 [file] [log] [blame]
Jean-Michel Trivi83283f22013-07-29 18:09:41 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
John Spurlock61560172015-02-06 19:46:04 -050017package com.android.server.audio;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070018
Jean-Michel Trivi0212be52014-11-24 14:43:10 -080019import android.annotation.NonNull;
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -080020import android.annotation.Nullable;
John Spurlock61560172015-02-06 19:46:04 -050021import android.media.AudioAttributes;
22import android.media.AudioFocusInfo;
23import android.media.AudioManager;
24import android.media.IAudioFocusDispatcher;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070025import android.os.IBinder;
26import android.util.Log;
27
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -080028import com.android.internal.annotations.GuardedBy;
John Spurlock61560172015-02-06 19:46:04 -050029import com.android.server.audio.MediaFocusControl.AudioFocusDeathHandler;
30
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070031import java.io.PrintWriter;
32
33/**
34 * @hide
35 * Class to handle all the information about a user of audio focus. The lifecycle of each
36 * instance is managed by android.media.MediaFocusControl, from its addition to the audio focus
Jean-Michel Trivi126cf032017-04-02 23:19:02 -070037 * stack, or the map of focus owners for an external focus policy, to its release.
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070038 */
John Spurlock61560172015-02-06 19:46:04 -050039public class FocusRequester {
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070040
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070041 // on purpose not using this classe's name, as it will only be used from MediaFocusControl
42 private static final String TAG = "MediaFocusControl";
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -070043 private static final boolean DEBUG = false;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070044
Jean-Michel Trivie8987722016-07-07 15:38:32 -070045 private AudioFocusDeathHandler mDeathHandler; // may be null
46 private IAudioFocusDispatcher mFocusDispatcher; // may be null
47 private final IBinder mSourceRef; // may be null
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070048 private final String mClientId;
49 private final String mPackageName;
50 private final int mCallingUid;
Jean-Michel Trivi0212be52014-11-24 14:43:10 -080051 private final MediaFocusControl mFocusController; // never null
Jean-Michel Trivi461922f2017-04-25 15:23:17 -070052 private final int mSdkTarget;
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -080053
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070054 /**
55 * the audio focus gain request that caused the addition of this object in the focus stack.
56 */
57 private final int mFocusGainRequest;
58 /**
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -080059 * the flags associated with the gain request that qualify the type of grant (e.g. accepting
60 * delay vs grant must be immediate)
61 */
62 private final int mGrantFlags;
63 /**
Jean-Michel Trivi23805662013-07-31 14:19:18 -070064 * the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070065 * it never lost focus.
66 */
67 private int mFocusLossReceived;
68 /**
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -080069 * whether this focus owner listener was notified when it lost focus
70 */
71 private boolean mFocusLossWasNotified;
72 /**
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -080073 * the audio attributes associated with the focus request
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070074 */
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -080075 private final AudioAttributes mAttributes;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070076
Jean-Michel Trivi0212be52014-11-24 14:43:10 -080077 /**
78 * Class constructor
79 * @param aa
80 * @param focusRequest
81 * @param grantFlags
82 * @param afl
83 * @param source
84 * @param id
85 * @param hdlr
86 * @param pn
87 * @param uid
88 * @param ctlr cannot be null
89 */
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -080090 FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags,
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070091 IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
Jean-Michel Trivi461922f2017-04-25 15:23:17 -070092 String pn, int uid, @NonNull MediaFocusControl ctlr, int sdk) {
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -080093 mAttributes = aa;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -070094 mFocusDispatcher = afl;
95 mSourceRef = source;
96 mClientId = id;
97 mDeathHandler = hdlr;
98 mPackageName = pn;
99 mCallingUid = uid;
100 mFocusGainRequest = focusRequest;
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -0800101 mGrantFlags = grantFlags;
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700102 mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
Jean-Michel Trivi087b6722017-05-10 13:05:06 -0700103 mFocusLossWasNotified = true;
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800104 mFocusController = ctlr;
Jean-Michel Trivi461922f2017-04-25 15:23:17 -0700105 mSdkTarget = sdk;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700106 }
107
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700108 FocusRequester(AudioFocusInfo afi, IAudioFocusDispatcher afl,
109 IBinder source, AudioFocusDeathHandler hdlr, @NonNull MediaFocusControl ctlr) {
110 mAttributes = afi.getAttributes();
111 mClientId = afi.getClientId();
112 mPackageName = afi.getPackageName();
113 mCallingUid = afi.getClientUid();
114 mFocusGainRequest = afi.getGainRequest();
115 mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
Jean-Michel Trivi087b6722017-05-10 13:05:06 -0700116 mFocusLossWasNotified = true;
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700117 mGrantFlags = afi.getFlags();
Jean-Michel Trivi461922f2017-04-25 15:23:17 -0700118 mSdkTarget = afi.getSdkTarget();
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700119
120 mFocusDispatcher = afl;
121 mSourceRef = source;
122 mDeathHandler = hdlr;
123 mFocusController = ctlr;
124 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700125
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700126 boolean hasSameClient(String otherClient) {
127 try {
128 return mClientId.compareTo(otherClient) == 0;
129 } catch (NullPointerException e) {
130 return false;
131 }
132 }
133
Jean-Michel Trivi958876f2014-11-16 15:40:22 -0800134 boolean isLockedFocusOwner() {
135 return ((mGrantFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0);
136 }
137
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700138 boolean hasSameBinder(IBinder ib) {
139 return (mSourceRef != null) && mSourceRef.equals(ib);
140 }
141
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700142 boolean hasSameDispatcher(IAudioFocusDispatcher fd) {
143 return (mFocusDispatcher != null) && mFocusDispatcher.equals(fd);
144 }
145
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700146 boolean hasSamePackage(String pack) {
147 try {
148 return mPackageName.compareTo(pack) == 0;
149 } catch (NullPointerException e) {
150 return false;
151 }
152 }
153
154 boolean hasSameUid(int uid) {
155 return mCallingUid == uid;
156 }
157
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800158 int getClientUid() {
159 return mCallingUid;
160 }
161
Jean-Michel Trivi958876f2014-11-16 15:40:22 -0800162 String getClientId() {
163 return mClientId;
164 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700165
166 int getGainRequest() {
167 return mFocusGainRequest;
168 }
169
Jean-Michel Trivifd6ad742014-11-10 14:38:30 -0800170 int getGrantFlags() {
171 return mGrantFlags;
172 }
173
174 AudioAttributes getAudioAttributes() {
175 return mAttributes;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700176 }
177
Jean-Michel Trivi461922f2017-04-25 15:23:17 -0700178 int getSdkTarget() {
179 return mSdkTarget;
180 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700181
182 private static String focusChangeToString(int focus) {
183 switch(focus) {
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700184 case AudioManager.AUDIOFOCUS_NONE:
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700185 return "none";
186 case AudioManager.AUDIOFOCUS_GAIN:
187 return "GAIN";
188 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
189 return "GAIN_TRANSIENT";
190 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
191 return "GAIN_TRANSIENT_MAY_DUCK";
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700192 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
193 return "GAIN_TRANSIENT_EXCLUSIVE";
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700194 case AudioManager.AUDIOFOCUS_LOSS:
195 return "LOSS";
196 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
197 return "LOSS_TRANSIENT";
198 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
199 return "LOSS_TRANSIENT_CAN_DUCK";
200 default:
201 return "[invalid focus change" + focus + "]";
202 }
203 }
204
205 private String focusGainToString() {
206 return focusChangeToString(mFocusGainRequest);
207 }
208
209 private String focusLossToString() {
210 return focusChangeToString(mFocusLossReceived);
211 }
212
Jean-Michel Trivi958876f2014-11-16 15:40:22 -0800213 private static String flagsToString(int flags) {
214 String msg = new String();
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800215 if ((flags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK) != 0) {
216 msg += "DELAY_OK";
217 }
218 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) != 0) {
219 if (!msg.isEmpty()) { msg += "|"; }
220 msg += "LOCK";
221 }
222 if ((flags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0) {
223 if (!msg.isEmpty()) { msg += "|"; }
224 msg += "PAUSES_ON_DUCKABLE_LOSS";
225 }
Jean-Michel Trivi958876f2014-11-16 15:40:22 -0800226 return msg;
227 }
228
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700229 void dump(PrintWriter pw) {
230 pw.println(" source:" + mSourceRef
231 + " -- pack: " + mPackageName
232 + " -- client: " + mClientId
233 + " -- gain: " + focusGainToString()
Jean-Michel Trivi958876f2014-11-16 15:40:22 -0800234 + " -- flags: " + flagsToString(mGrantFlags)
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700235 + " -- loss: " + focusLossToString()
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800236 + " -- notified: " + mFocusLossWasNotified
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700237 + " -- uid: " + mCallingUid
Jean-Michel Trivi461922f2017-04-25 15:23:17 -0700238 + " -- attr: " + mAttributes
239 + " -- sdk:" + mSdkTarget);
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700240 }
241
242
243 void release() {
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800244 final IBinder srcRef = mSourceRef;
245 final AudioFocusDeathHandler deathHdlr = mDeathHandler;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700246 try {
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800247 if (srcRef != null && deathHdlr != null) {
248 srcRef.unlinkToDeath(deathHdlr, 0);
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700249 }
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800250 } catch (java.util.NoSuchElementException e) { }
251 mDeathHandler = null;
252 mFocusDispatcher = null;
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700253 }
254
255 @Override
256 protected void finalize() throws Throwable {
257 release();
258 super.finalize();
259 }
260
261 /**
262 * For a given audio focus gain request, return the audio focus loss type that will result
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700263 * from it, taking into account any previous focus loss.
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700264 * @param gainRequest
265 * @return the audio focus loss type that matches the gain request
266 */
267 private int focusLossForGainRequest(int gainRequest) {
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700268 switch(gainRequest) {
269 case AudioManager.AUDIOFOCUS_GAIN:
270 switch(mFocusLossReceived) {
271 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
272 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
273 case AudioManager.AUDIOFOCUS_LOSS:
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700274 case AudioManager.AUDIOFOCUS_NONE:
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700275 return AudioManager.AUDIOFOCUS_LOSS;
276 }
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700277 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700278 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
279 switch(mFocusLossReceived) {
280 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
281 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700282 case AudioManager.AUDIOFOCUS_NONE:
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700283 return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
284 case AudioManager.AUDIOFOCUS_LOSS:
285 return AudioManager.AUDIOFOCUS_LOSS;
286 }
287 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
288 switch(mFocusLossReceived) {
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700289 case AudioManager.AUDIOFOCUS_NONE:
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700290 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700291 return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700292 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
293 return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
294 case AudioManager.AUDIOFOCUS_LOSS:
295 return AudioManager.AUDIOFOCUS_LOSS;
296 }
297 default:
298 Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest);
Jean-Michel Trivi23805662013-07-31 14:19:18 -0700299 return AudioManager.AUDIOFOCUS_NONE;
Jean-Michel Trivi53e6e282013-07-30 14:21:34 -0700300 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700301 }
302
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800303 /**
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800304 * Handle the loss of focus resulting from a given focus gain.
305 * @param focusGain the focus gain from which the loss of focus is resulting
306 * @param frWinner the new focus owner
307 * @return true if the focus loss is definitive, false otherwise.
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800308 */
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800309 @GuardedBy("MediaFocusControl.mAudioFocusLock")
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800310 boolean handleFocusLossFromGain(int focusGain, final FocusRequester frWinner, boolean forceDuck)
311 {
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800312 final int focusLoss = focusLossForGainRequest(focusGain);
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800313 handleFocusLoss(focusLoss, frWinner, forceDuck);
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800314 return (focusLoss == AudioManager.AUDIOFOCUS_LOSS);
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700315 }
316
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800317 @GuardedBy("MediaFocusControl.mAudioFocusLock")
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700318 void handleFocusGain(int focusGain) {
319 try {
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800320 mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
321 mFocusController.notifyExtPolicyFocusGrant_syncAf(toAudioFocusInfo(),
322 AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
Jean-Michel Trivie8987722016-07-07 15:38:32 -0700323 final IAudioFocusDispatcher fd = mFocusDispatcher;
324 if (fd != null) {
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700325 if (DEBUG) {
326 Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to "
327 + mClientId);
328 }
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800329 if (mFocusLossWasNotified) {
330 fd.dispatchAudioFocusChange(focusGain, mClientId);
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800331 }
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700332 }
Jean-Michel Trivi270f1c92017-05-05 11:43:31 -0700333 mFocusController.unduckPlayers(this);
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700334 } catch (android.os.RemoteException e) {
335 Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
336 }
337 }
338
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800339 @GuardedBy("MediaFocusControl.mAudioFocusLock")
Jean-Michel Trivi270f1c92017-05-05 11:43:31 -0700340 void handleFocusGainFromRequest(int focusRequestResult) {
341 if (focusRequestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
342 mFocusController.unduckPlayers(this);
343 }
344 }
345
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800346 @GuardedBy("MediaFocusControl.mAudioFocusLock")
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800347 void handleFocusLoss(int focusLoss, @Nullable final FocusRequester frWinner, boolean forceDuck)
348 {
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700349 try {
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700350 if (focusLoss != mFocusLossReceived) {
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800351 mFocusLossReceived = focusLoss;
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800352 mFocusLossWasNotified = false;
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800353 // before dispatching a focus loss, check if the following conditions are met:
354 // 1/ the framework is not supposed to notify the focus loser on a DUCK loss
Jean-Michel Trivi7b8da922017-05-01 17:51:14 -0700355 // (i.e. it has a focus controller that implements a ducking policy)
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800356 // 2/ it is a DUCK loss
357 // 3/ the focus loser isn't flagged as pausing in a DUCK loss
358 // if they are, do not notify the focus loser
359 if (!mFocusController.mustNotifyFocusOwnerOnDuck()
360 && mFocusLossReceived == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
361 && (mGrantFlags
362 & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) == 0) {
363 if (DEBUG) {
364 Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived)
365 + " to " + mClientId + ", to be handled externally");
366 }
367 mFocusController.notifyExtPolicyFocusLoss_syncAf(
368 toAudioFocusInfo(), false /* wasDispatched */);
369 return;
370 }
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800371
372 // check enforcement by the framework
373 boolean handled = false;
374 if (focusLoss == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
375 && MediaFocusControl.ENFORCE_DUCKING
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800376 && frWinner != null) {
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800377 // candidate for enforcement by the framework
Jean-Michel Trivid9fef5c2017-12-28 15:25:35 -0800378 if (frWinner.mCallingUid != this.mCallingUid) {
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800379 if (!forceDuck && ((mGrantFlags
380 & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0)) {
Jean-Michel Trivi7b8da922017-05-01 17:51:14 -0700381 // the focus loser declared it would pause instead of duck, let it
382 // handle it (the framework doesn't pause for apps)
383 handled = false;
Jean-Michel Trivi087b6722017-05-10 13:05:06 -0700384 Log.v(TAG, "not ducking uid " + this.mCallingUid + " - flags");
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800385 } else if (!forceDuck && (MediaFocusControl.ENFORCE_DUCKING_FOR_NEW &&
386 this.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL))
387 {
Jean-Michel Trivi087b6722017-05-10 13:05:06 -0700388 // legacy behavior, apps used to be notified when they should be ducking
389 handled = false;
390 Log.v(TAG, "not ducking uid " + this.mCallingUid + " - old SDK");
Jean-Michel Trivi7b8da922017-05-01 17:51:14 -0700391 } else {
Jean-Michel Trivi9228af62018-01-05 17:06:17 -0800392 handled = mFocusController.duckPlayers(frWinner, this, forceDuck);
Jean-Michel Trivi7b8da922017-05-01 17:51:14 -0700393 }
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800394 } // else: the focus change is within the same app, so let the dispatching
395 // happen as if the framework was not involved.
396 }
397
398 if (handled) {
399 if (DEBUG) {
400 Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived)
401 + " to " + mClientId + ", ducking implemented by framework");
402 }
Jean-Michel Trivi08124922017-05-05 09:44:28 -0700403 mFocusController.notifyExtPolicyFocusLoss_syncAf(
404 toAudioFocusInfo(), false /* wasDispatched */);
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800405 return; // with mFocusLossWasNotified = false
406 }
407
Jean-Michel Trivie8987722016-07-07 15:38:32 -0700408 final IAudioFocusDispatcher fd = mFocusDispatcher;
409 if (fd != null) {
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700410 if (DEBUG) {
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800411 Log.v(TAG, "dispatching " + focusChangeToString(mFocusLossReceived) + " to "
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700412 + mClientId);
413 }
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800414 mFocusController.notifyExtPolicyFocusLoss_syncAf(
415 toAudioFocusInfo(), true /* wasDispatched */);
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800416 mFocusLossWasNotified = true;
Jean-Michel Trivie8987722016-07-07 15:38:32 -0700417 fd.dispatchAudioFocusChange(mFocusLossReceived, mClientId);
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700418 }
Jean-Michel Trivicbb212f2013-07-30 15:09:33 -0700419 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700420 } catch (android.os.RemoteException e) {
421 Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
422 }
423 }
424
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700425 int dispatchFocusChange(int focusChange) {
426 if (mFocusDispatcher == null) {
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800427 if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusChange: no focus dispatcher"); }
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700428 return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
429 }
430 if (focusChange == AudioManager.AUDIOFOCUS_NONE) {
431 if (MediaFocusControl.DEBUG) { Log.v(TAG, "dispatchFocusChange: AUDIOFOCUS_NONE"); }
432 return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
433 } else if ((focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
434 || focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
435 || focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
436 || focusChange == AudioManager.AUDIOFOCUS_GAIN)
437 && (mFocusGainRequest != focusChange)){
438 Log.w(TAG, "focus gain was requested with " + mFocusGainRequest
439 + ", dispatching " + focusChange);
440 } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
441 || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
442 || focusChange == AudioManager.AUDIOFOCUS_LOSS) {
443 mFocusLossReceived = focusChange;
444 }
445 try {
446 mFocusDispatcher.dispatchAudioFocusChange(focusChange, mClientId);
447 } catch (android.os.RemoteException e) {
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800448 Log.e(TAG, "dispatchFocusChange: error talking to focus listener " + mClientId, e);
Jean-Michel Trivi126cf032017-04-02 23:19:02 -0700449 return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
450 }
451 return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
452 }
453
Jean-Michel Trivie2d8aae2018-01-30 15:09:47 -0800454 void dispatchFocusResultFromExtPolicy(int requestResult) {
455 if (mFocusDispatcher == null) {
456 if (MediaFocusControl.DEBUG) {
457 Log.e(TAG, "dispatchFocusResultFromExtPolicy: no focus dispatcher");
458 }
459 }
460 if (DEBUG) {
461 Log.v(TAG, "dispatching result" + requestResult + " to " + mClientId);
462 }
463 try {
464 mFocusDispatcher.dispatchFocusResultFromExtPolicy(requestResult, mClientId);
465 } catch (android.os.RemoteException e) {
466 Log.e(TAG, "dispatchFocusResultFromExtPolicy: error talking to focus listener"
467 + mClientId, e);
468 }
469 }
470
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800471 AudioFocusInfo toAudioFocusInfo() {
Jean-Michel Trivi99489cc2017-01-25 19:08:49 -0800472 return new AudioFocusInfo(mAttributes, mCallingUid, mClientId, mPackageName,
Jean-Michel Trivi461922f2017-04-25 15:23:17 -0700473 mFocusGainRequest, mFocusLossReceived, mGrantFlags, mSdkTarget);
Jean-Michel Trivi0212be52014-11-24 14:43:10 -0800474 }
Jean-Michel Trivi83283f22013-07-29 18:09:41 -0700475}