/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.onehanded; import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME; import android.annotation.IntDef; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings; import android.text.TextUtils; import androidx.annotation.Nullable; import com.android.wm.shell.R; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * APIs for querying or updating one handed settings. */ public final class OneHandedSettingsUtil { private static final String TAG = "OneHandedSettingsUtil"; private static final String ONE_HANDED_MODE_TARGET_NAME = ONE_HANDED_COMPONENT_NAME.getShortClassName(); @IntDef(prefix = {"ONE_HANDED_TIMEOUT_"}, value = { ONE_HANDED_TIMEOUT_NEVER, ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS, ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS, ONE_HANDED_TIMEOUT_LONG_IN_SECONDS, }) @Retention(RetentionPolicy.SOURCE) public @interface OneHandedTimeout { } /** * Never stop one handed automatically */ public static final int ONE_HANDED_TIMEOUT_NEVER = 0; /** * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS} */ public static final int ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS = 4; /** * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS} */ public static final int ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS = 8; /** * Auto stop one handed in {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_LONG_IN_SECONDS} */ public static final int ONE_HANDED_TIMEOUT_LONG_IN_SECONDS = 12; /** * Registers one handed preference settings observer * * @param key Setting key to monitor in observer * @param resolver ContentResolver of context * @param observer Observer from caller * @param newUserId New user id to be registered * @return uri key for observing */ @Nullable public Uri registerSettingsKeyObserver(String key, ContentResolver resolver, ContentObserver observer, int newUserId) { Uri uriKey = null; uriKey = Settings.Secure.getUriFor(key); if (resolver != null && uriKey != null) { resolver.registerContentObserver(uriKey, false, observer, newUserId); } return uriKey; } /** * Unregisters one handed preference settings observer. * * @param resolver ContentResolver of context * @param observer preference key change observer */ public void unregisterSettingsKeyObserver(ContentResolver resolver, ContentObserver observer) { if (resolver != null) { resolver.unregisterContentObserver(observer); } } /** * Queries one handed enable or disable flag from Settings provider. * * @return enable or disable one handed mode flag. */ public boolean getSettingsOneHandedModeEnabled(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.ONE_HANDED_MODE_ENABLED, 0 /* Disabled */, userId) == 1; } /** * Sets one handed enable or disable flag from Settings provider. * * @return true if the value was set, false on database errors */ public boolean setOneHandedModeEnabled(ContentResolver resolver, int enabled, int userId) { return Settings.Secure.putIntForUser(resolver, Settings.Secure.ONE_HANDED_MODE_ENABLED, enabled, userId); } /** * Queries taps app to exit config from Settings provider. * * @return enable or disable taps app exit. */ public boolean getSettingsTapsAppToExit(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.TAPS_APP_TO_EXIT, 1, userId) == 1; } /** * Queries timeout value from Settings provider. Default is. * {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS} * * @return timeout value in seconds. */ public @OneHandedTimeout int getSettingsOneHandedModeTimeout(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.ONE_HANDED_MODE_TIMEOUT, ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS, userId); } /** * Returns whether swipe bottom to notification gesture enabled or not. */ public boolean getSettingsSwipeToNotificationEnabled(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0, userId) == 1; } /** * Queries tutorial shown counts from Settings provider. Default is 0. * * @return counts tutorial shown counts. */ public int getTutorialShownCounts(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0, userId); } /** * Queries one-handed mode shortcut enabled in settings or not. * * @return true if user enabled one-handed shortcut in settings, false otherwise. */ public boolean getShortcutEnabled(ContentResolver resolver, int userId) { // Checks SOFTWARE_SHORTCUT_KEY final String targetsSwKey = Settings.Secure.getStringForUser(resolver, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userId); if (!TextUtils.isEmpty(targetsSwKey) && targetsSwKey.contains( ONE_HANDED_MODE_TARGET_NAME)) { return true; } // Checks HARDWARE_SHORTCUT_KEY final String targetsHwKey = Settings.Secure.getStringForUser(resolver, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userId); if (!TextUtils.isEmpty(targetsHwKey) && targetsHwKey.contains( ONE_HANDED_MODE_TARGET_NAME)) { return true; } return false; } /** * Sets tutorial shown counts. * * @return true if the value was set, false on database errors. */ public boolean setTutorialShownCounts(ContentResolver resolver, int shownCounts, int userId) { return Settings.Secure.putIntForUser(resolver, Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, shownCounts, userId); } /** * Sets one handed activated or not to notify state for shortcut. * * @return true if one handed mode is activated. */ public boolean getOneHandedModeActivated(ContentResolver resolver, int userId) { return Settings.Secure.getIntForUser(resolver, Settings.Secure.ONE_HANDED_MODE_ACTIVATED, 0, userId) == 1; } /** * Sets one handed activated or not to notify state for shortcut. * * @return true if the value was set, false on database errors. */ public boolean setOneHandedModeActivated(ContentResolver resolver, int state, int userId) { return Settings.Secure.putIntForUser(resolver, Settings.Secure.ONE_HANDED_MODE_ACTIVATED, state, userId); } /** * Obtains one-handed mode transition duration from resource config. * * @return durationMs The duration in milli-seconds */ public int getTransitionDuration(Context context) { return context.getResources().getInteger( R.integer.config_one_handed_translate_animation_duration); } /** * Obtains one-handed mode offset fraction from resource config. * * @return fraction The fraction of offset of the whole screen. */ public float getTranslationFraction(Context context) { return context.getResources().getFraction(R.fraction.config_one_handed_offset, 1, 1); } void dump(PrintWriter pw, String prefix, ContentResolver resolver, int userId) { final String innerPrefix = " "; pw.println(TAG); pw.print(innerPrefix + "isOneHandedModeEnable="); pw.println(getSettingsOneHandedModeEnabled(resolver, userId)); pw.print(innerPrefix + "isSwipeToNotificationEnabled="); pw.println(getSettingsSwipeToNotificationEnabled(resolver, userId)); pw.print(innerPrefix + "oneHandedTimeOut="); pw.println(getSettingsOneHandedModeTimeout(resolver, userId)); pw.print(innerPrefix + "tapsAppToExit="); pw.println(getSettingsTapsAppToExit(resolver, userId)); pw.print(innerPrefix + "shortcutActivated="); pw.println(getOneHandedModeActivated(resolver, userId)); pw.print(innerPrefix + "tutorialShownCounts="); pw.println(getTutorialShownCounts(resolver, userId)); } public OneHandedSettingsUtil() { } }