summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/companion/Association.aidl (renamed from core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl)13
-rw-r--r--core/java/android/companion/Association.java179
-rw-r--r--core/java/android/companion/ICompanionDeviceDiscoveryService.aidl5
-rw-r--r--core/java/com/android/internal/infra/AndroidFuture.aidl2
-rw-r--r--core/java/com/android/internal/infra/PerUser.java59
-rw-r--r--core/java/com/android/internal/util/FunctionalUtils.java33
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java22
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java189
8 files changed, 340 insertions, 162 deletions
diff --git a/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl b/core/java/android/companion/Association.aidl
index c9dc019bd2f2..2a28f1f094ad 100644
--- a/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
+++ b/core/java/android/companion/Association.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -10,16 +10,9 @@
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing per missions and
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package android.companion;
-/** @hide */
-interface ICompanionDeviceDiscoveryServiceCallback {
- @UnsupportedAppUsage
- oneway void onDeviceSelected(String packageName, int userId, String deviceAddress);
- @UnsupportedAppUsage
- oneway void onDeviceSelectionCancel();
-}
+parcelable Association;
diff --git a/core/java/android/companion/Association.java b/core/java/android/companion/Association.java
new file mode 100644
index 000000000000..3fa6a3e76634
--- /dev/null
+++ b/core/java/android/companion/Association.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.companion;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+import java.util.Objects;
+
+/**
+ * A record indicating that a device with a given address was confirmed by the user to be
+ * associated to a given companion app
+ *
+ * @hide
+ */
+@DataClass(genEqualsHashCode = true, genToString = true)
+public class Association implements Parcelable {
+
+ public final int userId;
+ public final @NonNull String deviceAddress;
+ public final @NonNull String companionAppPackage;
+
+
+
+
+ // Code below generated by codegen v1.0.13.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/companion/Association.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @DataClass.Generated.Member
+ public Association(
+ int userId,
+ @NonNull String deviceAddress,
+ @NonNull String companionAppPackage) {
+ this.userId = userId;
+ this.deviceAddress = deviceAddress;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, deviceAddress);
+ this.companionAppPackage = companionAppPackage;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, companionAppPackage);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "Association { " +
+ "userId = " + userId + ", " +
+ "deviceAddress = " + deviceAddress + ", " +
+ "companionAppPackage = " + companionAppPackage +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public boolean equals(@Nullable Object o) {
+ // You can override field equality logic by defining either of the methods like:
+ // boolean fieldNameEquals(Association other) { ... }
+ // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ @SuppressWarnings("unchecked")
+ Association that = (Association) o;
+ //noinspection PointlessBooleanExpression
+ return true
+ && userId == that.userId
+ && Objects.equals(deviceAddress, that.deviceAddress)
+ && Objects.equals(companionAppPackage, that.companionAppPackage);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int hashCode() {
+ // You can override field hashCode logic by defining methods like:
+ // int fieldNameHashCode() { ... }
+
+ int _hash = 1;
+ _hash = 31 * _hash + userId;
+ _hash = 31 * _hash + Objects.hashCode(deviceAddress);
+ _hash = 31 * _hash + Objects.hashCode(companionAppPackage);
+ return _hash;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeInt(userId);
+ dest.writeString(deviceAddress);
+ dest.writeString(companionAppPackage);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ protected Association(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ int _userId = in.readInt();
+ String _deviceAddress = in.readString();
+ String _companionAppPackage = in.readString();
+
+ this.userId = _userId;
+ this.deviceAddress = _deviceAddress;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, deviceAddress);
+ this.companionAppPackage = _companionAppPackage;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, companionAppPackage);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<Association> CREATOR
+ = new Parcelable.Creator<Association>() {
+ @Override
+ public Association[] newArray(int size) {
+ return new Association[size];
+ }
+
+ @Override
+ public Association createFromParcel(@NonNull Parcel in) {
+ return new Association(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1573767103332L,
+ codegenVersion = "1.0.13",
+ sourceFile = "frameworks/base/core/java/android/companion/Association.java",
+ inputSignatures = "public final int userId\npublic final @android.annotation.NonNull java.lang.String deviceAddress\npublic final @android.annotation.NonNull java.lang.String companionAppPackage\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+}
diff --git a/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
index 5398c3cea68d..5e3d46caae91 100644
--- a/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
+++ b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
@@ -16,9 +16,10 @@
package android.companion;
+import android.companion.Association;
import android.companion.AssociationRequest;
-import android.companion.ICompanionDeviceDiscoveryServiceCallback;
import android.companion.IFindDeviceCallback;
+import com.android.internal.infra.AndroidFuture;
/** @hide */
@@ -27,5 +28,5 @@ interface ICompanionDeviceDiscoveryService {
in AssociationRequest request,
in String callingPackage,
in IFindDeviceCallback findCallback,
- in ICompanionDeviceDiscoveryServiceCallback serviceCallback);
+ in AndroidFuture<Association> serviceCallback);
}
diff --git a/core/java/com/android/internal/infra/AndroidFuture.aidl b/core/java/com/android/internal/infra/AndroidFuture.aidl
index b19aab8ab0d5..5f623b183168 100644
--- a/core/java/com/android/internal/infra/AndroidFuture.aidl
+++ b/core/java/com/android/internal/infra/AndroidFuture.aidl
@@ -17,4 +17,4 @@
package com.android.internal.infra;
/** @hide */
-parcelable AndroidFuture;
+parcelable AndroidFuture<T>;
diff --git a/core/java/com/android/internal/infra/PerUser.java b/core/java/com/android/internal/infra/PerUser.java
new file mode 100644
index 000000000000..560ca8cff8df
--- /dev/null
+++ b/core/java/com/android/internal/infra/PerUser.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.infra;
+
+import android.annotation.NonNull;
+import android.util.SparseArray;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A {@link SparseArray} customized for a common use-case of storing state per-user.
+ *
+ * Unlike a normal {@link SparseArray} this will always create a value on {@link #get} if one is
+ * not present instead of returning null.
+ *
+ * @param <T> user state type
+ */
+public abstract class PerUser<T> extends SparseArray<T> {
+
+ /**
+ * Initialize state for the given user
+ */
+ protected abstract @NonNull T create(int userId);
+
+ /**
+ * Same as {@link #get(int)}, renamed for readability.
+ *
+ * This will never return null, deferring to {@link #create} instead
+ * when called for the first time.
+ */
+ public @NonNull T forUser(int userId) {
+ return get(userId);
+ }
+
+ @Override
+ public @NonNull T get(int userId) {
+ T userState = super.get(userId);
+ if (userState != null) {
+ return userState;
+ } else {
+ userState = Preconditions.checkNotNull(create(userId));
+ put(userId, userState);
+ return userState;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/util/FunctionalUtils.java b/core/java/com/android/internal/util/FunctionalUtils.java
index b955f672fe93..3c9791791a68 100644
--- a/core/java/com/android/internal/util/FunctionalUtils.java
+++ b/core/java/com/android/internal/util/FunctionalUtils.java
@@ -19,6 +19,7 @@ package com.android.internal.util;
import android.os.RemoteException;
import android.util.ExceptionUtils;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -54,6 +55,13 @@ public class FunctionalUtils {
/**
* @see #uncheckExceptions(ThrowingConsumer)
*/
+ public static <A, B> BiConsumer<A, B> uncheckExceptions(ThrowingBiConsumer<A, B> action) {
+ return action;
+ }
+
+ /**
+ * @see #uncheckExceptions(ThrowingConsumer)
+ */
public static <T> Supplier<T> uncheckExceptions(ThrowingSupplier<T> action) {
return action;
}
@@ -185,4 +193,29 @@ public class FunctionalUtils {
}
}
}
+
+ /**
+ * A {@link BiConsumer} that allows throwing checked exceptions from its single abstract method.
+ *
+ * Can be used together with {@link #uncheckExceptions} to effectively turn a lambda expression
+ * that throws a checked exception into a regular {@link Function}
+ *
+ * @param <A> see {@link BiConsumer}
+ * @param <B> see {@link BiConsumer}
+ */
+ @FunctionalInterface
+ @SuppressWarnings("FunctionalInterfaceMethodChanged")
+ public interface ThrowingBiConsumer<A, B> extends BiConsumer<A, B> {
+ /** @see ThrowingFunction */
+ void acceptOrThrow(A a, B b) throws Exception;
+
+ @Override
+ default void accept(A a, B b) {
+ try {
+ acceptOrThrow(a, b);
+ } catch (Exception ex) {
+ throw ExceptionUtils.propagate(ex);
+ }
+ }
+ }
}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index d11b5c573ca9..7aa997e39307 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -37,12 +37,12 @@ import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
+import android.companion.Association;
import android.companion.AssociationRequest;
import android.companion.BluetoothDeviceFilter;
import android.companion.BluetoothLeDeviceFilter;
import android.companion.DeviceFilter;
import android.companion.ICompanionDeviceDiscoveryService;
-import android.companion.ICompanionDeviceDiscoveryServiceCallback;
import android.companion.IFindDeviceCallback;
import android.companion.WifiDeviceFilter;
import android.content.BroadcastReceiver;
@@ -63,6 +63,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
+import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.Preconditions;
@@ -97,7 +98,7 @@ public class DeviceDiscoveryService extends Service {
DevicesAdapter mDevicesAdapter;
IFindDeviceCallback mFindCallback;
- ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
+ AndroidFuture<Association> mServiceCallback;
boolean mIsScanning = false;
@Nullable DeviceChooserActivity mActivity = null;
@@ -107,7 +108,7 @@ public class DeviceDiscoveryService extends Service {
public void startDiscovery(AssociationRequest request,
String callingPackage,
IFindDeviceCallback findCallback,
- ICompanionDeviceDiscoveryServiceCallback serviceCallback) {
+ AndroidFuture serviceCallback) {
if (DEBUG) {
Log.i(LOG_TAG,
"startDiscovery() called with: filter = [" + request
@@ -303,23 +304,12 @@ public class DeviceDiscoveryService extends Service {
}
void onDeviceSelected(String callingPackage, String deviceAddress) {
- try {
- mServiceCallback.onDeviceSelected(
- //TODO is this the right userId?
- callingPackage, getUserId(), deviceAddress);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to record association: "
- + callingPackage + " <-> " + deviceAddress);
- }
+ mServiceCallback.complete(new Association(getUserId(), deviceAddress, callingPackage));
}
void onCancel() {
if (DEBUG) Log.i(LOG_TAG, "onCancel()");
- try {
- mServiceCallback.onDeviceSelectionCancel();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
+ mServiceCallback.cancel(true);
}
class DevicesAdapter extends ArrayAdapter<DeviceFilterPair> {
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"