summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2013-07-31 15:53:07 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-07-31 15:53:08 +0000
commit3a6f25512c0a682b10961a5a7428e3393ffb0b75 (patch)
treec9a9cda07be247a1b5bd0c9eb8634a433f6bd550
parent46fc6a6e3b8c16d66b4880cde59dff43ab1792db (diff)
parentcbb212ff6f06b004ae19dfb6958ee3852716bbdc (diff)
downloadframeworks_base-3a6f25512c0a682b10961a5a7428e3393ffb0b75.zip
frameworks_base-3a6f25512c0a682b10961a5a7428e3393ffb0b75.tar.gz
frameworks_base-3a6f25512c0a682b10961a5a7428e3393ffb0b75.tar.bz2
Merge "Focus gain sends focus loss through the focus stack"
-rw-r--r--media/java/android/media/FocusRequester.java41
-rw-r--r--media/java/android/media/MediaFocusControl.java27
2 files changed, 42 insertions, 26 deletions
diff --git a/media/java/android/media/FocusRequester.java b/media/java/android/media/FocusRequester.java
index 6b34b56..020f3e1 100644
--- a/media/java/android/media/FocusRequester.java
+++ b/media/java/android/media/FocusRequester.java
@@ -37,9 +37,10 @@ class FocusRequester {
// on purpose not using this classe's name, as it will only be used from MediaFocusControl
private static final String TAG = "MediaFocusControl";
+ private static final boolean DEBUG = false;
private AudioFocusDeathHandler mDeathHandler;
- private final IAudioFocusDispatcher mFocusDispatcher;
+ private final IAudioFocusDispatcher mFocusDispatcher; // may be null
private final IBinder mSourceRef;
private final String mClientId;
private final String mPackageName;
@@ -73,10 +74,6 @@ class FocusRequester {
}
- boolean canDispatchFocus() {
- return (mFocusDispatcher != null);
- }
-
boolean hasSameClient(String otherClient) {
try {
return mClientId.compareTo(otherClient) == 0;
@@ -197,7 +194,7 @@ class FocusRequester {
switch(mFocusLossReceived) {
case AUDIOFOCUS_NONE:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
+ return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
case AudioManager.AUDIOFOCUS_LOSS:
@@ -210,20 +207,19 @@ class FocusRequester {
}
void handleExternalFocusGain(int focusGain) {
- try {
- int focusLoss = focusLossForGainRequest(focusGain);
- if (focusLoss != mFocusLossReceived) {
- mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
- mFocusLossReceived = focusLoss;
- }
- } catch (android.os.RemoteException e) {
- Log.e(TAG, "Failure to signal loss of focus: ", e);
- }
+ int focusLoss = focusLossForGainRequest(focusGain);
+ handleFocusLoss(focusLoss);
}
void handleFocusGain(int focusGain) {
try {
- mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
+ if (mFocusDispatcher != null) {
+ if (DEBUG) {
+ Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to "
+ + mClientId);
+ }
+ 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);
@@ -232,9 +228,16 @@ class FocusRequester {
void handleFocusLoss(int focusLoss) {
try {
- mFocusDispatcher.dispatchAudioFocusChange(
- focusLoss, mClientId);
- mFocusLossReceived = focusLoss;
+ if (focusLoss != mFocusLossReceived) {
+ if (mFocusDispatcher != null) {
+ if (DEBUG) {
+ Log.v(TAG, "dispatching " + focusChangeToString(focusLoss) + " to "
+ + mClientId);
+ }
+ mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
+ }
+ mFocusLossReceived = focusLoss;
+ }
} catch (android.os.RemoteException e) {
Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
}
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index ca57b92..c5b1101 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -265,7 +265,7 @@ public class MediaFocusControl implements OnFinished {
*/
protected void discardAudioFocusOwner() {
synchronized(mAudioFocusLock) {
- if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
+ if (!mFocusStack.empty()) {
// notify the current focus owner it lost focus after removing it from stack
final FocusRequester exFocusOwner = mFocusStack.pop();
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
@@ -280,13 +280,26 @@ public class MediaFocusControl implements OnFinished {
private void notifyTopOfAudioFocusStack() {
// notify the top of the stack it gained focus
- if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
+ if (!mFocusStack.empty()) {
if (canReassignAudioFocus()) {
mFocusStack.peek().handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
}
}
}
+ /**
+ * Focus is requested, propagate the associated loss throughout the stack.
+ * @param focusGain the new focus gain that will later be added at the top of the stack
+ */
+ private void propagateFocusLossFromGain_syncAf(int focusGain) {
+ // going through the audio focus stack to signal new focus, traversing order doesn't
+ // matter as all entries respond to the same external focus gain
+ Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+ while(stackIterator.hasNext()) {
+ stackIterator.next().handleExternalFocusGain(focusGain);
+ }
+ }
+
private final Stack<FocusRequester> mFocusStack = new Stack<FocusRequester>();
/**
@@ -462,14 +475,14 @@ public class MediaFocusControl implements OnFinished {
fr.release();
}
- // notify current top of stack it is losing focus
- if (!mFocusStack.empty() && mFocusStack.peek().canDispatchFocus()) {
- mFocusStack.peek().handleExternalFocusGain(focusChangeHint);
- }
-
// focus requester might already be somewhere below in the stack, remove it
removeFocusStackEntry(clientId, false /* signal */);
+ // propagate the focus change through the stack
+ if (!mFocusStack.empty()) {
+ propagateFocusLossFromGain_syncAf(focusChangeHint);
+ }
+
// push focus requester at the top of the audio focus stack
mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
clientId, afdh, callingPackageName, Binder.getCallingUid()));