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.policy; 18 19 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.CLEARED; 20 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.KIOSK_SETUP; 21 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.LOCKED; 22 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PSEUDO_LOCKED; 23 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PSEUDO_UNLOCKED; 24 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_FAILED; 25 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_IN_PROGRESS; 26 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.SETUP_SUCCEEDED; 27 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.UNLOCKED; 28 import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.UNPROVISIONED; 29 30 import android.app.admin.DevicePolicyManager; 31 import android.content.Context; 32 33 import com.android.devicelockcontroller.policy.DeviceStateController.DeviceState; 34 import com.android.devicelockcontroller.storage.SetupParametersClient; 35 import com.android.devicelockcontroller.util.LogUtil; 36 37 import com.google.common.util.concurrent.Futures; 38 import com.google.common.util.concurrent.ListenableFuture; 39 import com.google.common.util.concurrent.MoreExecutors; 40 41 import java.util.ArrayList; 42 import java.util.List; 43 44 /** Enforces restrictions on Kiosk app and controller. */ 45 final class PackagePolicyHandler implements PolicyHandler { 46 private static final String TAG = "PackagePolicyHandler"; 47 48 private final Context mContext; 49 private final DevicePolicyManager mDpm; 50 PackagePolicyHandler(Context context, DevicePolicyManager dpm)51 PackagePolicyHandler(Context context, DevicePolicyManager dpm) { 52 mContext = context; 53 mDpm = dpm; 54 } 55 56 @Override setPolicyForState(@eviceState int state)57 public ListenableFuture<@ResultType Integer> setPolicyForState(@DeviceState int state) { 58 switch (state) { 59 case KIOSK_SETUP: 60 case UNLOCKED: 61 case LOCKED: 62 return enablePackageProtection(true /* enableForKiosk */, state); 63 case CLEARED: 64 case UNPROVISIONED: 65 return enablePackageProtection(false /* enableForKiosk */, state); 66 case SETUP_IN_PROGRESS: 67 case SETUP_SUCCEEDED: 68 case SETUP_FAILED: 69 case PSEUDO_LOCKED: 70 case PSEUDO_UNLOCKED: 71 return Futures.immediateFuture(SUCCESS); 72 default: 73 return Futures.immediateFailedFuture( 74 new IllegalStateException(String.valueOf(state))); 75 } 76 } 77 enablePackageProtection(boolean enableForKiosk, @DeviceState int state)78 private ListenableFuture<@ResultType Integer> enablePackageProtection(boolean enableForKiosk, 79 @DeviceState int state) { 80 return Futures.transform(SetupParametersClient.getInstance().getKioskPackage(), 81 kioskPackageName -> { 82 if (kioskPackageName == null) { 83 LogUtil.d(TAG, "Kiosk package is not set for state: " + state); 84 } else { 85 try { 86 mDpm.setUninstallBlocked(null /* admin */, kioskPackageName, 87 enableForKiosk); 88 } catch (SecurityException e) { 89 LogUtil.e(TAG, "Unable to set device policy", e); 90 return FAILURE; 91 } 92 } 93 94 final List<String> pkgList = new ArrayList<>(); 95 96 // The controller itself should always have user control disabled 97 pkgList.add(mContext.getPackageName()); 98 99 if (kioskPackageName != null && enableForKiosk) { 100 pkgList.add(kioskPackageName); 101 } 102 103 try { 104 mDpm.setUserControlDisabledPackages(null /* admin */, pkgList); 105 } catch (SecurityException e) { 106 LogUtil.e(TAG, "Failed to setUserControlDisabledPackages", e); 107 return FAILURE; 108 } 109 110 return SUCCESS; 111 }, MoreExecutors.directExecutor()); 112 } 113 } 114