/* * Copyright (C) 2012 The Android Open Source Project * modified * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only */ package helium314.keyboard.latin; import android.content.Context; import android.media.AudioManager; import android.os.Vibrator; import android.view.HapticFeedbackConstants; import android.view.View; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode; import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.settings.SettingsValues; /** * This class gathers audio feedback and haptic feedback functions. *

* It offers a consistent and simple interface that allows LatinIME to forget about the * complexity of settings and the like. */ public final class AudioAndHapticFeedbackManager { private AudioManager mAudioManager; private Vibrator mVibrator; private SettingsValues mSettingsValues; private boolean mSoundOn; private static final AudioAndHapticFeedbackManager sInstance = new AudioAndHapticFeedbackManager(); public static AudioAndHapticFeedbackManager getInstance() { return sInstance; } private AudioAndHapticFeedbackManager() { // Intentional empty constructor for singleton. } public static void init(final Context context) { sInstance.initInternal(context); } private void initInternal(final Context context) { mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); } public void performHapticAndAudioFeedback(final int code, final View viewToPerformHapticFeedbackOn) { performHapticFeedback(viewToPerformHapticFeedbackOn); performAudioFeedback(code); } public boolean hasVibrator() { return mVibrator != null && mVibrator.hasVibrator(); } public void vibrate(final long milliseconds) { if (mVibrator == null) { return; } mVibrator.vibrate(milliseconds); } private boolean reevaluateIfSoundIsOn() { if (mSettingsValues == null || !mSettingsValues.mSoundOn || mAudioManager == null) { return false; } return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; } public void performAudioFeedback(final int code) { // if mAudioManager is null, we can't play a sound anyway, so return if (mAudioManager == null) { return; } if (!mSoundOn) { return; } final int sound = switch (code) { case KeyCode.DELETE -> AudioManager.FX_KEYPRESS_DELETE; case Constants.CODE_ENTER -> AudioManager.FX_KEYPRESS_RETURN; case Constants.CODE_SPACE -> AudioManager.FX_KEYPRESS_SPACEBAR; default -> AudioManager.FX_KEYPRESS_STANDARD; }; mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume); } public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) { if (!mSettingsValues.mVibrateOn) { return; } if (mSettingsValues.mKeypressVibrationDuration >= 0) { vibrate(mSettingsValues.mKeypressVibrationDuration); return; } // Go ahead with the system default if (viewToPerformHapticFeedbackOn != null) { viewToPerformHapticFeedbackOn.performHapticFeedback( HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } } public void onSettingsChanged(final SettingsValues settingsValues) { mSettingsValues = settingsValues; mSoundOn = reevaluateIfSoundIsOn(); } public void onRingerModeChanged() { mSoundOn = reevaluateIfSoundIsOn(); } }