@Test public void testMarkAsDisposed_whenBound() throws Throwable { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); expectThrows(RuntimeException.class, mTransportClient::markAsDisposed); }
public void connectAsync(TransportConnectionListener listener, String caller) { synchronized (mStateLock) { checkStateIntegrityLocked(); switch (mState) { case State.UNUSABLE: log(Priority.WARN, caller, "Async connect: UNUSABLE client"); notifyListener(listener, null, caller); break; case State.IDLE: boolean hasBound = mContext.bindServiceAsUser( mBindIntent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); if (hasBound) { log(Priority.DEBUG, caller, "Async connect: service bound, connecting"); setStateLocked(State.BOUND_AND_CONNECTING, null); mListeners.put(listener, caller); } else { log(Priority.ERROR, "Async connect: bindService returned false"); mContext.unbindService(mConnection); notifyListener(listener, null, caller); } break; case State.BOUND_AND_CONNECTING: log( Priority.DEBUG, caller, "Async connect: already connecting, adding listener"); mListeners.put(listener, caller); break; case State.CONNECTED: log(Priority.DEBUG, caller, "Async connect: reusing transport"); notifyListener(listener, mTransport, caller); break; } } }
TransportClient { public void connectAsync(TransportConnectionListener listener, String caller) { synchronized (mStateLock) { checkStateIntegrityLocked(); switch (mState) { case State.UNUSABLE: log(Priority.WARN, caller, "Async connect: UNUSABLE client"); notifyListener(listener, null, caller); break; case State.IDLE: boolean hasBound = mContext.bindServiceAsUser( mBindIntent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); if (hasBound) { log(Priority.DEBUG, caller, "Async connect: service bound, connecting"); setStateLocked(State.BOUND_AND_CONNECTING, null); mListeners.put(listener, caller); } else { log(Priority.ERROR, "Async connect: bindService returned false"); mContext.unbindService(mConnection); notifyListener(listener, null, caller); } break; case State.BOUND_AND_CONNECTING: log( Priority.DEBUG, caller, "Async connect: already connecting, adding listener"); mListeners.put(listener, caller); break; case State.CONNECTED: log(Priority.DEBUG, caller, "Async connect: reusing transport"); notifyListener(listener, mTransport, caller); break; } } } }
TransportClient { public void connectAsync(TransportConnectionListener listener, String caller) { synchronized (mStateLock) { checkStateIntegrityLocked(); switch (mState) { case State.UNUSABLE: log(Priority.WARN, caller, "Async connect: UNUSABLE client"); notifyListener(listener, null, caller); break; case State.IDLE: boolean hasBound = mContext.bindServiceAsUser( mBindIntent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); if (hasBound) { log(Priority.DEBUG, caller, "Async connect: service bound, connecting"); setStateLocked(State.BOUND_AND_CONNECTING, null); mListeners.put(listener, caller); } else { log(Priority.ERROR, "Async connect: bindService returned false"); mContext.unbindService(mConnection); notifyListener(listener, null, caller); } break; case State.BOUND_AND_CONNECTING: log( Priority.DEBUG, caller, "Async connect: already connecting, adding listener"); mListeners.put(listener, caller); break; case State.CONNECTED: log(Priority.DEBUG, caller, "Async connect: reusing transport"); notifyListener(listener, mTransport, caller); break; } } } TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller); @VisibleForTesting  TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller,
            Handler listenerHandler); }
TransportClient { public void connectAsync(TransportConnectionListener listener, String caller) { synchronized (mStateLock) { checkStateIntegrityLocked(); switch (mState) { case State.UNUSABLE: log(Priority.WARN, caller, "Async connect: UNUSABLE client"); notifyListener(listener, null, caller); break; case State.IDLE: boolean hasBound = mContext.bindServiceAsUser( mBindIntent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); if (hasBound) { log(Priority.DEBUG, caller, "Async connect: service bound, connecting"); setStateLocked(State.BOUND_AND_CONNECTING, null); mListeners.put(listener, caller); } else { log(Priority.ERROR, "Async connect: bindService returned false"); mContext.unbindService(mConnection); notifyListener(listener, null, caller); } break; case State.BOUND_AND_CONNECTING: log( Priority.DEBUG, caller, "Async connect: already connecting, adding listener"); mListeners.put(listener, caller); break; case State.CONNECTED: log(Priority.DEBUG, caller, "Async connect: reusing transport"); notifyListener(listener, mTransport, caller); break; } } } TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller); @VisibleForTesting  TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller,
            Handler listenerHandler); ComponentName getTransportComponent(); void connectAsync(TransportConnectionListener listener, String caller); void unbind(String caller); void markAsDisposed(); @WorkerThread @Nullable IBackupTransport connect(String caller); @WorkerThread IBackupTransport connectOrThrow(String caller); IBackupTransport getConnectedTransport(String caller); @Override String toString(); }
TransportClient { public void connectAsync(TransportConnectionListener listener, String caller) { synchronized (mStateLock) { checkStateIntegrityLocked(); switch (mState) { case State.UNUSABLE: log(Priority.WARN, caller, "Async connect: UNUSABLE client"); notifyListener(listener, null, caller); break; case State.IDLE: boolean hasBound = mContext.bindServiceAsUser( mBindIntent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM); if (hasBound) { log(Priority.DEBUG, caller, "Async connect: service bound, connecting"); setStateLocked(State.BOUND_AND_CONNECTING, null); mListeners.put(listener, caller); } else { log(Priority.ERROR, "Async connect: bindService returned false"); mContext.unbindService(mConnection); notifyListener(listener, null, caller); } break; case State.BOUND_AND_CONNECTING: log( Priority.DEBUG, caller, "Async connect: already connecting, adding listener"); mListeners.put(listener, caller); break; case State.CONNECTED: log(Priority.DEBUG, caller, "Async connect: reusing transport"); notifyListener(listener, mTransport, caller); break; } } } TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller); @VisibleForTesting  TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller,
            Handler listenerHandler); ComponentName getTransportComponent(); void connectAsync(TransportConnectionListener listener, String caller); void unbind(String caller); void markAsDisposed(); @WorkerThread @Nullable IBackupTransport connect(String caller); @WorkerThread IBackupTransport connectOrThrow(String caller); IBackupTransport getConnectedTransport(String caller); @Override String toString();  }