Merge "MediaBrowser: Allow to connect while disconnecting" into oc-dev

This commit is contained in:
TreeHugger Robot
2017-05-16 06:28:04 +00:00
committed by Android (Google) Code Review

View File

@@ -148,62 +148,60 @@ public final class MediaBrowser {
* </p> * </p>
*/ */
public void connect() { public void connect() {
if (mState != CONNECT_STATE_DISCONNECTED) { if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
throw new IllegalStateException("connect() called while not disconnected (state=" throw new IllegalStateException("connect() called while neither disconnecting nor "
+ getStateLabel(mState) + ")"); + "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);
} }
mState = CONNECT_STATE_CONNECTING; mState = CONNECT_STATE_CONNECTING;
mHandler.post(new Runnable() {
final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE); @Override
intent.setComponent(mServiceComponent); public void run() {
if (mState == CONNECT_STATE_DISCONNECTING) {
final ServiceConnection thisConnection = mServiceConnection = new MediaServiceConnection(); return;
}
boolean bound = false; mState = CONNECT_STATE_CONNECTING;
try { // TODO: remove this extra check.
bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); if (DBG) {
} catch (Exception ex) { if (mServiceConnection != null) {
Log.e(TAG, "Failed binding to service " + mServiceComponent); throw new RuntimeException("mServiceConnection should be null. Instead it"
} + " is " + mServiceConnection);
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 (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 (DBG) { final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
Log.d(TAG, "connect..."); intent.setComponent(mServiceComponent);
dump();
} 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);
}
if (!bound) {
// Tell them that it didn't work.
forceCloseConnection();
mCallback.onConnectionFailed();
}
if (DBG) {
Log.d(TAG, "connect...");
dump();
}
}
});
} }
/** /**
@@ -218,6 +216,7 @@ public final class MediaBrowser {
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
// connect() could be called before this. Then we will disconnect and reconnect.
if (mServiceCallbacks != null) { if (mServiceCallbacks != null) {
try { try {
mServiceBinder.disconnect(mServiceCallbacks); mServiceBinder.disconnect(mServiceCallbacks);
@@ -227,7 +226,13 @@ public final class MediaBrowser {
Log.w(TAG, "RemoteException during connect for " + mServiceComponent); Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
} }
} }
int state = mState;
forceCloseConnection(); 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) { if (DBG) {
Log.d(TAG, "disconnect..."); Log.d(TAG, "disconnect...");
dump(); dump();
@@ -245,6 +250,9 @@ public final class MediaBrowser {
* a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback * a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback
* for a clean shutdown, but everywhere else is a dirty shutdown and should * for a clean shutdown, but everywhere else is a dirty shutdown and should
* notify the app. * notify the app.
* <p>
* Also, mState should be updated properly. Mostly it should be CONNECT_STATE_DIACONNECTED
* except for disconnect().
*/ */
private void forceCloseConnection() { private void forceCloseConnection() {
if (mServiceConnection != null) { 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. * Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
*/ */
private boolean isCurrent(IMediaBrowserServiceCallbacks callback, String funcName) { private boolean isCurrent(IMediaBrowserServiceCallbacks callback, String funcName) {
if (mServiceCallbacks != callback) { if (mServiceCallbacks != callback || mState == CONNECT_STATE_DISCONNECTING
if (mState != CONNECT_STATE_DISCONNECTED) { || mState == CONNECT_STATE_DISCONNECTED) {
if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection=" Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ mServiceCallbacks + " this=" + this); + 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. * Return true if this is the current ServiceConnection. Also logs if it's not.
*/ */
private boolean isCurrent(String funcName) { private boolean isCurrent(String funcName) {
if (mServiceConnection != this) { if (mServiceConnection != this || mState == CONNECT_STATE_DISCONNECTING
if (mState != CONNECT_STATE_DISCONNECTED) { || mState == CONNECT_STATE_DISCONNECTED) {
if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
// Check mState, because otherwise this log is noisy. // Check mState, because otherwise this log is noisy.
Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection=" Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+ mServiceConnection + " this=" + this); + mServiceConnection + " this=" + this);