Merge "Update ObservableServiceConnection to bind to services as the current user." into udc-dev

This commit is contained in:
Lucas Silva
2023-04-04 22:28:40 +00:00
committed by Android (Google) Code Review
2 changed files with 39 additions and 18 deletions

View File

@@ -25,6 +25,7 @@ import android.os.IBinder;
import android.util.Log; import android.util.Log;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.UserTracker;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -108,6 +109,7 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
private final Context mContext; private final Context mContext;
private final Intent mServiceIntent; private final Intent mServiceIntent;
private final UserTracker mUserTracker;
private final int mFlags; private final int mFlags;
private final Executor mExecutor; private final Executor mExecutor;
private final ServiceTransformer<T> mTransformer; private final ServiceTransformer<T> mTransformer;
@@ -127,10 +129,12 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
*/ */
@Inject @Inject
public ObservableServiceConnection(Context context, Intent serviceIntent, public ObservableServiceConnection(Context context, Intent serviceIntent,
UserTracker userTracker,
@Main Executor executor, @Main Executor executor,
ServiceTransformer<T> transformer) { ServiceTransformer<T> transformer) {
mContext = context; mContext = context;
mServiceIntent = serviceIntent; mServiceIntent = serviceIntent;
mUserTracker = userTracker;
mFlags = Context.BIND_AUTO_CREATE; mFlags = Context.BIND_AUTO_CREATE;
mExecutor = executor; mExecutor = executor;
mTransformer = transformer; mTransformer = transformer;
@@ -145,7 +149,8 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
public boolean bind() { public boolean bind() {
boolean bindResult = false; boolean bindResult = false;
try { try {
bindResult = mContext.bindService(mServiceIntent, mFlags, mExecutor, this); bindResult = mContext.bindServiceAsUser(mServiceIntent, this, mFlags,
mUserTracker.getUserHandle());
} catch (SecurityException e) { } catch (SecurityException e) {
Log.d(TAG, "Could not bind to service", e); Log.d(TAG, "Could not bind to service", e);
mContext.unbindService(this); mContext.unbindService(this);
@@ -228,11 +233,13 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
@Override @Override
public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) { mExecutor.execute(() -> {
Log.d(TAG, "onServiceConnected"); if (DEBUG) {
} Log.d(TAG, "onServiceConnected");
mProxy = mTransformer.convert(service); }
applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy)); mProxy = mTransformer.convert(service);
applyToCallbacksLocked(callback -> callback.onConnected(this, mProxy));
});
} }
private void applyToCallbacksLocked(Consumer<Callback<T>> applicator) { private void applyToCallbacksLocked(Consumer<Callback<T>> applicator) {
@@ -250,16 +257,16 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
@Override @Override
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_DISCONNECTED));
} }
@Override @Override
public void onBindingDied(ComponentName name) { public void onBindingDied(ComponentName name) {
onDisconnected(DISCONNECT_REASON_DISCONNECTED); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_BINDING_DIED));
} }
@Override @Override
public void onNullBinding(ComponentName name) { public void onNullBinding(ComponentName name) {
onDisconnected(DISCONNECT_REASON_NULL_BINDING); mExecutor.execute(() -> onDisconnected(DISCONNECT_REASON_NULL_BINDING));
} }
} }

View File

@@ -29,12 +29,15 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.UserInfo;
import android.os.IBinder; import android.os.IBinder;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.settings.FakeUserTracker;
import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.FakeSystemClock;
@@ -44,6 +47,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.Objects; import java.util.Objects;
@SmallTest @SmallTest
@@ -93,15 +97,22 @@ public class ObservableServiceConnectionTest extends SysuiTestCase {
FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private FakeUserTracker mUserTracker;
private static final int MAIN_USER_ID = 10;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); 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 @Test
public void testConnect() { public void testConnect() {
ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext,
mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer);
// Register twice to ensure only one callback occurs. // Register twice to ensure only one callback occurs.
connection.addCallback(mCallback); connection.addCallback(mCallback);
connection.addCallback(mCallback); connection.addCallback(mCallback);
@@ -121,15 +132,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase {
@Test @Test
public void testDisconnect() { public void testDisconnect() {
ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext,
mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer);
connection.addCallback(mCallback); connection.addCallback(mCallback);
connection.onServiceDisconnected(mComponentName); connection.onServiceDisconnected(mComponentName);
mExecutor.runAllReady();
// Disconnects before binds should be ignored. // Disconnects before binds should be ignored.
verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); verify(mCallback, never()).onDisconnected(eq(connection), anyInt());
when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(),
.thenReturn(true); eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true);
connection.bind(); connection.bind();
connection.onServiceDisconnected(mComponentName); connection.onServiceDisconnected(mComponentName);
@@ -151,15 +163,16 @@ public class ObservableServiceConnectionTest extends SysuiTestCase {
@Test @Test
public void testUnbind() { public void testUnbind() {
ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext,
mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer);
connection.addCallback(mCallback); connection.addCallback(mCallback);
connection.onServiceDisconnected(mComponentName); connection.onServiceDisconnected(mComponentName);
mExecutor.runAllReady();
// Disconnects before binds should be ignored. // Disconnects before binds should be ignored.
verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); verify(mCallback, never()).onDisconnected(eq(connection), anyInt());
when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) when(mContext.bindServiceAsUser(eq(mIntent), eq(connection), anyInt(),
.thenReturn(true); eq(UserHandle.of(MAIN_USER_ID)))).thenReturn(true);
connection.bind(); connection.bind();
mExecutor.runAllReady(); mExecutor.runAllReady();
@@ -175,10 +188,11 @@ public class ObservableServiceConnectionTest extends SysuiTestCase {
@Test @Test
public void testBindServiceThrowsError() { public void testBindServiceThrowsError() {
ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext,
mIntent, mExecutor, mTransformer); mIntent, mUserTracker, mExecutor, mTransformer);
connection.addCallback(mCallback); 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()); .thenThrow(new SecurityException());
// Verify that the exception was caught and that bind returns false, and we properly // Verify that the exception was caught and that bind returns false, and we properly