1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
/*
* 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);
}
|