Merge "[CDM perm sync] Introduce a new startSystemDataTransfer API with callback"

This commit is contained in:
Jeff Sharkey
2022-06-29 00:03:31 +00:00
committed by Android (Google) Code Review
7 changed files with 125 additions and 6 deletions

View File

@@ -9010,7 +9010,8 @@ package android.companion {
method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
method public void requestNotificationAccess(android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
method public void startSystemDataTransfer(int) throws android.companion.DeviceNotAssociatedException;
method @Deprecated public void startSystemDataTransfer(int) throws android.companion.DeviceNotAssociatedException;
method public void startSystemDataTransfer(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.companion.CompanionException>) throws android.companion.DeviceNotAssociatedException;
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
field public static final String EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION";
field @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -9036,6 +9037,9 @@ package android.companion {
field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
}
public class CompanionException extends java.lang.RuntimeException {
}
public interface DeviceFilter<D extends android.os.Parcelable> extends android.os.Parcelable {
}

View File

@@ -38,6 +38,7 @@ import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.net.MacAddress;
import android.os.Handler;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -964,12 +965,44 @@ public final class CompanionDeviceManager {
* @param associationId The unique {@link AssociationInfo#getId ID} assigned to the Association
* of the companion device recorded by CompanionDeviceManager
* @throws DeviceNotAssociatedException Exception if the companion device is not associated
*
* @deprecated Use {@link #startSystemDataTransfer(int, Executor, OutcomeReceiver)} instead.
*/
@Deprecated
@UserHandleAware
public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException {
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId);
associationId, null);
} catch (RemoteException e) {
ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
throw e.rethrowFromSystemServer();
}
}
/**
* Start system data transfer which has been previously approved by the user.
*
* <p>Before calling this method, the app needs to make sure there's a communication channel
* between two devices, and has prompted user consent dialogs built by one of these methods:
* {@link #buildPermissionTransferUserConsentIntent(int)}.
* The transfer may fail if the communication channel is disconnected during the transfer.</p>
*
* @param associationId The unique {@link AssociationInfo#getId ID} assigned to the Association
* of the companion device recorded by CompanionDeviceManager
* @param executor The executor which will be used to invoke the result callback.
* @param result The callback to notify the app of the result of the system data transfer.
* @throws DeviceNotAssociatedException Exception if the companion device is not associated
*/
@UserHandleAware
public void startSystemDataTransfer(
int associationId,
@NonNull Executor executor,
@NonNull OutcomeReceiver<Void, CompanionException> result)
throws DeviceNotAssociatedException {
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId, new SystemDataTransferCallbackProxy(executor, result));
} catch (RemoteException e) {
ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
throw e.rethrowFromSystemServer();
@@ -1045,6 +1078,27 @@ public final class CompanionDeviceManager {
}
}
private static class SystemDataTransferCallbackProxy extends ISystemDataTransferCallback.Stub {
private final Executor mExecutor;
private final OutcomeReceiver<Void, CompanionException> mCallback;
private SystemDataTransferCallbackProxy(Executor executor,
OutcomeReceiver<Void, CompanionException> callback) {
mExecutor = executor;
mCallback = callback;
}
@Override
public void onResult() {
mExecutor.execute(() -> mCallback.onResult(null));
}
@Override
public void onError(String error) {
mExecutor.execute(() -> mCallback.onError(new CompanionException(error)));
}
}
/**
* Representation of an active system data transport.
* <p>

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 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;
/**
* {@code CompanionException} can be thrown during the companion system data transfer process.
*/
public class CompanionException extends RuntimeException {
/** @hide */
public CompanionException(@NonNull String message) {
super(message);
}
}

View File

@@ -19,6 +19,7 @@ package android.companion;
import android.app.PendingIntent;
import android.companion.IAssociationRequestCallback;
import android.companion.IOnAssociationsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.content.ComponentName;
@@ -75,7 +76,8 @@ interface ICompanionDeviceManager {
PendingIntent buildPermissionTransferUserConsentIntent(String callingPackage, int userId,
int associationId);
void startSystemDataTransfer(String packageName, int userId, int associationId);
void startSystemDataTransfer(String packageName, int userId, int associationId,
in ISystemDataTransferCallback callback);
void attachSystemDataTransport(String packageName, int userId, int associationId, in ParcelFileDescriptor fd);

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2022 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 per missions and
* limitations under the License.
*/
package android.companion;
/** @hide */
interface ISystemDataTransferCallback {
oneway void onResult();
oneway void onError(String error);
}

View File

@@ -62,6 +62,7 @@ import android.companion.DeviceNotAssociatedException;
import android.companion.IAssociationRequestCallback;
import android.companion.ICompanionDeviceManager;
import android.companion.IOnAssociationsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
@@ -725,9 +726,10 @@ public class CompanionDeviceManagerService extends SystemService {
}
@Override
public void startSystemDataTransfer(String packageName, int userId, int associationId) {
public void startSystemDataTransfer(String packageName, int userId, int associationId,
ISystemDataTransferCallback callback) {
mSystemDataTransferProcessor.startSystemDataTransfer(packageName, userId,
associationId);
associationId, callback);
}
@Override

View File

@@ -29,6 +29,7 @@ import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.companion.AssociationInfo;
import android.companion.DeviceNotAssociatedException;
import android.companion.ISystemDataTransferCallback;
import android.companion.datatransfer.PermissionSyncRequest;
import android.companion.datatransfer.SystemDataTransferRequest;
import android.content.ComponentName;
@@ -167,8 +168,11 @@ public class SystemDataTransferProcessor {
/**
* Start system data transfer. It should first try to establish a secure channel and then sync
* system data.
*
* TODO: execute callback when the transfer finishes successfully or with errors.
*/
public void startSystemDataTransfer(String packageName, int userId, int associationId) {
public void startSystemDataTransfer(String packageName, int userId, int associationId,
ISystemDataTransferCallback callback) {
Slog.i(LOG_TAG, "Start system data transfer for package [" + packageName
+ "] userId [" + userId + "] associationId [" + associationId + "]");