Merge "Audio focus request managed by FocusRequester class"
This commit is contained in:
committed by
Android (Google) Code Review
commit
fec4a907b1
210
media/java/android/media/FocusRequester.java
Normal file
210
media/java/android/media/FocusRequester.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media;
|
||||
|
||||
import android.media.MediaFocusControl.AudioFocusDeathHandler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
class FocusRequester {
|
||||
|
||||
/**
|
||||
* Used to indicate no audio focus has been gained or lost.
|
||||
*/
|
||||
private static final int AUDIOFOCUS_NONE = 0;
|
||||
|
||||
// on purpose not using this classe's name, as it will only be used from MediaFocusControl
|
||||
private static final String TAG = "MediaFocusControl";
|
||||
|
||||
private AudioFocusDeathHandler mDeathHandler;
|
||||
private final IAudioFocusDispatcher mFocusDispatcher;
|
||||
private final IBinder mSourceRef;
|
||||
private final String mClientId;
|
||||
private final String mPackageName;
|
||||
private final int mCallingUid;
|
||||
/**
|
||||
* the audio focus gain request that caused the addition of this object in the focus stack.
|
||||
*/
|
||||
private final int mFocusGainRequest;
|
||||
/**
|
||||
* the audio focus loss received my mFocusDispatcher, is MediaFocusControl.AUDIOFOCUS_NONE if
|
||||
* it never lost focus.
|
||||
*/
|
||||
private int mFocusLossReceived;
|
||||
/**
|
||||
* the stream type associated with the focus request
|
||||
*/
|
||||
private final int mStreamType;
|
||||
|
||||
FocusRequester(int streamType, int focusRequest,
|
||||
IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
|
||||
String pn, int uid) {
|
||||
mStreamType = streamType;
|
||||
mFocusDispatcher = afl;
|
||||
mSourceRef = source;
|
||||
mClientId = id;
|
||||
mDeathHandler = hdlr;
|
||||
mPackageName = pn;
|
||||
mCallingUid = uid;
|
||||
mFocusGainRequest = focusRequest;
|
||||
mFocusLossReceived = AUDIOFOCUS_NONE;
|
||||
}
|
||||
|
||||
|
||||
boolean canDispatchFocus() {
|
||||
return (mFocusDispatcher != null);
|
||||
}
|
||||
|
||||
boolean hasSameClient(String otherClient) {
|
||||
try {
|
||||
return mClientId.compareTo(otherClient) == 0;
|
||||
} catch (NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSameBinder(IBinder ib) {
|
||||
return (mSourceRef != null) && mSourceRef.equals(ib);
|
||||
}
|
||||
|
||||
boolean hasSamePackage(String pack) {
|
||||
try {
|
||||
return mPackageName.compareTo(pack) == 0;
|
||||
} catch (NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSameUid(int uid) {
|
||||
return mCallingUid == uid;
|
||||
}
|
||||
|
||||
|
||||
int getGainRequest() {
|
||||
return mFocusGainRequest;
|
||||
}
|
||||
|
||||
int getStreamType() {
|
||||
return mStreamType;
|
||||
}
|
||||
|
||||
|
||||
private static String focusChangeToString(int focus) {
|
||||
switch(focus) {
|
||||
case 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_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 String focusGainToString() {
|
||||
return focusChangeToString(mFocusGainRequest);
|
||||
}
|
||||
|
||||
private String focusLossToString() {
|
||||
return focusChangeToString(mFocusLossReceived);
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw) {
|
||||
pw.println(" source:" + mSourceRef
|
||||
+ " -- pack: " + mPackageName
|
||||
+ " -- client: " + mClientId
|
||||
+ " -- gain: " + focusGainToString()
|
||||
+ " -- loss: " + focusLossToString()
|
||||
+ " -- uid: " + mCallingUid
|
||||
+ " -- stream: " + mStreamType);
|
||||
}
|
||||
|
||||
|
||||
void release() {
|
||||
try {
|
||||
if (mSourceRef != null && mDeathHandler != null) {
|
||||
mSourceRef.unlinkToDeath(mDeathHandler, 0);
|
||||
mDeathHandler = null;
|
||||
}
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
Log.e(TAG, "FocusRequester.release() hit ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
release();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given audio focus gain request, return the audio focus loss type that will result
|
||||
* from it.
|
||||
* @param gainRequest
|
||||
* @return the audio focus loss type that matches the gain request
|
||||
*/
|
||||
private int focusLossForGainRequest(int gainRequest) {
|
||||
// FIXME to be updated to take into account mFocusLossReceived
|
||||
return -gainRequest; // focus loss codes are the inverse of the gain codes
|
||||
}
|
||||
|
||||
void handleExternalFocusGain(int focusGain) {
|
||||
try {
|
||||
int focusLoss = focusLossForGainRequest(focusGain);
|
||||
mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
|
||||
mFocusLossReceived = focusLoss;
|
||||
} catch (android.os.RemoteException e) {
|
||||
Log.e(TAG, "Failure to signal loss of focus: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFocusGain(int focusGain) {
|
||||
try {
|
||||
mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
|
||||
mFocusLossReceived = AUDIOFOCUS_NONE;
|
||||
} catch (android.os.RemoteException e) {
|
||||
Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFocusLoss(int focusLoss) {
|
||||
try {
|
||||
mFocusDispatcher.dispatchAudioFocusChange(
|
||||
focusLoss, mClientId);
|
||||
} catch (android.os.RemoteException e) {
|
||||
Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,11 +66,6 @@ public class MediaFocusControl implements OnFinished {
|
||||
/** Debug volumes */
|
||||
protected static final boolean DEBUG_VOL = false;
|
||||
|
||||
/**
|
||||
* Used to indicate no audio focus has been gained or lost.
|
||||
*/
|
||||
private static final int AUDIOFOCUS_NONE = 0;
|
||||
|
||||
/** Used to alter media button redirection when the phone is ringing. */
|
||||
private boolean mIsRinging = false;
|
||||
|
||||
@@ -270,11 +265,11 @@ public class MediaFocusControl implements OnFinished {
|
||||
*/
|
||||
protected void discardAudioFocusOwner() {
|
||||
synchronized(mAudioFocusLock) {
|
||||
if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
|
||||
// notify the current focus owner it lost focus after removing it from stack
|
||||
final FocusStackEntry exFocusOwner = mFocusStack.pop();
|
||||
final FocusRequester exFocusOwner = mFocusStack.pop();
|
||||
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
|
||||
exFocusOwner.unlinkToDeath();
|
||||
exFocusOwner.release();
|
||||
// clear RCD
|
||||
synchronized(mRCStack) {
|
||||
clearRemoteControlDisplay_syncAfRcs();
|
||||
@@ -285,128 +280,14 @@ public class MediaFocusControl implements OnFinished {
|
||||
|
||||
private void notifyTopOfAudioFocusStack() {
|
||||
// notify the top of the stack it gained focus
|
||||
if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
|
||||
if (canReassignAudioFocus()) {
|
||||
mFocusStack.peek().handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class FocusStackEntry {
|
||||
int mStreamType = -1;// no stream type
|
||||
IAudioFocusDispatcher mFocusDispatcher = null;
|
||||
IBinder mSourceRef = null;
|
||||
String mClientId;
|
||||
/** the audio focus gain request that caused the addition of this entry in the stack */
|
||||
int mFocusGainRequest;
|
||||
int mFocusLossReceived;
|
||||
AudioFocusDeathHandler mHandler;
|
||||
String mPackageName;
|
||||
int mCallingUid;
|
||||
|
||||
static String focusChangeToString(int focus) {
|
||||
switch(focus) {
|
||||
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_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 + "]";
|
||||
}
|
||||
}
|
||||
|
||||
String focusGainToString() {
|
||||
return focusChangeToString(mFocusGainRequest);
|
||||
}
|
||||
|
||||
String focusLossToString() {
|
||||
if (mFocusLossReceived == 0) {
|
||||
return "none";
|
||||
} else {
|
||||
return focusChangeToString(mFocusLossReceived);
|
||||
}
|
||||
}
|
||||
|
||||
FocusStackEntry(int streamType, int focusRequest,
|
||||
IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
|
||||
String pn, int uid) {
|
||||
mStreamType = streamType;
|
||||
mFocusDispatcher = afl;
|
||||
mSourceRef = source;
|
||||
mClientId = id;
|
||||
mFocusGainRequest = focusRequest;
|
||||
mFocusLossReceived = AUDIOFOCUS_NONE;
|
||||
mHandler = hdlr;
|
||||
mPackageName = pn;
|
||||
mCallingUid = uid;
|
||||
}
|
||||
|
||||
void unlinkToDeath() {
|
||||
try {
|
||||
if (mSourceRef != null && mHandler != null) {
|
||||
mSourceRef.unlinkToDeath(mHandler, 0);
|
||||
mHandler = null;
|
||||
}
|
||||
} catch (java.util.NoSuchElementException e) {
|
||||
Log.e(TAG, "Encountered " + e + " in FocusStackEntry.unlinkToDeath()");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
unlinkToDeath(); // unlink exception handled inside method
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given audio focus gain request, return the audio focus loss type that will result
|
||||
* from it.
|
||||
* @param gainRequest
|
||||
* @return the audio focus loss type that matches the gain request
|
||||
*/
|
||||
int focusLossForGainRequest(int gainRequest) {
|
||||
return -1 * gainRequest; // focus loss codes are the inverse of the gain codes
|
||||
}
|
||||
|
||||
void handleExternalFocusGain(int focusGain) {
|
||||
try {
|
||||
int focusLoss = focusLossForGainRequest(focusGain);
|
||||
mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
|
||||
mFocusLossReceived = focusLoss;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, " Failure to signal loss of focus: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFocusGain(int focusGain) {
|
||||
try {
|
||||
mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
|
||||
mFocusLossReceived = AUDIOFOCUS_NONE;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, " Failure to signal gain of audio focus due to: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFocusLoss(int focusLoss) {
|
||||
try {
|
||||
mFocusDispatcher.dispatchAudioFocusChange(
|
||||
focusLoss, mClientId);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
|
||||
private final Stack<FocusRequester> mFocusStack = new Stack<FocusRequester>();
|
||||
|
||||
/**
|
||||
* Helper function:
|
||||
@@ -415,16 +296,9 @@ public class MediaFocusControl implements OnFinished {
|
||||
private void dumpFocusStack(PrintWriter pw) {
|
||||
pw.println("\nAudio Focus stack entries (last is top of stack):");
|
||||
synchronized(mAudioFocusLock) {
|
||||
Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
|
||||
Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
|
||||
while(stackIterator.hasNext()) {
|
||||
FocusStackEntry fse = stackIterator.next();
|
||||
pw.println(" source:" + fse.mSourceRef
|
||||
+ " -- pack: " + fse.mPackageName
|
||||
+ " -- client: " + fse.mClientId
|
||||
+ " -- gain: " + fse.focusGainToString()
|
||||
+ " -- loss: " + fse.focusLossToString()
|
||||
+ " -- uid: " + fse.mCallingUid
|
||||
+ " -- stream: " + fse.mStreamType);
|
||||
stackIterator.next().dump(pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,11 +313,11 @@ public class MediaFocusControl implements OnFinished {
|
||||
*/
|
||||
private void removeFocusStackEntry(String clientToRemove, boolean signal) {
|
||||
// is the current top of the focus stack abandoning focus? (because of request, not death)
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientToRemove))
|
||||
{
|
||||
//Log.i(TAG, " removeFocusStackEntry() removing top of stack");
|
||||
FocusStackEntry fse = mFocusStack.pop();
|
||||
fse.unlinkToDeath();
|
||||
FocusRequester fr = mFocusStack.pop();
|
||||
fr.release();
|
||||
if (signal) {
|
||||
// notify the new top of the stack it gained focus
|
||||
notifyTopOfAudioFocusStack();
|
||||
@@ -457,14 +331,14 @@ public class MediaFocusControl implements OnFinished {
|
||||
// no need to update focus.
|
||||
// (using an iterator on the stack so we can safely remove an entry after having
|
||||
// evaluated it, traversal order doesn't matter here)
|
||||
Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
|
||||
Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
|
||||
while(stackIterator.hasNext()) {
|
||||
FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
|
||||
if(fse.mClientId.equals(clientToRemove)) {
|
||||
FocusRequester fr = (FocusRequester)stackIterator.next();
|
||||
if(fr.hasSameClient(clientToRemove)) {
|
||||
Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for "
|
||||
+ fse.mClientId);
|
||||
+ clientToRemove);
|
||||
stackIterator.remove();
|
||||
fse.unlinkToDeath();
|
||||
fr.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,15 +352,14 @@ public class MediaFocusControl implements OnFinished {
|
||||
private void removeFocusStackEntryForClient(IBinder cb) {
|
||||
// is the owner of the audio focus part of the client to remove?
|
||||
boolean isTopOfStackForClientToRemove = !mFocusStack.isEmpty() &&
|
||||
mFocusStack.peek().mSourceRef.equals(cb);
|
||||
mFocusStack.peek().hasSameBinder(cb);
|
||||
// (using an iterator on the stack so we can safely remove an entry after having
|
||||
// evaluated it, traversal order doesn't matter here)
|
||||
Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
|
||||
Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
|
||||
while(stackIterator.hasNext()) {
|
||||
FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
|
||||
if(fse.mSourceRef.equals(cb)) {
|
||||
Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for "
|
||||
+ fse.mClientId);
|
||||
FocusRequester fr = (FocusRequester)stackIterator.next();
|
||||
if(fr.hasSameBinder(cb)) {
|
||||
Log.i(TAG, "AudioFocus removeFocusStackEntry(): removing entry for " + cb);
|
||||
stackIterator.remove();
|
||||
// the client just died, no need to unlink to its death
|
||||
}
|
||||
@@ -509,7 +382,7 @@ public class MediaFocusControl implements OnFinished {
|
||||
private boolean canReassignAudioFocus() {
|
||||
// focus requests are rejected during a phone call or when the phone is ringing
|
||||
// this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
|
||||
if (!mFocusStack.isEmpty() && IN_VOICE_COMM_FOCUS_ID.equals(mFocusStack.peek().mClientId)) {
|
||||
if (!mFocusStack.isEmpty() && mFocusStack.peek().hasSameClient(IN_VOICE_COMM_FOCUS_ID)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -519,7 +392,7 @@ public class MediaFocusControl implements OnFinished {
|
||||
* Inner class to monitor audio focus client deaths, and remove them from the audio focus
|
||||
* stack if necessary.
|
||||
*/
|
||||
private class AudioFocusDeathHandler implements IBinder.DeathRecipient {
|
||||
protected class AudioFocusDeathHandler implements IBinder.DeathRecipient {
|
||||
private IBinder mCb; // To be notified of client's death
|
||||
|
||||
AudioFocusDeathHandler(IBinder cb) {
|
||||
@@ -574,10 +447,10 @@ public class MediaFocusControl implements OnFinished {
|
||||
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
|
||||
}
|
||||
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientId)) {
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientId)) {
|
||||
// if focus is already owned by this client and the reason for acquiring the focus
|
||||
// hasn't changed, don't do anything
|
||||
if (mFocusStack.peek().mFocusGainRequest == focusChangeHint) {
|
||||
if (mFocusStack.peek().getGainRequest() == focusChangeHint) {
|
||||
// unlink death handler so it can be gc'ed.
|
||||
// linkToDeath() creates a JNI global reference preventing collection.
|
||||
cb.unlinkToDeath(afdh, 0);
|
||||
@@ -585,12 +458,12 @@ public class MediaFocusControl implements OnFinished {
|
||||
}
|
||||
// the reason for the audio focus request has changed: remove the current top of
|
||||
// stack and respond as if we had a new focus owner
|
||||
FocusStackEntry fse = mFocusStack.pop();
|
||||
fse.unlinkToDeath();
|
||||
FocusRequester fr = mFocusStack.pop();
|
||||
fr.release();
|
||||
}
|
||||
|
||||
// notify current top of stack it is losing focus
|
||||
if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
|
||||
if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
|
||||
mFocusStack.peek().handleExternalFocusGain(focusChangeHint);
|
||||
}
|
||||
|
||||
@@ -598,7 +471,7 @@ public class MediaFocusControl implements OnFinished {
|
||||
removeFocusStackEntry(clientId, false /* signal */);
|
||||
|
||||
// push focus requester at the top of the audio focus stack
|
||||
mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
|
||||
mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
|
||||
clientId, afdh, callingPackageName, Binder.getCallingUid()));
|
||||
|
||||
// there's a new top of the stack, let the remote control know
|
||||
@@ -1609,13 +1482,13 @@ public class MediaFocusControl implements OnFinished {
|
||||
// characteristics:
|
||||
// - focus gain on STREAM_MUSIC stream
|
||||
// - non-transient focus gain on a stream other than music
|
||||
FocusStackEntry af = null;
|
||||
FocusRequester af = null;
|
||||
try {
|
||||
for (int index = mFocusStack.size()-1; index >= 0; index--) {
|
||||
FocusStackEntry fse = mFocusStack.elementAt(index);
|
||||
if ((fse.mStreamType == AudioManager.STREAM_MUSIC)
|
||||
|| (fse.mFocusGainRequest == AudioManager.AUDIOFOCUS_GAIN)) {
|
||||
af = fse;
|
||||
FocusRequester fr = mFocusStack.elementAt(index);
|
||||
if ((fr.getStreamType() == AudioManager.STREAM_MUSIC)
|
||||
|| (fr.getGainRequest() == AudioManager.AUDIOFOCUS_GAIN)) {
|
||||
af = fr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1629,16 +1502,13 @@ public class MediaFocusControl implements OnFinished {
|
||||
}
|
||||
|
||||
// if the audio focus and RC owners belong to different packages, there is a mismatch, clear
|
||||
if ((mRCStack.peek().mCallingPackageName != null)
|
||||
&& (af.mPackageName != null)
|
||||
&& !(mRCStack.peek().mCallingPackageName.compareTo(
|
||||
af.mPackageName) == 0)) {
|
||||
if (!af.hasSamePackage(mRCStack.peek().mCallingPackageName)) {
|
||||
clearRemoteControlDisplay_syncAfRcs();
|
||||
return;
|
||||
}
|
||||
// if the audio focus didn't originate from the same Uid as the one in which the remote
|
||||
// control information will be retrieved, clear
|
||||
if (mRCStack.peek().mCallingUid != af.mCallingUid) {
|
||||
if (!af.hasSameUid(mRCStack.peek().mCallingUid)) {
|
||||
clearRemoteControlDisplay_syncAfRcs();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user