184 lines
8.3 KiB
Java
184 lines
8.3 KiB
Java
/*
|
|
* 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.service.ambientcontext;
|
|
|
|
import android.annotation.BinderThread;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.SystemApi;
|
|
import android.app.Service;
|
|
import android.app.ambientcontext.AmbientContextEvent;
|
|
import android.app.ambientcontext.AmbientContextEventRequest;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.os.IBinder;
|
|
import android.os.RemoteCallback;
|
|
import android.util.Slog;
|
|
|
|
import java.util.Objects;
|
|
import java.util.function.Consumer;
|
|
|
|
/**
|
|
* Abstract base class for {@link AmbientContextEvent} detection service.
|
|
*
|
|
* <p> A service that provides requested ambient context events to the system.
|
|
* The system's default AmbientContextDetectionService implementation is configured in
|
|
* {@code config_defaultAmbientContextDetectionService}. If this config has no value, a stub is
|
|
* returned.
|
|
*
|
|
* See: {@code AmbientContextManagerService}.
|
|
*
|
|
* <pre>
|
|
* {@literal
|
|
* <service android:name=".YourAmbientContextDetectionService"
|
|
* android:permission="android.permission.BIND_AMBIENT_CONTEXT_DETECTION_SERVICE">
|
|
* </service>}
|
|
* </pre>
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public abstract class AmbientContextDetectionService extends Service {
|
|
private static final String TAG = AmbientContextDetectionService.class.getSimpleName();
|
|
|
|
/**
|
|
* The {@link Intent} that must be declared as handled by the service. To be supported, the
|
|
* service must also require the
|
|
* {@link android.Manifest.permission#BIND_AMBIENT_CONTEXT_DETECTION_SERVICE}
|
|
* permission so that other applications can not abuse it.
|
|
*/
|
|
public static final String SERVICE_INTERFACE =
|
|
"android.service.ambientcontext.AmbientContextDetectionService";
|
|
|
|
@Nullable
|
|
@Override
|
|
public final IBinder onBind(@NonNull Intent intent) {
|
|
if (SERVICE_INTERFACE.equals(intent.getAction())) {
|
|
return new IAmbientContextDetectionService.Stub() {
|
|
/** {@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);
|
|
};
|
|
AmbientContextDetectionService.this.onStartDetection(
|
|
request, packageName, detectionResultConsumer, statusConsumer);
|
|
Slog.d(TAG, "startDetection " + request);
|
|
}
|
|
|
|
/** {@inheritDoc} */
|
|
@Override
|
|
public void stopDetection(String packageName) {
|
|
Objects.requireNonNull(packageName);
|
|
AmbientContextDetectionService.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);
|
|
};
|
|
AmbientContextDetectionService.this.onQueryServiceStatus(
|
|
eventTypes, packageName, consumer);
|
|
}
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @param detectionResultConsumer the consumer for the detected event
|
|
* @param statusConsumer the consumer for the service status.
|
|
*/
|
|
@BinderThread
|
|
public abstract void onStartDetection(
|
|
@NonNull AmbientContextEventRequest request,
|
|
@NonNull String packageName,
|
|
@NonNull Consumer<AmbientContextDetectionResult> detectionResultConsumer,
|
|
@NonNull Consumer<AmbientContextDetectionServiceStatus> statusConsumer);
|
|
|
|
/**
|
|
* 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 int[] eventTypes,
|
|
@NonNull String packageName,
|
|
@NonNull Consumer<AmbientContextDetectionServiceStatus> consumer);
|
|
}
|