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