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 package com.android.settings.biometrics2.ui.model 17 18 import android.content.Intent.EXTRA_USER_ID 19 import android.os.Bundle 20 import android.os.UserHandle 21 import androidx.annotation.VisibleForTesting 22 import com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE 23 import com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN 24 import com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE 25 import java.time.Clock 26 27 /** 28 * Secret credential data including 29 * 1. userId 30 * 2. challenge 31 * 3. token 32 * 4. gkPwHandle 33 */ 34 class CredentialModel(bundle: Bundle?, private val clock: Clock) { 35 36 private val mInitMillis = clock.millis() 37 38 /** userId for this credential */ 39 val userId: Int = (bundle ?: Bundle()).getInt(EXTRA_USER_ID, UserHandle.myUserId()) 40 41 private var clearGkPwHandleMillis: Long? = null 42 43 /** Gatekeeper password handle */ 44 var gkPwHandle: Long = (bundle ?: Bundle()).getLong(EXTRA_KEY_GK_PW_HANDLE, INVALID_GK_PW_HANDLE) 45 private set 46 47 val isValidGkPwHandle: Boolean 48 get() = gkPwHandle != INVALID_GK_PW_HANDLE 49 50 /** Clear gatekeeper password handle data */ clearGkPwHandlenull51 fun clearGkPwHandle() { 52 clearGkPwHandleMillis = clock.millis() 53 gkPwHandle = INVALID_GK_PW_HANDLE 54 } 55 56 /** Check user id is valid or not */ 57 val isValidUserId: Boolean 58 get() = userId != UserHandle.USER_NULL 59 60 private var updateChallengeMillis: Long? = null 61 62 var challenge: Long = (bundle ?: Bundle()).getLong(EXTRA_KEY_CHALLENGE, INVALID_CHALLENGE) 63 set(value) { 64 updateChallengeMillis = clock.millis() 65 field = value 66 } 67 68 val isValidChallenge: Boolean 69 get() = challenge != INVALID_CHALLENGE 70 71 private var updateTokenMillis: Long? = null 72 73 /** Challenge token */ 74 var token: ByteArray? = (bundle ?: Bundle()).getByteArray(EXTRA_KEY_CHALLENGE_TOKEN) 75 set(value) { 76 updateTokenMillis = clock.millis() 77 field = value 78 } 79 80 val isValidToken: Boolean 81 get() = token != null 82 83 /** Returns a string representation of the object */ toStringnull84 override fun toString(): String { 85 val gkPwHandleLen = "$gkPwHandle".length 86 val tokenLen = token?.size ?: 0 87 val challengeLen = "$challenge".length 88 return (javaClass.simpleName + ":{initMillis:$mInitMillis" 89 + ", userId:$userId" 90 + ", challenge:{len:$challengeLen" 91 + ", updateMillis:$updateChallengeMillis}" 92 + ", token:{len:$tokenLen, isValid:$isValidToken" 93 + ", updateMillis:$updateTokenMillis}" 94 + ", gkPwHandle:{len:$gkPwHandleLen, isValid:$isValidGkPwHandle" 95 + ", clearMillis:$clearGkPwHandleMillis}" 96 + " }") 97 } 98 99 companion object { 100 /** Default value for an invalid challenge */ 101 @VisibleForTesting 102 const val INVALID_CHALLENGE = -1L 103 104 /** Default value if GkPwHandle is invalid */ 105 @VisibleForTesting 106 const val INVALID_GK_PW_HANDLE = 0L 107 } 108 } 109