1 /*
2  * Copyright (C) 2024 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.settings.biometrics.fingerprint2.domain.interactor
18 
19 import android.content.Context
20 import android.os.Process
21 import android.os.VibrationAttributes
22 import android.os.VibrationEffect
23 import android.os.Vibrator
24 
25 /** Indicates the possible vibration effects for fingerprint enrollment */
26 sealed class FingerprintVibrationEffects {
27   /** A vibration indicating an error */
28   data object UdfpsError : FingerprintVibrationEffects()
29 
30   /**
31    * A vibration indicating success, this usually occurs when progress on the UDFPS enrollment has
32    * been made
33    */
34   data object UdfpsSuccess : FingerprintVibrationEffects()
35 
36   /** This vibration typically occurs when a help message is shown during UDFPS enrollment */
37   data object UdfpsHelp : FingerprintVibrationEffects()
38 }
39 
40 /** Interface for sending haptic feedback */
41 interface VibrationInteractor {
42   /** This will send a haptic vibration */
vibratenull43   fun vibrate(effect: FingerprintVibrationEffects, caller: String)
44 }
45 
46 /** Implementation of the VibrationInteractor interface */
47 class VibrationInteractorImpl(val applicationContext: Context) : VibrationInteractor {
48   val vibrator = applicationContext.getSystemService(Vibrator::class.java)!!
49 
50   override fun vibrate(effect: FingerprintVibrationEffects, caller: String) {
51     val callerString = "$caller::$effect"
52     val res =
53       when (effect) {
54         FingerprintVibrationEffects.UdfpsHelp,
55         FingerprintVibrationEffects.UdfpsError ->
56           Pair(VIBRATE_EFFECT_ERROR, FINGERPRINT_ENROLLING_SONIFICATION_ATTRIBUTES)
57         FingerprintVibrationEffects.UdfpsSuccess ->
58           Pair(VIBRATE_EFFECT_SUCCESS, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES)
59       }
60     vibrator.vibrate(
61       Process.myUid(),
62       applicationContext.opPackageName,
63       res.first,
64       callerString,
65       res.second,
66     )
67   }
68 
69   companion object {
70     private val VIBRATE_EFFECT_ERROR = VibrationEffect.createWaveform(longArrayOf(0, 5, 55, 60), -1)
71     private val FINGERPRINT_ENROLLING_SONIFICATION_ATTRIBUTES =
72       VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ACCESSIBILITY)
73     private val HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
74       VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK)
75     private val VIBRATE_EFFECT_SUCCESS = VibrationEffect.get(VibrationEffect.EFFECT_CLICK)
76   }
77 }
78