Loading packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java +16 −9 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.IBinder; import android.util.Log; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.UserTracker; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -108,6 +109,7 @@ public class ObservableServiceConnection<T> implements ServiceConnection { private final Context mContext; private final Intent mServiceIntent; private final UserTracker mUserTracker; private final int mFlags; private final Executor mExecutor; private final ServiceTransformer<T> mTransformer; Loading @@ -127,10 +129,12 @@ public class ObservableServiceConnection<T> implements ServiceConnection { */ @Inject public ObservableServiceConnection(Context context, Intent serviceIntent, UserTracker userTracker, @Main Executor executor, ServiceTransformer<T> transformer) { mContext = context; mServiceIntent = serviceIntent; mUserTracker = userTracker; mFlags = Context.BIND_AUTO_CREATE; mExecutor = executor; mTransformer = transformer; Loading @@ -145,7 +149,8 @@ public class ObservableServiceConnection<T> implements ServiceConnection { public boolean bind() { boolean bindResult = false; try { bindResult = mContext.bindService(mServiceIntent, mFlags, mExecutor, this); bindResult = mContext.bindServiceAsUser(mServiceIntent, this, mFlags, mUserTracker.getUserHandle()); } catch (SecurityException e) { Log.d(TAG, "Could not bind to service", e); mContext.unbindService(this); Loading Loading @@ -228,11 +233,13 @@ public class ObservableServiceConnection<T> implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { mExecutor.execute(() -> { if (DEBUG) { Log.d(TAG, "onServiceConnected"); } mProxy = mTransformer.convert(service); applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy)); }); } private void applyToCallbacksLocked(Consumer<Callback<T>> applicator) { Loading @@ -250,16 +257,16 @@ public class ObservableServiceConnection<T> implements ServiceConnection { @Override public void onServiceDisconnected(ComponentName name) { onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_DISCONNECTED)); } @Override public void onBindingDied(ComponentName name) { onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_BINDING_DIED)); } @Override public void onNullBinding(ComponentName name) { onDisconnected(DISCONNECT_REASON_NULL_BINDING); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_NULL_BINDING)); } } packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java +23 −9 Original line number Diff line number Diff line Loading @@ -29,12 +29,15 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.os.IBinder; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.settings.FakeUserTracker; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; Loading @@ -44,6 +47,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.List; import java.util.Objects; @SmallTest Loading Loading @@ -93,15 +97,22 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); private FakeUserTracker mUserTracker; private static final int MAIN_USER_ID = 10; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mUserTracker = new FakeUserTracker(); // Set the main user as the current user. mUserTracker.set(List.of(new UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)), 0); } @Test public void testConnect() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); // Register twice to ensure only one callback occurs. connection.addCallback(mCallback); connection.addCallback(mCallback); Loading @@ -121,15 +132,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testDisconnect() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); connection.onServiceDisconnected(mComponentName); mExecutor.runAllReady(); // Disconnects before binds should be ignored. verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) .thenReturn(true); when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true); connection.bind(); connection.onServiceDisconnected(mComponentName); Loading @@ -151,15 +163,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testUnbind() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); connection.onServiceDisconnected(mComponentName); mExecutor.runAllReady(); // Disconnects before binds should be ignored. verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) .thenReturn(true); when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true); connection.bind(); mExecutor.runAllReady(); Loading @@ -175,10 +188,11 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testBindServiceThrowsError() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))) .thenThrow(new SecurityException()); // Verify that the exception was caught and that bind returns false, and we properly Loading Loading
packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java +16 −9 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.IBinder; import android.util.Log; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.UserTracker; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -108,6 +109,7 @@ public class ObservableServiceConnection<T> implements ServiceConnection { private final Context mContext; private final Intent mServiceIntent; private final UserTracker mUserTracker; private final int mFlags; private final Executor mExecutor; private final ServiceTransformer<T> mTransformer; Loading @@ -127,10 +129,12 @@ public class ObservableServiceConnection<T> implements ServiceConnection { */ @Inject public ObservableServiceConnection(Context context, Intent serviceIntent, UserTracker userTracker, @Main Executor executor, ServiceTransformer<T> transformer) { mContext = context; mServiceIntent = serviceIntent; mUserTracker = userTracker; mFlags = Context.BIND_AUTO_CREATE; mExecutor = executor; mTransformer = transformer; Loading @@ -145,7 +149,8 @@ public class ObservableServiceConnection<T> implements ServiceConnection { public boolean bind() { boolean bindResult = false; try { bindResult = mContext.bindService(mServiceIntent, mFlags, mExecutor, this); bindResult = mContext.bindServiceAsUser(mServiceIntent, this, mFlags, mUserTracker.getUserHandle()); } catch (SecurityException e) { Log.d(TAG, "Could not bind to service", e); mContext.unbindService(this); Loading Loading @@ -228,11 +233,13 @@ public class ObservableServiceConnection<T> implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { mExecutor.execute(() -> { if (DEBUG) { Log.d(TAG, "onServiceConnected"); } mProxy = mTransformer.convert(service); applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy)); }); } private void applyToCallbacksLocked(Consumer<Callback<T>> applicator) { Loading @@ -250,16 +257,16 @@ public class ObservableServiceConnection<T> implements ServiceConnection { @Override public void onServiceDisconnected(ComponentName name) { onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_DISCONNECTED)); } @Override public void onBindingDied(ComponentName name) { onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_BINDING_DIED)); } @Override public void onNullBinding(ComponentName name) { onDisconnected(DISCONNECT_REASON_NULL_BINDING); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_NULL_BINDING)); } }
packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java +23 −9 Original line number Diff line number Diff line Loading @@ -29,12 +29,15 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.os.IBinder; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.settings.FakeUserTracker; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; Loading @@ -44,6 +47,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.List; import java.util.Objects; @SmallTest Loading Loading @@ -93,15 +97,22 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); private FakeUserTracker mUserTracker; private static final int MAIN_USER_ID = 10; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mUserTracker = new FakeUserTracker(); // Set the main user as the current user. mUserTracker.set(List.of(new UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)), 0); } @Test public void testConnect() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); // Register twice to ensure only one callback occurs. connection.addCallback(mCallback); connection.addCallback(mCallback); Loading @@ -121,15 +132,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testDisconnect() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); connection.onServiceDisconnected(mComponentName); mExecutor.runAllReady(); // Disconnects before binds should be ignored. verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) .thenReturn(true); when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true); connection.bind(); connection.onServiceDisconnected(mComponentName); Loading @@ -151,15 +163,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testUnbind() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); connection.onServiceDisconnected(mComponentName); mExecutor.runAllReady(); // Disconnects before binds should be ignored. verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) .thenReturn(true); when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true); connection.bind(); mExecutor.runAllReady(); Loading @@ -175,10 +188,11 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testBindServiceThrowsError() { ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer); connection.addCallback(mCallback); when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(), eq(UserHandle.of(MAIN_USER_ID)))) .thenThrow(new SecurityException()); // Verify that the exception was caught and that bind returns false, and we properly Loading