Address API review feedback for AmbientContext. Add shell method for more test coverage. Do not unregister request from the same client and delegate to AiAi to handle it.

Test: CTS tests
Bug: 219740201
Change-Id: I8fa9df9cab9965d84d301760f4f7fba08dc44f54
(cherry picked from commit 542fc25dff)
This commit is contained in:
Kathy Chen
2022-02-24 03:53:37 +00:00
parent 8ea0eb7019
commit c7a552d74f
6 changed files with 60 additions and 40 deletions

View File

@@ -10865,10 +10865,11 @@ package android.service.ambientcontext {
}
public static final class AmbientContextDetectionResult.Builder {
ctor public AmbientContextDetectionResult.Builder();
ctor public AmbientContextDetectionResult.Builder(@NonNull String);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionResult.Builder addEvent(@NonNull android.app.ambientcontext.AmbientContextEvent);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionResult.Builder addEvents(@NonNull java.util.List<android.app.ambientcontext.AmbientContextEvent>);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionResult build();
method @NonNull public android.service.ambientcontext.AmbientContextDetectionResult.Builder setPackageName(@NonNull String);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionResult.Builder clearEvents();
}
public abstract class AmbientContextDetectionService extends android.app.Service {
@@ -10889,9 +10890,8 @@ package android.service.ambientcontext {
}
public static final class AmbientContextDetectionServiceStatus.Builder {
ctor public AmbientContextDetectionServiceStatus.Builder();
ctor public AmbientContextDetectionServiceStatus.Builder(@NonNull String);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionServiceStatus build();
method @NonNull public android.service.ambientcontext.AmbientContextDetectionServiceStatus.Builder setPackageName(@NonNull String);
method @NonNull public android.service.ambientcontext.AmbientContextDetectionServiceStatus.Builder setStatusCode(int);
}

View File

@@ -26,6 +26,7 @@ import com.android.internal.util.AnnotationValidations;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Represents a {@code AmbientContextEvent} detection result reported by the detection service.
@@ -127,7 +128,9 @@ public final class AmbientContextDetectionResult implements Parcelable {
private @NonNull String mPackageName;
private long mBuilderFieldsSet = 0L;
public Builder() {
public Builder(@NonNull String packageName) {
Objects.requireNonNull(packageName);
mPackageName = packageName;
}
/**
@@ -144,26 +147,37 @@ public final class AmbientContextDetectionResult implements Parcelable {
}
/**
* The package to deliver the response to.
* Adds a list of events to the builder.
*/
public @NonNull Builder setPackageName(@NonNull String value) {
public @NonNull Builder addEvents(@NonNull List<AmbientContextEvent> values) {
checkNotUsed();
mBuilderFieldsSet |= 0x2;
mPackageName = value;
if (mEvents == null) {
mBuilderFieldsSet |= 0x1;
mEvents = new ArrayList<>();
}
mEvents.addAll(values);
return this;
}
/**
* Clears all events from the builder.
*/
public @NonNull Builder clearEvents() {
checkNotUsed();
if (mEvents != null) {
mEvents.clear();
}
return this;
}
/** Builds the instance. This builder should not be touched after calling this! */
public @NonNull AmbientContextDetectionResult build() {
checkNotUsed();
mBuilderFieldsSet |= 0x4; // Mark builder used
mBuilderFieldsSet |= 0x2; // Mark builder used
if ((mBuilderFieldsSet & 0x1) == 0) {
mEvents = new ArrayList<>();
}
if ((mBuilderFieldsSet & 0x2) == 0) {
mPackageName = "";
}
AmbientContextDetectionResult o = new AmbientContextDetectionResult(
mEvents,
mPackageName);
@@ -171,7 +185,7 @@ public final class AmbientContextDetectionResult implements Parcelable {
}
private void checkNotUsed() {
if ((mBuilderFieldsSet & 0x4) != 0) {
if ((mBuilderFieldsSet & 0x2) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}

View File

@@ -134,12 +134,18 @@ public abstract class AmbientContextDetectionService extends Service {
}
/**
* Starts detection and provides detected events to the statusConsumer. The ongoing detection
* will keep running, until onStopDetection is called. If there were previously requested
* detection from the same package, the previous request will be replaced with the new request.
* The implementation should keep track of whether the user consented each requested
* AmbientContextEvent for the app. If not consented, the statusConsumer should get a response
* with STATUS_ACCESS_DENIED.
* Called when a client app requests starting detection of the events in the request. The
* implementation should keep track of whether the user has explicitly consented to detecting
* the events using on-going ambient sensor (e.g. microphone), and agreed to share the
* detection results with this client app. If the user has not consented, the detection
* should not start, and the statusConsumer should get a response with STATUS_ACCESS_DENIED.
* If the user has made the consent and the underlying services are available, the
* implementation should start detection and provide detected events to the
* detectionResultConsumer. If the type of event needs immediate attention, the implementation
* should send result as soon as detected. Otherwise, the implementation can bulk send response.
* The ongoing detection will keep running, until onStopDetection is called. If there were
* previously requested detection from the same package, regardless of the type of events in
* the request, the previous request will be replaced with the new request.
*
* @param request The request with events to detect.
* @param packageName the requesting app's package name

View File

@@ -24,6 +24,8 @@ import android.os.Parcelable;
import com.android.internal.util.AnnotationValidations;
import java.util.Objects;
/**
* Represents a status for the {@code AmbientContextDetectionService}.
*
@@ -121,7 +123,9 @@ public final class AmbientContextDetectionServiceStatus implements Parcelable {
private @NonNull String mPackageName;
private long mBuilderFieldsSet = 0L;
public Builder() {
public Builder(@NonNull String packageName) {
Objects.requireNonNull(packageName);
mPackageName = packageName;
}
/**
@@ -134,27 +138,14 @@ public final class AmbientContextDetectionServiceStatus implements Parcelable {
return this;
}
/**
* The package to deliver the response to.
*/
public @NonNull Builder setPackageName(@NonNull String value) {
checkNotUsed();
mBuilderFieldsSet |= 0x2;
mPackageName = value;
return this;
}
/** Builds the instance. This builder should not be touched after calling this! */
public @NonNull AmbientContextDetectionServiceStatus build() {
checkNotUsed();
mBuilderFieldsSet |= 0x4; // Mark builder used
mBuilderFieldsSet |= 0x2; // Mark builder used
if ((mBuilderFieldsSet & 0x1) == 0) {
mStatusCode = AmbientContextManager.STATUS_UNKNOWN;
}
if ((mBuilderFieldsSet & 0x2) == 0) {
mPackageName = "";
}
AmbientContextDetectionServiceStatus o = new AmbientContextDetectionServiceStatus(
mStatusCode,
mPackageName);
@@ -162,7 +153,7 @@ public final class AmbientContextDetectionServiceStatus implements Parcelable {
}
private void checkNotUsed() {
if ((mBuilderFieldsSet & 0x4) != 0) {
if ((mBuilderFieldsSet & 0x2) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}

View File

@@ -171,16 +171,15 @@ final class AmbientContextManagerPerUserService extends
return;
}
// Remove any existing intent and unregister for this package before adding a new one.
// Remove any existing PendingIntent for this package.
String callingPackage = pendingIntent.getCreatorPackage();
PendingIntent duplicatePendingIntent = findExistingRequestByPackage(callingPackage);
if (duplicatePendingIntent != null) {
Slog.d(TAG, "Unregister duplicate request from " + callingPackage);
onUnregisterObserver(callingPackage);
Slog.d(TAG, "Replace duplicate request from " + callingPackage);
mExistingPendingIntents.remove(duplicatePendingIntent);
}
// Register new package and add request to mExistingRequests
// Register package and add pendingIntent to mExistingPendingIntents
startDetection(request, callingPackage, createDetectionResultRemoteCallback(),
getServerStatusCallback(clientStatusCallback));
mExistingPendingIntents.add(pendingIntent);

View File

@@ -110,6 +110,8 @@ final class AmbientContextShellCommand extends ShellCommand {
return runStopDetection();
case "get-last-status-code":
return getLastStatusCode();
case "get-last-package-name":
return getLastPackageName();
case "query-service-status":
return runQueryServiceStatus();
case "get-bound-package":
@@ -157,6 +159,13 @@ final class AmbientContextShellCommand extends ShellCommand {
return lastResponse.getStatusCode();
}
private int getLastPackageName() {
AmbientContextDetectionServiceStatus lastResponse =
sTestableCallbackInternal.getLastStatus();
out.println(lastResponse == null ? "" : lastResponse.getPackageName());
return 0;
}
@Override
public void onHelp() {
PrintWriter pw = getOutPrintWriter();
@@ -167,6 +176,7 @@ final class AmbientContextShellCommand extends ShellCommand {
pw.println(" start-detection USER_ID PACKAGE_NAME: Starts AmbientContextEvent detection.");
pw.println(" stop-detection USER_ID: Stops AmbientContextEvent detection.");
pw.println(" get-last-status-code: Prints the latest request status code.");
pw.println(" get-last-package-name: Prints the latest request package name.");
pw.println(" query-event-status USER_ID PACKAGE_NAME: Prints the event status code.");
pw.println(" get-bound-package USER_ID:"
+ " Print the bound package that implements the service.");