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.systemui.haptics
18 
19 import android.annotation.SuppressLint
20 import android.media.AudioAttributes
21 import android.os.VibrationAttributes
22 import android.os.VibrationEffect
23 import com.android.systemui.statusbar.VibratorHelper
24 import com.android.systemui.util.concurrency.FakeExecutor
25 import com.android.systemui.util.time.FakeSystemClock
26 
27 /** A fake [VibratorHelper] that only keeps track of the latest vibration effects delivered */
28 @SuppressLint("VisibleForTests")
29 class FakeVibratorHelper : VibratorHelper(EmptyVibrator(), FakeExecutor(FakeSystemClock())) {
30 
31     /** A customizable map of primitive ids and their durations in ms */
32     val primitiveDurations: HashMap<Int, Int> = ALL_PRIMITIVE_DURATIONS
33 
34     private val vibrationEffectHistory = ArrayList<VibrationEffect>()
35 
36     val totalVibrations: Int
37         get() = vibrationEffectHistory.size
38 
vibratenull39     override fun vibrate(effect: VibrationEffect) {
40         vibrationEffectHistory.add(effect)
41     }
42 
vibratenull43     override fun vibrate(effect: VibrationEffect, attributes: VibrationAttributes) = vibrate(effect)
44 
45     override fun vibrate(effect: VibrationEffect, attributes: AudioAttributes) = vibrate(effect)
46 
47     override fun vibrate(
48         uid: Int,
49         opPkg: String?,
50         vibe: VibrationEffect,
51         reason: String?,
52         attributes: VibrationAttributes,
53     ) = vibrate(vibe)
54 
55     override fun getPrimitiveDurations(vararg primitiveIds: Int): IntArray =
56         primitiveIds.map { primitiveDurations[it] ?: 0 }.toIntArray()
57 
hasVibratedWithEffectsnull58     fun hasVibratedWithEffects(vararg effects: VibrationEffect): Boolean =
59         vibrationEffectHistory.containsAll(effects.toList())
60 
61     fun timesVibratedWithEffect(effect: VibrationEffect): Int =
62         vibrationEffectHistory.count { it == effect }
63 
64     companion object {
65         val ALL_PRIMITIVE_DURATIONS =
66             hashMapOf(
67                 VibrationEffect.Composition.PRIMITIVE_NOOP to 0,
68                 VibrationEffect.Composition.PRIMITIVE_CLICK to 12,
69                 VibrationEffect.Composition.PRIMITIVE_THUD to 300,
70                 VibrationEffect.Composition.PRIMITIVE_SPIN to 133,
71                 VibrationEffect.Composition.PRIMITIVE_QUICK_RISE to 150,
72                 VibrationEffect.Composition.PRIMITIVE_SLOW_RISE to 500,
73                 VibrationEffect.Composition.PRIMITIVE_QUICK_FALL to 100,
74                 VibrationEffect.Composition.PRIMITIVE_TICK to 5,
75                 VibrationEffect.Composition.PRIMITIVE_LOW_TICK to 12,
76             )
77     }
78 }
79