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 
17 package com.android.server.accessibility.magnification;
18 
19 import android.annotation.Nullable;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.os.UserHandle;
23 import android.os.VibrationEffect;
24 import android.os.Vibrator;
25 import android.provider.Settings;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 
29 /**
30  * Class to encapsulate all the logic to fire a vibration when user reaches the screen's left or
31  * right edge, when it's in magnification mode.
32  */
33 public class FullScreenMagnificationVibrationHelper {
34     private static final long VIBRATION_DURATION_MS = 10L;
35     private static final int VIBRATION_AMPLITUDE = VibrationEffect.MAX_AMPLITUDE / 2;
36 
37     @Nullable
38     private final Vibrator mVibrator;
39     private final ContentResolver mContentResolver;
40     private final VibrationEffect mVibrationEffect = VibrationEffect.get(
41             VibrationEffect.EFFECT_CLICK);
42     @VisibleForTesting
43     VibrationEffectSupportedProvider mIsVibrationEffectSupportedProvider;
44 
FullScreenMagnificationVibrationHelper(Context context)45     public FullScreenMagnificationVibrationHelper(Context context) {
46         mContentResolver = context.getContentResolver();
47         mVibrator = context.getSystemService(Vibrator.class);
48         mIsVibrationEffectSupportedProvider =
49                 () -> mVibrator != null && mVibrator.areAllEffectsSupported(
50                         VibrationEffect.EFFECT_CLICK) == Vibrator.VIBRATION_EFFECT_SUPPORT_YES;
51     }
52 
53 
vibrateIfSettingEnabled()54     void vibrateIfSettingEnabled() {
55         if (mVibrator != null && mVibrator.hasVibrator() && isEdgeHapticSettingEnabled()) {
56             if (mIsVibrationEffectSupportedProvider.isVibrationEffectSupported()) {
57                 mVibrator.vibrate(mVibrationEffect);
58             } else {
59                 mVibrator.vibrate(VibrationEffect.createOneShot(VIBRATION_DURATION_MS,
60                         VIBRATION_AMPLITUDE));
61             }
62         }
63     }
64 
isEdgeHapticSettingEnabled()65     private boolean isEdgeHapticSettingEnabled() {
66         return Settings.Secure.getIntForUser(
67                 mContentResolver,
68                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_EDGE_HAPTIC_ENABLED,
69                 0, UserHandle.USER_CURRENT)
70                 == 1;
71     }
72 
73     @VisibleForTesting
74     interface VibrationEffectSupportedProvider {
isVibrationEffectSupported()75         boolean isVibrationEffectSupported();
76     }
77 }
78 
79