1 /* 2 * Copyright (C) 2020 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.wm.shell.onehanded; 18 19 import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME; 20 21 import android.annotation.IntDef; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.database.ContentObserver; 25 import android.net.Uri; 26 import android.provider.Settings; 27 import android.text.TextUtils; 28 29 import androidx.annotation.Nullable; 30 31 import com.android.wm.shell.R; 32 33 import java.io.PrintWriter; 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 37 /** 38 * APIs for querying or updating one handed settings. 39 */ 40 public final class OneHandedSettingsUtil { 41 private static final String TAG = "OneHandedSettingsUtil"; 42 private static final String ONE_HANDED_MODE_TARGET_NAME = 43 ONE_HANDED_COMPONENT_NAME.getShortClassName(); 44 45 @IntDef(prefix = {"ONE_HANDED_TIMEOUT_"}, value = { 46 ONE_HANDED_TIMEOUT_NEVER, 47 ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS, 48 ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS, 49 ONE_HANDED_TIMEOUT_LONG_IN_SECONDS, 50 }) 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface OneHandedTimeout { 53 } 54 55 /** 56 * Never stop one handed automatically 57 */ 58 public static final int ONE_HANDED_TIMEOUT_NEVER = 0; 59 /** 60 * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS} 61 */ 62 public static final int ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS = 4; 63 /** 64 * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS} 65 */ 66 public static final int ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS = 8; 67 /** 68 * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_LONG_IN_SECONDS} 69 */ 70 public static final int ONE_HANDED_TIMEOUT_LONG_IN_SECONDS = 12; 71 72 /** 73 * Registers one handed preference settings observer 74 * 75 * @param key Setting key to monitor in observer 76 * @param resolver ContentResolver of context 77 * @param observer Observer from caller 78 * @param newUserId New user id to be registered 79 * @return uri key for observing 80 */ 81 @Nullable registerSettingsKeyObserver(String key, ContentResolver resolver, ContentObserver observer, int newUserId)82 public Uri registerSettingsKeyObserver(String key, ContentResolver resolver, 83 ContentObserver observer, int newUserId) { 84 Uri uriKey = null; 85 uriKey = Settings.Secure.getUriFor(key); 86 if (resolver != null && uriKey != null) { 87 resolver.registerContentObserver(uriKey, false, observer, newUserId); 88 } 89 return uriKey; 90 } 91 92 /** 93 * Unregisters one handed preference settings observer. 94 * 95 * @param resolver ContentResolver of context 96 * @param observer preference key change observer 97 */ unregisterSettingsKeyObserver(ContentResolver resolver, ContentObserver observer)98 public void unregisterSettingsKeyObserver(ContentResolver resolver, 99 ContentObserver observer) { 100 if (resolver != null) { 101 resolver.unregisterContentObserver(observer); 102 } 103 } 104 105 /** 106 * Queries one handed enable or disable flag from Settings provider. 107 * 108 * @return enable or disable one handed mode flag. 109 */ getSettingsOneHandedModeEnabled(ContentResolver resolver, int userId)110 public boolean getSettingsOneHandedModeEnabled(ContentResolver resolver, int userId) { 111 return Settings.Secure.getIntForUser(resolver, 112 Settings.Secure.ONE_HANDED_MODE_ENABLED, 0 /* Disabled */, userId) == 1; 113 } 114 115 /** 116 * Sets one handed enable or disable flag from Settings provider. 117 * 118 * @return true if the value was set, false on database errors 119 */ setOneHandedModeEnabled(ContentResolver resolver, int enabled, int userId)120 public boolean setOneHandedModeEnabled(ContentResolver resolver, int enabled, int userId) { 121 return Settings.Secure.putIntForUser(resolver, 122 Settings.Secure.ONE_HANDED_MODE_ENABLED, enabled, userId); 123 } 124 125 126 /** 127 * Queries taps app to exit config from Settings provider. 128 * 129 * @return enable or disable taps app exit. 130 */ getSettingsTapsAppToExit(ContentResolver resolver, int userId)131 public boolean getSettingsTapsAppToExit(ContentResolver resolver, int userId) { 132 return Settings.Secure.getIntForUser(resolver, 133 Settings.Secure.TAPS_APP_TO_EXIT, 1, userId) == 1; 134 } 135 136 /** 137 * Queries timeout value from Settings provider. Default is. 138 * {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS} 139 * 140 * @return timeout value in seconds. 141 */ getSettingsOneHandedModeTimeout(ContentResolver resolver, int userId)142 public @OneHandedTimeout int getSettingsOneHandedModeTimeout(ContentResolver resolver, 143 int userId) { 144 return Settings.Secure.getIntForUser(resolver, 145 Settings.Secure.ONE_HANDED_MODE_TIMEOUT, ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS, 146 userId); 147 } 148 149 /** 150 * Returns whether swipe bottom to notification gesture enabled or not. 151 */ getSettingsSwipeToNotificationEnabled(ContentResolver resolver, int userId)152 public boolean getSettingsSwipeToNotificationEnabled(ContentResolver resolver, int userId) { 153 return Settings.Secure.getIntForUser(resolver, 154 Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0, userId) == 1; 155 } 156 157 158 /** 159 * Queries tutorial shown counts from Settings provider. Default is 0. 160 * 161 * @return counts tutorial shown counts. 162 */ getTutorialShownCounts(ContentResolver resolver, int userId)163 public int getTutorialShownCounts(ContentResolver resolver, int userId) { 164 return Settings.Secure.getIntForUser(resolver, 165 Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0, userId); 166 } 167 168 /** 169 * Queries one-handed mode shortcut enabled in settings or not. 170 * 171 * @return true if user enabled one-handed shortcut in settings, false otherwise. 172 */ getShortcutEnabled(ContentResolver resolver, int userId)173 public boolean getShortcutEnabled(ContentResolver resolver, int userId) { 174 // Checks SOFTWARE_SHORTCUT_KEY 175 final String targetsSwKey = Settings.Secure.getStringForUser(resolver, 176 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userId); 177 if (!TextUtils.isEmpty(targetsSwKey) && targetsSwKey.contains( 178 ONE_HANDED_MODE_TARGET_NAME)) { 179 return true; 180 } 181 182 // Checks HARDWARE_SHORTCUT_KEY 183 final String targetsHwKey = Settings.Secure.getStringForUser(resolver, 184 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userId); 185 if (!TextUtils.isEmpty(targetsHwKey) && targetsHwKey.contains( 186 ONE_HANDED_MODE_TARGET_NAME)) { 187 return true; 188 } 189 return false; 190 } 191 192 /** 193 * Sets tutorial shown counts. 194 * 195 * @return true if the value was set, false on database errors. 196 */ setTutorialShownCounts(ContentResolver resolver, int shownCounts, int userId)197 public boolean setTutorialShownCounts(ContentResolver resolver, int shownCounts, int userId) { 198 return Settings.Secure.putIntForUser(resolver, 199 Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, shownCounts, userId); 200 } 201 202 /** 203 * Sets one handed activated or not to notify state for shortcut. 204 * 205 * @return true if one handed mode is activated. 206 */ getOneHandedModeActivated(ContentResolver resolver, int userId)207 public boolean getOneHandedModeActivated(ContentResolver resolver, int userId) { 208 return Settings.Secure.getIntForUser(resolver, 209 Settings.Secure.ONE_HANDED_MODE_ACTIVATED, 0, userId) == 1; 210 } 211 212 /** 213 * Sets one handed activated or not to notify state for shortcut. 214 * 215 * @return true if the value was set, false on database errors. 216 */ setOneHandedModeActivated(ContentResolver resolver, int state, int userId)217 public boolean setOneHandedModeActivated(ContentResolver resolver, int state, int userId) { 218 return Settings.Secure.putIntForUser(resolver, 219 Settings.Secure.ONE_HANDED_MODE_ACTIVATED, state, userId); 220 } 221 222 /** 223 * Obtains one-handed mode transition duration from resource config. 224 * 225 * @return durationMs The duration in milli-seconds 226 */ getTransitionDuration(Context context)227 public int getTransitionDuration(Context context) { 228 return context.getResources().getInteger( 229 R.integer.config_one_handed_translate_animation_duration); 230 } 231 232 /** 233 * Obtains one-handed mode offset fraction from resource config. 234 * 235 * @return fraction The fraction of offset of the whole screen. 236 */ getTranslationFraction(Context context)237 public float getTranslationFraction(Context context) { 238 return context.getResources().getFraction(R.fraction.config_one_handed_offset, 1, 1); 239 } 240 dump(PrintWriter pw, String prefix, ContentResolver resolver, int userId)241 void dump(PrintWriter pw, String prefix, ContentResolver resolver, 242 int userId) { 243 final String innerPrefix = " "; 244 pw.println(TAG); 245 pw.print(innerPrefix + "isOneHandedModeEnable="); 246 pw.println(getSettingsOneHandedModeEnabled(resolver, userId)); 247 pw.print(innerPrefix + "isSwipeToNotificationEnabled="); 248 pw.println(getSettingsSwipeToNotificationEnabled(resolver, userId)); 249 pw.print(innerPrefix + "oneHandedTimeOut="); 250 pw.println(getSettingsOneHandedModeTimeout(resolver, userId)); 251 pw.print(innerPrefix + "tapsAppToExit="); 252 pw.println(getSettingsTapsAppToExit(resolver, userId)); 253 pw.print(innerPrefix + "shortcutActivated="); 254 pw.println(getOneHandedModeActivated(resolver, userId)); 255 pw.print(innerPrefix + "tutorialShownCounts="); 256 pw.println(getTutorialShownCounts(resolver, userId)); 257 } 258 OneHandedSettingsUtil()259 public OneHandedSettingsUtil() { 260 } 261 } 262