• 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.ISetupParametersService.Stub.asInterface;
20 
21 import android.annotation.SuppressLint;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.os.Bundle;
25 
26 import androidx.annotation.GuardedBy;
27 import androidx.annotation.NonNull;
28 import androidx.annotation.Nullable;
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.devicelockcontroller.DeviceLockControllerApplication;
32 import com.android.devicelockcontroller.common.DeviceLockConstants.ProvisioningType;
33 
34 import com.google.common.util.concurrent.ListenableFuture;
35 import com.google.common.util.concurrent.ListeningExecutorService;
36 import com.google.common.util.concurrent.MoreExecutors;
37 
38 import java.util.List;
39 import java.util.concurrent.Executors;
40 
41 /**
42  * Class used to access Setup Parameters from any users.
43  * Storage is hosted by user 0 and is accessed indirectly using a service.
44  */
45 public final class SetupParametersClient extends DlcClient
46         implements SetupParametersClientInterface {
47     private static final Object sInstanceLock = new Object();
48 
49     @SuppressLint("StaticFieldLeak") // Only holds application context.
50     @GuardedBy("sInstanceLock")
51     private static SetupParametersClient sClient;
52 
SetupParametersClient(@onNull Context context, ListeningExecutorService executorService)53     private SetupParametersClient(@NonNull Context context,
54             ListeningExecutorService executorService) {
55         super(context, new ComponentName(context, SetupParametersService.class), executorService);
56     }
57 
58     /**
59      * Get the SetupParametersClient singleton instance.
60      */
getInstance()61     public static SetupParametersClient getInstance() {
62         return getInstance(DeviceLockControllerApplication.getAppContext(),
63                 /* executorService= */ null);
64     }
65 
66     /**
67      * Get the SetupParametersClient singleton instance.
68      */
69     @VisibleForTesting
getInstance(Context appContext, @Nullable ListeningExecutorService executorService)70     public static SetupParametersClient getInstance(Context appContext,
71             @Nullable ListeningExecutorService executorService) {
72         synchronized (sInstanceLock) {
73             if (sClient == null) {
74                 sClient = new SetupParametersClient(
75                         appContext,
76                         executorService == null
77                                 ? MoreExecutors.listeningDecorator(Executors.newCachedThreadPool())
78                                 : executorService);
79             }
80             return sClient;
81         }
82     }
83 
84     /**
85      * Reset the Client singleton instance
86      */
87     @VisibleForTesting
reset()88     public static void reset() {
89         synchronized (sInstanceLock) {
90             if (sClient != null) {
91                 sClient.tearDown();
92                 sClient = null;
93             }
94         }
95     }
96 
97     /**
98      * Override setup parameters if there exists any; otherwise create new parameters.
99      * Note that this API can only be called in debuggable build for debugging purpose.
100      */
101     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
overridePrefs(Bundle bundle)102     public ListenableFuture<Void> overridePrefs(Bundle bundle) {
103         return call(() -> {
104             asInterface(getService()).overridePrefs(bundle);
105             return null;
106         });
107     }
108 
109     /**
110      * Clear any existing setup parameters.
111      * Note that this API can only be called in debuggable build for debugging purpose.
112      */
113     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
clear()114     public ListenableFuture<Void> clear() {
115         return call(() -> {
116             asInterface(getService()).clear();
117             return null;
118         });
119     }
120 
121     /**
122      * Parse setup parameters from the extras bundle.
123      *
124      * @param bundle Bundle with provisioning parameters.
125      */
126     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
127     public ListenableFuture<Void> createPrefs(Bundle bundle) {
128         return call(() -> {
129             asInterface(getService()).createPrefs(bundle);
130             return null;
131         });
132     }
133 
134     /**
135      * Get the name of the package implementing the kiosk app.
136      *
137      * @return kiosk app package name.
138      */
139     @Override
140     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
141     public ListenableFuture<String> getKioskPackage() {
142         return call(() -> asInterface(getService()).getKioskPackage());
143     }
144 
145     /**
146      * Get the setup activity for the kiosk app.
147      *
148      * @return Setup activity.
149      */
150     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
151     public ListenableFuture<String> getKioskSetupActivity() {
152         return call(() -> asInterface(getService()).getKioskSetupActivity());
153     }
154 
155     /**
156      * Check if the configuration disables outgoing calls.
157      *
158      * @return True if outgoign calls are disabled.
159      */
160     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
161     public ListenableFuture<Boolean> getOutgoingCallsDisabled() {
162         return call(() -> asInterface(getService()).getOutgoingCallsDisabled());
163     }
164 
165     /**
166      * Get package allowlist provisioned by the server.
167      *
168      * @return List of allowed packages.
169      */
170     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
171     public ListenableFuture<List<String>> getKioskAllowlist() {
172         return call(() -> asInterface(getService()).getKioskAllowlist());
173     }
174 
175     /**
176      * Check if notifications are enabled in lock task mode.
177      *
178      * @return True if notification are enabled.
179      */
180     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
181     public ListenableFuture<Boolean> isNotificationsInLockTaskModeEnabled() {
182         return call(() -> asInterface(getService()).isNotificationsInLockTaskModeEnabled());
183     }
184 
185     /**
186      * Get the provisioning type of this configuration.
187      *
188      * @return The type of provisioning which could be one of {@link ProvisioningType}.
189      */
190     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
191     public ListenableFuture<@ProvisioningType Integer> getProvisioningType() {
192         return call(() -> asInterface(getService()).getProvisioningType());
193     }
194 
195     /**
196      * Check if provision is mandatory.
197      *
198      * @return True if the provision should be mandatory.
199      */
200     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
201     public ListenableFuture<Boolean> isProvisionMandatory() {
202         return call(() -> asInterface(getService()).isProvisionMandatory());
203     }
204 
205     /**
206      * Get the name of the provider of the kiosk app.
207      *
208      * @return the name of the provider.
209      */
210     @Nullable
211     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
212     public ListenableFuture<String> getKioskAppProviderName() {
213         return call(() -> asInterface(getService()).getKioskAppProviderName());
214     }
215 
216     /**
217      * Check if installing from unknown sources should be disallowed on this device after
218      * provision
219      *
220      * @return True if installing from unknown sources is disallowed.
221      */
222     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
223     public ListenableFuture<Boolean> isInstallingFromUnknownSourcesDisallowed() {
224         return call(() -> asInterface(getService()).isInstallingFromUnknownSourcesDisallowed());
225     }
226 
227     /**
228      * Get the Terms and Conditions URL of the partner for enrolling in a Device Lock program.
229      *
230      * @return The URL to the terms and conditions.
231      */
232     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
233     public ListenableFuture<String> getTermsAndConditionsUrl() {
234         return call(() -> asInterface(getService()).getTermsAndConditionsUrl());
235     }
236 
237     /**
238      * The URL to the support page the user can use to get help.
239      *
240      * @return The URL to the support page.
241      */
242     @SuppressWarnings("GuardedBy") // mLock already held in "call" (error prone).
243     public ListenableFuture<String> getSupportUrl() {
244         return call(() -> asInterface(getService()).getSupportUrl());
245     }
246 }
247