Merge "Add an API to set if ContextSync is enabled"

This commit is contained in:
Guojing Yuan
2023-01-17 21:14:20 +00:00
committed by Android (Google) Code Review
8 changed files with 152 additions and 46 deletions

View File

@@ -9187,6 +9187,7 @@ package android.companion {
method @Nullable public String getDeviceProfile();
method @Nullable public CharSequence getDisplayName();
method public int getId();
method public int getSystemDataSyncFlags();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.companion.AssociationInfo> CREATOR;
}
@@ -9256,8 +9257,10 @@ package android.companion {
method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.Callback);
method @Nullable public android.content.IntentSender buildAssociationCancellationIntent();
method @Nullable public android.content.IntentSender buildPermissionTransferUserConsentIntent(int) throws android.companion.DeviceNotAssociatedException;
method public void disableSystemDataSync(int, int);
method @Deprecated public void disassociate(@NonNull String);
method public void disassociate(int);
method public void enableSystemDataSync(int, int);
method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations();
method @Deprecated @NonNull public java.util.List<java.lang.String> getAssociations();
method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
@@ -9268,6 +9271,7 @@ package android.companion {
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";
field public static final int FLAG_CALL_METADATA = 1; // 0x1
field public static final int RESULT_CANCELED = 0; // 0x0
field public static final int RESULT_DISCOVERY_TIMEOUT = 2; // 0x2
field public static final int RESULT_INTERNAL_ERROR = 3; // 0x3

View File

@@ -56,6 +56,7 @@ public final class AssociationInfo implements Parcelable {
private final boolean mSelfManaged;
private final boolean mNotifyOnDeviceNearby;
private final int mSystemDataSyncFlags;
/**
* Indicates that the association has been revoked (removed), but we keep the association
@@ -73,7 +74,6 @@ public final class AssociationInfo implements Parcelable {
/**
* Creates a new Association.
* Only to be used by the CompanionDeviceManagerService.
*
* @hide
*/
@@ -81,7 +81,7 @@ public final class AssociationInfo implements Parcelable {
@Nullable MacAddress macAddress, @Nullable CharSequence displayName,
@Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice,
boolean selfManaged, boolean notifyOnDeviceNearby, boolean revoked,
long timeApprovedMs, long lastTimeConnectedMs) {
long timeApprovedMs, long lastTimeConnectedMs, int systemDataSyncFlags) {
if (id <= 0) {
throw new IllegalArgumentException("Association ID should be greater than 0");
}
@@ -105,6 +105,7 @@ public final class AssociationInfo implements Parcelable {
mRevoked = revoked;
mTimeApprovedMs = timeApprovedMs;
mLastTimeConnectedMs = lastTimeConnectedMs;
mSystemDataSyncFlags = systemDataSyncFlags;
}
/**
@@ -220,6 +221,16 @@ public final class AssociationInfo implements Parcelable {
return mLastTimeConnectedMs;
}
/**
* @return Enabled system data sync flags set via
* {@link CompanionDeviceManager#enableSystemDataSync(int, int)} and
* {@link CompanionDeviceManager#disableSystemDataSync(int, int)}.
* Or by default all flags are 1 (enabled).
*/
public int getSystemDataSyncFlags() {
return mSystemDataSyncFlags;
}
/**
* Utility method for checking if the association represents a device with the given MAC
* address.
@@ -287,6 +298,7 @@ public final class AssociationInfo implements Parcelable {
+ ", mLastTimeConnectedMs=" + (
mLastTimeConnectedMs == Long.MAX_VALUE
? LAST_TIME_CONNECTED_NONE : new Date(mLastTimeConnectedMs))
+ ", mSystemDataSyncFlags=" + mSystemDataSyncFlags
+ '}';
}
@@ -306,14 +318,15 @@ public final class AssociationInfo implements Parcelable {
&& Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress)
&& Objects.equals(mDisplayName, that.mDisplayName)
&& Objects.equals(mDeviceProfile, that.mDeviceProfile)
&& Objects.equals(mAssociatedDevice, that.mAssociatedDevice);
&& Objects.equals(mAssociatedDevice, that.mAssociatedDevice)
&& mSystemDataSyncFlags == that.mSystemDataSyncFlags;
}
@Override
public int hashCode() {
return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName,
mDeviceProfile, mAssociatedDevice, mSelfManaged, mNotifyOnDeviceNearby, mRevoked,
mTimeApprovedMs, mLastTimeConnectedMs);
mTimeApprovedMs, mLastTimeConnectedMs, mSystemDataSyncFlags);
}
@Override
@@ -338,6 +351,7 @@ public final class AssociationInfo implements Parcelable {
dest.writeBoolean(mRevoked);
dest.writeLong(mTimeApprovedMs);
dest.writeLong(mLastTimeConnectedMs);
dest.writeInt(mSystemDataSyncFlags);
}
private AssociationInfo(@NonNull Parcel in) {
@@ -356,6 +370,7 @@ public final class AssociationInfo implements Parcelable {
mRevoked = in.readBoolean();
mTimeApprovedMs = in.readLong();
mLastTimeConnectedMs = in.readLong();
mSystemDataSyncFlags = in.readInt();
}
@NonNull
@@ -390,27 +405,24 @@ public final class AssociationInfo implements Parcelable {
return new Builder(info);
}
/**
* @hide
*/
/** @hide */
public static final class Builder implements NonActionableBuilder {
@NonNull
private final AssociationInfo mOriginalInfo;
private boolean mNotifyOnDeviceNearby;
private boolean mRevoked;
private long mLastTimeConnectedMs;
private int mSystemDataSyncFlags;
private Builder(@NonNull AssociationInfo info) {
mOriginalInfo = info;
mNotifyOnDeviceNearby = info.mNotifyOnDeviceNearby;
mRevoked = info.mRevoked;
mLastTimeConnectedMs = info.mLastTimeConnectedMs;
mSystemDataSyncFlags = info.mSystemDataSyncFlags;
}
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@Override
@NonNull
public Builder setLastTimeConnected(long lastTimeConnectedMs) {
@@ -423,10 +435,7 @@ public final class AssociationInfo implements Parcelable {
return this;
}
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@Override
@NonNull
public Builder setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby) {
@@ -434,10 +443,7 @@ public final class AssociationInfo implements Parcelable {
return this;
}
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@Override
@NonNull
public Builder setRevoked(boolean revoked) {
@@ -445,9 +451,15 @@ public final class AssociationInfo implements Parcelable {
return this;
}
/**
* @hide
*/
/** @hide */
@Override
@NonNull
public Builder setSystemDataSyncFlags(int flags) {
mSystemDataSyncFlags = flags;
return this;
}
/** @hide */
@NonNull
public AssociationInfo build() {
return new AssociationInfo(
@@ -462,7 +474,8 @@ public final class AssociationInfo implements Parcelable {
mNotifyOnDeviceNearby,
mRevoked,
mOriginalInfo.mTimeApprovedMs,
mLastTimeConnectedMs
mLastTimeConnectedMs,
mSystemDataSyncFlags
);
}
}
@@ -480,25 +493,20 @@ public final class AssociationInfo implements Parcelable {
* @hide
*/
public interface NonActionableBuilder {
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@NonNull
Builder setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby);
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@NonNull
Builder setLastTimeConnected(long lastTimeConnectedMs);
/**
* Should only be used by the CompanionDeviceManagerService.
* @hide
*/
/** @hide */
@NonNull
Builder setRevoked(boolean revoked);
/** @hide */
@NonNull
Builder setSystemDataSyncFlags(int flags);
}
}

View File

@@ -166,6 +166,19 @@ public final class CompanionDeviceManager {
*/
public static final String REASON_CANCELED = "canceled";
/** @hide */
@IntDef(flag = true, prefix = { "FLAG_" }, value = {
FLAG_CALL_METADATA,
})
@Retention(RetentionPolicy.SOURCE)
public @interface DataSyncTypes {}
/**
* Used by {@link #enableSystemDataSync(int, int)}}.
* Sync call metadata like muting, ending and silencing a call.
*
*/
public static final int FLAG_CALL_METADATA = 1;
/**
* A device, returned in the activity result of the {@link IntentSender} received in
@@ -468,6 +481,49 @@ public final class CompanionDeviceManager {
}
}
/**
* <p>Enable system data sync (it only supports call metadata sync for now).
* By default all supported system data types are enabled.</p>
*
* <p>Calling this API requires a uses-feature
* {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
*
* @param associationId id of the device association.
* @param flags system data types to be enabled.
*/
public void enableSystemDataSync(int associationId, @DataSyncTypes int flags) {
if (!checkFeaturePresent()) {
return;
}
try {
mService.enableSystemDataSync(associationId, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* <p>Disable system data sync (it only supports call metadata sync for now).
* By default all supported system data types are enabled.</p>
*
* <p>Calling this API requires a uses-feature
* {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
*
* @param associationId id of the device association.
* @param flags system data types to be disabled.
*/
public void disableSystemDataSync(int associationId, @DataSyncTypes int flags) {
if (!checkFeaturePresent()) {
return;
}
try {
mService.disableSystemDataSync(associationId, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* <p>Calling this API requires a uses-feature

View File

@@ -84,4 +84,8 @@ interface ICompanionDeviceManager {
boolean isCompanionApplicationBound(String packageName, int userId);
PendingIntent buildAssociationCancellationIntent(in String callingPackage, int userId);
void enableSystemDataSync(int associationId, int flags);
void disableSystemDataSync(int associationId, int flags);
}

View File

@@ -268,9 +268,9 @@ class AssociationRequestsProcessor {
@NonNull ResultReceiver resultReceiver) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
createAssociation(userId, packageName, macAddress,
request.getDisplayName(), request.getDeviceProfile(),
request.getAssociatedDevice(), request.isSelfManaged(),
createAssociation(userId, packageName, macAddress, request.getDisplayName(),
request.getDeviceProfile(), request.getAssociatedDevice(),
request.isSelfManaged(),
callback, resultReceiver);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
@@ -287,7 +287,8 @@ class AssociationRequestsProcessor {
final AssociationInfo association = new AssociationInfo(id, userId, packageName,
macAddress, displayName, deviceProfile, associatedDevice, selfManaged,
/* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE);
/* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE,
/* systemDataSyncFlags */ ~0);
if (deviceProfile != null) {
// If the "Device Profile" is specified, make the companion application a holder of the
@@ -315,6 +316,20 @@ class AssociationRequestsProcessor {
// that there are other devices with the same profile, so the role holder won't be removed.
}
public void enableSystemDataSync(int associationId, int flags) {
AssociationInfo association = mAssociationStore.getAssociationById(associationId);
AssociationInfo updated = AssociationInfo.builder(association)
.setSystemDataSyncFlags(association.getSystemDataSyncFlags() | flags).build();
mAssociationStore.updateAssociation(updated);
}
public void disableSystemDataSync(int associationId, int flags) {
AssociationInfo association = mAssociationStore.getAssociationById(associationId);
AssociationInfo updated = AssociationInfo.builder(association)
.setSystemDataSyncFlags(association.getSystemDataSyncFlags() & (~flags)).build();
mAssociationStore.updateAssociation(updated);
}
private void addAssociationToStore(@NonNull AssociationInfo association,
@Nullable String deviceProfile) {
Slog.i(TAG, "New CDM association created=" + association);

View File

@@ -713,6 +713,18 @@ public class CompanionDeviceManagerService extends SystemService {
mTransportManager.detachSystemDataTransport(packageName, userId, associationId);
}
@Override
public void enableSystemDataSync(int associationId, int flags) {
getAssociationWithCallerChecks(associationId);
mAssociationRequestsProcessor.enableSystemDataSync(associationId, flags);
}
@Override
public void disableSystemDataSync(int associationId, int flags) {
getAssociationWithCallerChecks(associationId);
mAssociationRequestsProcessor.disableSystemDataSync(associationId, flags);
}
@Override
public void notifyDeviceAppeared(int associationId) {
if (DEBUG) Log.i(TAG, "notifyDevice_Appeared() id=" + associationId);

View File

@@ -132,7 +132,8 @@ import java.util.concurrent.ConcurrentMap;
* notify_device_nearby="false"
* revoked="false"
* last_time_connected="1634641160229"
* time_approved="1634389553216"/>
* time_approved="1634389553216"
* system_data_sync_flags="-1"/>
*
* <association
* id="3"
@@ -143,7 +144,8 @@ import java.util.concurrent.ConcurrentMap;
* notify_device_nearby="false"
* revoked="false"
* last_time_connected="1634641160229"
* time_approved="1634641160229"/>
* time_approved="1634641160229"
* system_data_sync_flags="-1"/>
* </associations>
*
* <previously-used-ids>
@@ -185,6 +187,7 @@ final class PersistentDataStore {
private static final String XML_ATTR_REVOKED = "revoked";
private static final String XML_ATTR_TIME_APPROVED = "time_approved";
private static final String XML_ATTR_LAST_TIME_CONNECTED = "last_time_connected";
private static final String XML_ATTR_SYSTEM_DATA_SYNC_FLAGS = "system_data_sync_flags";
private static final String LEGACY_XML_ATTR_DEVICE = "device";
@@ -429,7 +432,7 @@ final class PersistentDataStore {
out.add(new AssociationInfo(associationId, userId, appPackage,
MacAddress.fromString(deviceAddress), null, profile, null,
/* managedByCompanionApp */ false, notify, /* revoked */ false, timeApproved,
Long.MAX_VALUE));
Long.MAX_VALUE, /* systemDataSyncFlags */ -1));
}
private static void readAssociationsV1(@NonNull TypedXmlPullParser parser,
@@ -462,10 +465,12 @@ final class PersistentDataStore {
final long timeApproved = readLongAttribute(parser, XML_ATTR_TIME_APPROVED, 0L);
final long lastTimeConnected = readLongAttribute(
parser, XML_ATTR_LAST_TIME_CONNECTED, Long.MAX_VALUE);
final int systemDataSyncFlags = readIntAttribute(parser,
XML_ATTR_SYSTEM_DATA_SYNC_FLAGS, -1);
final AssociationInfo associationInfo = createAssociationInfoNoThrow(associationId, userId,
appPackage, macAddress, displayName, profile, selfManaged, notify, revoked,
timeApproved, lastTimeConnected);
timeApproved, lastTimeConnected, systemDataSyncFlags);
if (associationInfo != null) {
out.add(associationInfo);
}
@@ -523,6 +528,7 @@ final class PersistentDataStore {
writeLongAttribute(serializer, XML_ATTR_TIME_APPROVED, a.getTimeApprovedMs());
writeLongAttribute(
serializer, XML_ATTR_LAST_TIME_CONNECTED, a.getLastTimeConnectedMs());
writeIntAttribute(serializer, XML_ATTR_SYSTEM_DATA_SYNC_FLAGS, a.getSystemDataSyncFlags());
serializer.endTag(null, XML_TAG_ASSOCIATION);
}
@@ -561,14 +567,15 @@ final class PersistentDataStore {
private static AssociationInfo createAssociationInfoNoThrow(int associationId,
@UserIdInt int userId, @NonNull String appPackage, @Nullable MacAddress macAddress,
@Nullable CharSequence displayName, @Nullable String profile, boolean selfManaged,
boolean notify, boolean revoked, long timeApproved, long lastTimeConnected) {
boolean notify, boolean revoked, long timeApproved, long lastTimeConnected,
int systemDataSyncFlags) {
AssociationInfo associationInfo = null;
try {
// We do not persist AssociatedDevice, which means that AssociationInfo retrieved from
// datastore is not guaranteed to be identical to the one from initial association.
associationInfo = new AssociationInfo(associationId, userId, appPackage, macAddress,
displayName, profile, null, selfManaged, notify, revoked,
timeApproved, lastTimeConnected);
timeApproved, lastTimeConnected, systemDataSyncFlags);
} catch (Exception e) {
if (DEBUG) Log.w(TAG, "Could not create AssociationInfo", e);
}

View File

@@ -332,7 +332,7 @@ public class VirtualDeviceManagerServiceTest {
new CameraAccessController(mContext, mLocalService, mCameraAccessBlockedCallback);
mAssociationInfo = new AssociationInfo(/* associationId= */ 1, 0, null,
MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0);
MacAddress.BROADCAST_ADDRESS, "", null, null, true, false, false, 0, 0, -1);
mVdms = new VirtualDeviceManagerService(mContext);
mLocalService = mVdms.getLocalServiceInstance();