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 androidx.annotation.IntDef; 20 import androidx.annotation.MainThread; 21 22 import com.google.common.util.concurrent.ListenableFuture; 23 24 import java.lang.annotation.ElementType; 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.lang.annotation.Target; 28 29 // TODO: rework the state and events for vNext 30 31 /** 32 * Interface for the device lock controller state machine. 33 */ 34 @MainThread 35 public interface DeviceStateController { 36 /** 37 * Enforce all policies for the current device state. 38 */ enforcePoliciesForCurrentState()39 ListenableFuture<Void> enforcePoliciesForCurrentState(); 40 41 /** 42 * Moves the device to a new state based on the input event 43 */ setNextStateForEvent(@eviceEvent int event)44 ListenableFuture<Void> setNextStateForEvent(@DeviceEvent int event); 45 46 /** 47 * Returns the current state of the device 48 */ 49 @DeviceState getState()50 int getState(); 51 52 /** 53 * Returns true if the device is in locked state. 54 */ isLocked()55 boolean isLocked(); 56 57 /** 58 * Returns true if the device needs to check in with DeviceLock server 59 */ isCheckInNeeded()60 boolean isCheckInNeeded(); 61 62 /** 63 * Returns true if the device is in setup flow. 64 */ isInSetupState()65 boolean isInSetupState(); 66 67 /** 68 * Register a callback to get notified on state change. 69 */ addCallback(StateListener listener)70 void addCallback(StateListener listener); 71 72 /** 73 * Remove a previously registered callback. 74 */ removeCallback(StateListener listener)75 void removeCallback(StateListener listener); 76 77 /** 78 * Device state definitions 79 */ 80 @Target(ElementType.TYPE_USE) 81 @Retention(RetentionPolicy.SOURCE) 82 @IntDef({ 83 DeviceState.UNPROVISIONED, 84 DeviceState.SETUP_IN_PROGRESS, 85 DeviceState.SETUP_SUCCEEDED, 86 DeviceState.SETUP_FAILED, 87 DeviceState.KIOSK_SETUP, 88 DeviceState.UNLOCKED, 89 DeviceState.LOCKED, 90 DeviceState.CLEARED, 91 DeviceState.PSEUDO_LOCKED, 92 DeviceState.PSEUDO_UNLOCKED, 93 }) 94 @interface DeviceState { 95 96 /* DLC is not provisioned */ 97 int UNPROVISIONED = 0; 98 99 /* Setup flow is in progress. This is where kiosk app will be downloaded. */ 100 int SETUP_IN_PROGRESS = 1; 101 102 /* Setup has succeeded */ 103 int SETUP_SUCCEEDED = 2; 104 105 /* Setup has failed */ 106 int SETUP_FAILED = 3; 107 108 /* Showing kiosk setup activity */ 109 int KIOSK_SETUP = 4; 110 111 /* Device is unlocked */ 112 int UNLOCKED = 5; 113 114 /* Device is locked */ 115 int LOCKED = 6; 116 117 /* Fully cleared from locking */ 118 int CLEARED = 7; 119 120 /* Device appears to be locked. No Actual locking is performed. Used for testing */ 121 int PSEUDO_LOCKED = 8; 122 123 /* Device appears to be unlocked. No Actual unlocking is performed. Used for testing */ 124 int PSEUDO_UNLOCKED = 9; 125 } 126 127 /** 128 * Get the corresponding string for input {@link DeviceState}. 129 */ stateToString(@eviceState int state)130 static String stateToString(@DeviceState int state) { 131 switch (state) { 132 case DeviceState.UNPROVISIONED: 133 return "UNPROVISIONED"; 134 case DeviceState.SETUP_IN_PROGRESS: 135 return "SETUP_IN_PROGRESS"; 136 case DeviceState.SETUP_SUCCEEDED: 137 return "SETUP_SUCCEEDED"; 138 case DeviceState.SETUP_FAILED: 139 return "SETUP_FAILED"; 140 case DeviceState.KIOSK_SETUP: 141 return "KIOSK_SETUP"; 142 case DeviceState.UNLOCKED: 143 return "UNLOCKED"; 144 case DeviceState.LOCKED: 145 return "LOCKED"; 146 case DeviceState.CLEARED: 147 return "CLEARED"; 148 case DeviceState.PSEUDO_LOCKED: 149 return "PSEUDO_LOCKED"; 150 case DeviceState.PSEUDO_UNLOCKED: 151 return "PSEUDO_UNLOCKED"; 152 default: 153 return "UNKNOWN_STATE"; 154 } 155 } 156 157 158 /** 159 * Device event definitions 160 */ 161 @Retention(RetentionPolicy.SOURCE) 162 @IntDef({ 163 DeviceEvent.PROVISIONING_SUCCESS, 164 DeviceEvent.SETUP_SUCCESS, 165 DeviceEvent.SETUP_FAILURE, 166 DeviceEvent.SETUP_COMPLETE, 167 DeviceEvent.LOCK_DEVICE, 168 DeviceEvent.UNLOCK_DEVICE, 169 DeviceEvent.CLEAR, 170 }) 171 @interface DeviceEvent { 172 173 /* App provisioned */ 174 int PROVISIONING_SUCCESS = 0; 175 176 /* Setup completed successfully */ 177 int SETUP_SUCCESS = 1; 178 179 /* Setup failed to complete */ 180 int SETUP_FAILURE = 2; 181 182 /* Setup has complete */ 183 int SETUP_COMPLETE = 3; 184 185 /* Lock device */ 186 int LOCK_DEVICE = 4; 187 188 /* Unlock device */ 189 int UNLOCK_DEVICE = 5; 190 191 /* Clear device lock restrictions */ 192 int CLEAR = 6; 193 } 194 195 /** 196 * Listener interface for state changes. 197 */ 198 interface StateListener { 199 /** 200 * Notified after the device transitions to a new state 201 */ onStateChanged(@eviceState int newState)202 ListenableFuture<Void> onStateChanged(@DeviceState int newState); 203 } 204 205 206 /** 207 * Get the corresponding string for the input {@link DeviceEvent} 208 */ eventToString(@eviceEvent int event)209 static String eventToString(@DeviceEvent int event) { 210 switch (event) { 211 case DeviceEvent.PROVISIONING_SUCCESS: 212 return "PROVISIONING_SUCCESS"; 213 case DeviceEvent.SETUP_SUCCESS: 214 return "SETUP_SUCCESS"; 215 case DeviceEvent.SETUP_FAILURE: 216 return "SETUP_FAILURE"; 217 case DeviceEvent.SETUP_COMPLETE: 218 return "SETUP_COMPLETE"; 219 case DeviceEvent.LOCK_DEVICE: 220 return "LOCK_DEVICE"; 221 case DeviceEvent.UNLOCK_DEVICE: 222 return "UNLOCK_DEVICE"; 223 case DeviceEvent.CLEAR: 224 return "CLEAR"; 225 default: 226 return "UNKNOWN_EVENT"; 227 } 228 } 229 } 230