1a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov/* 2a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * Copyright (C) 2009 The Android Open Source Project 3a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * 4a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * Licensed under the Apache License, Version 2.0 (the "License"); 5a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * you may not use this file except in compliance with the License. 6a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * You may obtain a copy of the License at 7a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * 8a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * http://www.apache.org/licenses/LICENSE-2.0 9a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * 10a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * Unless required by applicable law or agreed to in writing, software 11a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * distributed under the License is distributed on an "AS IS" BASIS, 12a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * See the License for the specific language governing permissions and 14a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * limitations under the License. 15a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov */ 16a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 17a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovpackage com.android.settings; 18a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 196f0b4d8143858e41cede1f935230e2a430b9fd2dSvetoslav Ganovimport android.accessibilityservice.AccessibilityServiceInfo; 20672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.app.ActionBar; 21672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.app.Activity; 2200453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackbornimport android.app.ActivityManagerNative; 23a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.app.AlertDialog; 24cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganovimport android.app.Dialog; 25672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.content.ComponentName; 26672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.content.Context; 27a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.content.DialogInterface; 2805b08a50f86a91ab2db6b7e47febadc593972609Charles Chenimport android.content.Intent; 291a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganovimport android.content.SharedPreferences; 30232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganovimport android.content.pm.ResolveInfo; 31a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.content.pm.ServiceInfo; 3200453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackbornimport android.content.res.Configuration; 333aa58b0f35c60f7bf4c97a6e12c201abf90824c7Svetoslav Ganovimport android.database.ContentObserver; 3405b08a50f86a91ab2db6b7e47febadc593972609Charles Chenimport android.net.Uri; 35a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.os.Bundle; 36672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.os.Handler; 37672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.os.Message; 3800453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackbornimport android.os.RemoteException; 3905b08a50f86a91ab2db6b7e47febadc593972609Charles Chenimport android.os.SystemProperties; 40a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.preference.CheckBoxPreference; 4182623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganovimport android.preference.ListPreference; 42a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.preference.Preference; 431a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganovimport android.preference.PreferenceActivity; 446e101d125a9b874ff0337b04c94564ccf95ac7c6David Brownimport android.preference.PreferenceCategory; 45a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.preference.PreferenceScreen; 46a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.provider.Settings; 47a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.text.TextUtils; 48672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.text.TextUtils.SimpleStringSplitter; 49672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.view.Gravity; 506e101d125a9b874ff0337b04c94564ccf95ac7c6David Brownimport android.view.KeyCharacterMap; 516e101d125a9b874ff0337b04c94564ccf95ac7c6David Brownimport android.view.KeyEvent; 52672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.view.Menu; 53672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.view.MenuInflater; 54672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.view.MenuItem; 55672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.view.View; 561a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 57a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport android.view.accessibility.AccessibilityManager; 58ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganovimport android.widget.LinearLayout; 59672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.widget.Switch; 60672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport android.widget.TextView; 61a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 62672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport com.android.internal.content.PackageMonitor; 6310fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brownimport com.android.internal.view.RotationPolicy; 64672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport com.android.settings.AccessibilitySettings.ToggleSwitch.OnBeforeCheckedChangeListener; 65672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 66672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport java.util.HashMap; 67a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport java.util.HashSet; 68a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport java.util.List; 69a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganovimport java.util.Map; 70672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolacheimport java.util.Set; 71a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 72a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov/** 73a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov * Activity with the accessibility settings. 74a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov */ 7582623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganovpublic class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable, 7682623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov Preference.OnPreferenceChangeListener { 7705b08a50f86a91ab2db6b7e47febadc593972609Charles Chen private static final String DEFAULT_SCREENREADER_MARKET_LINK = 7805b08a50f86a91ab2db6b7e47febadc593972609Charles Chen "market://search?q=pname:com.google.android.marvin.talkback"; 7905b08a50f86a91ab2db6b7e47febadc593972609Charles Chen 8000453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn private static final float LARGE_FONT_SCALE = 1.3f; 8100453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn 821a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market"; 831a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 84672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Timeout before we update the services if packages are added/removed since 85672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // the AccessibilityManagerService has to do that processing first to generate 86672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // the AccessibilityServiceInfo we need for proper presentation. 87232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000; 88672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 89cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov private static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':'; 90672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 911a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE = 921a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov "key_install_accessibility_service_offered_once"; 931a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 94672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Preference categories 95672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private static final String SERVICES_CATEGORY = "services_category"; 961a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String SYSTEM_CATEGORY = "system_category"; 97672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 98672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Preferences 99672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference"; 100672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE = 101672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache "toggle_power_button_ends_call_preference"; 1022121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE = 1032121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov "toggle_lock_screen_rotation_preference"; 1047e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE = 1057e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov "toggle_speak_password_preference"; 106672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE = 107672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache "select_long_press_timeout_preference"; 108672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private static final String TOGGLE_SCRIPT_INJECTION_PREFERENCE = 109672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache "toggle_script_injection_preference"; 110672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 111672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Extras passed to sub-fragments. 1121a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_PREFERENCE_KEY = "preference_key"; 1131a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_CHECKED = "checked"; 1141a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_TITLE = "title"; 1151a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_SUMMARY = "summary"; 116ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title"; 117ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message"; 118ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final String EXTRA_DISABLE_WARNING_TITLE = "disable_warning_title"; 119ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final String EXTRA_DISABLE_WARNING_MESSAGE = "disable_warning_message"; 1201a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_SETTINGS_TITLE = "settings_title"; 1211a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; 122672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 123672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Dialog IDs. 124ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1; 125a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 126672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Auxiliary members. 127232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov private final static SimpleStringSplitter sStringColonSplitter = 128cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR); 1293d64653d1f8dd58fb05ff845706eda5c7f344d0bSvetoslav Ganov 130232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov private static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>(); 131232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov 132672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private final Map<String, String> mLongPressTimeoutValuetoTitleMap = 133672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache new HashMap<String, String>(); 1346e101d125a9b874ff0337b04c94564ccf95ac7c6David Brown 135672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private final Configuration mCurConfig = new Configuration(); 136cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov 137672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor(); 13882623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov 139672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private final Handler mHandler = new Handler() { 140672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 141672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void dispatchMessage(Message msg) { 142672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.dispatchMessage(msg); 143232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov loadInstalledServices(); 144ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov updateServicesPreferences(); 145672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 146672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache }; 14700453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn 14810fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown private final RotationPolicy.RotationPolicyListener mRotationPolicyListener = 14910fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown new RotationPolicy.RotationPolicyListener() { 1503aa58b0f35c60f7bf4c97a6e12c201abf90824c7Svetoslav Ganov @Override 15110fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown public void onChange() { 15210fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown updateLockScreenRotationCheckbox(); 1533aa58b0f35c60f7bf4c97a6e12c201abf90824c7Svetoslav Ganov } 1543aa58b0f35c60f7bf4c97a6e12c201abf90824c7Svetoslav Ganov }; 1553aa58b0f35c60f7bf4c97a6e12c201abf90824c7Svetoslav Ganov 156672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Preference controls. 157672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private PreferenceCategory mServicesCategory; 1581a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private PreferenceCategory mSystemsCategory; 159672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 160672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private CheckBoxPreference mToggleLargeTextPreference; 161672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private CheckBoxPreference mTogglePowerButtonEndsCallPreference; 1622121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov private CheckBoxPreference mToggleLockScreenRotationPreference; 1637e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov private CheckBoxPreference mToggleSpeakPasswordPreference; 164672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private ListPreference mSelectLongPressTimeoutPreference; 1651a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private AccessibilityEnableScriptInjectionPreference mToggleScriptInjectionPreference; 1669b539cc584821761690d1065b309557265582bbfSvetoslav Ganov private Preference mNoServicesMessagePreference; 1671a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 1681a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private int mLongPressTimeoutDefault; 169a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 170a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov @Override 171d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani public void onCreate(Bundle icicle) { 172a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov super.onCreate(icicle); 173a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov addPreferencesFromResource(R.xml.accessibility_settings); 1741a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov initializeAllPreferences(); 175cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov } 176cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov 177cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov @Override 178672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onResume() { 179672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.onResume(); 180232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov loadInstalledServices(); 181ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov updateAllPreferences(); 182ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (mServicesCategory.getPreference(0) == mNoServicesMessagePreference) { 1831a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov offerInstallAccessibilitySerivceOnce(); 1841a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 1850c2cd20d53f6af983e3ba4661804afdc9756de78Dianne Hackborn mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false); 18610fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown RotationPolicy.registerRotationPolicyListener(getActivity(), 18710fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown mRotationPolicyListener); 188749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov } 189749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov 190749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov @Override 191749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov public void onPause() { 192672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSettingsPackageMonitor.unregister(); 19310fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown RotationPolicy.unregisterRotationPolicyListener(getActivity(), 19410fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown mRotationPolicyListener); 1951a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov super.onPause(); 1961a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 1971a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 19882623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov public boolean onPreferenceChange(Preference preference, Object newValue) { 199672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (preference == mSelectLongPressTimeoutPreference) { 2001a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov String stringValue = (String) newValue; 20182623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov Settings.Secure.putInt(getContentResolver(), 2021a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue)); 203672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSelectLongPressTimeoutPreference.setSummary( 2041a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mLongPressTimeoutValuetoTitleMap.get(stringValue)); 20582623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov return true; 20682623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov } 20782623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov return false; 20882623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov } 20982623019d21ceb36aaa9711a4267147883442ce3Svetoslav Ganov 210a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov @Override 211a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 212672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (mToggleLargeTextPreference == preference) { 2131a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov handleToggleLargeTextPreferenceClick(); 214672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return true; 215672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } else if (mTogglePowerButtonEndsCallPreference == preference) { 2161a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov handleTogglePowerButtonEndsCallPreferenceClick(); 217672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return true; 2182121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov } else if (mToggleLockScreenRotationPreference == preference) { 2192121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov handleLockScreenRotationPreferenceClick(); 220ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov return true; 2217e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov } else if (mToggleSpeakPasswordPreference == preference) { 2227e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov handleToggleSpeakPasswordPreferenceClick(); 223a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 224a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov return super.onPreferenceTreeClick(preferenceScreen, preference); 225a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 226a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 2271a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private void handleToggleLargeTextPreferenceClick() { 228672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache try { 2291a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1; 230672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig); 2311a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } catch (RemoteException re) { 232672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache /* ignore */ 2333d64653d1f8dd58fb05ff845706eda5c7f344d0bSvetoslav Ganov } 2343d64653d1f8dd58fb05ff845706eda5c7f344d0bSvetoslav Ganov } 2353d64653d1f8dd58fb05ff845706eda5c7f344d0bSvetoslav Ganov 2361a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private void handleTogglePowerButtonEndsCallPreferenceClick() { 2371a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov Settings.Secure.putInt(getContentResolver(), 2381a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2391a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov (mTogglePowerButtonEndsCallPreference.isChecked() 2401a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP 2411a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF)); 242a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 243a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 2442121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov private void handleLockScreenRotationPreferenceClick() { 24510fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown RotationPolicy.setRotationLockForAccessibility(getActivity(), 24610fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown !mToggleLockScreenRotationPreference.isChecked()); 2471a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 2481a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 2497e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov private void handleToggleSpeakPasswordPreferenceClick() { 2507e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov Settings.Secure.putInt(getContentResolver(), 2517e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 2527e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov mToggleSpeakPasswordPreference.isChecked() ? 1 : 0); 2537e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov } 2547e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov 2551a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private void initializeAllPreferences() { 256672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY); 2571a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY); 2581a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 2591a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Large text. 2601a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mToggleLargeTextPreference = 2611a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE); 2621a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 2631a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Power button ends calls. 2641a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mTogglePowerButtonEndsCallPreference = 2651a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE); 266ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) 267ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov || !Utils.isVoiceCapable(getActivity())) { 2681a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference); 2691a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 2701a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 2712121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov // Lock screen rotation. 2722121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov mToggleLockScreenRotationPreference = 2732121f097c092cace1fb49f9d4b9c12f16ab20ab0Svetoslav Ganov (CheckBoxPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE); 274ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 2757e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov // Speak passwords. 2767e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov mToggleSpeakPasswordPreference = 2777e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov (CheckBoxPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE); 2787e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov 2791a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Long press timeout. 2801a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mSelectLongPressTimeoutPreference = 2811a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov (ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE); 282672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this); 2831a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (mLongPressTimeoutValuetoTitleMap.size() == 0) { 2841a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov String[] timeoutValues = getResources().getStringArray( 2851a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov R.array.long_press_timeout_selector_values); 2861a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]); 2871a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov String[] timeoutTitles = getResources().getStringArray( 2881a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov R.array.long_press_timeout_selector_titles); 2891a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov final int timeoutValueCount = timeoutValues.length; 2901a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov for (int i = 0; i < timeoutValueCount; i++) { 2911a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]); 2921a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 2931a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 2941a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 2951a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Script injection. 2961a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mToggleScriptInjectionPreference = (AccessibilityEnableScriptInjectionPreference) 2971a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE); 298a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 299a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 300ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private void updateAllPreferences() { 301ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov updateServicesPreferences(); 302ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov updateSystemPreferences(); 3031a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 3041a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 305ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private void updateServicesPreferences() { 3061a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Since services category is auto generated we have to do a pass 3071a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // to generate it since services can come and go and then based on 3081a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // the global accessibility state to decided whether it is enabled. 3091a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 3101a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Generate. 311672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mServicesCategory.removeAll(); 312672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 313672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity()); 314a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 3156f0b4d8143858e41cede1f935230e2a430b9fd2dSvetoslav Ganov List<AccessibilityServiceInfo> installedServices = 3166f0b4d8143858e41cede1f935230e2a430b9fd2dSvetoslav Ganov accessibilityManager.getInstalledAccessibilityServiceList(); 317cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity()); 318a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 319cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov final boolean accessibilityEnabled = Settings.Secure.getInt(getContentResolver(), 320cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; 321a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov 322a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov for (int i = 0, count = installedServices.size(); i < count; ++i) { 323672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache AccessibilityServiceInfo info = installedServices.get(i); 324672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 325672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache PreferenceScreen preference = getPreferenceManager().createPreferenceScreen( 326672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache getActivity()); 327672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache String title = info.getResolveInfo().loadLabel(getPackageManager()).toString(); 328672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 329672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; 330672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ComponentName componentName = new ComponentName(serviceInfo.packageName, 331672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache serviceInfo.name); 332abc95ee82295b82ad0475a8b4c55a5196a5f014aSvetoslav Ganov 333672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preference.setKey(componentName.flattenToString()); 334672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 335672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preference.setTitle(title); 336cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov final boolean serviceEnabled = accessibilityEnabled 337cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov && enabledServices.contains(componentName); 338cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov if (serviceEnabled) { 339672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preference.setSummary(getString(R.string.accessibility_service_state_on)); 340672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } else { 341672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preference.setSummary(getString(R.string.accessibility_service_state_off)); 342672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 343672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 344672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preference.setOrder(i); 345ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName()); 3461a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov preference.setPersistent(true); 347672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 348672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Bundle extras = preference.getExtras(); 349672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey()); 350cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov extras.putBoolean(EXTRA_CHECKED, serviceEnabled); 351672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache extras.putString(EXTRA_TITLE, title); 3521a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 35363ad27860b870651bba9cdb713b767727b3a179dSvetoslav Ganov String description = info.loadDescription(getPackageManager()); 3541a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (TextUtils.isEmpty(description)) { 3551a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov description = getString(R.string.accessibility_service_default_description); 3561a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 3571a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov extras.putString(EXTRA_SUMMARY, description); 3581a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 359ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov CharSequence applicationLabel = info.getResolveInfo().loadLabel(getPackageManager()); 360ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 361ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString( 362ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov R.string.accessibility_service_security_warning_title, applicationLabel)); 363ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString( 364ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov R.string.accessibility_service_security_warning_summary, applicationLabel)); 365ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 366ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov extras.putString(EXTRA_DISABLE_WARNING_TITLE, getString( 367ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov R.string.accessibility_service_disable_warning_title, 368ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov applicationLabel)); 369ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov extras.putString(EXTRA_DISABLE_WARNING_MESSAGE, getString( 370ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov R.string.accessibility_service_disable_warning_summary, 371ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov applicationLabel)); 372672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 373672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache String settingsClassName = info.getSettingsActivityName(); 374672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (!TextUtils.isEmpty(settingsClassName)) { 375672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache extras.putString(EXTRA_SETTINGS_TITLE, 376672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache getString(R.string.accessibility_menu_item_settings)); 377672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache extras.putString(EXTRA_SETTINGS_COMPONENT_NAME, 378672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache new ComponentName(info.getResolveInfo().serviceInfo.packageName, 379672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache settingsClassName).flattenToString()); 380cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov } 381672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 382672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mServicesCategory.addPreference(preference); 383a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 3841a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 385ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (mServicesCategory.getPreferenceCount() == 0) { 386ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (mNoServicesMessagePreference == null) { 387ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mNoServicesMessagePreference = new Preference(getActivity()) { 388ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov @Override 389ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov protected void onBindView(View view) { 390ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov super.onBindView(view); 391ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 392ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov LinearLayout containerView = 393ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov (LinearLayout) view.findViewById(R.id.message_container); 394ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov containerView.setGravity(Gravity.CENTER); 395ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 396ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov TextView summaryView = (TextView) view.findViewById(R.id.summary); 3979b539cc584821761690d1065b309557265582bbfSvetoslav Ganov String title = getString(R.string.accessibility_no_services_installed); 398ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov summaryView.setText(title); 399ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov } 400ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov }; 401ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mNoServicesMessagePreference.setPersistent(false); 402ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mNoServicesMessagePreference.setLayoutResource( 403ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov R.layout.text_description_preference); 404ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mNoServicesMessagePreference.setSelectable(false); 405ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov } 406ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mServicesCategory.addPreference(mNoServicesMessagePreference); 407ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov } 408a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov } 40905b08a50f86a91ab2db6b7e47febadc593972609Charles Chen 410ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private void updateSystemPreferences() { 411672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Large text. 41200453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn try { 413ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration()); 414672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } catch (RemoteException re) { 415672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache /* ignore */ 41600453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn } 417ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE); 418672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 4191a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Power button ends calls. 420ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) 421ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov && Utils.isVoiceCapable(getActivity())) { 422ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(), 4231a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 424ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); 425ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov final boolean powerButtonEndsCall = 426ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov (incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP); 427ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall); 428672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 429672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 430ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov // Auto-rotate screen 43110fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown updateLockScreenRotationCheckbox(); 432ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 4337e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov // Speak passwords. 4347e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(), 4357e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0; 4367e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled); 4377e8dcbea65356807ca052ee5e98c9b25b7f0b1caSvetoslav Ganov 438672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Long press timeout. 439ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov final int longPressTimeout = Settings.Secure.getInt(getContentResolver(), 440ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault); 441ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov String value = String.valueOf(longPressTimeout); 442ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mSelectLongPressTimeoutPreference.setValue(value); 4431a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value)); 444672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 445672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Script injection. 446ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov final boolean scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(), 447ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1); 448ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mToggleScriptInjectionPreference.setInjectionAllowed(scriptInjectionAllowed); 4491a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 4501a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 45110fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown private void updateLockScreenRotationCheckbox() { 452b5858bbdc363e21bf87ac5643822ec9e57956c52Jeff Brown Context context = getActivity(); 453b5858bbdc363e21bf87ac5643822ec9e57956c52Jeff Brown if (context != null) { 454b5858bbdc363e21bf87ac5643822ec9e57956c52Jeff Brown mToggleLockScreenRotationPreference.setChecked( 455b5858bbdc363e21bf87ac5643822ec9e57956c52Jeff Brown !RotationPolicy.isRotationLocked(context)); 456b5858bbdc363e21bf87ac5643822ec9e57956c52Jeff Brown } 45710fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown } 45810fbf52ccb5c6657eef3bbe520c71ff7f729bad3Jeff Brown 4591a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private void offerInstallAccessibilitySerivceOnce() { 4609b539cc584821761690d1065b309557265582bbfSvetoslav Ganov // There is always one preference - if no services it is just a message. 4619b539cc584821761690d1065b309557265582bbfSvetoslav Ganov if (mServicesCategory.getPreference(0) != mNoServicesMessagePreference) { 4621a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov return; 4631a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 4641a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov SharedPreferences preferences = getActivity().getPreferences(Context.MODE_PRIVATE); 4651a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov final boolean offerInstallService = !preferences.getBoolean( 4661a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE, false); 4671a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (offerInstallService) { 4681a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov preferences.edit().putBoolean(KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE, 4691a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov true).commit(); 4701a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Notify user that they do not have any accessibility 4711a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // services installed and direct them to Market to get TalkBack. 4721a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES); 473672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 47400453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn } 47500453157ae62d3ba63fe42eccf5113d89e15cab7Dianne Hackborn 476cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov @Override 477cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov public Dialog onCreateDialog(int dialogId) { 478cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov switch (dialogId) { 479cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov case DIALOG_ID_NO_ACCESSIBILITY_SERVICES: 480cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov return new AlertDialog.Builder(getActivity()) 481cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov .setTitle(R.string.accessibility_service_no_apps_title) 482cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov .setMessage(R.string.accessibility_service_no_apps_message) 483cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov .setPositiveButton(android.R.string.ok, 484cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov new DialogInterface.OnClickListener() { 485cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov public void onClick(DialogInterface dialog, int which) { 486cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov // dismiss the dialog before launching the activity otherwise 487cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov // the dialog removal occurs after onSaveInstanceState which 488cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov // triggers an exception 4891a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov removeDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES); 490cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov String screenreaderMarketLink = SystemProperties.get( 4911a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov SYSTEM_PROPERTY_MARKET_URL, 4921a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov DEFAULT_SCREENREADER_MARKET_LINK); 493cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov Uri marketUri = Uri.parse(screenreaderMarketLink); 494cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri); 495cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov startActivity(marketIntent); 496cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov } 497cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov }) 498cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov .setNegativeButton(android.R.string.cancel, null) 499cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov .create(); 500cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov default: 501cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov return null; 502cdd8e34b4fd2a751490b5adfae048563fa14d9d5Svetoslav Ganov } 50305b08a50f86a91ab2db6b7e47febadc593972609Charles Chen } 504672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 505232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov private void loadInstalledServices() { 506232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov List<AccessibilityServiceInfo> installedServiceInfos = 507232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov AccessibilityManager.getInstance(getActivity()) 508232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov .getInstalledAccessibilityServiceList(); 509232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov Set<ComponentName> installedServices = sInstalledServices; 510232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov installedServices.clear(); 511232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov final int installedServiceInfoCount = installedServiceInfos.size(); 512232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov for (int i = 0; i < installedServiceInfoCount; i++) { 513232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo(); 514232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov ComponentName installedService = new ComponentName( 515232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov resolveInfo.serviceInfo.packageName, 516232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov resolveInfo.serviceInfo.name); 517232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov installedServices.add(installedService); 518232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov } 519232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov } 520232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov 521cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov private static Set<ComponentName> getEnabledServicesFromSettings(Context context) { 522cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(), 523cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 524cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov if (enabledServicesSetting == null) { 525cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov enabledServicesSetting = ""; 526cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov } 527cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov Set<ComponentName> enabledServices = new HashSet<ComponentName>(); 528cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov SimpleStringSplitter colonSplitter = sStringColonSplitter; 529cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov colonSplitter.setString(enabledServicesSetting); 530cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov while (colonSplitter.hasNext()) { 531cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov String componentNameString = colonSplitter.next(); 532cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov ComponentName enabledService = ComponentName.unflattenFromString( 533cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov componentNameString); 534cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov if (enabledService != null) { 535cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov enabledServices.add(enabledService); 536cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov } 537cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov } 538cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov return enabledServices; 539cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov } 540cb0a7a82a6c747fafd6c46c2949396a0b549a104Svetoslav Ganov 541672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private class SettingsPackageMonitor extends PackageMonitor { 542672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 543672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 544672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onPackageAdded(String packageName, int uid) { 545672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Message message = mHandler.obtainMessage(); 546232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS); 547672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 548672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 549672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 550672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onPackageAppeared(String packageName, int reason) { 551672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Message message = mHandler.obtainMessage(); 552232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS); 553672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 554672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 555672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 556672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onPackageDisappeared(String packageName, int reason) { 557672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Message message = mHandler.obtainMessage(); 558232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS); 559672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 560672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 561672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 562672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onPackageRemoved(String packageName, int uid) { 563672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Message message = mHandler.obtainMessage(); 564232d031a13244e8a2a9a56909e9cdaa2b35f6e00Svetoslav Ganov mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS); 565672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 566672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 567672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 5681a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private static ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) { 569672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ToggleSwitch toggleSwitch = new ToggleSwitch(activity); 570672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache final int padding = activity.getResources().getDimensionPixelSize( 571672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache R.dimen.action_bar_switch_padding); 572672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache toggleSwitch.setPadding(0, 0, padding, 0); 573672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 574672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ActionBar.DISPLAY_SHOW_CUSTOM); 575672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache activity.getActionBar().setCustomView(toggleSwitch, 576672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, 577672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ActionBar.LayoutParams.WRAP_CONTENT, 578672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Gravity.CENTER_VERTICAL | Gravity.RIGHT)); 579672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return toggleSwitch; 580672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 581672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 582672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public static class ToggleSwitch extends Switch { 583672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 584672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private OnBeforeCheckedChangeListener mOnBeforeListener; 585672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 586672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public static interface OnBeforeCheckedChangeListener { 587672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked); 588672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 589672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 590672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public ToggleSwitch(Context context) { 591672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super(context); 592672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 593672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 594672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) { 595672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mOnBeforeListener = listener; 596672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 597672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 598672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 599672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void setChecked(boolean checked) { 600672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (mOnBeforeListener != null 601672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) { 602672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return; 603672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 604672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.setChecked(checked); 605672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 606672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 6071a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov public void setCheckedInternal(boolean checked) { 608672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.setChecked(checked); 609672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 610672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 611672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 612ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov public static class ToggleAccessibilityServicePreferenceFragment 613ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov extends SettingsPreferenceFragment implements DialogInterface.OnClickListener { 614672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 615ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final int DIALOG_ID_ENABLE_WARNING = 1; 616ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private static final int DIALOG_ID_DISABLE_WARNING = 2; 617672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 618672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private String mPreferenceKey; 619672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 620672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private ToggleSwitch mToggleSwitch; 621672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 622ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private CharSequence mEnableWarningTitle; 623ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private CharSequence mEnableWarningMessage; 624ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private CharSequence mDisableWarningTitle; 625ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private CharSequence mDisableWarningMessage; 626ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov 627672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private Preference mSummaryPreference; 628672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 629672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private CharSequence mSettingsTitle; 630672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private Intent mSettingsIntent; 631672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 632ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov private int mShownDialogId; 633ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 6341a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // TODO: Showing sub-sub fragment does not handle the activity title 6351a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // so we do it but this is wrong. Do a real fix when there is time. 6361a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private CharSequence mOldActivityTitle; 637672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 638672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 639672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onCreate(Bundle savedInstanceState) { 640672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.onCreate(savedInstanceState); 641672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen( 642672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache getActivity()); 643672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache setPreferenceScreen(preferenceScreen); 644672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSummaryPreference = new Preference(getActivity()) { 645672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 646672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache protected void onBindView(View view) { 647672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.onBindView(view); 648672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache TextView summaryView = (TextView) view.findViewById(R.id.summary); 649672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache summaryView.setText(getSummary()); 6501a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov sendAccessibilityEvent(summaryView); 6511a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 6521a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 6531a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov private void sendAccessibilityEvent(View view) { 6541a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // Since the view is still not attached we create, populate, 6551a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // and send the event directly since we do not know when it 6561a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov // will be attached and posting commands is not as clean. 6571a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov AccessibilityManager accessibilityManager = 6581a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov AccessibilityManager.getInstance(getActivity()); 6591a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (accessibilityManager.isEnabled()) { 6601a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov AccessibilityEvent event = AccessibilityEvent.obtain(); 6611a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED); 6621a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov view.onInitializeAccessibilityEvent(event); 6631a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov view.dispatchPopulateAccessibilityEvent(event); 6641a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov accessibilityManager.sendAccessibilityEvent(event); 6651a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 666672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 667672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache }; 668672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSummaryPreference.setPersistent(false); 669672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSummaryPreference.setLayoutResource(R.layout.text_description_preference); 670672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache preferenceScreen.addPreference(mSummaryPreference); 671672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 672672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 6731a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov @Override 6741a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov public void onViewCreated(View view, Bundle savedInstanceState) { 6751a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov super.onViewCreated(view, savedInstanceState); 6761a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov installActionBarToggleSwitch(); 6771a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov processArguments(); 6781a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov getListView().setDivider(null); 6791a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov getListView().setEnabled(false); 6801a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 6811a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 6821a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov @Override 6831a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov public void onDestroyView() { 6841a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov getActivity().getActionBar().setCustomView(null); 6851a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (mOldActivityTitle != null) { 6861a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov getActivity().getActionBar().setTitle(mOldActivityTitle); 6871a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 6881b52e0d0240040478ebbe9ac2244816c39ddcd4eAmith Yamasani mToggleSwitch.setOnBeforeCheckedChangeListener(null); 6891a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov super.onDestroyView(); 6901a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 6911a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov 692ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov public void onPreferenceToggled(String preferenceKey, boolean enabled) { 693ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Parse the enabled services. 694ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Set<ComponentName> enabledServices = getEnabledServicesFromSettings(getActivity()); 695ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov 696ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Determine enabled services and accessibility state. 697ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey); 698ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov final boolean accessibilityEnabled; 699ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov if (enabled) { 700ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Enabling at least one service enables accessibility. 701ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov accessibilityEnabled = true; 702ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServices.add(toggledService); 703ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } else { 704ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Check how many enabled and installed services are present. 705ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov int enabledAndInstalledServiceCount = 0; 706ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Set<ComponentName> installedServices = sInstalledServices; 707ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov for (ComponentName enabledService : enabledServices) { 708ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov if (installedServices.contains(enabledService)) { 709ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledAndInstalledServiceCount++; 710ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 711ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 712ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Disabling the last service disables accessibility. 713ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov accessibilityEnabled = enabledAndInstalledServiceCount > 1 714ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov || (enabledAndInstalledServiceCount == 1 715ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov && !installedServices.contains(toggledService)); 716ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServices.remove(toggledService); 717ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 718ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov 719ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Update the enabled services setting. 720ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov StringBuilder enabledServicesBuilder = new StringBuilder(); 721ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Keep the enabled services even if they are not installed since we have 722ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // no way to know whether the application restore process has completed. 723ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // In general the system should be responsible for the clean up not settings. 724ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov for (ComponentName enabledService : enabledServices) { 725ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServicesBuilder.append(enabledService.flattenToString()); 726ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServicesBuilder.append(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR); 727ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 728ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov final int enabledServicesBuilderLength = enabledServicesBuilder.length(); 729ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov if (enabledServicesBuilderLength > 0) { 730ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1); 731ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 732ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Settings.Secure.putString(getContentResolver(), 733ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, 734ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov enabledServicesBuilder.toString()); 735ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov 736ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov // Update accessibility enabled. 737ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Settings.Secure.putInt(getContentResolver(), 738ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0); 739ec94c78ec82893254a71fc2d7f05c7b32a776a8eSvetoslav Ganov } 740672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 741672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 742672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 743672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache super.onCreateOptionsMenu(menu, inflater); 744672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache MenuItem menuItem = menu.add(mSettingsTitle); 745ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 746672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache menuItem.setIntent(mSettingsIntent); 747672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 748672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 749672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 750672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public Dialog onCreateDialog(int dialogId) { 751ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov CharSequence title = null; 752ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov CharSequence message = null; 753672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache switch (dialogId) { 754ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov case DIALOG_ID_ENABLE_WARNING: 755ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mShownDialogId = DIALOG_ID_ENABLE_WARNING; 756ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov title = mEnableWarningTitle; 757ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov message = mEnableWarningMessage; 758ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov break; 759ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov case DIALOG_ID_DISABLE_WARNING: 760ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mShownDialogId = DIALOG_ID_DISABLE_WARNING; 761ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov title = mDisableWarningTitle; 762ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov message = mDisableWarningMessage; 763ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov break; 764672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache default: 765672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache throw new IllegalArgumentException(); 766672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 767ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov return new AlertDialog.Builder(getActivity()) 768ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setTitle(title) 769ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setIcon(android.R.drawable.ic_dialog_alert) 770ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setMessage(message) 771ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setCancelable(true) 772ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setPositiveButton(android.R.string.ok, this) 773ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .setNegativeButton(android.R.string.cancel, this) 774ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov .create(); 775672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 776672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 777672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 778672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public void onClick(DialogInterface dialog, int which) { 779ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov final boolean checked; 780672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache switch (which) { 781672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache case DialogInterface.BUTTON_POSITIVE: 782ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov checked = (mShownDialogId == DIALOG_ID_ENABLE_WARNING); 783ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mToggleSwitch.setCheckedInternal(checked); 78496832f8cced282a1bca1bb7e4b1325cfa64f380dSvetoslav Ganov getArguments().putBoolean(EXTRA_CHECKED, checked); 785ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov onPreferenceToggled(mPreferenceKey, checked); 786672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache break; 787672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache case DialogInterface.BUTTON_NEGATIVE: 788ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING); 789ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mToggleSwitch.setCheckedInternal(checked); 79096832f8cced282a1bca1bb7e4b1325cfa64f380dSvetoslav Ganov getArguments().putBoolean(EXTRA_CHECKED, checked); 791ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov onPreferenceToggled(mPreferenceKey, checked); 792672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache break; 793672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache default: 794672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache throw new IllegalArgumentException(); 795672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 796672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 797672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 798672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private void installActionBarToggleSwitch() { 7991a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity()); 800672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() { 801672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache @Override 802672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) { 803672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (checked) { 804ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (!TextUtils.isEmpty(mEnableWarningMessage)) { 8051a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov toggleSwitch.setCheckedInternal(false); 80696832f8cced282a1bca1bb7e4b1325cfa64f380dSvetoslav Ganov getArguments().putBoolean(EXTRA_CHECKED, false); 807ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov showDialog(DIALOG_ID_ENABLE_WARNING); 808672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return true; 809672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 810672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache onPreferenceToggled(mPreferenceKey, true); 811672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } else { 812ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov if (!TextUtils.isEmpty(mDisableWarningMessage)) { 813ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov toggleSwitch.setCheckedInternal(true); 81496832f8cced282a1bca1bb7e4b1325cfa64f380dSvetoslav Ganov getArguments().putBoolean(EXTRA_CHECKED, true); 815ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov showDialog(DIALOG_ID_DISABLE_WARNING); 816ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov return true; 817ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov } 818672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache onPreferenceToggled(mPreferenceKey, false); 819672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 820672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache return false; 821672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 822672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache }); 823672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 824672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 825672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache private void processArguments() { 826672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Bundle arguments = getArguments(); 827672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 828672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Key. 829672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mPreferenceKey = arguments.getString(EXTRA_PREFERENCE_KEY); 830672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 831672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Enabled. 832672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache final boolean enabled = arguments.getBoolean(EXTRA_CHECKED); 8331a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mToggleSwitch.setCheckedInternal(enabled); 834672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 835672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Title. 8361a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov PreferenceActivity activity = (PreferenceActivity) getActivity(); 8371a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) { 8381a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov mOldActivityTitle = getActivity().getTitle(); 8391a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov String title = arguments.getString(EXTRA_TITLE); 840ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov getActivity().getActionBar().setTitle(title); 8411a97fa13d03d0966ccaa1480c33d8bedce734407Svetoslav Ganov } 842672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 843672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Summary. 844672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache String summary = arguments.getString(EXTRA_SUMMARY); 845672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSummaryPreference.setSummary(summary); 846672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 847672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache // Settings title and intent. 848672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache String settingsTitle = arguments.getString(EXTRA_SETTINGS_TITLE); 849672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache String settingsComponentName = arguments.getString(EXTRA_SETTINGS_COMPONENT_NAME); 850672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) { 851672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent( 852672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache ComponentName.unflattenFromString(settingsComponentName.toString())); 853672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) { 854672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSettingsTitle = settingsTitle; 855672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache mSettingsIntent = settingsIntent; 856672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache setHasOptionsMenu(true); 857672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 858672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 859672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache 860ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov // Enable warning title. 861ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mEnableWarningTitle = arguments.getCharSequence( 862ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov AccessibilitySettings.EXTRA_ENABLE_WARNING_TITLE); 863ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 864ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov // Enable warning message. 865ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mEnableWarningMessage = arguments.getCharSequence( 866ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov AccessibilitySettings.EXTRA_ENABLE_WARNING_MESSAGE); 867ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 868ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov // Disable warning title. 869ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mDisableWarningTitle = arguments.getString( 870ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov AccessibilitySettings.EXTRA_DISABLE_WARNING_TITLE); 871ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov 872ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov // Disable warning message. 873ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov mDisableWarningMessage = arguments.getString( 874ea5a50a708389b8ff0d898ffe080149d14377b07Svetoslav Ganov AccessibilitySettings.EXTRA_DISABLE_WARNING_MESSAGE); 875672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 876672b3c6576efa9e8e4ad0ebbea7f0c36ecf77d9bCostin Manolache } 877a05d0dc67eb6aae169308dda25fe235226fa395bsvetoslavganov} 878