Add 5s timeout to wakelock

Also filed a b/15110168 to anr the app if it doesn't finish with the
button event in 5s.

Change-Id: I23906b4c7f17d3d3a29eef92b523d8653c87017e
This commit is contained in:
RoboErik
2014-05-19 09:25:25 -07:00
parent 48dfae92d2
commit 418c10ca9d
5 changed files with 85 additions and 27 deletions

View File

@@ -28,7 +28,7 @@ import android.os.ResultReceiver;
*/
oneway interface ISessionCallback {
void onCommand(String command, in Bundle extras, in ResultReceiver cb);
void onMediaButton(in Intent mediaButtonIntent, in ResultReceiver cb);
void onMediaButton(in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb);
void onRequestRouteChange(in RouteInfo route);
void onRouteConnected(in RouteInfo route, in RouteOptions options);
void onRouteDisconnected(in RouteInfo route, int reason);

View File

@@ -119,13 +119,6 @@ public final class MediaSession {
*/
public static final int DISCONNECT_REASON_SESSION_DESTROYED = 5;
/**
* Status code indicating the call was handled.
*
* @hide
*/
public static final int RESULT_SUCCESS = 0;
private static final int MSG_MEDIA_BUTTON = 1;
private static final int MSG_COMMAND = 2;
private static final int MSG_ROUTE_CHANGE = 3;
@@ -563,14 +556,17 @@ public final class MediaSession {
}
@Override
public void onMediaButton(Intent mediaButtonIntent, ResultReceiver cb)
public void onMediaButton(Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb)
throws RemoteException {
MediaSession session = mMediaSession.get();
if (session != null) {
session.postMediaButton(mediaButtonIntent);
}
if (cb != null) {
cb.send(RESULT_SUCCESS, null);
try {
if (session != null) {
session.postMediaButton(mediaButtonIntent);
}
} finally {
if (cb != null) {
cb.send(sequenceNumber, null);
}
}
}

View File

@@ -137,6 +137,8 @@ public class MediaSessionLegacyHelper {
return;
}
holder.mMediaButtonListener = new MediaButtonListener(pi, context);
// TODO determine if handling transport performer commands should also
// set this flag
holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS;
holder.mSession.setFlags(holder.mFlags);
holder.mSession.getTransportPerformer().addListener(holder.mMediaButtonListener, mHandler);

View File

@@ -365,8 +365,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
return mSessionCb.mCb;
}
public void sendMediaButton(KeyEvent ke, ResultReceiver cb) {
mSessionCb.sendMediaButton(ke, cb);
public void sendMediaButton(KeyEvent ke, int sequenceId, ResultReceiver cb) {
mSessionCb.sendMediaButton(ke, sequenceId, cb);
}
public void dump(PrintWriter pw, String prefix) {
@@ -649,11 +649,11 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
mCb = cb;
}
public void sendMediaButton(KeyEvent keyEvent, ResultReceiver cb) {
public void sendMediaButton(KeyEvent keyEvent, int sequenceId, ResultReceiver cb) {
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
try {
mCb.onMediaButton(mediaButtonIntent, cb);
mCb.onMediaButton(mediaButtonIntent, sequenceId, cb);
} catch (RemoteException e) {
Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
}
@@ -789,7 +789,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
@Override
public void sendMediaButton(KeyEvent mediaButtonIntent) {
mSessionCb.sendMediaButton(mediaButtonIntent, null);
mSessionCb.sendMediaButton(mediaButtonIntent, 0, null);
}
@Override

View File

@@ -61,6 +61,8 @@ public class MediaSessionService extends SystemService implements Monitor {
private static final String TAG = "MediaSessionService";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int WAKELOCK_TIMEOUT = 5000;
private final SessionManagerImpl mSessionManagerImpl;
// private final MediaRouteProviderWatcher mRouteProviderWatcher;
private final MediaSessionStack mPriorityStack;
@@ -676,9 +678,6 @@ public class MediaSessionService extends SystemService implements Monitor {
final long token = Binder.clearCallingIdentity();
try {
if (needWakeLock) {
mMediaEventWakeLock.acquire();
}
synchronized (mLock) {
MediaSessionRecord mbSession = mPriorityStack
.getDefaultMediaButtonSession(mCurrentUserId);
@@ -686,9 +685,18 @@ public class MediaSessionService extends SystemService implements Monitor {
if (DEBUG) {
Log.d(TAG, "Sending media key to " + mbSession.getSessionInfo());
}
if (needWakeLock) {
mKeyEventReceiver.aquireWakeLockLocked();
}
// If we don't need a wakelock use -1 as the id so we
// won't release it later
mbSession.sendMediaButton(keyEvent,
needWakeLock ? mKeyEventDoneReceiver : null);
needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
mKeyEventReceiver);
} else {
if (needWakeLock) {
mMediaEventWakeLock.acquire();
}
if (DEBUG) {
Log.d(TAG, "Sending media key ordered broadcast");
}
@@ -743,15 +751,67 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
ResultReceiver mKeyEventDoneReceiver = new ResultReceiver(mHandler) {
private KeyEventWakeLockReceiver mKeyEventReceiver = new KeyEventWakeLockReceiver(mHandler);
class KeyEventWakeLockReceiver extends ResultReceiver implements Runnable {
private final Handler mHandler;
private int mRefCount = 0;
private int mLastTimeoutId = 0;
public KeyEventWakeLockReceiver(Handler handler) {
super(handler);
mHandler = handler;
}
public void onTimeout() {
synchronized (mLock) {
if (mRefCount == 0) {
// We've already released it, so just return
return;
}
mLastTimeoutId++;
mRefCount = 0;
releaseWakeLockLocked();
}
}
public void aquireWakeLockLocked() {
if (mRefCount == 0) {
mMediaEventWakeLock.acquire();
}
mRefCount++;
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, WAKELOCK_TIMEOUT);
}
@Override
public void run() {
onTimeout();
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
synchronized (mLock) {
if (mMediaEventWakeLock.isHeld()) {
mMediaEventWakeLock.release();
if (resultCode < mLastTimeoutId) {
// Ignore results from calls that were before the last
// timeout, just in case.
return;
} else {
synchronized (mLock) {
if (mRefCount > 0) {
mRefCount--;
if (mRefCount == 0) {
releaseWakeLockLocked();
}
}
}
}
}
private void releaseWakeLockLocked() {
mMediaEventWakeLock.release();
mHandler.removeCallbacks(this);
}
};
BroadcastReceiver mKeyEventDone = new BroadcastReceiver() {