Merge "resolved conflicts for merge of 74fb97de to master"
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index 4d42c5d..90824ab 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1287,6 +1287,7 @@
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
+ nUpdateRenderNodeProperties(displayList.getNativeDisplayList());
try {
status |= canvas.drawDisplayList(displayList, mRedrawClip,
RenderNode.FLAG_CLIP_CHILDREN);
@@ -1466,6 +1467,8 @@
static native void nDestroyLayer(long layerPtr);
+ private static native void nUpdateRenderNodeProperties(long displayListPtr);
+
class DrawPerformanceDataProvider extends GraphDataProvider {
private final int mGraphType;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4992960..5e512b6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10817,7 +10817,7 @@
* bounds of the View, and clipToOutline will be ignored.
*
* @param outline The new outline of the view.
- * Must be {@link android.view.Outline#isValid() valid.}
+ * Must be {@link android.graphics.Outline#isValid() valid.}
*
* @see #getClipToOutline()
* @see #setClipToOutline(boolean)
@@ -10856,7 +10856,8 @@
/**
* Sets whether the outline of the View will be used for clipping.
* <p>
- * The current implementation of outline clipping uses Canvas#clipPath(),
+ * The current implementation of outline clipping uses
+ * {@link Canvas#clipPath(Path) path clipping},
* and thus does not support anti-aliasing, and is expensive in terms of
* graphics performance. Therefore, it is strongly recommended that this
* property only be set temporarily, as in an animation. For the same
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
index 00d92fc..e45c1b9 100644
--- a/core/jni/android_view_GLRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -148,6 +148,13 @@
displayList->setData(newData);
}
+static void android_view_GLRenderer_updateRenderNodeProperties(JNIEnv* env, jobject clazz,
+ jlong renderNodePtr) {
+ using namespace android::uirenderer;
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->updateProperties();
+}
+
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -179,6 +186,7 @@
{ "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime },
{ "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer },
{ "nSetDisplayListData", "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData },
+ { "nUpdateRenderNodeProperties", "(J)V", (void*) android_view_GLRenderer_updateRenderNodeProperties },
#endif
{ "setupShadersDiskCache", "(Ljava/lang/String;)V",
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index a65ac87..4ea7ec7 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.view.View;
+
/**
* Defines an area of content.
*
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1568e99..1b5cefe 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1009,7 +1009,7 @@
}
if (state.mInnerRadius == -1
- && themeAttrs == null || themeAttrs[R.styleable.GradientDrawable_thicknessRatio] == 0) {
+ && (themeAttrs == null || themeAttrs[R.styleable.GradientDrawable_thicknessRatio] == 0)) {
state.mInnerRadiusRatio = a.getFloat(
R.styleable.GradientDrawable_innerRadiusRatio, DEFAULT_INNER_RADIUS_RATIO);
}
@@ -1020,7 +1020,7 @@
}
if (state.mThickness == -1
- && themeAttrs == null || themeAttrs[R.styleable.GradientDrawable_thicknessRatio] == 0) {
+ && (themeAttrs == null || themeAttrs[R.styleable.GradientDrawable_thicknessRatio] == 0)) {
state.mThicknessRatio = a.getFloat(
R.styleable.GradientDrawable_thicknessRatio, DEFAULT_THICKNESS_RATIO);
}
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 7a83967..7380bbf 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -75,6 +75,7 @@
success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
}
mLayer->setBlend(mBlend);
+ mDisplayList->updateProperties();
mLayer->updateDeferred(mRenderer, mDisplayList,
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
mDirtyRect.setEmpty();
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 3f6c7df..bd9bfe9 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -200,7 +200,6 @@
renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
dirtyRect.right, dirtyRect.bottom, !isBlend());
- displayList->updateProperties();
displayList->computeOrdering();
displayList->defer(deferredState, 0);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 5ef8abb..cdd789d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1919,7 +1919,6 @@
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
// compute 3d ordering
- displayList->updateProperties();
displayList->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
status = startFrame();
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 62a9d71..d3daec8 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -99,9 +99,11 @@
mProperties = mStagingProperties;
}
- for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
- RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
- childNode->updateProperties();
+ if (mDisplayListData) {
+ for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
+ RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
+ childNode->updateProperties();
+ }
}
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 9a7f9b4..756c9444 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -137,7 +137,7 @@
return properties().getHeight();
}
- void updateProperties();
+ ANDROID_API void updateProperties();
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8ebffc2..b3b4173 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -392,6 +392,8 @@
LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
"drawDisplayList called on a context with no canvas or surface!");
+ displayList->updateProperties();
+
EGLint width, height;
mGlobalContext->beginFrame(mEglSurface, &width, &height);
if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
diff --git a/media/java/android/media/MediaController.java b/media/java/android/media/MediaController.java
new file mode 100644
index 0000000..6e3a9b3
--- /dev/null
+++ b/media/java/android/media/MediaController.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 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.app.PendingIntent;
+import android.content.ComponentName;
+import android.media.MediaFocusControl.RcClientDeathHandler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.PrintWriter;
+
+/**
+ * @hide
+ * Class to handle all the information about a media player, encapsulating information
+ * about its use RemoteControlClient, playback type and volume... The lifecycle of each
+ * instance is managed by android.media.MediaFocusControl, from its addition to the player stack
+ * stack to its release.
+ */
+class MediaController implements DeathRecipient {
+
+ // 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;
+
+ /**
+ * A global counter for RemoteControlClient identifiers
+ */
+ private static int sLastRccId = 0;
+
+ //FIXME should be final static
+ public MediaFocusControl mController;
+
+ /**
+ * The target for the ACTION_MEDIA_BUTTON events.
+ * Always non null.
+ */
+ final public PendingIntent mMediaIntent;
+ /**
+ * The registered media button event receiver.
+ * Always non null.
+ */
+ final public ComponentName mReceiverComponent;
+
+ public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+
+ public IBinder mToken;
+ public String mCallingPackageName;
+ public int mCallingUid;
+ /**
+ * Provides access to the information to display on the remote control.
+ * May be null (when a media button event receiver is registered,
+ * but no remote control client has been registered) */
+ public IRemoteControlClient mRcClient;
+ public RcClientDeathHandler mRcClientDeathHandler;
+ /**
+ * Information only used for non-local playback
+ */
+ public int mPlaybackType;
+ public int mPlaybackVolume;
+ public int mPlaybackVolumeMax;
+ public int mPlaybackVolumeHandling;
+ public int mPlaybackStream;
+ public RccPlaybackState mPlaybackState;
+ public IRemoteVolumeObserver mRemoteVolumeObs;
+
+
+ protected static class RccPlaybackState {
+ public int mState;
+ public long mPositionMs;
+ public float mSpeed;
+
+ public RccPlaybackState(int state, long positionMs, float speed) {
+ mState = state;
+ mPositionMs = positionMs;
+ mSpeed = speed;
+ }
+
+ public void reset() {
+ mState = RemoteControlClient.PLAYSTATE_STOPPED;
+ mPositionMs = RemoteControlClient.PLAYBACK_POSITION_INVALID;
+ mSpeed = RemoteControlClient.PLAYBACK_SPEED_1X;
+ }
+
+ @Override
+ public String toString() {
+ return stateToString() + ", " + posToString() + ", " + mSpeed + "X";
+ }
+
+ private String posToString() {
+ if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_INVALID) {
+ return "PLAYBACK_POSITION_INVALID";
+ } else if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_ALWAYS_UNKNOWN) {
+ return "PLAYBACK_POSITION_ALWAYS_UNKNOWN";
+ } else {
+ return (String.valueOf(mPositionMs) + "ms");
+ }
+ }
+
+ private String stateToString() {
+ switch (mState) {
+ case RemoteControlClient.PLAYSTATE_NONE:
+ return "PLAYSTATE_NONE";
+ case RemoteControlClient.PLAYSTATE_STOPPED:
+ return "PLAYSTATE_STOPPED";
+ case RemoteControlClient.PLAYSTATE_PAUSED:
+ return "PLAYSTATE_PAUSED";
+ case RemoteControlClient.PLAYSTATE_PLAYING:
+ return "PLAYSTATE_PLAYING";
+ case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+ return "PLAYSTATE_FAST_FORWARDING";
+ case RemoteControlClient.PLAYSTATE_REWINDING:
+ return "PLAYSTATE_REWINDING";
+ case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+ return "PLAYSTATE_SKIPPING_FORWARDS";
+ case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+ return "PLAYSTATE_SKIPPING_BACKWARDS";
+ case RemoteControlClient.PLAYSTATE_BUFFERING:
+ return "PLAYSTATE_BUFFERING";
+ case RemoteControlClient.PLAYSTATE_ERROR:
+ return "PLAYSTATE_ERROR";
+ default:
+ return "[invalid playstate]";
+ }
+ }
+ }
+
+
+ void dump(PrintWriter pw) {
+ // FIXME to implement, remove dump from MediaFocusControl that accesses private members
+ }
+
+ public void resetPlaybackInfo() {
+ mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
+ mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+ mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+ mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+ mPlaybackStream = AudioManager.STREAM_MUSIC;
+ mPlaybackState.reset();
+ mRemoteVolumeObs = null;
+ }
+
+ /** precondition: mediaIntent != null */
+ public MediaController(MediaFocusControl controller, PendingIntent mediaIntent,
+ ComponentName eventReceiver, IBinder token) {
+ mController = controller;
+ mMediaIntent = mediaIntent;
+ mReceiverComponent = eventReceiver;
+ mToken = token;
+ mCallingUid = -1;
+ mRcClient = null;
+ mRccId = ++sLastRccId;
+ mPlaybackState = new RccPlaybackState(
+ RemoteControlClient.PLAYSTATE_STOPPED,
+ RemoteControlClient.PLAYBACK_POSITION_INVALID,
+ RemoteControlClient.PLAYBACK_SPEED_1X);
+
+ resetPlaybackInfo();
+ if (mToken != null) {
+ try {
+ mToken.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ //FIXME do not access the event handler directly
+ mController.mEventHandler.post(new Runnable() {
+ @Override public void run() {
+ mController.unregisterMediaButtonIntent(mMediaIntent);
+ }
+ });
+ }
+ }
+ }
+
+ public void unlinkToRcClientDeath() {
+ if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
+ try {
+ mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
+ mRcClientDeathHandler = null;
+ } catch (java.util.NoSuchElementException e) {
+ // not much we can do here
+ Log.e(TAG, "Error in unlinkToRcClientDeath()", e);
+ }
+ }
+ }
+
+ // FIXME rename to "release"? (as in FocusRequester class)
+ public void destroy() {
+ unlinkToRcClientDeath();
+ if (mToken != null) {
+ mToken.unlinkToDeath(this, 0);
+ mToken = null;
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ mController.unregisterMediaButtonIntent(mMediaIntent);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ destroy(); // unlink exception handled inside method
+ super.finalize();
+ }
+}
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index b155cda..1016dd4 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -73,7 +73,8 @@
private boolean mIsRinging = false;
private final PowerManager.WakeLock mMediaEventWakeLock;
- private final MediaEventHandler mEventHandler;
+ //FIXME should be private
+ protected final MediaEventHandler mEventHandler;
private final Context mContext;
private final ContentResolver mContentResolver;
private final VolumeController mVolumeController;
@@ -250,7 +251,7 @@
currentUser);
if (DEBUG_RC) { Log.d(TAG, " > enabled list: " + enabledNotifListeners); }
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// check whether the "enable" status of each RCD with a notification listener
// has changed
final String[] enabledComponents;
@@ -350,7 +351,8 @@
handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
}
- private class MediaEventHandler extends Handler {
+ //FIXME should be private
+ protected class MediaEventHandler extends Handler {
MediaEventHandler(Looper looper) {
super(looper);
}
@@ -368,7 +370,7 @@
case MSG_RCDISPLAY_UPDATE:
// msg.obj is guaranteed to be non null
- onRcDisplayUpdate( (RemoteControlStackEntry) msg.obj, msg.arg1);
+ onRcDisplayUpdate( (MediaController) msg.obj, msg.arg1);
break;
case MSG_REEVALUATE_REMOTE:
@@ -388,7 +390,7 @@
case MSG_RCC_NEW_PLAYBACK_STATE:
onNewPlaybackStateForRcc(msg.arg1 /* rccId */,
msg.arg2 /* state */,
- (RccPlaybackState)msg.obj /* newState */);
+ (MediaController.RccPlaybackState)msg.obj /* newState */);
break;
case MSG_RCC_SEEK_REQUEST:
@@ -463,7 +465,7 @@
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
exFocusOwner.release();
// clear RCD
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
clearRemoteControlDisplay_syncAfRcs();
}
}
@@ -527,7 +529,7 @@
// notify the new top of the stack it gained focus
notifyTopOfAudioFocusStack();
// there's a new top of the stack, let the remote control know
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}
@@ -574,7 +576,7 @@
// notify the new top of the stack it gained focus.
notifyTopOfAudioFocusStack();
// there's a new top of the stack, let the remote control know
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}
@@ -686,7 +688,7 @@
clientId, afdh, callingPackageName, Binder.getCallingUid()));
// there's a new top of the stack, let the remote control know
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}//synchronized(mAudioFocusLock)
@@ -750,7 +752,7 @@
}
// event filtering for telephony
synchronized(mRingingLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
if ((mMediaReceiverForCalls != null) &&
(mIsRinging || (mAudioService.getMode() == AudioSystem.MODE_IN_CALL))) {
dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
@@ -803,15 +805,15 @@
}
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- synchronized(mRCStack) {
- if (!mRCStack.empty()) {
+ synchronized(mMCStack) {
+ if (!mMCStack.empty()) {
// send the intent that was registered by the client
try {
- mRCStack.peek().mMediaIntent.send(mContext,
+ mMCStack.peek().mMediaIntent.send(mContext,
needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
keyIntent, this, mEventHandler);
} catch (CanceledException e) {
- Log.e(TAG, "Error sending pending intent " + mRCStack.peek());
+ Log.e(TAG, "Error sending pending intent " + mMCStack.peek());
e.printStackTrace();
}
} else {
@@ -1021,7 +1023,7 @@
};
/**
- * Synchronization on mCurrentRcLock always inside a block synchronized on mRCStack
+ * Synchronization on mCurrentRcLock always inside a block synchronized on mMCStack
*/
private final Object mCurrentRcLock = new Object();
/**
@@ -1054,8 +1056,9 @@
* Inner class to monitor remote control client deaths, and remove the client for the
* remote control stack if necessary.
*/
- private class RcClientDeathHandler implements IBinder.DeathRecipient {
- final private IBinder mCb; // To be notified of client's death
+ protected class RcClientDeathHandler implements IBinder.DeathRecipient {
+ //FIXME should be private
+ final protected IBinder mCb; // To be notified of client's death
final private PendingIntent mMediaIntent;
RcClientDeathHandler(IBinder cb, PendingIntent pi) {
@@ -1077,12 +1080,7 @@
}
}
- /**
- * A global counter for RemoteControlClient identifiers
- */
- private static int sLastRccId = 0;
-
- private class RemotePlaybackState {
+ protected class RemotePlaybackState {
int mRccId;
int mVolume;
int mVolumeMax;
@@ -1115,178 +1113,13 @@
*/
private boolean mHasRemotePlayback;
- private static class RccPlaybackState {
- public int mState;
- public long mPositionMs;
- public float mSpeed;
-
- public RccPlaybackState(int state, long positionMs, float speed) {
- mState = state;
- mPositionMs = positionMs;
- mSpeed = speed;
- }
-
- public void reset() {
- mState = RemoteControlClient.PLAYSTATE_STOPPED;
- mPositionMs = RemoteControlClient.PLAYBACK_POSITION_INVALID;
- mSpeed = RemoteControlClient.PLAYBACK_SPEED_1X;
- }
-
- @Override
- public String toString() {
- return stateToString() + ", " + posToString() + ", " + mSpeed + "X";
- }
-
- private String posToString() {
- if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_INVALID) {
- return "PLAYBACK_POSITION_INVALID";
- } else if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_ALWAYS_UNKNOWN) {
- return "PLAYBACK_POSITION_ALWAYS_UNKNOWN";
- } else {
- return (String.valueOf(mPositionMs) + "ms");
- }
- }
-
- private String stateToString() {
- switch (mState) {
- case RemoteControlClient.PLAYSTATE_NONE:
- return "PLAYSTATE_NONE";
- case RemoteControlClient.PLAYSTATE_STOPPED:
- return "PLAYSTATE_STOPPED";
- case RemoteControlClient.PLAYSTATE_PAUSED:
- return "PLAYSTATE_PAUSED";
- case RemoteControlClient.PLAYSTATE_PLAYING:
- return "PLAYSTATE_PLAYING";
- case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
- return "PLAYSTATE_FAST_FORWARDING";
- case RemoteControlClient.PLAYSTATE_REWINDING:
- return "PLAYSTATE_REWINDING";
- case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
- return "PLAYSTATE_SKIPPING_FORWARDS";
- case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
- return "PLAYSTATE_SKIPPING_BACKWARDS";
- case RemoteControlClient.PLAYSTATE_BUFFERING:
- return "PLAYSTATE_BUFFERING";
- case RemoteControlClient.PLAYSTATE_ERROR:
- return "PLAYSTATE_ERROR";
- default:
- return "[invalid playstate]";
- }
- }
- }
-
- protected static class RemoteControlStackEntry implements DeathRecipient {
- public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
- final public MediaFocusControl mController;
- /**
- * The target for the ACTION_MEDIA_BUTTON events.
- * Always non null.
- */
- final public PendingIntent mMediaIntent;
- /**
- * The registered media button event receiver.
- * Always non null.
- */
- final public ComponentName mReceiverComponent;
- public IBinder mToken;
- public String mCallingPackageName;
- public int mCallingUid;
- /**
- * Provides access to the information to display on the remote control.
- * May be null (when a media button event receiver is registered,
- * but no remote control client has been registered) */
- public IRemoteControlClient mRcClient;
- public RcClientDeathHandler mRcClientDeathHandler;
- /**
- * Information only used for non-local playback
- */
- public int mPlaybackType;
- public int mPlaybackVolume;
- public int mPlaybackVolumeMax;
- public int mPlaybackVolumeHandling;
- public int mPlaybackStream;
- public RccPlaybackState mPlaybackState;
- public IRemoteVolumeObserver mRemoteVolumeObs;
-
- public void resetPlaybackInfo() {
- mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
- mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
- mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
- mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
- mPlaybackStream = AudioManager.STREAM_MUSIC;
- mPlaybackState.reset();
- mRemoteVolumeObs = null;
- }
-
- /** precondition: mediaIntent != null */
- public RemoteControlStackEntry(MediaFocusControl controller, PendingIntent mediaIntent,
- ComponentName eventReceiver, IBinder token) {
- mController = controller;
- mMediaIntent = mediaIntent;
- mReceiverComponent = eventReceiver;
- mToken = token;
- mCallingUid = -1;
- mRcClient = null;
- mRccId = ++sLastRccId;
- mPlaybackState = new RccPlaybackState(
- RemoteControlClient.PLAYSTATE_STOPPED,
- RemoteControlClient.PLAYBACK_POSITION_INVALID,
- RemoteControlClient.PLAYBACK_SPEED_1X);
-
- resetPlaybackInfo();
- if (mToken != null) {
- try {
- mToken.linkToDeath(this, 0);
- } catch (RemoteException e) {
- mController.mEventHandler.post(new Runnable() {
- @Override public void run() {
- mController.unregisterMediaButtonIntent(mMediaIntent);
- }
- });
- }
- }
- }
-
- public void unlinkToRcClientDeath() {
- if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
- try {
- mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
- mRcClientDeathHandler = null;
- } catch (java.util.NoSuchElementException e) {
- // not much we can do here
- Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
- e.printStackTrace();
- }
- }
- }
-
- public void destroy() {
- unlinkToRcClientDeath();
- if (mToken != null) {
- mToken.unlinkToDeath(this, 0);
- mToken = null;
- }
- }
-
- @Override
- public void binderDied() {
- mController.unregisterMediaButtonIntent(mMediaIntent);
- }
-
- @Override
- protected void finalize() throws Throwable {
- destroy(); // unlink exception handled inside method
- super.finalize();
- }
- }
-
/**
* The stack of remote control event receivers.
* Code sections and methods that modify the remote control event receiver stack are
- * synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
+ * synchronized on mMCStack, but also BEFORE on mFocusLock as any change in either
* stack, audio focus or RC, can lead to a change in the remote control display
*/
- private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
+ private final Stack<MediaController> mMCStack = new Stack<MediaController>();
/**
* The component the telephony package can register so telephony calls have priority to
@@ -1300,17 +1133,17 @@
*/
private void dumpRCStack(PrintWriter pw) {
pw.println("\nRemote Control stack entries (last is top of stack):");
- synchronized(mRCStack) {
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ synchronized(mMCStack) {
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- pw.println(" pi: " + rcse.mMediaIntent +
- " -- pack: " + rcse.mCallingPackageName +
- " -- ercvr: " + rcse.mReceiverComponent +
- " -- client: " + rcse.mRcClient +
- " -- uid: " + rcse.mCallingUid +
- " -- type: " + rcse.mPlaybackType +
- " state: " + rcse.mPlaybackState);
+ MediaController mcse = stackIterator.next();
+ pw.println(" pi: " + mcse.mMediaIntent +
+ " -- pack: " + mcse.mCallingPackageName +
+ " -- ercvr: " + mcse.mReceiverComponent +
+ " -- client: " + mcse.mRcClient +
+ " -- uid: " + mcse.mCallingUid +
+ " -- type: " + mcse.mPlaybackType +
+ " state: " + mcse.mPlaybackState);
}
}
}
@@ -1322,18 +1155,18 @@
*/
private void dumpRCCStack(PrintWriter pw) {
pw.println("\nRemote Control Client stack entries (last is top of stack):");
- synchronized(mRCStack) {
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ synchronized(mMCStack) {
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- pw.println(" uid: " + rcse.mCallingUid +
- " -- id: " + rcse.mRccId +
- " -- type: " + rcse.mPlaybackType +
- " -- state: " + rcse.mPlaybackState +
- " -- vol handling: " + rcse.mPlaybackVolumeHandling +
- " -- vol: " + rcse.mPlaybackVolume +
- " -- volMax: " + rcse.mPlaybackVolumeMax +
- " -- volObs: " + rcse.mRemoteVolumeObs);
+ MediaController mcse = stackIterator.next();
+ pw.println(" uid: " + mcse.mCallingUid +
+ " -- id: " + mcse.mRccId +
+ " -- type: " + mcse.mPlaybackType +
+ " -- state: " + mcse.mPlaybackState +
+ " -- vol handling: " + mcse.mPlaybackVolumeHandling +
+ " -- vol: " + mcse.mPlaybackVolume +
+ " -- volMax: " + mcse.mPlaybackVolumeMax +
+ " -- volObs: " + mcse.mRemoteVolumeObs);
}
synchronized(mCurrentRcLock) {
pw.println("\nCurrent remote control generation ID = " + mCurrentRcClientGen);
@@ -1358,7 +1191,7 @@
*/
private void dumpRCDList(PrintWriter pw) {
pw.println("\nRemote Control Display list entries:");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
while (displayIterator.hasNext()) {
final DisplayInfoForServer di = displayIterator.next();
@@ -1377,47 +1210,47 @@
* Pre-condition: packageName != null
*/
private void cleanupMediaButtonReceiverForPackage(String packageName, boolean removeAll) {
- synchronized(mRCStack) {
- if (mRCStack.empty()) {
+ synchronized(mMCStack) {
+ if (mMCStack.empty()) {
return;
} else {
final PackageManager pm = mContext.getPackageManager();
- RemoteControlStackEntry oldTop = mRCStack.peek();
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ MediaController oldTop = mMCStack.peek();
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
// iterate over the stack entries
// (using an iterator on the stack so we can safely remove an entry after having
// evaluated it, traversal order doesn't matter here)
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- if (removeAll && packageName.equals(rcse.mMediaIntent.getCreatorPackage())) {
+ MediaController mcse = stackIterator.next();
+ if (removeAll && packageName.equals(mcse.mMediaIntent.getCreatorPackage())) {
// a stack entry is from the package being removed, remove it from the stack
stackIterator.remove();
- rcse.destroy();
- } else if (rcse.mReceiverComponent != null) {
+ mcse.destroy();
+ } else if (mcse.mReceiverComponent != null) {
try {
// Check to see if this receiver still exists.
- pm.getReceiverInfo(rcse.mReceiverComponent, 0);
+ pm.getReceiverInfo(mcse.mReceiverComponent, 0);
} catch (PackageManager.NameNotFoundException e) {
// Not found -- remove it!
stackIterator.remove();
- rcse.destroy();
+ mcse.destroy();
}
}
}
- if (mRCStack.empty()) {
+ if (mMCStack.empty()) {
// no saved media button receiver
mEventHandler.sendMessage(
mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
null));
- } else if (oldTop != mRCStack.peek()) {
+ } else if (oldTop != mMCStack.peek()) {
// the top of the stack has changed, save it in the system settings
// by posting a message to persist it; only do this however if it has
// a concrete component name (is not a transient registration)
- RemoteControlStackEntry rcse = mRCStack.peek();
- if (rcse.mReceiverComponent != null) {
+ MediaController mcse = mMCStack.peek();
+ if (mcse.mReceiverComponent != null) {
mEventHandler.sendMessage(
mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
- rcse.mReceiverComponent));
+ mcse.mReceiverComponent));
}
}
}
@@ -1451,28 +1284,28 @@
/**
* Helper function:
* Set the new remote control receiver at the top of the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mRCStack
+ * Called synchronized on mAudioFocusLock, then mMCStack
* precondition: mediaIntent != null
- * @return true if mRCStack was changed, false otherwise
+ * @return true if mMCStack was changed, false otherwise
*/
private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,
ComponentName target, IBinder token) {
// already at top of stack?
- if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) {
+ if (!mMCStack.empty() && mMCStack.peek().mMediaIntent.equals(mediaIntent)) {
return false;
}
if (mAppOps.noteOp(AppOpsManager.OP_TAKE_MEDIA_BUTTONS, Binder.getCallingUid(),
mediaIntent.getCreatorPackage()) != AppOpsManager.MODE_ALLOWED) {
return false;
}
- RemoteControlStackEntry rcse = null;
+ MediaController mcse = null;
boolean wasInsideStack = false;
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- rcse = mRCStack.elementAt(index);
- if(rcse.mMediaIntent.equals(mediaIntent)) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ mcse = mMCStack.elementAt(index);
+ if(mcse.mMediaIntent.equals(mediaIntent)) {
// ok to remove element while traversing the stack since we're leaving the loop
- mRCStack.removeElementAt(index);
+ mMCStack.removeElementAt(index);
wasInsideStack = true;
break;
}
@@ -1482,9 +1315,9 @@
Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
}
if (!wasInsideStack) {
- rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);
+ mcse = new MediaController(this, mediaIntent, target, token);
}
- mRCStack.push(rcse); // rcse is never null
+ mMCStack.push(mcse); // mcse is never null
// post message to persist the default media button receiver
if (target != null) {
@@ -1499,17 +1332,17 @@
/**
* Helper function:
* Remove the remote control receiver from the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mRCStack
+ * Called synchronized on mAudioFocusLock, then mMCStack
* precondition: pi != null
*/
private void removeMediaButtonReceiver_syncAfRcs(PendingIntent pi) {
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if (rcse.mMediaIntent.equals(pi)) {
- rcse.destroy();
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if (mcse.mMediaIntent.equals(pi)) {
+ mcse.destroy();
// ok to remove element while traversing the stack since we're leaving the loop
- mRCStack.removeElementAt(index);
+ mMCStack.removeElementAt(index);
break;
}
}
@@ -1521,10 +1354,10 @@
/**
* Helper function:
- * Called synchronized on mRCStack
+ * Called synchronized on mMCStack
*/
private boolean isCurrentRcController(PendingIntent pi) {
- if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(pi)) {
+ if (!mMCStack.empty() && mMCStack.peek().mMediaIntent.equals(pi)) {
return true;
}
return false;
@@ -1545,7 +1378,7 @@
*/
private void setNewRcClientOnDisplays_syncRcsCurrc(int newClientGeneration,
PendingIntent newMediaIntent, boolean clearing) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
if (mRcDisplays.size() > 0) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
while (displayIterator.hasNext()) {
@@ -1569,9 +1402,9 @@
private void setNewRcClientGenerationOnClients_syncRcsCurrc(int newClientGeneration) {
// (using an iterator on the stack so we can safely remove an entry if needed,
// traversal order doesn't matter here as we update all entries)
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry se = stackIterator.next();
+ MediaController se = stackIterator.next();
if ((se != null) && (se.mRcClient != null)) {
try {
se.mRcClient.setCurrentClientGenerationId(newClientGeneration);
@@ -1606,7 +1439,7 @@
private void onRcDisplayClear() {
if (DEBUG_RC) Log.i(TAG, "Clear remote control display");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
mCurrentRcClientGen++;
// synchronously update the displays and clients with the new client generation
@@ -1619,17 +1452,17 @@
/**
* Called when processing MSG_RCDISPLAY_UPDATE event
*/
- private void onRcDisplayUpdate(RemoteControlStackEntry rcse, int flags /* USED ?*/) {
- synchronized(mRCStack) {
+ private void onRcDisplayUpdate(MediaController mcse, int flags /* USED ?*/) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
- if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
+ if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(mcse.mRcClient))) {
if (DEBUG_RC) Log.i(TAG, "Display/update remote control ");
mCurrentRcClientGen++;
// synchronously update the displays and clients with
// the new client generation
setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
- rcse.mMediaIntent /*newMediaIntent*/,
+ mcse.mMediaIntent /*newMediaIntent*/,
false /*clearing*/);
// tell the current client that it needs to send info
@@ -1655,7 +1488,7 @@
* a single RemoteControlDisplay, NOT all of them, as with MSG_RCDISPLAY_UPDATE.
*/
private void onRcDisplayInitInfo(IRemoteControlDisplay newRcd, int w, int h) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
if (mCurrentRcClient != null) {
if (DEBUG_RC) { Log.i(TAG, "Init RCD with current info"); }
@@ -1682,7 +1515,7 @@
/**
* Helper function:
- * Called synchronized on mRCStack
+ * Called synchronized on mMCStack
*/
private void clearRemoteControlDisplay_syncAfRcs() {
synchronized(mCurrentRcLock) {
@@ -1697,35 +1530,35 @@
* checkUpdateRemoteControlDisplay_syncAfRcs() which checks the preconditions for
* this method.
* Preconditions:
- * - called synchronized mAudioFocusLock then on mRCStack
- * - mRCStack.isEmpty() is false
+ * - called synchronized mAudioFocusLock then on mMCStack
+ * - mMCStack.isEmpty() is false
*/
private void updateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
- RemoteControlStackEntry rcse = mRCStack.peek();
+ MediaController mcse = mMCStack.peek();
int infoFlagsAboutToBeUsed = infoChangedFlags;
// this is where we enforce opt-in for information display on the remote controls
// with the new AudioManager.registerRemoteControlClient() API
- if (rcse.mRcClient == null) {
+ if (mcse.mRcClient == null) {
//Log.w(TAG, "Can't update remote control display with null remote control client");
clearRemoteControlDisplay_syncAfRcs();
return;
}
synchronized(mCurrentRcLock) {
- if (!rcse.mRcClient.equals(mCurrentRcClient)) {
+ if (!mcse.mRcClient.equals(mCurrentRcClient)) {
// new RC client, assume every type of information shall be queried
infoFlagsAboutToBeUsed = RC_INFO_ALL;
}
- mCurrentRcClient = rcse.mRcClient;
- mCurrentRcClientIntent = rcse.mMediaIntent;
+ mCurrentRcClient = mcse.mRcClient;
+ mCurrentRcClientIntent = mcse.mMediaIntent;
}
// will cause onRcDisplayUpdate() to be called in AudioService's handler thread
mEventHandler.sendMessage( mEventHandler.obtainMessage(MSG_RCDISPLAY_UPDATE,
- infoFlagsAboutToBeUsed /* arg1 */, 0, rcse /* obj, != null */) );
+ infoFlagsAboutToBeUsed /* arg1 */, 0, mcse /* obj, != null */) );
}
/**
* Helper function:
- * Called synchronized on mAudioFocusLock, then mRCStack
+ * Called synchronized on mAudioFocusLock, then mMCStack
* Check whether the remote control display should be updated, triggers the update if required
* @param infoChangedFlags the flags corresponding to the remote control client information
* that has changed, if applicable (checking for the update conditions might trigger a
@@ -1734,7 +1567,7 @@
private void checkUpdateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
// determine whether the remote control display should be refreshed
// if either stack is empty, there is a mismatch, so clear the RC display
- if (mRCStack.isEmpty() || mFocusStack.isEmpty()) {
+ if (mMCStack.isEmpty() || mFocusStack.isEmpty()) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
@@ -1767,19 +1600,19 @@
}
// if the audio focus and RC owners belong to different packages, there is a mismatch, clear
- if (!af.hasSamePackage(mRCStack.peek().mCallingPackageName)) {
+ if (!af.hasSamePackage(mMCStack.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 (!af.hasSameUid(mRCStack.peek().mCallingUid)) {
+ if (!af.hasSameUid(mMCStack.peek().mCallingUid)) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
// refresh conditions were verified: update the remote controls
- // ok to call: synchronized mAudioFocusLock then on mRCStack, mRCStack is not empty
+ // ok to call: synchronized mAudioFocusLock then on mMCStack, mMCStack is not empty
updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
}
@@ -1797,25 +1630,25 @@
private void onPromoteRcc(int rccId) {
if (DEBUG_RC) { Log.d(TAG, "Promoting RCC " + rccId); }
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// ignore if given RCC ID is already at top of remote control stack
- if (!mRCStack.isEmpty() && (mRCStack.peek().mRccId == rccId)) {
+ if (!mMCStack.isEmpty() && (mMCStack.peek().mRccId == rccId)) {
return;
}
int indexToPromote = -1;
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if (rcse.mRccId == rccId) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if (mcse.mRccId == rccId) {
indexToPromote = index;
break;
}
}
if (indexToPromote >= 0) {
if (DEBUG_RC) { Log.d(TAG, " moving RCC from index " + indexToPromote
- + " to " + (mRCStack.size()-1)); }
- final RemoteControlStackEntry rcse = mRCStack.remove(indexToPromote);
- mRCStack.push(rcse);
+ + " to " + (mMCStack.size()-1)); }
+ final MediaController mcse = mMCStack.remove(indexToPromote);
+ mMCStack.push(mcse);
// the RC stack changed, reevaluate the display
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
@@ -1823,7 +1656,7 @@
// not expected to happen, indicates improper concurrent modification
Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
}
- }//synchronized(mRCStack)
+ }//synchronized(mMCStack)
}//synchronized(mAudioFocusLock)
}
@@ -1836,7 +1669,7 @@
Log.i(TAG, " Remote Control registerMediaButtonIntent() for " + mediaIntent);
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
if (pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token)) {
// new RC client, assume every type of information shall be queried
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
@@ -1854,7 +1687,7 @@
Log.i(TAG, " Remote Control unregisterMediaButtonIntent() for " + mediaIntent);
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
removeMediaButtonReceiver_syncAfRcs(mediaIntent);
if (topOfStackWillChange) {
@@ -1875,7 +1708,7 @@
Log.e(TAG, "Invalid permissions to register media button receiver for calls");
return;
}
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
mMediaReceiverForCalls = c;
}
}
@@ -1889,14 +1722,14 @@
Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
return;
}
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
mMediaReceiverForCalls = null;
}
}
/**
* see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
- * @return the unique ID of the RemoteControlStackEntry associated with the RemoteControlClient
+ * @return the unique ID of the MediaController associated with the RemoteControlClient
* Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient
* without modifying the RC stack, but while still causing the display to refresh (will
* become blank as a result of this)
@@ -1906,45 +1739,45 @@
if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient);
int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// store the new display information
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if(rcse.mMediaIntent.equals(mediaIntent)) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if(mcse.mMediaIntent.equals(mediaIntent)) {
// already had a remote control client?
- if (rcse.mRcClientDeathHandler != null) {
+ if (mcse.mRcClientDeathHandler != null) {
// stop monitoring the old client's death
- rcse.unlinkToRcClientDeath();
+ mcse.unlinkToRcClientDeath();
}
// save the new remote control client
- rcse.mRcClient = rcClient;
- rcse.mCallingPackageName = callingPackageName;
- rcse.mCallingUid = Binder.getCallingUid();
+ mcse.mRcClient = rcClient;
+ mcse.mCallingPackageName = callingPackageName;
+ mcse.mCallingUid = Binder.getCallingUid();
if (rcClient == null) {
- // here rcse.mRcClientDeathHandler is null;
- rcse.resetPlaybackInfo();
+ // here mcse.mRcClientDeathHandler is null;
+ mcse.resetPlaybackInfo();
break;
}
- rccId = rcse.mRccId;
+ rccId = mcse.mRccId;
// there is a new (non-null) client:
// 1/ give the new client the displays (if any)
if (mRcDisplays.size() > 0) {
- plugRemoteControlDisplaysIntoClient_syncRcStack(rcse.mRcClient);
+ plugRemoteControlDisplaysIntoClient_syncRcStack(mcse.mRcClient);
}
// 2/ monitor the new client's death
- IBinder b = rcse.mRcClient.asBinder();
+ IBinder b = mcse.mRcClient.asBinder();
RcClientDeathHandler rcdh =
- new RcClientDeathHandler(b, rcse.mMediaIntent);
+ new RcClientDeathHandler(b, mcse.mMediaIntent);
try {
b.linkToDeath(rcdh, 0);
} catch (RemoteException e) {
// remote control client is DOA, disqualify it
Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
- rcse.mRcClient = null;
+ mcse.mRcClient = null;
}
- rcse.mRcClientDeathHandler = rcdh;
+ mcse.mRcClientDeathHandler = rcdh;
break;
}
}//for
@@ -1958,7 +1791,7 @@
if (isCurrentRcController(mediaIntent)) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
- }//synchronized(mRCStack)
+ }//synchronized(mMCStack)
}//synchronized(mAudioFocusLock)
return rccId;
}
@@ -1971,20 +1804,20 @@
IRemoteControlClient rcClient) {
if (DEBUG_RC) Log.i(TAG, "Unregister remote control client rcClient="+rcClient);
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
boolean topRccChange = false;
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if ((rcse.mMediaIntent.equals(mediaIntent))
- && rcClient.equals(rcse.mRcClient)) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if ((mcse.mMediaIntent.equals(mediaIntent))
+ && rcClient.equals(mcse.mRcClient)) {
// we found the IRemoteControlClient to unregister
// stop monitoring its death
- rcse.unlinkToRcClientDeath();
+ mcse.unlinkToRcClientDeath();
// reset the client-related fields
- rcse.mRcClient = null;
- rcse.mCallingPackageName = null;
- topRccChange = (index == mRCStack.size()-1);
+ mcse.mRcClient = null;
+ mcse.mCallingPackageName = null;
+ topRccChange = (index == mMCStack.size()-1);
// there can only be one matching RCC in the RC stack, we're done
break;
}
@@ -2048,7 +1881,7 @@
}
public void binderDied() {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
Log.w(TAG, "RemoteControl: display " + mRcDisplay + " died");
// remove the display from the list
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
@@ -2066,7 +1899,7 @@
/**
* The remote control displays.
- * Access synchronized on mRCStack
+ * Access synchronized on mMCStack
*/
private ArrayList<DisplayInfoForServer> mRcDisplays = new ArrayList<DisplayInfoForServer>(1);
@@ -2094,12 +1927,12 @@
boolean enabled) {
// let all the remote control clients know whether the given display is enabled
// (so the remote control stack traversal order doesn't matter).
- final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ final Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- if(rcse.mRcClient != null) {
+ MediaController mcse = stackIterator.next();
+ if(mcse.mRcClient != null) {
try {
- rcse.mRcClient.enableRemoteControlDisplay(rcd, enabled);
+ mcse.mRcClient.enableRemoteControlDisplay(rcd, enabled);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting RCD to client: ", e);
}
@@ -2140,7 +1973,7 @@
ComponentName listenerComp) {
if (DEBUG_RC) Log.d(TAG, ">>> registerRemoteControlDisplay("+rcd+")");
synchronized(mAudioFocusLock) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
if ((rcd == null) || rcDisplayIsPluggedIn_syncRcStack(rcd)) {
return;
}
@@ -2156,12 +1989,12 @@
// let all the remote control clients know there is a new display (so the remote
// control stack traversal order doesn't matter).
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- if(rcse.mRcClient != null) {
+ MediaController mcse = stackIterator.next();
+ if(mcse.mRcClient != null) {
try {
- rcse.mRcClient.plugRemoteControlDisplay(rcd, w, h);
+ mcse.mRcClient.plugRemoteControlDisplay(rcd, w, h);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting RCD to client: ", e);
}
@@ -2186,7 +2019,7 @@
*/
protected void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
if (DEBUG_RC) Log.d(TAG, "<<< unregisterRemoteControlDisplay("+rcd+")");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
if (rcd == null) {
return;
}
@@ -2205,12 +2038,12 @@
if (displayWasPluggedIn) {
// disconnect this remote control display from all the clients, so the remote
// control stack traversal order doesn't matter
- final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ final Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- final RemoteControlStackEntry rcse = stackIterator.next();
- if(rcse.mRcClient != null) {
+ final MediaController mcse = stackIterator.next();
+ if(mcse.mRcClient != null) {
try {
- rcse.mRcClient.unplugRemoteControlDisplay(rcd);
+ mcse.mRcClient.unplugRemoteControlDisplay(rcd);
} catch (RemoteException e) {
Log.e(TAG, "Error disconnecting remote control display to client: ", e);
}
@@ -2232,7 +2065,7 @@
* display doesn't need to receive artwork.
*/
protected void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
boolean artworkSizeUpdate = false;
while (displayIterator.hasNext() && !artworkSizeUpdate) {
@@ -2248,12 +2081,12 @@
if (artworkSizeUpdate) {
// RCD is currently plugged in and its artwork size has changed, notify all RCCs,
// stack traversal order doesn't matter
- final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ final Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- final RemoteControlStackEntry rcse = stackIterator.next();
- if(rcse.mRcClient != null) {
+ final MediaController mcse = stackIterator.next();
+ if(mcse.mRcClient != null) {
try {
- rcse.mRcClient.setBitmapSizeForDisplay(rcd, w, h);
+ mcse.mRcClient.setBitmapSizeForDisplay(rcd, w, h);
} catch (RemoteException e) {
Log.e(TAG, "Error setting bitmap size for RCD on RCC: ", e);
}
@@ -2277,7 +2110,7 @@
*/
protected void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd,
boolean wantsSync) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
boolean rcdRegistered = false;
// store the information about this display
// (display stack traversal order doesn't matter).
@@ -2295,12 +2128,12 @@
}
// notify all current RemoteControlClients
// (stack traversal order doesn't matter as we notify all RCCs)
- final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ final Iterator<MediaController> stackIterator = mMCStack.iterator();
while (stackIterator.hasNext()) {
- final RemoteControlStackEntry rcse = stackIterator.next();
- if (rcse.mRcClient != null) {
+ final MediaController mcse = stackIterator.next();
+ if (mcse.mRcClient != null) {
try {
- rcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync);
+ mcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync);
} catch (RemoteException e) {
Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e);
}
@@ -2311,7 +2144,7 @@
protected void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
// ignore position change requests if invalid generation ID
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
if (mCurrentRcClientGen != generationId) {
return;
@@ -2326,7 +2159,7 @@
private void onSetRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
if(DEBUG_RC) Log.d(TAG, "onSetRemoteControlClientPlaybackPosition(genId=" + generationId +
", timeMs=" + timeMs + ")");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
if ((mCurrentRcClient != null) && (mCurrentRcClientGen == generationId)) {
// tell the current client to seek to the requested location
@@ -2349,7 +2182,7 @@
private void onUpdateRemoteControlClientMetadata(int genId, int key, Rating value) {
if(DEBUG_RC) Log.d(TAG, "onUpdateRemoteControlClientMetadata(genId=" + genId +
", what=" + key + ",rating=" + value + ")");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
synchronized(mCurrentRcLock) {
if ((mCurrentRcClient != null) && (mCurrentRcClientGen == genId)) {
try {
@@ -2380,20 +2213,20 @@
private void onNewPlaybackInfoForRcc(int rccId, int key, int value) {
if(DEBUG_RC) Log.d(TAG, "onNewPlaybackInfoForRcc(id=" + rccId +
", what=" + key + ",val=" + value + ")");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// iterating from top of stack as playback information changes are more likely
// on entries at the top of the remote control stack
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if (rcse.mRccId == rccId) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if (mcse.mRccId == rccId) {
switch (key) {
case RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE:
- rcse.mPlaybackType = value;
+ mcse.mPlaybackType = value;
postReevaluateRemote();
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME:
- rcse.mPlaybackVolume = value;
+ mcse.mPlaybackVolume = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolume = value;
@@ -2402,7 +2235,7 @@
}
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME_MAX:
- rcse.mPlaybackVolumeMax = value;
+ mcse.mPlaybackVolumeMax = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeMax = value;
@@ -2411,7 +2244,7 @@
}
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING:
- rcse.mPlaybackVolumeHandling = value;
+ mcse.mPlaybackVolumeHandling = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeHandling = value;
@@ -2420,7 +2253,7 @@
}
break;
case RemoteControlClient.PLAYBACKINFO_USES_STREAM:
- rcse.mPlaybackStream = value;
+ mcse.mPlaybackStream = value;
break;
default:
Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
@@ -2431,7 +2264,7 @@
}//for
} catch (ArrayIndexOutOfBoundsException e) {
// not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index mRCStack on onNewPlaybackInfoForRcc, lock error? ", e);
+ Log.e(TAG, "Wrong index mMCStack on onNewPlaybackInfoForRcc, lock error? ", e);
}
}
}
@@ -2439,20 +2272,21 @@
protected void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_STATE, SENDMSG_QUEUE,
rccId /* arg1 */, state /* arg2 */,
- new RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
+ new MediaController.RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
}
- private void onNewPlaybackStateForRcc(int rccId, int state, RccPlaybackState newState) {
+ private void onNewPlaybackStateForRcc(int rccId, int state,
+ MediaController.RccPlaybackState newState) {
if(DEBUG_RC) Log.d(TAG, "onNewPlaybackStateForRcc(id=" + rccId + ", state=" + state
+ ", time=" + newState.mPositionMs + ", speed=" + newState.mSpeed + ")");
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// iterating from top of stack as playback information changes are more likely
// on entries at the top of the remote control stack
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if (rcse.mRccId == rccId) {
- rcse.mPlaybackState = newState;
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if (mcse.mRccId == rccId) {
+ mcse.mPlaybackState = newState;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemoteIsActive = isPlaystateActive(state);
@@ -2469,7 +2303,7 @@
}//for
} catch (ArrayIndexOutOfBoundsException e) {
// not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index on mRCStack in onNewPlaybackStateForRcc, lock error? ", e);
+ Log.e(TAG, "Wrong index on mMCStack in onNewPlaybackStateForRcc, lock error? ", e);
}
}
}
@@ -2481,15 +2315,15 @@
// handler for MSG_RCC_NEW_VOLUME_OBS
private void onRegisterVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if (rcse.mRccId == rccId) {
- rcse.mRemoteVolumeObs = rvo;
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if (mcse.mRccId == rccId) {
+ mcse.mRemoteVolumeObs = rvo;
break;
}
}
@@ -2507,21 +2341,21 @@
* @return false if no remote playing is currently playing
*/
protected boolean checkUpdateRemoteStateIfActive(int streamType) {
- synchronized(mRCStack) {
+ synchronized(mMCStack) {
// iterating from top of stack as active playback is more likely on entries at the top
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
- if ((rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
- && isPlaystateActive(rcse.mPlaybackState.mState)
- && (rcse.mPlaybackStream == streamType)) {
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
+ if ((mcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
+ && isPlaystateActive(mcse.mPlaybackState.mState)
+ && (mcse.mPlaybackStream == streamType)) {
if (DEBUG_RC) Log.d(TAG, "remote playback active on stream " + streamType
- + ", vol =" + rcse.mPlaybackVolume);
+ + ", vol =" + mcse.mPlaybackVolume);
synchronized (mMainRemote) {
- mMainRemote.mRccId = rcse.mRccId;
- mMainRemote.mVolume = rcse.mPlaybackVolume;
- mMainRemote.mVolumeMax = rcse.mPlaybackVolumeMax;
- mMainRemote.mVolumeHandling = rcse.mPlaybackVolumeHandling;
+ mMainRemote.mRccId = mcse.mRccId;
+ mMainRemote.mVolume = mcse.mPlaybackVolume;
+ mMainRemote.mVolumeMax = mcse.mPlaybackVolumeMax;
+ mMainRemote.mVolumeHandling = mcse.mPlaybackVolumeHandling;
mMainRemoteIsActive = true;
}
return true;
@@ -2588,16 +2422,16 @@
return;
}
IRemoteVolumeObserver rvo = null;
- synchronized (mRCStack) {
+ synchronized (mMCStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
//FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
- if (rcse.mRccId == rccId) {
- rvo = rcse.mRemoteVolumeObs;
+ if (mcse.mRccId == rccId) {
+ rvo = mcse.mRemoteVolumeObs;
break;
}
}
@@ -2643,16 +2477,16 @@
rccId = mMainRemote.mRccId;
}
IRemoteVolumeObserver rvo = null;
- synchronized (mRCStack) {
+ synchronized (mMCStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mRCStack.size()-1; index >= 0; index--) {
- final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+ for (int index = mMCStack.size()-1; index >= 0; index--) {
+ final MediaController mcse = mMCStack.elementAt(index);
//FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
- if (rcse.mRccId == rccId) {
- rvo = rcse.mRemoteVolumeObs;
+ if (mcse.mRccId == rccId) {
+ rvo = mcse.mRemoteVolumeObs;
break;
}
}
@@ -2683,13 +2517,13 @@
if (DEBUG_VOL) { Log.w(TAG, "onReevaluateRemote()"); }
// is there a registered RemoteControlClient that is handling remote playback
boolean hasRemotePlayback = false;
- synchronized (mRCStack) {
+ synchronized (mMCStack) {
// iteration stops when PLAYBACK_TYPE_REMOTE is found, so remote control stack
// traversal order doesn't matter
- Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ Iterator<MediaController> stackIterator = mMCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = stackIterator.next();
- if (rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
+ MediaController mcse = stackIterator.next();
+ if (mcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
hasRemotePlayback = true;
break;
}