• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 com.android.devicelockcontroller.storage;
18 
19 import static com.android.devicelockcontroller.storage.IGlobalParametersService.Stub.asInterface;
20 
21 import android.annotation.SuppressLint;
22 import android.content.ComponentName;
23 import android.content.Context;
24 
25 import androidx.annotation.GuardedBy;
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import androidx.annotation.VisibleForTesting;
29 
30 import com.android.devicelockcontroller.DeviceLockControllerApplication;
31 import com.android.devicelockcontroller.common.DeviceLockConstants.DeviceProvisionState;
32 
33 import com.google.common.util.concurrent.ListenableFuture;
34 import com.google.common.util.concurrent.ListeningExecutorService;
35 import com.google.common.util.concurrent.MoreExecutors;
36 
37 import java.util.List;
38 import java.util.concurrent.Executors;
39 
40 /**
41  * A class used to access Global Parameters from any user.
42  */
43 public final class GlobalParametersClient extends DlcClient {
44 
45     private static final Object sInstanceLock = new Object();
46 
47     @SuppressLint("StaticFieldLeak") // Only holds application context.
48     @GuardedBy("sInstanceLock")
49     private static GlobalParametersClient sClient;
50 
GlobalParametersClient(@onNull Context context, ListeningExecutorService executorService)51     private GlobalParametersClient(@NonNull Context context,
52             ListeningExecutorService executorService) {
53         super(context, new ComponentName(context, GlobalParametersService.class), executorService);
54     }
55 
56     /**
57      * Get the GlobalParametersClient singleton instance.
58      */
getInstance()59     public static GlobalParametersClient getInstance() {
60         return getInstance(DeviceLockControllerApplication.getAppContext(),
61                 /* executorService= */ null);
62     }
63 
64     /**
65      * Get the GlobalParametersClient singleton instance.
66      */
67     @VisibleForTesting
getInstance(Context appContext, @Nullable ListeningExecutorService executorService)68     public static GlobalParametersClient getInstance(Context appContext,
69             @Nullable ListeningExecutorService executorService) {
70         synchronized (sInstanceLock) {
71             if (sClient == null) {
72                 sClient = new GlobalParametersClient(
73                         appContext,
74                         executorService == null
75                                 ? MoreExecutors.listeningDecorator(Executors.newCachedThreadPool())
76                                 : executorService);
77             }
78             return sClient;
79         }
80     }
81 
82     /**
83      * Reset the Client singleton instance
84      */
85     @VisibleForTesting
reset()86     public static void reset() {
87         synchronized (sInstanceLock) {
88             if (sClient != null) {
89                 sClient.tearDown();
90                 sClient = null;
91             }
92         }
93     }
94 
95     /**
96      * Clear any existing global parameters.
97      * Note that this API can only be called in debuggable build for debugging purpose.
98      */
99     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
clear()100     public ListenableFuture<Void> clear() {
101         return call(() -> {
102             asInterface(getService()).clear();
103             return null;
104         });
105     }
106 
107     /**
108      * Gets the list of packages allowlisted in lock task mode.
109      *
110      * @return List of packages that are allowed in lock task mode.
111      */
112     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
getLockTaskAllowlist()113     public ListenableFuture<List<String>> getLockTaskAllowlist() {
114         return call(() -> asInterface(getService()).getLockTaskAllowlist());
115     }
116 
117     /**
118      * Sets the list of packages allowlisted in lock task mode.
119      *
120      * @param allowlist List of packages that are allowed in lock task mode.
121      */
122     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
setLockTaskAllowlist(List<String> allowlist)123     public ListenableFuture<Void> setLockTaskAllowlist(List<String> allowlist) {
124         return call(() -> {
125             asInterface(getService()).setLockTaskAllowlist(allowlist);
126             return null;
127         });
128     }
129 
130     /**
131      * Checks if a check-in request needs to be performed.
132      *
133      * @return true if check-in request needs to be performed.
134      */
135     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
136     public ListenableFuture<Boolean> needCheckIn() {
137         return call(() -> asInterface(getService()).needCheckIn());
138     }
139 
140     /**
141      * Sets the value of whether this device needs to perform check-in request.
142      *
143      * @param needCheckIn new state of whether the device needs to perform check-in request.
144      */
145     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
146     public ListenableFuture<Void> setNeedCheckIn(boolean needCheckIn) {
147         return call(() -> {
148             asInterface(getService()).setNeedCheckIn(needCheckIn);
149             return null;
150         });
151     }
152 
153     /**
154      * Gets the unique identifier that is regisered to DeviceLock backend server.
155      *
156      * @return The registered device unique identifier; null if device has never checked in with
157      * backed server.
158      */
159     @Nullable
160     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
161     public ListenableFuture<String> getRegisteredDeviceId() {
162         return call(() -> asInterface(getService()).getRegisteredDeviceId());
163     }
164 
165     /**
166      * Set the unique identifier that is registered to DeviceLock backend server.
167      *
168      * @param registeredDeviceId The registered device unique identifier.
169      */
170     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
171     public ListenableFuture<Void> setRegisteredDeviceId(String registeredDeviceId) {
172         return call(() -> {
173             asInterface(getService()).setRegisteredDeviceId(registeredDeviceId);
174             return null;
175         });
176     }
177 
178     /**
179      * Check if provision should be forced.
180      *
181      * @return True if the provision should be forced without any delays.
182      */
183     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
184     public ListenableFuture<Boolean> isProvisionForced() {
185         return call(() -> asInterface(getService()).isProvisionForced());
186     }
187 
188     /**
189      * Set provision is forced
190      *
191      * @param isForced The new value of the forced provision flag.
192      */
193     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
194     public ListenableFuture<Void> setProvisionForced(boolean isForced) {
195         return call(() -> {
196             asInterface(getService()).setProvisionForced(isForced);
197             return null;
198         });
199     }
200 
201     /**
202      * Get the enrollment token assigned by the Device Lock backend server.
203      *
204      * @return A string value of the enrollment token.
205      */
206     @Nullable
207     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
208     public ListenableFuture<String> getEnrollmentToken() {
209         return call(() -> asInterface(getService()).getEnrollmentToken());
210     }
211 
212     /**
213      * Set the enrollment token assigned by the Device Lock backend server.
214      *
215      * @param token The string value of the enrollment token.
216      */
217     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
218     public ListenableFuture<Void> setEnrollmentToken(String token) {
219         return call(() -> {
220             asInterface(getService()).setEnrollmentToken(token);
221             return null;
222         });
223     }
224 
225     /**
226      * Get the kiosk app signature.
227      *
228      * @return the kiosk app signature.
229      */
230     @Nullable
231     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
232     public ListenableFuture<String> getKioskSignature() {
233         return call(() -> asInterface(getService()).getKioskSignature());
234     }
235 
236     /**
237      * Sets the kiosk app signature.
238      *
239      * @param signature Kiosk app signature.
240      */
241     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
242     public ListenableFuture<Void> setKioskSignature(String signature) {
243         return call(() -> {
244             asInterface(getService()).setKioskSignature(signature);
245             return null;
246         });
247     }
248 
249     /**
250      * Get the last received provision state determined by device lock server.
251      *
252      * @return one of {@link DeviceProvisionState}.
253      */
254     public ListenableFuture<Integer> getLastReceivedProvisionState() {
255         return call(() -> asInterface(getService()).getLastReceivedProvisionState());
256     }
257 
258     /**
259      * Set the last received provision state determined by device lock server.
260      *
261      * @param provisionState The provision state determined by device lock server
262      */
263     public ListenableFuture<Void> setLastReceivedProvisionState(
264             @DeviceProvisionState int provisionState) {
265         return call(() -> {
266             asInterface(getService()).setLastReceivedProvisionState(provisionState);
267             return null;
268         });
269     }
270 }
271