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.policy; 18 19 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState; 20 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.CLEARED; 21 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.KIOSK_SETUP; 22 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.LOCKED; 23 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PSEUDO_LOCKED; 24 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PSEUDO_UNLOCKED; 25 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_FAILED; 26 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_IN_PROGRESS; 27 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_SUCCEEDED; 28 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.UNLOCKED; 29 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.UNPROVISIONED; 30 31 import android.content.Context; 32 import android.os.OutcomeReceiver; 33 34 import androidx.concurrent.futures.CallbackToFutureAdapter; 35 36 import com.android.devicelockcontroller.SystemDeviceLockManager; 37 import com.android.devicelockcontroller.storage.SetupParametersClient; 38 import com.android.devicelockcontroller.storage.SetupParametersClientInterface; 39 import com.android.devicelockcontroller.util.LogUtil; 40 41 import com.google.common.util.concurrent.Futures; 42 import com.google.common.util.concurrent.ListenableFuture; 43 import com.google.common.util.concurrent.MoreExecutors; 44 45 /** Handles kiosk app role. */ 46 public final class RolePolicyHandler implements PolicyHandler { 47 private static final String TAG = "RolePolicyHandler"; 48 49 private final Context mContext; 50 private final SystemDeviceLockManager mSystemDeviceLockManager; 51 private final SetupParametersClientInterface mSetupParametersClient; 52 RolePolicyHandler(Context context, SystemDeviceLockManager systemDeviceLockManager)53 RolePolicyHandler(Context context, SystemDeviceLockManager systemDeviceLockManager) { 54 mContext = context; 55 mSystemDeviceLockManager = systemDeviceLockManager; 56 mSetupParametersClient = SetupParametersClient.getInstance(); 57 } 58 59 private ListenableFuture<@ResultType Integer> getAddFinancedDeviceLockKioskRoleFuture(String packageName)60 getAddFinancedDeviceLockKioskRoleFuture(String packageName) { 61 return CallbackToFutureAdapter.getFuture( 62 completer -> { 63 mSystemDeviceLockManager.addFinancedDeviceKioskRole(packageName, 64 mContext.getMainExecutor(), 65 new OutcomeReceiver<>() { 66 @Override 67 public void onResult(Void result) { 68 completer.set(SUCCESS); 69 } 70 71 @Override 72 public void onError(Exception ex) { 73 LogUtil.e(TAG, "Failed to add financed device kiosk role", 74 ex); 75 completer.set(FAILURE); 76 } 77 }); 78 // Used only for debugging. 79 return "getAddFinancedDeviceLockKioskRoleFuture"; 80 }); 81 } 82 83 private ListenableFuture<@ResultType Integer> 84 getAddFinancedDeviceLockKioskRoleFuture() { 85 return Futures.transformAsync(mSetupParametersClient.getKioskPackage(), 86 kioskPackageName -> kioskPackageName == null 87 ? Futures.immediateFuture(FAILURE) 88 : getAddFinancedDeviceLockKioskRoleFuture(kioskPackageName), 89 MoreExecutors.directExecutor()); 90 } 91 92 private ListenableFuture<@ResultType Integer> 93 getRemoveFinancedDeviceLockKioskRoleFuture(String packageName) { 94 return CallbackToFutureAdapter.getFuture( 95 completer -> { 96 mSystemDeviceLockManager.removeFinancedDeviceKioskRole(packageName, 97 mContext.getMainExecutor(), 98 new OutcomeReceiver<>() { 99 @Override 100 public void onResult(Void result) { 101 completer.set(SUCCESS); 102 } 103 104 @Override 105 public void onError(Exception ex) { 106 LogUtil.e(TAG, "Failed to remove financed device kiosk role", 107 ex); 108 completer.set(FAILURE); 109 } 110 }); 111 // Used only for debugging. 112 return "getRemoveFinancedDeviceLockKioskRoleFuture"; 113 }); 114 } 115 116 private ListenableFuture<@ResultType Integer> 117 getRemoveFinancedDeviceLockKioskRoleFuture() { 118 return Futures.transformAsync(mSetupParametersClient.getKioskPackage(), 119 kioskPackageName -> kioskPackageName == null 120 ? Futures.immediateFuture(FAILURE) 121 : getRemoveFinancedDeviceLockKioskRoleFuture(kioskPackageName), 122 MoreExecutors.directExecutor()); 123 } 124 125 @Override 126 public ListenableFuture<@ResultType Integer> setPolicyForState(@DeviceState int state) { 127 switch (state) { 128 case UNPROVISIONED: 129 case KIOSK_SETUP: 130 case UNLOCKED: 131 case LOCKED: 132 case SETUP_IN_PROGRESS: 133 case SETUP_FAILED: 134 case PSEUDO_LOCKED: 135 case PSEUDO_UNLOCKED: 136 return Futures.immediateFuture(SUCCESS); 137 case SETUP_SUCCEEDED: 138 return getAddFinancedDeviceLockKioskRoleFuture(); 139 case CLEARED: 140 return getRemoveFinancedDeviceLockKioskRoleFuture(); 141 default: 142 return Futures.immediateFailedFuture( 143 new IllegalStateException(String.valueOf(state))); 144 } 145 } 146 } 147