Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0531364 authored by Charlie Wang's avatar Charlie Wang
Browse files

Wearable events for AmbientContextManager.

WearableSensingService implements the EVENT_WEARABLE_VENDOR_START AmbientContextEvents that
AmbientContextManager supports. Only AmbientContextRequests of all
events greater than EVENT_WEARABLE_VENDOR_START will be accepeted by the
WearableSensingService. A request with a mixture of event types will not
be accepted. None Wearable events will be delegated to the default
AmbientContextDetectionService on the system.

Bug: 244181656
Test: Builds. atest CtsAmbientContextServiceTestCases atest CtsWearableSensingServiceTestCases
Ignore-AOSP-First: to prevent new feature leak.
API-Coverage-Bug: 259453662
Change-Id: Ib66be763978117f052eed33d66652e34ed655bfc
parent 9e4eb522
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1387,12 +1387,15 @@ package android.app.ambientcontext {
    method @NonNull public java.time.Instant getEndTime();
    method public int getEventType();
    method @NonNull public java.time.Instant getStartTime();
    method @NonNull public android.os.PersistableBundle getVendorData();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.ambientcontext.AmbientContextEvent> CREATOR;
    field public static final int EVENT_BACK_DOUBLE_TAP = 3; // 0x3
    field public static final int EVENT_COUGH = 1; // 0x1
    field public static final int EVENT_SNORE = 2; // 0x2
    field public static final int EVENT_UNKNOWN = 0; // 0x0
    field public static final int EVENT_VENDOR_WEARABLE_START = 100000; // 0x186a0
    field public static final String KEY_VENDOR_WEARABLE_EVENT_NAME = "wearable_event_name";
    field public static final int LEVEL_HIGH = 5; // 0x5
    field public static final int LEVEL_LOW = 1; // 0x1
    field public static final int LEVEL_MEDIUM = 3; // 0x3
@@ -1409,6 +1412,7 @@ package android.app.ambientcontext {
    method @NonNull public android.app.ambientcontext.AmbientContextEvent.Builder setEndTime(@NonNull java.time.Instant);
    method @NonNull public android.app.ambientcontext.AmbientContextEvent.Builder setEventType(int);
    method @NonNull public android.app.ambientcontext.AmbientContextEvent.Builder setStartTime(@NonNull java.time.Instant);
    method @NonNull public android.app.ambientcontext.AmbientContextEvent.Builder setVendorData(@NonNull android.os.PersistableBundle);
  }
  public final class AmbientContextEventRequest implements android.os.Parcelable {
@@ -12580,6 +12584,9 @@ package android.service.wearable {
    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method @BinderThread public abstract void onDataProvided(@NonNull android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull java.util.function.Consumer<java.lang.Integer>);
    method @BinderThread public abstract void onDataStreamProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
    method @BinderThread public abstract void onQueryServiceStatus(@NonNull java.util.Set<java.lang.Integer>, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>);
    method @BinderThread public abstract void onStartDetection(@NonNull android.app.ambientcontext.AmbientContextEventRequest, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionResult>);
    method public abstract void onStopDetection(@NonNull String);
    field public static final String SERVICE_INTERFACE = "android.service.wearable.WearableSensingService";
  }
+82 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcelable;
import android.os.PersistableBundle;

import com.android.internal.util.DataClass;
import com.android.internal.util.Parcelling;
@@ -66,12 +67,25 @@ public final class AmbientContextEvent implements Parcelable {
     */
    public static final int EVENT_BACK_DOUBLE_TAP = 3;

    /**
     * Integer indicating the start of wearable vendor defined events that can be detected.
     * These depend on the vendor implementation.
     */
    public static final int EVENT_VENDOR_WEARABLE_START = 100000;

    /**
     * Name for the mVendorData object for this AmbientContextEvent. The mVendorData must be present
     * in the object, or it will be rejected.
     */
    public static final String KEY_VENDOR_WEARABLE_EVENT_NAME = "wearable_event_name";

    /** @hide */
    @IntDef(prefix = { "EVENT_" }, value = {
            EVENT_UNKNOWN,
            EVENT_COUGH,
            EVENT_SNORE,
            EVENT_BACK_DOUBLE_TAP,
            EVENT_VENDOR_WEARABLE_START,
    }) public @interface EventCode {}

    /** The integer indicating an unknown level. */
@@ -139,6 +153,19 @@ public final class AmbientContextEvent implements Parcelable {
        return LEVEL_UNKNOWN;
    }

    /**
     * Vendor defined specific values for vendor event types.
     *
     * <p> The use of this vendor data is discouraged. For data defined in the range above
     * {@code EVENT_VENDOR_WEARABLE_START} this bundle must include the
     * {@link KEY_VENDOR_WEARABLE_EVENT_NAME} field or it will be rejected. In addition, to increase
     * transparency of this data contents of this bundle will be logged to logcat.</p>
     */
    private final @NonNull PersistableBundle mVendorData;
    private static PersistableBundle defaultVendorData() {
        return new PersistableBundle();
    }



    // Code below generated by codegen v1.0.23.
@@ -159,7 +186,8 @@ public final class AmbientContextEvent implements Parcelable {
        EVENT_UNKNOWN,
        EVENT_COUGH,
        EVENT_SNORE,
        EVENT_BACK_DOUBLE_TAP
        EVENT_BACK_DOUBLE_TAP,
        EVENT_VENDOR_WEARABLE_START
    })
    @Retention(RetentionPolicy.SOURCE)
    @DataClass.Generated.Member
@@ -177,6 +205,8 @@ public final class AmbientContextEvent implements Parcelable {
                    return "EVENT_SNORE";
            case EVENT_BACK_DOUBLE_TAP:
                    return "EVENT_BACK_DOUBLE_TAP";
            case EVENT_VENDOR_WEARABLE_START:
                    return "EVENT_VENDOR_WEARABLE_START";
            default: return Integer.toHexString(value);
        }
    }
@@ -220,7 +250,8 @@ public final class AmbientContextEvent implements Parcelable {
            @NonNull Instant startTime,
            @NonNull Instant endTime,
            @LevelValue int confidenceLevel,
            @LevelValue int densityLevel) {
            @LevelValue int densityLevel,
            @NonNull PersistableBundle vendorData) {
        this.mEventType = eventType;
        com.android.internal.util.AnnotationValidations.validate(
                EventCode.class, null, mEventType);
@@ -236,6 +267,9 @@ public final class AmbientContextEvent implements Parcelable {
        this.mDensityLevel = densityLevel;
        com.android.internal.util.AnnotationValidations.validate(
                LevelValue.class, null, mDensityLevel);
        this.mVendorData = vendorData;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mVendorData);

        // onConstructed(); // You can define this method to get a callback
    }
@@ -279,6 +313,19 @@ public final class AmbientContextEvent implements Parcelable {
        return mDensityLevel;
    }

    /**
     * Vendor defined specific values for vendor event types.
     *
     * <p> The use of this vendor data is discouraged. For data defined in the range above
     * {@code EVENT_VENDOR_WEARABLE_START} this bundle must include the
     * {@link KEY_VENDOR_WEARABLE_EVENT_NAME} field or it will be rejected. In addition, to increase
     * transparency of this data contents of this bundle will be logged to logcat.</p>
     */
    @DataClass.Generated.Member
    public @NonNull PersistableBundle getVendorData() {
        return mVendorData;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
@@ -290,7 +337,8 @@ public final class AmbientContextEvent implements Parcelable {
                "startTime = " + mStartTime + ", " +
                "endTime = " + mEndTime + ", " +
                "confidenceLevel = " + mConfidenceLevel + ", " +
                "densityLevel = " + mDensityLevel +
                "densityLevel = " + mDensityLevel + ", " +
                "vendorData = " + mVendorData +
        " }";
    }

@@ -327,6 +375,7 @@ public final class AmbientContextEvent implements Parcelable {
        sParcellingForEndTime.parcel(mEndTime, dest, flags);
        dest.writeInt(mConfidenceLevel);
        dest.writeInt(mDensityLevel);
        dest.writeTypedObject(mVendorData, flags);
    }

    @Override
@@ -345,6 +394,7 @@ public final class AmbientContextEvent implements Parcelable {
        Instant endTime = sParcellingForEndTime.unparcel(in);
        int confidenceLevel = in.readInt();
        int densityLevel = in.readInt();
        PersistableBundle vendorData = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR);

        this.mEventType = eventType;
        com.android.internal.util.AnnotationValidations.validate(
@@ -361,6 +411,9 @@ public final class AmbientContextEvent implements Parcelable {
        this.mDensityLevel = densityLevel;
        com.android.internal.util.AnnotationValidations.validate(
                LevelValue.class, null, mDensityLevel);
        this.mVendorData = vendorData;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mVendorData);

        // onConstructed(); // You can define this method to get a callback
    }
@@ -391,6 +444,7 @@ public final class AmbientContextEvent implements Parcelable {
        private @NonNull Instant mEndTime;
        private @LevelValue int mConfidenceLevel;
        private @LevelValue int mDensityLevel;
        private @NonNull PersistableBundle mVendorData;

        private long mBuilderFieldsSet = 0L;

@@ -451,10 +505,26 @@ public final class AmbientContextEvent implements Parcelable {
            return this;
        }

        /**
         * Vendor defined specific values for vendor event types.
         *
         * <p> The use of this vendor data is discouraged. For data defined in the range above
         * {@code EVENT_VENDOR_WEARABLE_START} this bundle must include the
         * {@link KEY_VENDOR_WEARABLE_EVENT_NAME} field or it will be rejected. In addition, to increase
         * transparency of this data contents of this bundle will be logged to logcat.</p>
         */
        @DataClass.Generated.Member
        public @NonNull Builder setVendorData(@NonNull PersistableBundle value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x20;
            mVendorData = value;
            return this;
        }

        /** Builds the instance. This builder should not be touched after calling this! */
        public @NonNull AmbientContextEvent build() {
            checkNotUsed();
            mBuilderFieldsSet |= 0x20; // Mark builder used
            mBuilderFieldsSet |= 0x40; // Mark builder used

            if ((mBuilderFieldsSet & 0x1) == 0) {
                mEventType = defaultEventType();
@@ -471,17 +541,21 @@ public final class AmbientContextEvent implements Parcelable {
            if ((mBuilderFieldsSet & 0x10) == 0) {
                mDensityLevel = defaultDensityLevel();
            }
            if ((mBuilderFieldsSet & 0x20) == 0) {
                mVendorData = defaultVendorData();
            }
            AmbientContextEvent o = new AmbientContextEvent(
                    mEventType,
                    mStartTime,
                    mEndTime,
                    mConfidenceLevel,
                    mDensityLevel);
                    mDensityLevel,
                    mVendorData);
            return o;
        }

        private void checkNotUsed() {
            if ((mBuilderFieldsSet & 0x20) != 0) {
            if ((mBuilderFieldsSet & 0x40) != 0) {
                throw new IllegalStateException(
                        "This Builder should not be reused. Use a new Builder instance instead");
            }
@@ -489,10 +563,10 @@ public final class AmbientContextEvent implements Parcelable {
    }

    @DataClass.Generated(
            time = 1659950304931L,
            time = 1671217108067L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/app/ambientcontext/AmbientContextEvent.java",
            inputSignatures = "public static final  int EVENT_UNKNOWN\npublic static final  int EVENT_COUGH\npublic static final  int EVENT_SNORE\npublic static final  int EVENT_BACK_DOUBLE_TAP\npublic static final  int LEVEL_UNKNOWN\npublic static final  int LEVEL_LOW\npublic static final  int LEVEL_MEDIUM_LOW\npublic static final  int LEVEL_MEDIUM\npublic static final  int LEVEL_MEDIUM_HIGH\npublic static final  int LEVEL_HIGH\nprivate final @android.app.ambientcontext.AmbientContextEvent.EventCode int mEventType\nprivate final @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) @android.annotation.NonNull java.time.Instant mStartTime\nprivate final @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) @android.annotation.NonNull java.time.Instant mEndTime\nprivate final @android.app.ambientcontext.AmbientContextEvent.LevelValue int mConfidenceLevel\nprivate final @android.app.ambientcontext.AmbientContextEvent.LevelValue int mDensityLevel\nprivate static  int defaultEventType()\nprivate static @android.annotation.NonNull java.time.Instant defaultStartTime()\nprivate static @android.annotation.NonNull java.time.Instant defaultEndTime()\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultDensityLevel()\nclass AmbientContextEvent extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=false, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
            inputSignatures = "public static final  int EVENT_UNKNOWN\npublic static final  int EVENT_COUGH\npublic static final  int EVENT_SNORE\npublic static final  int EVENT_BACK_DOUBLE_TAP\npublic static final  int EVENT_VENDOR_WEARABLE_START\npublic static final  java.lang.String KEY_VENDOR_WEARABLE_EVENT_NAME\npublic static final  int LEVEL_UNKNOWN\npublic static final  int LEVEL_LOW\npublic static final  int LEVEL_MEDIUM_LOW\npublic static final  int LEVEL_MEDIUM\npublic static final  int LEVEL_MEDIUM_HIGH\npublic static final  int LEVEL_HIGH\nprivate final @android.app.ambientcontext.AmbientContextEvent.EventCode int mEventType\nprivate final @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) @android.annotation.NonNull java.time.Instant mStartTime\nprivate final @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) @android.annotation.NonNull java.time.Instant mEndTime\nprivate final @android.app.ambientcontext.AmbientContextEvent.LevelValue int mConfidenceLevel\nprivate final @android.app.ambientcontext.AmbientContextEvent.LevelValue int mDensityLevel\nprivate final @android.annotation.NonNull android.os.PersistableBundle mVendorData\nprivate static  int defaultEventType()\nprivate static @android.annotation.NonNull java.time.Instant defaultStartTime()\nprivate static @android.annotation.NonNull java.time.Instant defaultEndTime()\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultDensityLevel()\nprivate static  android.os.PersistableBundle defaultVendorData()\nclass AmbientContextEvent extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=false, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
    @Deprecated
    private void __metadata() {}

+14 −1
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ public final class AmbientContextManager {
     */
    @NonNull public static List<AmbientContextEvent> getEventsFromIntent(@NonNull Intent intent) {
        if (intent.hasExtra(AmbientContextManager.EXTRA_AMBIENT_CONTEXT_EVENTS)) {
            return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS, android.app.ambientcontext.AmbientContextEvent.class);
            return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS,
                    android.app.ambientcontext.AmbientContextEvent.class);
        } else {
            return new ArrayList<>();
        }
@@ -143,6 +144,9 @@ public final class AmbientContextManager {
     * If any of the events are not consented by user, the response has
     * {@link AmbientContextManager#STATUS_ACCESS_DENIED}, and the app can
     * call {@link #startConsentActivity} to redirect the user to the consent screen.
     * If the AmbientContextRequest contains a mixed set of events containing values both greater
     * than and less than {@link AmbientContextEvent.EVENT_VENDOR_WEARABLE_START}, the request
     * will be rejected with {@link AmbientContextManager#STATUS_NOT_SUPPORTED}.
     * <p />
     *
     * Example:
@@ -197,6 +201,9 @@ public final class AmbientContextManager {

    /**
     * Requests the consent data host to open an activity that allows users to modify consent.
     * If the eventTypes contains a mixed set of events containing values both greater than and less
     * than {@link AmbientContextEvent.EVENT_VENDOR_WEARABLE_START}, the request will be rejected
     * with {@link AmbientContextManager#STATUS_NOT_SUPPORTED}.
     *
     * @param eventTypes The set of event codes to be consented.
     */
@@ -226,6 +233,9 @@ public final class AmbientContextManager {
     * observer receives a callback on the provided {@link PendingIntent} when the requested
     * event is detected. Registering another observer from the same package that has already been
     * registered will override the previous observer.
     * If the AmbientContextRequest contains a mixed set of events containing values both greater
     * than and less than {@link AmbientContextEvent.EVENT_VENDOR_WEARABLE_START}, the request
     * will be rejected with {@link AmbientContextManager#STATUS_NOT_SUPPORTED}.
     * <p />
     *
     * Example:
@@ -308,6 +318,9 @@ public final class AmbientContextManager {
     * {@link #registerObserver(AmbientContextEventRequest, PendingIntent, Executor, Consumer)},
     * the previous observer will be replaced with the new observer with the PendingIntent callback.
     * Or vice versa.
     * If the AmbientContextRequest contains a mixed set of events containing values both greater
     * than and less than {@link AmbientContextEvent.EVENT_VENDOR_WEARABLE_START}, the request
     * will be rejected with {@link AmbientContextManager#STATUS_NOT_SUPPORTED}.
     *
     * When the registration completes, a status will be returned to client through
     * {@link AmbientContextCallback#onRegistrationComplete(int)}.
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.service.wearable;

import android.app.ambientcontext.AmbientContextEventRequest;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.SharedMemory;
@@ -29,4 +30,8 @@ import android.os.SharedMemory;
oneway interface IWearableSensingService {
    void provideDataStream(in ParcelFileDescriptor parcelFileDescriptor, in RemoteCallback callback);
    void provideData(in PersistableBundle data, in SharedMemory sharedMemory, in RemoteCallback callback);
    void startDetection(in AmbientContextEventRequest request, in String packageName,
            in RemoteCallback detectionResultCallback, in RemoteCallback statusCallback);
    void stopDetection(in String packageName);
    void queryServiceStatus(in int[] eventTypes, in String packageName, in RemoteCallback callback);
}
 No newline at end of file
+117 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.app.ambientcontext.AmbientContextEvent;
import android.app.ambientcontext.AmbientContextEventRequest;
import android.app.wearable.WearableSensingManager;
import android.content.Intent;
import android.os.Bundle;
@@ -30,9 +31,14 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.SharedMemory;
import android.service.ambientcontext.AmbientContextDetectionResult;
import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
import android.util.Slog;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;

/**
@@ -116,6 +122,60 @@ public abstract class WearableSensingService extends Service {
                    };
                    WearableSensingService.this.onDataProvided(data, sharedMemory, consumer);
                }

                /** {@inheritDoc} */
                @Override
                public void startDetection(@NonNull AmbientContextEventRequest request,
                        String packageName, RemoteCallback detectionResultCallback,
                        RemoteCallback statusCallback) {
                    Objects.requireNonNull(request);
                    Objects.requireNonNull(packageName);
                    Objects.requireNonNull(detectionResultCallback);
                    Objects.requireNonNull(statusCallback);
                    Consumer<AmbientContextDetectionResult> detectionResultConsumer = result -> {
                        Bundle bundle = new Bundle();
                        bundle.putParcelable(
                                AmbientContextDetectionResult.RESULT_RESPONSE_BUNDLE_KEY, result);
                        detectionResultCallback.sendResult(bundle);
                    };
                    Consumer<AmbientContextDetectionServiceStatus> statusConsumer = status -> {
                        Bundle bundle = new Bundle();
                        bundle.putParcelable(
                                AmbientContextDetectionServiceStatus.STATUS_RESPONSE_BUNDLE_KEY,
                                status);
                        statusCallback.sendResult(bundle);
                    };
                    WearableSensingService.this.onStartDetection(
                            request, packageName, statusConsumer, detectionResultConsumer);
                    Slog.d(TAG, "startDetection " + request);
                }

                /** {@inheritDoc} */
                @Override
                public void stopDetection(String packageName) {
                    Objects.requireNonNull(packageName);
                    WearableSensingService.this.onStopDetection(packageName);
                }

                /** {@inheritDoc} */
                @Override
                public void queryServiceStatus(@AmbientContextEvent.EventCode int[] eventTypes,
                        String packageName, RemoteCallback callback) {
                    Objects.requireNonNull(eventTypes);
                    Objects.requireNonNull(packageName);
                    Objects.requireNonNull(callback);
                    Consumer<AmbientContextDetectionServiceStatus> consumer = response -> {
                        Bundle bundle = new Bundle();
                        bundle.putParcelable(
                                AmbientContextDetectionServiceStatus.STATUS_RESPONSE_BUNDLE_KEY,
                                response);
                        callback.sendResult(bundle);
                    };
                    Integer[] events = intArrayToIntegerArray(eventTypes);
                    WearableSensingService.this.onQueryServiceStatus(
                            new HashSet<>(Arrays.asList(events)), packageName, consumer);
                }

            };
        }
        Slog.w(TAG, "Incorrect service interface, returning null.");
@@ -155,4 +215,61 @@ public abstract class WearableSensingService extends Service {
            @NonNull PersistableBundle data,
            @Nullable SharedMemory sharedMemory,
            @NonNull Consumer<Integer> statusConsumer);

    /**
     * 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 batch response.
     * The ongoing detection will keep running, until onStopDetection is called. If there were
     * previously requested detections from the same package, regardless of the type of events in
     * the request, the previous request will be replaced with the new request and pending events
     * are discarded.
     *
     * @param request The request with events to detect.
     * @param packageName the requesting app's package name
     * @param statusConsumer the consumer for the service status.
     * @param detectionResultConsumer the consumer for the detected event
     */
    @BinderThread
    public abstract void onStartDetection(@NonNull AmbientContextEventRequest request,
            @NonNull String packageName,
            @NonNull Consumer<AmbientContextDetectionServiceStatus> statusConsumer,
            @NonNull Consumer<AmbientContextDetectionResult> detectionResultConsumer);

    /**
     * Stops detection of the events. Events that are not being detected will be ignored.
     *
     * @param packageName stops detection for the given package.
     */
    public abstract void onStopDetection(@NonNull String packageName);

    /**
     * Called when a query for the detection status occurs. The implementation should check
     * the detection status of the requested events for the package, and provide results in a
     * {@link AmbientContextDetectionServiceStatus} for the consumer.
     *
     * @param eventTypes The events to check for status.
     * @param packageName the requesting app's package name
     * @param consumer the consumer for the query results
     */
    @BinderThread
    public abstract void onQueryServiceStatus(@NonNull Set<Integer> eventTypes,
            @NonNull String packageName,
            @NonNull Consumer<AmbientContextDetectionServiceStatus> consumer);

    @NonNull
    private static Integer[] intArrayToIntegerArray(@NonNull int[] integerSet) {
        Integer[] intArray = new Integer[integerSet.length];
        int i = 0;
        for (Integer type : integerSet) {
            intArray[i++] = type;
        }
        return intArray;
    }
}
Loading