diff --git a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java index c6da55c1e20a1..968dcc95ef50d 100644 --- a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java +++ b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java @@ -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; @@ -108,6 +109,7 @@ public class ObservableServiceConnection 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 mTransformer; @@ -127,10 +129,12 @@ public class ObservableServiceConnection implements ServiceConnection { */ @Inject public ObservableServiceConnection(Context context, Intent serviceIntent, + UserTracker userTracker, @Main Executor executor, ServiceTransformer transformer) { mContext = context; mServiceIntent = serviceIntent; + mUserTracker = userTracker; mFlags = Context.BIND_AUTO_CREATE; mExecutor = executor; mTransformer = transformer; @@ -145,7 +149,8 @@ public class ObservableServiceConnection 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); @@ -228,11 +233,13 @@ public class ObservableServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { - if (DEBUG) { - Log.d(TAG, "onServiceConnected"); - } - mProxy = mTransformer.convert(service); - applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy)); + mExecutor.execute(() -> { + if (DEBUG) { + Log.d(TAG, "onServiceConnected"); + } + mProxy = mTransformer.convert(service); + applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy)); + }); } private void applyToCallbacksLocked(Consumer> applicator) { @@ -250,16 +257,16 @@ public class ObservableServiceConnection 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)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java index f9bfafc13f35c..766a5ce322bf1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java @@ -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; @@ -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 @@ -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 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); @@ -121,15 +132,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testDisconnect() { ObservableServiceConnection 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); @@ -151,15 +163,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testUnbind() { ObservableServiceConnection 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(); @@ -175,10 +188,11 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { @Test public void testBindServiceThrowsError() { ObservableServiceConnection 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