1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.attention;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.app.Service;
24 import android.content.Intent;
25 import android.os.IBinder;
26 import android.os.RemoteException;
27 
28 import com.android.internal.util.Preconditions;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 
34 /**
35  * Abstract base class for Attention service.
36  *
37  * <p> An attention service provides attention estimation related features to the system.
38  * The system's default AttentionService implementation is configured in
39  * {@code config_AttentionComponent}. If this config has no value, a stub is returned.
40  *
41  * See: {@link com.android.server.attention.AttentionManagerService}.
42  *
43  * <pre>
44  * {@literal
45  * <service android:name=".YourAttentionService"
46  *          android:permission="android.permission.BIND_ATTENTION_SERVICE">
47  * </service>}
48  * </pre>
49  *
50  * @hide
51  */
52 @SystemApi
53 public abstract class AttentionService extends Service {
54     /**
55      * The {@link Intent} that must be declared as handled by the service. To be supported, the
56      * service must also require the {@link android.Manifest.permission#BIND_ATTENTION_SERVICE}
57      * permission so that other applications can not abuse it.
58      */
59     public static final String SERVICE_INTERFACE =
60             "android.service.attention.AttentionService";
61 
62     /** Attention is absent. */
63     public static final int ATTENTION_SUCCESS_ABSENT = 0;
64 
65     /** Attention is present. */
66     public static final int ATTENTION_SUCCESS_PRESENT = 1;
67 
68     /** Unknown reasons for failing to determine the attention. */
69     public static final int ATTENTION_FAILURE_UNKNOWN = 2;
70 
71     /** Request has been cancelled. */
72     public static final int ATTENTION_FAILURE_CANCELLED = 3;
73 
74     /** Preempted by other client. */
75     public static final int ATTENTION_FAILURE_PREEMPTED = 4;
76 
77     /** Request timed out. */
78     public static final int ATTENTION_FAILURE_TIMED_OUT = 5;
79 
80     /** Camera permission is not granted. */
81     public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6;
82 
83     /**
84      * Result codes for when attention check was successful.
85      *
86      * @hide
87      */
88     @IntDef(prefix = {"ATTENTION_SUCCESS_"}, value = {ATTENTION_SUCCESS_ABSENT,
89             ATTENTION_SUCCESS_PRESENT})
90     @Retention(RetentionPolicy.SOURCE)
91     public @interface AttentionSuccessCodes {
92     }
93 
94     /**
95      * Result codes explaining why attention check was not successful.
96      *
97      * @hide
98      */
99     @IntDef(prefix = {"ATTENTION_FAILURE_"}, value = {ATTENTION_FAILURE_UNKNOWN,
100             ATTENTION_FAILURE_CANCELLED, ATTENTION_FAILURE_PREEMPTED, ATTENTION_FAILURE_TIMED_OUT,
101             ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT})
102     @Retention(RetentionPolicy.SOURCE)
103     public @interface AttentionFailureCodes {
104     }
105 
106     private final IAttentionService.Stub mBinder = new IAttentionService.Stub() {
107 
108         /** {@inheritDoc} */
109         @Override
110         public void checkAttention(IAttentionCallback callback) {
111             Preconditions.checkNotNull(callback);
112             AttentionService.this.onCheckAttention(new AttentionCallback(callback));
113         }
114 
115         /** {@inheritDoc} */
116         @Override
117         public void cancelAttentionCheck(IAttentionCallback callback) {
118             Preconditions.checkNotNull(callback);
119             AttentionService.this.onCancelAttentionCheck(new AttentionCallback(callback));
120         }
121     };
122 
123     @Nullable
124     @Override
onBind(@onNull Intent intent)125     public final IBinder onBind(@NonNull Intent intent) {
126         if (SERVICE_INTERFACE.equals(intent.getAction())) {
127             return mBinder;
128         }
129         return null;
130     }
131 
132     /**
133      * Checks the user attention and calls into the provided callback.
134      *
135      * @param callback the callback to return the result to
136      */
onCheckAttention(@onNull AttentionCallback callback)137     public abstract void onCheckAttention(@NonNull AttentionCallback callback);
138 
139     /**
140      * Cancels pending work for a given callback.
141      *
142      * Implementation must call back with a failure code of {@link #ATTENTION_FAILURE_CANCELLED}.
143      */
onCancelAttentionCheck(@onNull AttentionCallback callback)144     public abstract void onCancelAttentionCheck(@NonNull AttentionCallback callback);
145 
146     /** Callbacks for AttentionService results. */
147     public static final class AttentionCallback {
148         @NonNull private final IAttentionCallback mCallback;
149 
AttentionCallback(@onNull IAttentionCallback callback)150         private AttentionCallback(@NonNull IAttentionCallback callback) {
151             mCallback = callback;
152         }
153 
154         /**
155          * Signals a success and provides the result code.
156          *
157          * @param timestamp of when the attention signal was computed; system throttles the requests
158          *                  so this is useful to know how fresh the result is.
159          */
onSuccess(@ttentionSuccessCodes int result, long timestamp)160         public void onSuccess(@AttentionSuccessCodes int result, long timestamp) {
161             try {
162                 mCallback.onSuccess(result, timestamp);
163             } catch (RemoteException e) {
164                 e.rethrowFromSystemServer();
165             }
166         }
167 
168         /** Signals a failure and provides the error code. */
onFailure(@ttentionFailureCodes int error)169         public void onFailure(@AttentionFailureCodes int error) {
170             try {
171                 mCallback.onFailure(error);
172             } catch (RemoteException e) {
173                 e.rethrowFromSystemServer();
174             }
175         }
176     }
177 }
178