1 /* 2 * Copyright (C) 2021 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.settings.gestures; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.database.ContentObserver; 22 import android.net.Uri; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.provider.Settings; 26 27 /** Common code for long press power settings shared between controllers. */ 28 final class PowerMenuSettingsUtils { 29 30 /** Setting storing the current behaviour of long press power. */ 31 private static final String POWER_BUTTON_LONG_PRESS_SETTING = 32 Settings.Global.POWER_BUTTON_LONG_PRESS; 33 34 /** Setting storing the current behaviour of key chord power + volume up. */ 35 private static final String KEY_CHORD_POWER_VOLUME_UP_SETTING = 36 Settings.Global.KEY_CHORD_POWER_VOLUME_UP; 37 38 /** 39 * Value used for long press power button behaviour when long press power for Assistant is 40 * disabled. 41 * 42 * <p>If this value matches long press power for Assistant, then it falls back to Global Actions 43 * panel (i.e., the Power Menu), depending on their respective settings. 44 */ 45 private static final int POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE = 46 com.android.internal.R.integer.config_longPressOnPowerBehavior; 47 48 /** 49 * Value used for key chord power + volume up behaviour when long press power for Assistant is 50 * disabled. 51 */ 52 private static final int KEY_CHORD_POWER_VOLUME_UP_DEFAULT_VALUE_RESOURCE = 53 com.android.internal.R.integer.config_keyChordPowerVolumeUp; 54 55 private static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; // a.k.a., Power Menu 56 private static final int LONG_PRESS_POWER_ASSISTANT_VALUE = 5; // Settings.Secure.ASSISTANT 57 58 private static final int KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS = 2; 59 60 private static final Uri POWER_BUTTON_LONG_PRESS_URI = 61 Settings.Global.getUriFor(POWER_BUTTON_LONG_PRESS_SETTING); 62 63 /** 64 * @return true if long press power for assistant is currently enabled. 65 */ isLongPressPowerForAssistantEnabled(Context context)66 public static boolean isLongPressPowerForAssistantEnabled(Context context) { 67 int longPressPowerSettingValue = Settings.Global.getInt( 68 context.getContentResolver(), 69 POWER_BUTTON_LONG_PRESS_SETTING, 70 context.getResources().getInteger(POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE)); 71 return longPressPowerSettingValue == LONG_PRESS_POWER_ASSISTANT_VALUE; 72 } 73 74 /** 75 * @return true if long press power for assistant setting is available on the device. 76 */ isLongPressPowerSettingAvailable(Context context)77 public static boolean isLongPressPowerSettingAvailable(Context context) { 78 if (!context.getResources().getBoolean( 79 com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable)) { 80 return false; 81 } 82 83 int defaultLongPressPowerSettingValue = 84 context.getResources().getInteger(POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE); 85 switch (defaultLongPressPowerSettingValue) { 86 case LONG_PRESS_POWER_GLOBAL_ACTIONS: 87 case LONG_PRESS_POWER_ASSISTANT_VALUE: 88 // We support switching between Power Menu and Digital Assistant. 89 return true; 90 default: 91 // All other combinations are not supported. 92 return false; 93 } 94 } 95 setLongPressPowerForAssistant(Context context)96 public static boolean setLongPressPowerForAssistant(Context context) { 97 if (Settings.Global.putInt( 98 context.getContentResolver(), 99 POWER_BUTTON_LONG_PRESS_SETTING, 100 LONG_PRESS_POWER_ASSISTANT_VALUE)) { 101 // Make power + volume up buttons to open the power menu 102 Settings.Global.putInt( 103 context.getContentResolver(), 104 KEY_CHORD_POWER_VOLUME_UP_SETTING, 105 KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS); 106 return true; 107 } 108 return false; 109 } 110 setLongPressPowerForPowerMenu(Context context)111 public static boolean setLongPressPowerForPowerMenu(Context context) { 112 if (Settings.Global.putInt( 113 context.getContentResolver(), 114 POWER_BUTTON_LONG_PRESS_SETTING, 115 LONG_PRESS_POWER_GLOBAL_ACTIONS)) { 116 // We restore power + volume up buttons to the default action. 117 int keyChordDefaultValue = 118 context.getResources() 119 .getInteger(KEY_CHORD_POWER_VOLUME_UP_DEFAULT_VALUE_RESOURCE); 120 Settings.Global.putInt( 121 context.getContentResolver(), 122 KEY_CHORD_POWER_VOLUME_UP_SETTING, 123 keyChordDefaultValue); 124 return true; 125 } 126 return false; 127 } 128 129 private final Context mContext; 130 private final SettingsObserver mSettingsObserver; 131 PowerMenuSettingsUtils(Context context)132 PowerMenuSettingsUtils(Context context) { 133 mContext = context; 134 mSettingsObserver = new SettingsObserver(new Handler(Looper.getMainLooper())); 135 } 136 137 /** 138 * Registers callback for observing SettingsProvider state. 139 * 140 * @param callback for state changes 141 */ registerObserver(SettingsStateCallback callback)142 public void registerObserver(SettingsStateCallback callback) { 143 mSettingsObserver.setCallback(callback); 144 final ContentResolver resolver = mContext.getContentResolver(); 145 resolver.registerContentObserver(POWER_BUTTON_LONG_PRESS_URI, true, mSettingsObserver); 146 } 147 148 /** Unregisters callback for observing SettingsProvider state. */ unregisterObserver()149 public void unregisterObserver() { 150 final ContentResolver resolver = mContext.getContentResolver(); 151 resolver.unregisterContentObserver(mSettingsObserver); 152 } 153 154 /** An interface for when SettingsProvider key state changes. */ 155 public interface SettingsStateCallback { 156 /** Callback method for SettingsProvider key state changes. */ onChange(Uri uri)157 void onChange(Uri uri); 158 } 159 160 private static final class SettingsObserver extends ContentObserver { 161 private SettingsStateCallback mCallback; 162 SettingsObserver(Handler handler)163 SettingsObserver(Handler handler) { 164 super(handler); 165 } 166 setCallback(SettingsStateCallback callback)167 private void setCallback(SettingsStateCallback callback) { 168 mCallback = callback; 169 } 170 171 @Override onChange(boolean selfChange, Uri uri)172 public void onChange(boolean selfChange, Uri uri) { 173 if (mCallback != null) { 174 mCallback.onChange(uri); 175 } 176 } 177 } 178 } 179