summaryrefslogtreecommitdiff
path: root/services/companion
diff options
context:
space:
mode:
authorEugene Susla <eugenesusla@google.com>2019-11-14 11:18:50 -0800
committerEugene Susla <eugenesusla@google.com>2019-12-20 15:50:11 -0800
commitb45b15a7012d27545be0efda226e66327c2a2840 (patch)
tree31af8454101d3050b7349ee0466a27ca73c1817b /services/companion
parent0d2e2c2be0374fdf426212368ab2e593612bf151 (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.java189
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"