diff options
author | Eugene Susla <eugenesusla@google.com> | 2019-11-14 11:18:50 -0800 |
---|---|---|
committer | Eugene Susla <eugenesusla@google.com> | 2019-12-20 15:50:11 -0800 |
commit | b45b15a7012d27545be0efda226e66327c2a2840 (patch) | |
tree | 31af8454101d3050b7349ee0466a27ca73c1817b /services/companion | |
parent | 0d2e2c2be0374fdf426212368ab2e593612bf151 (diff) |
Use ServiceConnector and @DataClass in companion service
Refactor CompanionDeviceManagerService away from hand-rolled
ServiceConnection management in favor of ServiceConnector
Test: using toy app, ensure companion API still works
Change-Id: I90f937adf4e6f9af2137c77de91ba5cf93fa2212
Diffstat (limited to 'services/companion')
-rw-r--r-- | services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java | 189 |
1 files changed, 56 insertions, 133 deletions
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 8f1e1568ead6..e976811a3094 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -18,6 +18,7 @@ package com.android.server.companion; import static com.android.internal.util.CollectionUtils.size; +import static com.android.internal.util.FunctionalUtils.uncheckExceptions; import static com.android.internal.util.Preconditions.checkArgument; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkState; @@ -26,16 +27,15 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainRunna import android.annotation.CheckResult; import android.annotation.Nullable; import android.app.PendingIntent; +import android.companion.Association; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; import android.companion.ICompanionDeviceDiscoveryService; -import android.companion.ICompanionDeviceDiscoveryServiceCallback; import android.companion.ICompanionDeviceManager; import android.companion.IFindDeviceCallback; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; import android.content.pm.FeatureInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageItemInfo; @@ -67,6 +67,9 @@ import android.util.Xml; import com.android.internal.app.IAppOpsService; import com.android.internal.content.PackageMonitor; +import com.android.internal.infra.AndroidFuture; +import com.android.internal.infra.PerUser; +import com.android.internal.infra.ServiceConnector; import com.android.internal.notification.NotificationAccessConfirmationActivityContract; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; @@ -118,12 +121,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind private final CompanionDeviceManagerImpl mImpl; private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>(); private IDeviceIdleController mIdleController; - private ServiceConnection mServiceConnection; + private PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>> mServiceConnectors; private IAppOpsService mAppOpsManager; private IFindDeviceCallback mFindDeviceCallback; private AssociationRequest mRequest; private String mCallingPackage; + private AndroidFuture<Association> mOngoingDeviceDiscovery; private final Object mLock = new Object(); @@ -134,6 +138,19 @@ public class CompanionDeviceManagerService extends SystemService implements Bind ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); mAppOpsManager = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); + + Intent serviceIntent = new Intent().setComponent(SERVICE_TO_BIND_TO); + mServiceConnectors = new PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>>() { + @Override + protected ServiceConnector<ICompanionDeviceDiscoveryService> create(int userId) { + return new ServiceConnector.Impl<>( + getContext(), + serviceIntent, 0/* bindingFlags */, userId, + ICompanionDeviceDiscoveryService.Stub::asInterface); + } + }; + + registerPackageMonitor(); } @@ -187,7 +204,10 @@ public class CompanionDeviceManagerService extends SystemService implements Bind private void cleanup() { synchronized (mLock) { - mServiceConnection = unbind(mServiceConnection); + AndroidFuture<Association> ongoingDeviceDiscovery = mOngoingDeviceDiscovery; + if (ongoingDeviceDiscovery != null && !ongoingDeviceDiscovery.isDone()) { + ongoingDeviceDiscovery.cancel(true); + } mFindDeviceCallback = unlinkToDeath(mFindDeviceCallback, this, 0); mRequest = null; mCallingPackage = null; @@ -207,15 +227,6 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return null; } - @Nullable - @CheckResult - private ServiceConnection unbind(@Nullable ServiceConnection conn) { - if (conn != null) { - getContext().unbindService(conn); - } - return null; - } - class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub { @Override @@ -243,13 +254,27 @@ public class CompanionDeviceManagerService extends SystemService implements Bind checkCallerIsSystemOr(callingPackage); int userId = getCallingUserId(); checkUsesFeature(callingPackage, userId); + + mFindDeviceCallback = callback; + mRequest = request; + mCallingPackage = callingPackage; + callback.asBinder().linkToDeath(CompanionDeviceManagerService.this /* recipient */, 0); + final long callingIdentity = Binder.clearCallingIdentity(); try { - getContext().bindServiceAsUser( - new Intent().setComponent(SERVICE_TO_BIND_TO), - createServiceConnection(request, callback, callingPackage), - Context.BIND_AUTO_CREATE, - UserHandle.of(userId)); + mOngoingDeviceDiscovery = mServiceConnectors.forUser(userId).postAsync(service -> { + AndroidFuture<Association> future = new AndroidFuture<>(); + service.startDiscovery(request, callingPackage, callback, future); + return future; + }).whenComplete(uncheckExceptions((association, err) -> { + if (err == null) { + addAssociation(association); + } else { + Log.e(LOG_TAG, "Failed to discover device(s)", err); + callback.onFailure("No devices found: " + err.getMessage()); + } + cleanup(); + })); } finally { Binder.restoreCallingIdentity(callingIdentity); } @@ -386,82 +411,14 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return Binder.getCallingUid() == Process.SYSTEM_UID; } - private ServiceConnection createServiceConnection( - final AssociationRequest request, - final IFindDeviceCallback findDeviceCallback, - final String callingPackage) { - mServiceConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - if (DEBUG) { - Slog.i(LOG_TAG, - "onServiceConnected(name = " + name + ", service = " - + service + ")"); - } - - mFindDeviceCallback = findDeviceCallback; - mRequest = request; - mCallingPackage = callingPackage; - - try { - mFindDeviceCallback.asBinder().linkToDeath( - CompanionDeviceManagerService.this, 0); - } catch (RemoteException e) { - cleanup(); - return; - } - - try { - ICompanionDeviceDiscoveryService.Stub - .asInterface(service) - .startDiscovery( - request, - callingPackage, - findDeviceCallback, - getServiceCallback()); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error while initiating device discovery", e); - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - if (DEBUG) Slog.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")"); - } - }; - return mServiceConnection; - } - - private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() { - return new ICompanionDeviceDiscoveryServiceCallback.Stub() { - - @Override - public boolean onTransact(int code, Parcel data, Parcel reply, int flags) - throws RemoteException { - try { - return super.onTransact(code, data, reply, flags); - } catch (Throwable e) { - Slog.e(LOG_TAG, "Error during IPC", e); - throw ExceptionUtils.propagate(e, RemoteException.class); - } - } - - @Override - public void onDeviceSelected(String packageName, int userId, String deviceAddress) { - addAssociation(userId, packageName, deviceAddress); - cleanup(); - } - - @Override - public void onDeviceSelectionCancel() { - cleanup(); - } - }; + void addAssociation(int userId, String packageName, String deviceAddress) { + addAssociation(new Association(userId, deviceAddress, packageName)); } - void addAssociation(int userId, String packageName, String deviceAddress) { - updateSpecialAccessPermissionForAssociatedPackage(packageName, userId); - recordAssociation(packageName, deviceAddress); + void addAssociation(Association association) { + updateSpecialAccessPermissionForAssociatedPackage( + association.companionAppPackage, association.userId); + recordAssociation(association); } void removeAssociation(int userId, String pkg, String deviceMacAddress) { @@ -525,14 +482,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind }, getContext(), packageName, userId).recycleOnUse()); } - private void recordAssociation(String priviledgedPackage, String deviceAddress) { + private void recordAssociation(Association association) { if (DEBUG) { - Log.i(LOG_TAG, "recordAssociation(priviledgedPackage = " + priviledgedPackage - + ", deviceAddress = " + deviceAddress + ")"); + Log.i(LOG_TAG, "recordAssociation(" + association + ")"); } - int userId = getCallingUserId(); - updateAssociations(associations -> CollectionUtils.add(associations, - new Association(userId, deviceAddress, priviledgedPackage))); + updateAssociations(associations -> CollectionUtils.add(associations, association)); + } + + private void recordAssociation(String privilegedPackage, String deviceAddress) { + recordAssociation(new Association(getCallingUserId(), deviceAddress, privilegedPackage)); } private void updateAssociations(Function<Set<Association>, Set<Association>> update) { @@ -629,41 +587,6 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } } - - - private class Association { - public final int uid; - public final String deviceAddress; - public final String companionAppPackage; - - private Association(int uid, String deviceAddress, String companionAppPackage) { - this.uid = uid; - this.deviceAddress = checkNotNull(deviceAddress); - this.companionAppPackage = checkNotNull(companionAppPackage); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Association that = (Association) o; - - if (uid != that.uid) return false; - if (!deviceAddress.equals(that.deviceAddress)) return false; - return companionAppPackage.equals(that.companionAppPackage); - - } - - @Override - public int hashCode() { - int result = uid; - result = 31 * result + deviceAddress.hashCode(); - result = 31 * result + companionAppPackage.hashCode(); - return result; - } - } - private class ShellCmd extends ShellCommand { public static final String USAGE = "help\n" + "list USER_ID\n" |