1 /*
2  * Copyright (C) 2021 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.hardware.devicestate;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.TestApi;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.util.concurrent.Executor;
26 
27 /**
28  * A request to alter the state of the device managed by {@link DeviceStateManager}.
29  * <p>
30  * Once constructed, a {@link DeviceStateRequest request} can be submitted with a call to
31  * {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
32  * DeviceStateRequest.Callback)}.
33  * <p>
34  * By default, the request is kept active until a call to
35  * {@link DeviceStateManager#cancelStateRequest} or until one of the following occurs:
36  * <ul>
37  *     <li>Another processes submits a request succeeding this request in which case the request
38  *     will be suspended until the interrupting request is canceled.
39  *     <li>The requested state has become unsupported.
40  *     <li>The process submitting the request dies.
41  * </ul>
42  * However, this behavior can be changed by setting flags on the request. For example, the
43  * {@link #FLAG_CANCEL_WHEN_BASE_CHANGES} flag will extend this behavior to also cancel the
44  * request whenever the base (non-override) device state changes.
45  *
46  * @see DeviceStateManager
47  *
48  * @hide
49  */
50 @TestApi
51 public final class DeviceStateRequest {
52     /**
53      * Flag that indicates the request should be canceled automatically when the base
54      * (non-override) device state changes. Useful when the requestor only wants the request to
55      * remain active while the base state remains constant and automatically cancel when the user
56      * manipulates the device into a different state.
57      */
58     public static final int FLAG_CANCEL_WHEN_BASE_CHANGES = 1 << 0;
59 
60     /** @hide */
61     @IntDef(prefix = {"FLAG_"}, flag = true, value = {
62             FLAG_CANCEL_WHEN_BASE_CHANGES,
63     })
64     @Retention(RetentionPolicy.SOURCE)
65     public @interface RequestFlags {}
66 
67     /**
68      * Creates a new {@link Builder} for a {@link DeviceStateRequest}. Must be one of the supported
69      * states for the device which can be queried with a call to
70      * {@link DeviceStateManager#getSupportedStates()}.
71      *
72      * @param requestedState the device state being requested.
73      */
74     @NonNull
newBuilder(int requestedState)75     public static Builder newBuilder(int requestedState) {
76         return new Builder(requestedState);
77     }
78 
79     /**
80      * Builder for {@link DeviceStateRequest}. An instance can be obtained through
81      * {@link #newBuilder(int)}.
82      */
83     public static final class Builder {
84         private final int mRequestedState;
85         private int mFlags;
86 
Builder(int requestedState)87         private Builder(int requestedState) {
88             mRequestedState = requestedState;
89         }
90 
91         /**
92          * Sets the flag bits provided within {@code flags} with all other bits remaining
93          * unchanged.
94          */
95         @NonNull
setFlags(@equestFlags int flags)96         public Builder setFlags(@RequestFlags int flags) {
97             mFlags |= flags;
98             return this;
99         }
100 
101         /**
102          * Returns a new {@link DeviceStateRequest} object whose state matches the state set on the
103          * builder.
104          */
105         @NonNull
build()106         public DeviceStateRequest build() {
107             return new DeviceStateRequest(mRequestedState, mFlags);
108         }
109     }
110 
111     /** Callback to track the status of a request. */
112     public interface Callback {
113         /**
114          * Called to indicate the request has become active and the device state will match the
115          * requested state.
116          * <p>
117          * Guaranteed to be called after a call to
118          * {@link DeviceStateManager.DeviceStateCallback#onDeviceStateChanged(DeviceState)} with a
119          * state matching the requested state.
120          */
onRequestActivated(@onNull DeviceStateRequest request)121         default void onRequestActivated(@NonNull DeviceStateRequest request) {}
122 
123         /**
124          * Called to indicate the request has been temporarily suspended.
125          * <p>
126          * Guaranteed to be called before a call to
127          * {@link DeviceStateManager.DeviceStateCallback#onDeviceStateChanged(DeviceState)}.
128          */
onRequestSuspended(@onNull DeviceStateRequest request)129         default void onRequestSuspended(@NonNull DeviceStateRequest request) {}
130 
131         /**
132          * Called to indicate the request has been canceled. The request can be resubmitted with
133          * another call to {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
134          * DeviceStateRequest.Callback)}.
135          * <p>
136          * Guaranteed to be called before a call to
137          * {@link DeviceStateManager.DeviceStateCallback#onDeviceStateChanged(DeviceState)}.
138          * <p>
139          * Note: A call to {@link #onRequestSuspended(DeviceStateRequest)} is not guaranteed to
140          * occur before this method.
141          */
onRequestCanceled(@onNull DeviceStateRequest request)142         default void onRequestCanceled(@NonNull DeviceStateRequest request) {}
143     }
144 
145     private final int mRequestedState;
146     @RequestFlags
147     private final int mFlags;
148 
DeviceStateRequest(int requestedState, @RequestFlags int flags)149     private DeviceStateRequest(int requestedState, @RequestFlags int flags) {
150         mRequestedState = requestedState;
151         mFlags = flags;
152     }
153 
getState()154     public int getState() {
155         return mRequestedState;
156     }
157 
158     @RequestFlags
getFlags()159     public int getFlags() {
160         return mFlags;
161     }
162 }
163