1 /* <lambda>null2 * Copyright 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 17 package androidx.core.haptics 18 19 import android.content.Context 20 import android.os.Vibrator 21 import androidx.annotation.RequiresPermission 22 import androidx.annotation.VisibleForTesting 23 import androidx.core.content.ContextCompat 24 import androidx.core.haptics.device.HapticDeviceProfile 25 import androidx.core.haptics.impl.HapticManagerImpl 26 import androidx.core.haptics.impl.VibratorWrapperImpl 27 import androidx.core.haptics.signal.HapticSignal 28 import androidx.core.haptics.signal.ResolvableSignal 29 30 /** 31 * Manager for interactions with a device vibrator. 32 * 33 * <p>If your process exits, any vibration you started will stop. 34 */ 35 public interface HapticManager { 36 37 public companion object { 38 39 /** 40 * Creates a haptic manager for the system vibrator. 41 * 42 * This returns a manager instance only if the device has a vibrator motor, i.e. the system 43 * vibrator check [Vibrator.hasVibrator] returns true, and returns null otherwise. 44 * 45 * @sample androidx.core.haptics.samples.PlaySystemStandardClick 46 * @param context Context to load the device vibrator. 47 * @return a new instance of HapticManager for the system vibrator, or null if the device 48 * does not have a vibrator motor. 49 */ 50 @JvmStatic 51 public fun create(context: Context): HapticManager? { 52 return requireNotNull(ContextCompat.getSystemService(context, Vibrator::class.java)) { 53 "Vibrator service not found" 54 } 55 .let { systemVibrator -> 56 if (systemVibrator.hasVibrator()) { 57 HapticManagerImpl(VibratorWrapperImpl(systemVibrator)) 58 } else { 59 null 60 } 61 } 62 } 63 64 /** Creates a haptic manager for the given vibrator. */ 65 @VisibleForTesting 66 internal fun createForVibrator(vibrator: VibratorWrapper): HapticManager? { 67 return if (vibrator.hasVibrator()) { 68 HapticManagerImpl(vibrator) 69 } else { 70 null 71 } 72 } 73 } 74 75 /** A [HapticDeviceProfile] describing the vibrator hardware capabilities for the device. */ 76 public val deviceProfile: HapticDeviceProfile 77 78 /** 79 * Play a [HapticSignal]. 80 * 81 * @sample androidx.core.haptics.samples.PlayHapticSignal 82 * @param signal The haptic signal to be played. 83 * @param attrs The attributes corresponding to the haptic signal. For example, specify 84 * [HapticAttributes.USAGE_NOTIFICATION] for notification vibrations or 85 * [HapticAttributes.USAGE_TOUCH] for touch feedback haptics. 86 */ 87 @RequiresPermission(android.Manifest.permission.VIBRATE) 88 public fun play(signal: HapticSignal, attrs: HapticAttributes) 89 90 /** 91 * Resolves and plays a given [ResolvableSignal]. 92 * 93 * If the same signal will be played by this vibrator multiple times then consider resolving the 94 * [HapticSignal] only once using this [deviceProfile] and then reusing it. 95 * 96 * @sample androidx.core.haptics.samples.PlayResolvableHapticSignal 97 * @param signal The haptic signal to be resolved using this device profile and played. 98 * @param attrs The attributes corresponding to the haptic signal. For example, specify 99 * [HapticAttributes.USAGE_NOTIFICATION] for notification vibrations or 100 * [HapticAttributes.USAGE_TOUCH] for touch feedback haptics. 101 */ 102 @RequiresPermission(android.Manifest.permission.VIBRATE) 103 public fun play(signal: ResolvableSignal, attrs: HapticAttributes) { 104 signal.resolve(deviceProfile)?.let { resolvedSignal -> play(resolvedSignal, attrs) } 105 } 106 107 /** 108 * Cancel any [HapticSignal] currently playing. 109 * 110 * @sample androidx.core.haptics.samples.PlayThenCancel 111 */ 112 @RequiresPermission(android.Manifest.permission.VIBRATE) public fun cancel() 113 } 114