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.server.biometrics.log; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Intent; 22 import android.hardware.biometrics.AuthenticateOptions; 23 import android.hardware.biometrics.IBiometricContextListener; 24 import android.hardware.biometrics.common.AuthenticateReason; 25 import android.hardware.biometrics.common.DisplayState; 26 import android.hardware.biometrics.common.OperationContext; 27 import android.hardware.biometrics.common.OperationReason; 28 import android.hardware.biometrics.common.WakeReason; 29 import android.hardware.face.FaceAuthenticateOptions; 30 import android.hardware.fingerprint.FingerprintAuthenticateOptions; 31 import android.os.PowerManager; 32 import android.view.Surface; 33 34 /** 35 * Wrapper around {@link OperationContext} to include properties that are not 36 * shared with the HAL. 37 * 38 * When useful, these properties should move to the wrapped object for use by HAL in 39 * future releases. 40 */ 41 public class OperationContextExt { 42 43 @NonNull private final OperationContext mAidlContext; 44 @Nullable private BiometricContextSessionInfo mSessionInfo; 45 private boolean mIsDisplayOn = false; 46 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 47 @Surface.Rotation private int mOrientation = Surface.ROTATION_0; 48 private int mFoldState = IBiometricContextListener.FoldState.UNKNOWN; 49 private final boolean mIsBP; 50 51 /** Create a context. */ OperationContextExt(boolean isBP)52 public OperationContextExt(boolean isBP) { 53 this(new OperationContext(), isBP); 54 } 55 56 /** Create a wrapped context. */ OperationContextExt(@onNull OperationContext context, boolean isBP)57 public OperationContextExt(@NonNull OperationContext context, boolean isBP) { 58 mAidlContext = context; 59 mIsBP = isBP; 60 } 61 62 /** 63 * Gets the subset of the context that can be shared with the HAL. 64 * 65 * When starting a new operation use methods like to update & fetch the context: 66 * <ul> 67 * <li>{@link #toAidlContext(FaceAuthenticateOptions)} 68 * <li>{@link #toAidlContext(FingerprintAuthenticateOptions)} 69 * </ul> 70 * 71 * Use this method for any subsequent calls to the HAL or for operations that do 72 * not accept any options. 73 * 74 * @return the underlying AIDL context 75 */ 76 @NonNull toAidlContext()77 public OperationContext toAidlContext() { 78 return mAidlContext; 79 } 80 81 /** 82 * Gets the subset of the context that can be shared with the HAL and updates 83 * it with the given options. 84 * 85 * @param options authenticate options 86 * @return the underlying AIDL context 87 */ 88 @NonNull toAidlContext(@onNull FaceAuthenticateOptions options)89 public OperationContext toAidlContext(@NonNull FaceAuthenticateOptions options) { 90 mAidlContext.authenticateReason = AuthenticateReason 91 .faceAuthenticateReason(getAuthReason(options)); 92 mAidlContext.wakeReason = getWakeReason(options); 93 94 return mAidlContext; 95 } 96 97 /** 98 * Gets the subset of the context that can be shared with the HAL and updates 99 * it with the given options. 100 * 101 * @param options authenticate options 102 * @return the underlying AIDL context 103 */ 104 @NonNull toAidlContext(@onNull FingerprintAuthenticateOptions options)105 public OperationContext toAidlContext(@NonNull FingerprintAuthenticateOptions options) { 106 mAidlContext.authenticateReason = AuthenticateReason 107 .fingerprintAuthenticateReason(getAuthReason(options)); 108 mAidlContext.wakeReason = getWakeReason(options); 109 110 return mAidlContext; 111 } 112 113 @AuthenticateReason.Face getAuthReason(@onNull FaceAuthenticateOptions options)114 private int getAuthReason(@NonNull FaceAuthenticateOptions options) { 115 switch (options.getAuthenticateReason()) { 116 case FaceAuthenticateOptions.AUTHENTICATE_REASON_STARTED_WAKING_UP: 117 return AuthenticateReason.Face.STARTED_WAKING_UP; 118 case FaceAuthenticateOptions.AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN: 119 return AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN; 120 case FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE: 121 return AuthenticateReason.Face.ASSISTANT_VISIBLE; 122 case FaceAuthenticateOptions.AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN: 123 return AuthenticateReason.Face.ALTERNATE_BIOMETRIC_BOUNCER_SHOWN; 124 case FaceAuthenticateOptions.AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED: 125 return AuthenticateReason.Face.NOTIFICATION_PANEL_CLICKED; 126 case FaceAuthenticateOptions.AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED: 127 return AuthenticateReason.Face.OCCLUDING_APP_REQUESTED; 128 case FaceAuthenticateOptions.AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED: 129 return AuthenticateReason.Face.PICK_UP_GESTURE_TRIGGERED; 130 case FaceAuthenticateOptions.AUTHENTICATE_REASON_QS_EXPANDED: 131 return AuthenticateReason.Face.QS_EXPANDED; 132 case FaceAuthenticateOptions.AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER: 133 return AuthenticateReason.Face.SWIPE_UP_ON_BOUNCER; 134 case FaceAuthenticateOptions.AUTHENTICATE_REASON_UDFPS_POINTER_DOWN: 135 return AuthenticateReason.Face.UDFPS_POINTER_DOWN; 136 default: 137 return AuthenticateReason.Face.UNKNOWN; 138 } 139 } 140 141 @WakeReason getWakeReason(@onNull FaceAuthenticateOptions options)142 private int getWakeReason(@NonNull FaceAuthenticateOptions options) { 143 switch (options.getWakeReason()) { 144 case PowerManager.WAKE_REASON_POWER_BUTTON: 145 return WakeReason.POWER_BUTTON; 146 case PowerManager.WAKE_REASON_GESTURE: 147 return WakeReason.GESTURE; 148 case PowerManager.WAKE_REASON_WAKE_KEY: 149 return WakeReason.WAKE_KEY; 150 case PowerManager.WAKE_REASON_WAKE_MOTION: 151 return WakeReason.WAKE_MOTION; 152 case PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED: 153 return WakeReason.DISPLAY_GROUP_ADDED; 154 case PowerManager.WAKE_REASON_TAP: 155 return WakeReason.TAP; 156 case PowerManager.WAKE_REASON_LIFT: 157 return WakeReason.LIFT; 158 case PowerManager.WAKE_REASON_BIOMETRIC: 159 return WakeReason.BIOMETRIC; 160 case PowerManager.WAKE_REASON_CAMERA_LAUNCH: 161 case PowerManager.WAKE_REASON_HDMI: 162 case PowerManager.WAKE_REASON_DISPLAY_GROUP_TURNED_ON: 163 case PowerManager.WAKE_REASON_UNFOLD_DEVICE: 164 case PowerManager.WAKE_REASON_DREAM_FINISHED: 165 case PowerManager.WAKE_REASON_TILT: 166 case PowerManager.WAKE_REASON_APPLICATION: 167 case PowerManager.WAKE_REASON_PLUGGED_IN: 168 default: 169 return WakeReason.UNKNOWN; 170 } 171 } 172 173 @AuthenticateReason.Fingerprint getAuthReason(@onNull FingerprintAuthenticateOptions options)174 private int getAuthReason(@NonNull FingerprintAuthenticateOptions options) { 175 return AuthenticateReason.Fingerprint.UNKNOWN; 176 } 177 178 @WakeReason getWakeReason(@onNull FingerprintAuthenticateOptions options)179 private int getWakeReason(@NonNull FingerprintAuthenticateOptions options) { 180 return WakeReason.UNKNOWN; 181 } 182 183 /** {@link OperationContext#id}. */ getId()184 public int getId() { 185 return mAidlContext.id; 186 } 187 188 /** Gets the current order counter for the session and increment the counter. */ getOrderAndIncrement()189 public int getOrderAndIncrement() { 190 final BiometricContextSessionInfo info = mSessionInfo; 191 return info != null ? info.getOrderAndIncrement() : -1; 192 } 193 194 /** {@link OperationContext#reason}. */ 195 @OperationReason getReason()196 public byte getReason() { 197 return mAidlContext.reason; 198 } 199 200 /** {@link OperationContext#wakeReason}. */ 201 @WakeReason getWakeReason()202 public int getWakeReason() { 203 return mAidlContext.wakeReason; 204 } 205 206 /** If the screen is currently on. */ isDisplayOn()207 public boolean isDisplayOn() { 208 return mIsDisplayOn; 209 } 210 211 /** @deprecated prefer {@link #getDisplayState()} to {@link OperationContext#isAod}. */ isAod()212 public boolean isAod() { 213 return mAidlContext.isAod; 214 } 215 216 /** {@link OperationContext#displayState}. */ 217 @DisplayState getDisplayState()218 public int getDisplayState() { 219 return mAidlContext.displayState; 220 } 221 222 /** {@link OperationContext#isCrypto}. */ isCrypto()223 public boolean isCrypto() { 224 return mAidlContext.isCrypto; 225 } 226 227 /** The dock state when this event occurred {@see Intent.EXTRA_DOCK_STATE_UNDOCKED}. */ getDockState()228 public int getDockState() { 229 return mDockState; 230 } 231 232 /** The fold state of the device when this event occurred. */ getFoldState()233 public int getFoldState() { 234 return mFoldState; 235 } 236 237 /** The orientation of the device when this event occurred. */ 238 @Surface.Rotation getOrientation()239 public int getOrientation() { 240 return mOrientation; 241 } 242 243 /** Update this object with the latest values from the given context. */ update(@onNull BiometricContext biometricContext, boolean isCrypto)244 OperationContextExt update(@NonNull BiometricContext biometricContext, boolean isCrypto) { 245 mAidlContext.isAod = biometricContext.isAod(); 246 mAidlContext.displayState = toAidlDisplayState(biometricContext.getDisplayState()); 247 mAidlContext.isCrypto = isCrypto; 248 setFirstSessionId(biometricContext); 249 250 mIsDisplayOn = biometricContext.isDisplayOn(); 251 mDockState = biometricContext.getDockedState(); 252 mFoldState = biometricContext.getFoldState(); 253 mOrientation = biometricContext.getCurrentRotation(); 254 255 return this; 256 } 257 258 @DisplayState toAidlDisplayState(@uthenticateOptions.DisplayState int state)259 private static int toAidlDisplayState(@AuthenticateOptions.DisplayState int state) { 260 switch (state) { 261 case AuthenticateOptions.DISPLAY_STATE_AOD: 262 return DisplayState.AOD; 263 case AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN: 264 return DisplayState.LOCKSCREEN; 265 case AuthenticateOptions.DISPLAY_STATE_NO_UI: 266 return DisplayState.NO_UI; 267 case AuthenticateOptions.DISPLAY_STATE_SCREENSAVER: 268 return DisplayState.SCREENSAVER; 269 } 270 return DisplayState.UNKNOWN; 271 } 272 setFirstSessionId(@onNull BiometricContext biometricContext)273 private void setFirstSessionId(@NonNull BiometricContext biometricContext) { 274 if (mIsBP) { 275 mSessionInfo = biometricContext.getBiometricPromptSessionInfo(); 276 if (mSessionInfo != null) { 277 mAidlContext.id = mSessionInfo.getId(); 278 mAidlContext.reason = OperationReason.BIOMETRIC_PROMPT; 279 return; 280 } 281 } else { 282 mSessionInfo = biometricContext.getKeyguardEntrySessionInfo(); 283 if (mSessionInfo != null) { 284 mAidlContext.id = mSessionInfo.getId(); 285 mAidlContext.reason = OperationReason.KEYGUARD; 286 return; 287 } 288 } 289 290 // no session 291 mAidlContext.id = 0; 292 mAidlContext.reason = OperationReason.UNKNOWN; 293 } 294 } 295