• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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;
18 
19 import static com.android.devicelockcontroller.IDeviceLockControllerService.KEY_HARDWARE_ID_RESULT;
20 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceEvent.CLEAR;
21 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceEvent.LOCK_DEVICE;
22 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceEvent.UNLOCK_DEVICE;
23 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PSEUDO_LOCKED;
24 
25 import android.app.Service;
26 import android.content.Intent;
27 import android.os.Bundle;
28 import android.os.IBinder;
29 import android.os.RemoteCallback;
30 
31 import androidx.annotation.NonNull;
32 import androidx.work.WorkManager;
33 
34 import com.android.devicelockcontroller.policy.DevicePolicyController;
35 import com.android.devicelockcontroller.policy.DeviceStateController;
36 import com.android.devicelockcontroller.policy.PolicyObjectsInterface;
37 import com.android.devicelockcontroller.provision.worker.ReportDeviceLockProgramCompleteWorker;
38 import com.android.devicelockcontroller.storage.GlobalParametersClient;
39 import com.android.devicelockcontroller.util.LogUtil;
40 
41 import com.google.common.util.concurrent.FutureCallback;
42 import com.google.common.util.concurrent.Futures;
43 import com.google.common.util.concurrent.MoreExecutors;
44 
45 /**
46  * Device Lock Controller Service. This is hosted in an APK and is bound
47  * by the Device Lock System Service.
48  */
49 public final class DeviceLockControllerService extends Service {
50     private static final String TAG = "DeviceLockControllerService";
51     private DevicePolicyController mPolicyController;
52     private DeviceStateController mStateController;
53 
54     private final IDeviceLockControllerService.Stub mBinder =
55             new IDeviceLockControllerService.Stub() {
56                 @Override
57                 public void lockDevice(RemoteCallback remoteCallback) {
58                     Futures.addCallback(
59                             Futures.transformAsync(
60                                     mStateController.setNextStateForEvent(LOCK_DEVICE),
61                                     (Void unused) -> mStateController.getState() == PSEUDO_LOCKED
62                                             ? Futures.immediateFuture(true)
63                                             : mPolicyController.launchActivityInLockedMode(),
64                                     DeviceLockControllerService.this.getMainExecutor()),
65                             remoteCallbackWrapper(remoteCallback, KEY_LOCK_DEVICE_RESULT),
66                             MoreExecutors.directExecutor());
67                 }
68 
69                 @Override
70                 public void unlockDevice(RemoteCallback remoteCallback) {
71                     Futures.addCallback(
72                             Futures.transform(
73                                     mStateController.setNextStateForEvent(UNLOCK_DEVICE),
74                                     (Void unused) -> true, MoreExecutors.directExecutor()),
75                             remoteCallbackWrapper(remoteCallback, KEY_UNLOCK_DEVICE_RESULT),
76                             MoreExecutors.directExecutor());
77 
78                 }
79 
80                 @Override
81                 public void isDeviceLocked(RemoteCallback remoteCallback) {
82                     final boolean isLocked = mStateController.isLocked();
83                     sendResult(IDeviceLockControllerService.KEY_IS_DEVICE_LOCKED_RESULT,
84                             remoteCallback, isLocked);
85                 }
86 
87                 @Override
88                 public void getDeviceIdentifier(RemoteCallback remoteCallback) {
89                     Futures.addCallback(
90                             GlobalParametersClient.getInstance().getRegisteredDeviceId(),
91                             remoteCallbackWrapper(remoteCallback, KEY_HARDWARE_ID_RESULT),
92                             MoreExecutors.directExecutor());
93                 }
94 
95                 @Override
96                 public void clearDeviceRestrictions(RemoteCallback remoteCallback) {
97                     Futures.addCallback(
98                             Futures.transform(mStateController.setNextStateForEvent(CLEAR),
99                                     (Void unused) -> {
100                                         WorkManager workManager =
101                                                 WorkManager.getInstance(getApplicationContext());
102                                         ReportDeviceLockProgramCompleteWorker
103                                                 .reportDeviceLockProgramComplete(workManager);
104                                         return true;
105                                     }, MoreExecutors.directExecutor()),
106                             remoteCallbackWrapper(remoteCallback, KEY_CLEAR_DEVICE_RESULT),
107                             MoreExecutors.directExecutor());
108 
109                 }
110             };
111 
112     @NonNull
remoteCallbackWrapper(RemoteCallback remoteCallback, final String key)113     private static FutureCallback<Object> remoteCallbackWrapper(RemoteCallback remoteCallback,
114             final String key) {
115         return new FutureCallback<>() {
116             @Override
117             public void onSuccess(Object result) {
118                 sendResult(key, remoteCallback, result);
119             }
120 
121             @Override
122             public void onFailure(Throwable t) {
123                 LogUtil.e(TAG, "Failed to perform the request", t);
124                 sendResult(key, remoteCallback, null);
125             }
126         };
127     }
128 
129     private static void sendResult(String key, RemoteCallback remoteCallback, Object result) {
130         final Bundle bundle = new Bundle();
131         if (result instanceof Boolean) {
132             bundle.putBoolean(key, (Boolean) result);
133         } else if (result instanceof String) {
134             bundle.putString(key, (String) result);
135         }
136         remoteCallback.sendResult(bundle);
137     }
138 
139     @Override
140     public void onCreate() {
141         LogUtil.d(TAG, "onCreate");
142 
143         final PolicyObjectsInterface policyObjects = (PolicyObjectsInterface) getApplication();
144         mStateController = policyObjects.getStateController();
145         mPolicyController = policyObjects.getPolicyController();
146     }
147 
148     @Override
149     public IBinder onBind(Intent intent) {
150         return mBinder;
151     }
152 }
153