summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/java/android/media/browse/MediaBrowser.java112
1 files changed, 61 insertions, 51 deletions
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 789d5e0d8478..ece19e46e479 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -148,62 +148,60 @@ public final class MediaBrowser {
* </p>
*/
public void connect() {
- if (mState != CONNECT_STATE_DISCONNECTED) {
- throw new IllegalStateException("connect() called while not disconnected (state="
- + getStateLabel(mState) + ")");
- }
- // TODO: remove this extra check.
- if (DBG) {
- if (mServiceConnection != null) {
- throw new RuntimeException("mServiceConnection should be null. Instead it is "
- + mServiceConnection);
- }
- }
- if (mServiceBinder != null) {
- throw new RuntimeException("mServiceBinder should be null. Instead it is "
- + mServiceBinder);
- }
- if (mServiceCallbacks != null) {
- throw new RuntimeException("mServiceCallbacks should be null. Instead it is "
- + mServiceCallbacks);
+ if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
+ throw new IllegalStateException("connect() called while neither disconnecting nor "
+ + "disconnected (state=" + getStateLabel(mState) + ")");
}
mState = CONNECT_STATE_CONNECTING;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mState == CONNECT_STATE_DISCONNECTING) {
+ return;
+ }
+ mState = CONNECT_STATE_CONNECTING;
+ // TODO: remove this extra check.
+ if (DBG) {
+ if (mServiceConnection != null) {
+ throw new RuntimeException("mServiceConnection should be null. Instead it"
+ + " is " + mServiceConnection);
+ }
+ }
+ if (mServiceBinder != null) {
+ throw new RuntimeException("mServiceBinder should be null. Instead it is "
+ + mServiceBinder);
+ }
+ if (mServiceCallbacks != null) {
+ throw new RuntimeException("mServiceCallbacks should be null. Instead it is "
+ + mServiceCallbacks);
+ }
- final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
- intent.setComponent(mServiceComponent);
+ final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
+ intent.setComponent(mServiceComponent);
- final ServiceConnection thisConnection = mServiceConnection = new MediaServiceConnection();
+ mServiceConnection = new MediaServiceConnection();
- boolean bound = false;
- try {
- bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
- } catch (Exception ex) {
- Log.e(TAG, "Failed binding to service " + mServiceComponent);
- }
+ boolean bound = false;
+ try {
+ bound = mContext.bindService(intent, mServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ } catch (Exception ex) {
+ Log.e(TAG, "Failed binding to service " + mServiceComponent);
+ }
- if (!bound) {
- // Tell them that it didn't work. We are already on the main thread,
- // but we don't want to do callbacks inside of connect(). So post it,
- // and then check that we are on the same ServiceConnection. We know
- // we won't also get an onServiceConnected or onServiceDisconnected,
- // so we won't be doing double callbacks.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- // Ensure that nobody else came in or tried to connect again.
- if (thisConnection == mServiceConnection) {
- forceCloseConnection();
- mCallback.onConnectionFailed();
- }
+ if (!bound) {
+ // Tell them that it didn't work.
+ forceCloseConnection();
+ mCallback.onConnectionFailed();
}
- });
- }
- if (DBG) {
- Log.d(TAG, "connect...");
- dump();
- }
+ if (DBG) {
+ Log.d(TAG, "connect...");
+ dump();
+ }
+ }
+ });
}
/**
@@ -218,6 +216,7 @@ public final class MediaBrowser {
mHandler.post(new Runnable() {
@Override
public void run() {
+ // connect() could be called before this. Then we will disconnect and reconnect.
if (mServiceCallbacks != null) {
try {
mServiceBinder.disconnect(mServiceCallbacks);
@@ -227,7 +226,13 @@ public final class MediaBrowser {
Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
}
}
+ int state = mState;
forceCloseConnection();
+ // If the state was not CONNECT_STATE_DISCONNECTING, keep the state so that
+ // the operation came after disconnect() can be handled properly.
+ if (state != CONNECT_STATE_DISCONNECTING) {
+ mState = state;
+ }
if (DBG) {
Log.d(TAG, "disconnect...");
dump();
@@ -245,6 +250,9 @@ public final class MediaBrowser {
* a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback
* for a clean shutdown, but everywhere else is a dirty shutdown and should
* notify the app.
+ * <p>
+ * Also, mState should be updated properly. Mostly it should be CONNECT_STATE_DIACONNECTED
+ * except for disconnect().
*/
private void forceCloseConnection() {
if (mServiceConnection != null) {
@@ -684,8 +692,9 @@ public final class MediaBrowser {
* Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
*/
private boolean isCurrent(IMediaBrowserServiceCallbacks callback, String funcName) {
- if (mServiceCallbacks != callback) {
- if (mState != CONNECT_STATE_DISCONNECTED) {
+ if (mServiceCallbacks != callback || mState == CONNECT_STATE_DISCONNECTING
+ || mState == CONNECT_STATE_DISCONNECTED) {
+ if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ mServiceCallbacks + " this=" + this);
}
@@ -1040,8 +1049,9 @@ public final class MediaBrowser {
* Return true if this is the current ServiceConnection. Also logs if it's not.
*/
private boolean isCurrent(String funcName) {
- if (mServiceConnection != this) {
- if (mState != CONNECT_STATE_DISCONNECTED) {
+ if (mServiceConnection != this || mState == CONNECT_STATE_DISCONNECTING
+ || mState == CONNECT_STATE_DISCONNECTED) {
+ if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
// Check mState, because otherwise this log is noisy.
Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ mServiceConnection + " this=" + this);