Update of accessibility settings

1. Removed the global toggle switch - now each accessibility
   feature has to be turned on or off separately.

2. Added a setting for the screen rotation (same as Dispaly)
   since most of blind users want that behavior.

bug:5166161
bug:5127475

Change-Id: I659aef62a8499461075f43520a3008fa7b8ff911
This commit is contained in:
Svetoslav Ganov
2011-08-31 16:47:57 -07:00
parent 9a4543e1de
commit ea5a50a708
4 changed files with 193 additions and 226 deletions

View File

@@ -15,6 +15,7 @@
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:orientation="vertical" >

View File

@@ -2718,38 +2718,49 @@ found in the list of installed applications.</string>
<!-- Summary for the allowed state of script injection. [CHAR LIMIT=15] --> <!-- Summary for the allowed state of script injection. [CHAR LIMIT=15] -->
<string name="accessibility_script_injection_allowed">Allowed</string> <string name="accessibility_script_injection_allowed">Allowed</string>
<!-- Summary for the disallowed state of script injection. [CHAR LIMIT=15] --> <!-- Summary for the disallowed state of script injection. [CHAR LIMIT=15] -->
<string name="accessibility_script_injection_disallowed">Disallowed</string> <string name="accessibility_script_injection_disallowed">Not allowed</string>
<!-- Title for the dialog button to allow script injection. [CHAR LIMIT=15] --> <!-- Title for the dialog button to allow script injection. [CHAR LIMIT=15] -->
<string name="accessibility_script_injection_button_allow">Allow</string> <string name="accessibility_script_injection_button_allow">Allow</string>
<!-- Title for the dialog button to disallow script injection. [CHAR LIMIT=15] --> <!-- Title for the dialog button to disallow script injection. [CHAR LIMIT=15] -->
<string name="accessibility_script_injection_button_disallow">Don\'t Allow</string> <string name="accessibility_script_injection_button_disallow">Don\'t Allow</string>
<!-- Warning message about security implications of enabling an accessibility service, <!-- Title for a warning message about security implications of enabling an accessibility service,
displayed as a dialog message when the user selects to enable an accessibility service (tablet). [CHAR LIMIT=NONE] --> displayed as a dialog message when the user selects to enable an accessibility service (tablet). [CHAR LIMIT=NONE] -->
<string name="accessibility_service_security_warning"> <string name="accessibility_service_security_warning_title">Use
<xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
<!-- Summary for a warning message about security implications of enabling an accessibility service,
displayed as a dialog message when the user selects to enable an accessibility service (tablet). [CHAR LIMIT=NONE] -->
<string name="accessibility_service_security_warning_summary">
<xliff:g id="accessibility_service_name">%1$s</xliff:g> can <xliff:g id="accessibility_service_name">%1$s</xliff:g> can
collect all of the text you type, except passwords. This includes personal data such as credit card collect all of the text you type, except passwords. This includes personal data such as credit card
numbers. It can also collect data about your interactions with the device.</string> numbers. It can also collect data about your interactions with the device.</string>
<!-- Title for a warning about disabling accessibility displayed as a dialog message when the user
selects to disable accessibility. This avoids accidental disabling. [CHAR LIMIT=30] --> <!-- Title for a warning about disabling an accessibility service displayed as a dialog message when the user
<string name="accessibility_disable_warning_title">Turn accessibility off?</string> selects to disable that service. This avoids accidental disabling. [CHAR LIMIT=NONE] -->
<!-- Summary for a warning about disabling accessibility displayed as a dialog message when the user <string name="accessibility_service_disable_warning_title">Stop
selects to disable accessibility. This avoids accidental disabling. [CHAR LIMIT=NONE] --> <xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
<string name="accessibility_disable_warning_summary">Touching OK will stop spoken <!-- Summary for a warning about disabling accessibility service displayed as a dialog message when the user
descriptions and all other accessibility features you\'ve been using.</string> selects to disable that service. This avoids accidental disabling. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_disable_warning_summary">Touching OK will
stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>.</string>
<!-- Title for the prompt that lets users know that they have no accessibility related apps <!-- Title for the prompt that lets users know that they have no accessibility related apps
installed and that they can install TalkBack from Market. [CHAR LIMIT=50] --> installed and that they can install TalkBack from Market. [CHAR LIMIT=50] -->
<string name="accessibility_service_no_apps_title">No accessibility applications <string name="accessibility_service_no_apps_title">No accessibility applications</string>
</string>
<!-- Message for the prompt that lets users know that they have no accessibility related apps <!-- Message for the prompt that lets users know that they have no accessibility related apps
installed and that they can install TalkBack from Market. [CHAR LIMIT=NONE] --> installed and that they can install TalkBack from Market. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_no_apps_message">You don\'t have accessibility <string name="accessibility_service_no_apps_message">You don\'t have accessibility
applications installed. Do you want to download a screen reader from the Android Market?</string> applications installed. Do you want to download a screen reader from the Android Market?</string>
<!-- Title for a warning about downloading accessibility scripts displayed as a dialog message
when the user selects to enable script downloading. [CHAR LIMIT=40] -->
<string name="accessibility_script_injection_security_warning_title">Install accessibility scripts?</string>
<!-- Warning message about security implications of downloading accessibility scripts, <!-- Warning message about security implications of downloading accessibility scripts,
displayed as a dialog message when the user selects to enable script downloading. [CHAR LIMIT=NONE] --> displayed as a dialog message when the user selects to enable script downloading. [CHAR LIMIT=NONE] -->
<string name="accessibility_script_injection_security_warning">Do you want applications to install <string name="accessibility_script_injection_security_warning_summary">Do you want applications to install
scripts from Google that will make their content more accessible?</string> scripts from Google that will make their content more accessible?</string>
<!-- Warning message that the interaction model changes on enabling touch exploration. [CHAR LIMIT=NONE] --> <!-- Warning message that the interaction model changes on enabling touch exploration. [CHAR LIMIT=NONE] -->
<string name="accessibility_touch_exploration_warning">This feature changes the <string name="accessibility_touch_exploration_warning">This feature changes the
way your device responds to touch. Turn on?</string> way your device responds to touch. Turn on?</string>
@@ -2757,6 +2768,7 @@ found in the list of installed applications.</string>
<string name="accessibility_service_default_description">This accessibility service has no <string name="accessibility_service_default_description">This accessibility service has no
description.\n\nAccessibility services provide various types of feedback when you interact description.\n\nAccessibility services provide various types of feedback when you interact
with the device. </string> with the device. </string>
<!-- Accessibility settings: button for lauching settings for an accessibility service --> <!-- Accessibility settings: button for lauching settings for an accessibility service -->
<string name="settings_button">Settings</string> <string name="settings_button">Settings</string>

View File

@@ -30,13 +30,17 @@
<CheckBoxPreference <CheckBoxPreference
android:key="toggle_large_text_preference" android:key="toggle_large_text_preference"
android:title="@string/accessibility_toggle_large_text_title" android:title="@string/accessibility_toggle_large_text_title"
android:persistent="true"/> android:persistent="false"/>
<CheckBoxPreference <CheckBoxPreference
android:key="toggle_power_button_ends_call_preference" android:key="toggle_power_button_ends_call_preference"
android:title="@string/accessibility_power_button_ends_call_title" android:title="@string/accessibility_power_button_ends_call_title"
android:persistent="true"> android:persistent="false"/>
</CheckBoxPreference>
<CheckBoxPreference
android:key="toggle_auto_rotate_screen_preference"
android:title="@string/accelerometer_title"
android:persistent="false"/>
<PreferenceScreen <PreferenceScreen
android:key="toggle_touch_exploration_preference" android:key="toggle_touch_exploration_preference"
@@ -44,7 +48,8 @@
android:fragment="com.android.settings.AccessibilitySettings$ToggleTouchExplorationFragment" > android:fragment="com.android.settings.AccessibilitySettings$ToggleTouchExplorationFragment" >
<extra android:name="title" android:value="@string/accessibility_touch_exploration_title" /> <extra android:name="title" android:value="@string/accessibility_touch_exploration_title" />
<extra android:name="summary" android:value="@string/accessibility_touch_exploration_summary" /> <extra android:name="summary" android:value="@string/accessibility_touch_exploration_summary" />
<extra android:name="warning_message" android:value="@string/accessibility_touch_exploration_warning" /> <extra android:name="enable_warning_title" android:value="@android:string/dialog_alert_title" />
<extra android:name="enable_warning_message" android:value="@string/accessibility_touch_exploration_warning" />
<extra android:name="settings_title" android:value="@string/accessibility_menu_item_tutorial" /> <extra android:name="settings_title" android:value="@string/accessibility_menu_item_tutorial" />
<extra android:name="settings_component_name" android:value="com.android.settings/com.android.settings.AccessibilityTutorialActivity" /> <extra android:name="settings_component_name" android:value="com.android.settings/com.android.settings.AccessibilityTutorialActivity" />
</PreferenceScreen> </PreferenceScreen>
@@ -53,17 +58,17 @@
android:title="@string/accessibility_long_press_timeout_title" android:title="@string/accessibility_long_press_timeout_title"
android:entries="@array/long_press_timeout_selector_titles" android:entries="@array/long_press_timeout_selector_titles"
android:entryValues="@array/long_press_timeout_selector_values" android:entryValues="@array/long_press_timeout_selector_values"
android:persistent="true" /> android:persistent="false"/>
<com.android.settings.AccessibilityEnableScriptInjectionPreference <com.android.settings.AccessibilityEnableScriptInjectionPreference
android:key="toggle_script_injection_preference" android:key="toggle_script_injection_preference"
android:title="@string/accessibility_script_injection_title" android:title="@string/accessibility_script_injection_title"
android:dialogTitle="@android:string/dialog_alert_title" android:dialogTitle="@string/accessibility_script_injection_security_warning_title"
android:dialogIcon="@android:drawable/ic_dialog_alert" android:dialogIcon="@android:drawable/ic_dialog_alert"
android:dialogMessage="@string/accessibility_script_injection_security_warning" android:dialogMessage="@string/accessibility_script_injection_security_warning_summary"
android:positiveButtonText="@string/accessibility_script_injection_button_allow" android:positiveButtonText="@string/accessibility_script_injection_button_allow"
android:negativeButtonText="@string/accessibility_script_injection_button_disallow" android:negativeButtonText="@string/accessibility_script_injection_button_disallow"
android:persistent="true" /> android:persistent="false"/>
</PreferenceCategory> </PreferenceCategory>

View File

@@ -53,6 +53,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.LinearLayout;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
@@ -99,6 +100,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference"; private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference";
private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE = private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
"toggle_power_button_ends_call_preference"; "toggle_power_button_ends_call_preference";
private static final String TOGGLE_AUTO_ROTATE_SCREEN_PREFERENCE =
"toggle_auto_rotate_screen_preference";
private static final String TOGGLE_TOUCH_EXPLORATION_PREFERENCE = private static final String TOGGLE_TOUCH_EXPLORATION_PREFERENCE =
"toggle_touch_exploration_preference"; "toggle_touch_exploration_preference";
private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE = private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
@@ -111,13 +114,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private static final String EXTRA_CHECKED = "checked"; private static final String EXTRA_CHECKED = "checked";
private static final String EXTRA_TITLE = "title"; private static final String EXTRA_TITLE = "title";
private static final String EXTRA_SUMMARY = "summary"; private static final String EXTRA_SUMMARY = "summary";
private static final String EXTRA_WARNING_MESSAGE = "warning_message"; private static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title";
private static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message";
private static final String EXTRA_DISABLE_WARNING_TITLE = "disable_warning_title";
private static final String EXTRA_DISABLE_WARNING_MESSAGE = "disable_warning_message";
private static final String EXTRA_SETTINGS_TITLE = "settings_title"; private static final String EXTRA_SETTINGS_TITLE = "settings_title";
private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
// Dialog IDs. // Dialog IDs.
private static final int DIALOG_ID_DISABLE_ACCESSIBILITY = 1; private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 2;
// Auxiliary members. // Auxiliary members.
private final SimpleStringSplitter mStringColonSplitter = private final SimpleStringSplitter mStringColonSplitter =
@@ -134,18 +139,17 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override @Override
public void dispatchMessage(Message msg) { public void dispatchMessage(Message msg) {
super.dispatchMessage(msg); super.dispatchMessage(msg);
updateServicesPreferences(mToggleAccessibilitySwitch.isChecked()); updateServicesPreferences();
} }
}; };
// Preference controls. // Preference controls.
private ToggleSwitch mToggleAccessibilitySwitch;
private PreferenceCategory mServicesCategory; private PreferenceCategory mServicesCategory;
private PreferenceCategory mSystemsCategory; private PreferenceCategory mSystemsCategory;
private CheckBoxPreference mToggleLargeTextPreference; private CheckBoxPreference mToggleLargeTextPreference;
private CheckBoxPreference mTogglePowerButtonEndsCallPreference; private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
private CheckBoxPreference mToggleAutoRotateScreenPreference;
private Preference mToggleTouchExplorationPreference; private Preference mToggleTouchExplorationPreference;
private ListPreference mSelectLongPressTimeoutPreference; private ListPreference mSelectLongPressTimeoutPreference;
private AccessibilityEnableScriptInjectionPreference mToggleScriptInjectionPreference; private AccessibilityEnableScriptInjectionPreference mToggleScriptInjectionPreference;
@@ -162,9 +166,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
final boolean accessibilityEnabled = mToggleAccessibilitySwitch.isChecked(); updateAllPreferences();
updateAllPreferences(accessibilityEnabled); if (mServicesCategory.getPreference(0) == mNoServicesMessagePreference) {
if (accessibilityEnabled) {
offerInstallAccessibilitySerivceOnce(); offerInstallAccessibilitySerivceOnce();
} }
mSettingsPackageMonitor.register(getActivity(), false); mSettingsPackageMonitor.register(getActivity(), false);
@@ -176,18 +179,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
super.onPause(); super.onPause();
} }
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
addToggleAccessibilitySwitch();
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDestroyView() {
removeToggleAccessibilitySwitch();
super.onDestroyView();
}
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mSelectLongPressTimeoutPreference) { if (preference == mSelectLongPressTimeoutPreference) {
String stringValue = (String) newValue; String stringValue = (String) newValue;
@@ -202,13 +193,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
final String key = preference.getKey();
if (mToggleLargeTextPreference == preference) { if (mToggleLargeTextPreference == preference) {
handleToggleLargeTextPreferenceClick(); handleToggleLargeTextPreferenceClick();
return true; return true;
} else if (mTogglePowerButtonEndsCallPreference == preference) { } else if (mTogglePowerButtonEndsCallPreference == preference) {
handleTogglePowerButtonEndsCallPreferenceClick(); handleTogglePowerButtonEndsCallPreferenceClick();
return true; return true;
} else if (mToggleAutoRotateScreenPreference == preference) {
handleToggleAutoRotateScreenPreferenceClick();
return true;
} }
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
@@ -230,88 +223,34 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
: Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF)); : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
} }
private void addToggleAccessibilitySwitch() { private void handleToggleAutoRotateScreenPreferenceClick() {
mToggleAccessibilitySwitch = createAndAddActionBarToggleSwitch(getActivity()); Settings.System.putInt(getContentResolver(),
final boolean checked = (Settings.Secure.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION,
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1); (mToggleAutoRotateScreenPreference.isChecked() ? 1 : 0));
mToggleAccessibilitySwitch.setChecked(checked);
mToggleAccessibilitySwitch.setOnBeforeCheckedChangeListener(
new OnBeforeCheckedChangeListener() {
@Override
public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
if (!checked) {
toggleSwitch.setCheckedInternal(true);
showDialog(DIALOG_ID_DISABLE_ACCESSIBILITY);
return true;
}
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 1);
updateAllPreferences(true);
offerInstallAccessibilitySerivceOnce();
return false;
}
});
}
public void removeToggleAccessibilitySwitch() {
mToggleAccessibilitySwitch.setOnBeforeCheckedChangeListener(null);
getActivity().getActionBar().setCustomView(null);
} }
private void initializeAllPreferences() { private void initializeAllPreferences() {
// The basic logic here is if accessibility is not enabled all accessibility
// settings will have no effect but still their selected state should be kept
// unchanged, so the user can see what settings will be enabled when turning
// on accessibility.
final boolean accessibilityEnabled = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1);
mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY); mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY); mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
// Large text. // Large text.
mToggleLargeTextPreference = mToggleLargeTextPreference =
(CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE); (CheckBoxPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE);
if (accessibilityEnabled) {
try {
mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
} catch (RemoteException re) {
/* ignore */
}
mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
}
// Power button ends calls. // Power button ends calls.
mTogglePowerButtonEndsCallPreference = mTogglePowerButtonEndsCallPreference =
(CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE); (CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
&& Utils.isVoiceCapable(getActivity())) { || !Utils.isVoiceCapable(getActivity())) {
if (accessibilityEnabled) {
final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
final boolean powerButtonEndsCall =
(incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
}
} else {
mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference); mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
} }
// Auto-rotate screen
mToggleAutoRotateScreenPreference =
(CheckBoxPreference) findPreference(TOGGLE_AUTO_ROTATE_SCREEN_PREFERENCE);
// Touch exploration enabled. // Touch exploration enabled.
mToggleTouchExplorationPreference = findPreference(TOGGLE_TOUCH_EXPLORATION_PREFERENCE); mToggleTouchExplorationPreference = findPreference(TOGGLE_TOUCH_EXPLORATION_PREFERENCE);
final boolean touchExplorationEnabled = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1);
if (touchExplorationEnabled) {
mToggleTouchExplorationPreference.setSummary(
getString(R.string.accessibility_service_state_on));
mToggleTouchExplorationPreference.getExtras().putBoolean(EXTRA_CHECKED, true);
} else {
mToggleTouchExplorationPreference.setSummary(
getString(R.string.accessibility_service_state_off));
mToggleTouchExplorationPreference.getExtras().putBoolean(EXTRA_CHECKED, false);
}
// Long press timeout. // Long press timeout.
mSelectLongPressTimeoutPreference = mSelectLongPressTimeoutPreference =
@@ -328,34 +267,18 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]); mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
} }
} }
if (accessibilityEnabled) {
final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
String value = String.valueOf(longPressTimeout);
mSelectLongPressTimeoutPreference.setValue(value);
mSelectLongPressTimeoutPreference.setSummary(
mLongPressTimeoutValuetoTitleMap.get(value));
} else {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.LONG_PRESS_TIMEOUT,
mLongPressTimeoutDefault);
}
// Script injection. // Script injection.
mToggleScriptInjectionPreference = (AccessibilityEnableScriptInjectionPreference) mToggleScriptInjectionPreference = (AccessibilityEnableScriptInjectionPreference)
findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE); findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE);
if (accessibilityEnabled) {
final boolean scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
mToggleScriptInjectionPreference.setInjectionAllowed(scriptInjectionAllowed);
}
} }
private void updateAllPreferences(boolean accessibilityEnabled) { private void updateAllPreferences() {
updateServicesPreferences(accessibilityEnabled); updateServicesPreferences();
updateSystemPreferences(accessibilityEnabled); updateSystemPreferences();
} }
private void updateServicesPreferences(boolean accessibilityEnabled) { private void updateServicesPreferences() {
// Since services category is auto generated we have to do a pass // Since services category is auto generated we have to do a pass
// to generate it since services can come and go and then based on // to generate it since services can come and go and then based on
// the global accessibility state to decided whether it is enabled. // the global accessibility state to decided whether it is enabled.
@@ -381,7 +304,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
for (int i = 0, count = installedServices.size(); i < count; ++i) { for (int i = 0, count = installedServices.size(); i < count; ++i) {
AccessibilityServiceInfo info = installedServices.get(i); AccessibilityServiceInfo info = installedServices.get(i);
String key = info.getId();
PreferenceScreen preference = getPreferenceManager().createPreferenceScreen( PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
getActivity()); getActivity());
@@ -416,9 +338,19 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
extras.putString(EXTRA_SUMMARY, description); extras.putString(EXTRA_SUMMARY, description);
extras.putString(EXTRA_WARNING_MESSAGE, getString( CharSequence applicationLabel = info.getResolveInfo().loadLabel(getPackageManager());
R.string.accessibility_service_security_warning,
info.getResolveInfo().loadLabel(getPackageManager()))); extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
R.string.accessibility_service_security_warning_title, applicationLabel));
extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
R.string.accessibility_service_security_warning_summary, applicationLabel));
extras.putString(EXTRA_DISABLE_WARNING_TITLE, getString(
R.string.accessibility_service_disable_warning_title,
applicationLabel));
extras.putString(EXTRA_DISABLE_WARNING_MESSAGE, getString(
R.string.accessibility_service_disable_warning_summary,
applicationLabel));
String settingsClassName = info.getSettingsActivityName(); String settingsClassName = info.getSettingsActivityName();
if (!TextUtils.isEmpty(settingsClassName)) { if (!TextUtils.isEmpty(settingsClassName)) {
@@ -432,48 +364,59 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
mServicesCategory.addPreference(preference); mServicesCategory.addPreference(preference);
} }
// Update enabled state. if (mServicesCategory.getPreferenceCount() == 0) {
mServicesCategory.setEnabled(accessibilityEnabled); if (mNoServicesMessagePreference == null) {
mNoServicesMessagePreference = new Preference(getActivity()) {
@Override
protected void onBindView(View view) {
super.onBindView(view);
LinearLayout containerView =
(LinearLayout) view.findViewById(R.id.message_container);
containerView.setGravity(Gravity.CENTER);
TextView summaryView = (TextView) view.findViewById(R.id.summary);
String title = getString(R.string.accessibility_service_no_apps_title);
summaryView.setText(title);
}
};
mNoServicesMessagePreference.setPersistent(false);
mNoServicesMessagePreference.setLayoutResource(
R.layout.text_description_preference);
mNoServicesMessagePreference.setSelectable(false);
}
mServicesCategory.addPreference(mNoServicesMessagePreference);
}
} }
private void updateSystemPreferences(boolean accessibilityEnabled) { private Preference mNoServicesMessagePreference;
// The basic logic here is if accessibility is not enabled all accessibility
// settings will have no effect but still their selected state should be kept
// unchanged, so the user can see what settings will be enabled when turning
// on accessibility.
private void updateSystemPreferences() {
// Large text. // Large text.
mToggleLargeTextPreference.setEnabled(accessibilityEnabled);
if (accessibilityEnabled) {
mCurConfig.fontScale =
mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
} else {
mCurConfig.fontScale = 1;
}
try { try {
ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig); mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
} catch (RemoteException re) { } catch (RemoteException re) {
/* ignore */ /* ignore */
} }
mToggleLargeTextPreference.setChecked(mCurConfig.fontScale == LARGE_FONT_SCALE);
// Power button ends calls. // Power button ends calls.
if (mTogglePowerButtonEndsCallPreference != null) { if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
mTogglePowerButtonEndsCallPreference.setEnabled(accessibilityEnabled); && Utils.isVoiceCapable(getActivity())) {
final int powerButtonEndsCall; final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
if (accessibilityEnabled) {
powerButtonEndsCall = mTogglePowerButtonEndsCallPreference.isChecked()
? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
: Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
} else {
powerButtonEndsCall = Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
}
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
powerButtonEndsCall); Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
final boolean powerButtonEndsCall =
(incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
} }
// Auto-rotate screen
final boolean autoRotationEnabled = Settings.System.getInt(getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0) != 0;
mToggleAutoRotateScreenPreference.setChecked(autoRotationEnabled);
// Touch exploration enabled. // Touch exploration enabled.
mToggleTouchExplorationPreference.setEnabled(accessibilityEnabled);
final boolean touchExplorationEnabled = (Settings.Secure.getInt(getContentResolver(), final boolean touchExplorationEnabled = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1); Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1);
if (touchExplorationEnabled) { if (touchExplorationEnabled) {
@@ -487,29 +430,16 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
// Long press timeout. // Long press timeout.
mSelectLongPressTimeoutPreference.setEnabled(accessibilityEnabled); final int longPressTimeout = Settings.Secure.getInt(getContentResolver(),
final int longPressTimeout; Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault);
if (accessibilityEnabled) { String value = String.valueOf(longPressTimeout);
String value = mSelectLongPressTimeoutPreference.getValue(); mSelectLongPressTimeoutPreference.setValue(value);
longPressTimeout = (value != null) ? Integer.parseInt(value) : mLongPressTimeoutDefault;
} else {
longPressTimeout = mLongPressTimeoutDefault;
}
Settings.Secure.putInt(getContentResolver(), Settings.Secure.LONG_PRESS_TIMEOUT,
longPressTimeout);
String value = mSelectLongPressTimeoutPreference.getValue();
mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value)); mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
// Script injection. // Script injection.
mToggleScriptInjectionPreference.setEnabled(accessibilityEnabled); final boolean scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(),
final boolean scriptInjectionAllowed; Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
if (accessibilityEnabled) { mToggleScriptInjectionPreference.setInjectionAllowed(scriptInjectionAllowed);
scriptInjectionAllowed = mToggleScriptInjectionPreference.isInjectionAllowed();
} else {
scriptInjectionAllowed = false;
}
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
scriptInjectionAllowed ? 1 : 0);
} }
private void offerInstallAccessibilitySerivceOnce() { private void offerInstallAccessibilitySerivceOnce() {
@@ -531,31 +461,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override @Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
switch (dialogId) { switch (dialogId) {
case DIALOG_ID_DISABLE_ACCESSIBILITY:
return (new AlertDialog.Builder(getActivity()))
.setTitle(R.string.accessibility_disable_warning_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(getResources().
getString(R.string.accessibility_disable_warning_summary))
.setCancelable(true)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0);
mToggleAccessibilitySwitch.setCheckedInternal(
false);
updateAllPreferences(false);
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mToggleAccessibilitySwitch.setCheckedInternal(
true);
}
})
.create();
case DIALOG_ID_NO_ACCESSIBILITY_SERVICES: case DIALOG_ID_NO_ACCESSIBILITY_SERVICES:
return new AlertDialog.Builder(getActivity()) return new AlertDialog.Builder(getActivity())
.setTitle(R.string.accessibility_service_no_apps_title) .setTitle(R.string.accessibility_service_no_apps_title)
@@ -670,6 +575,10 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
enabledServices += preferenceKey; enabledServices += preferenceKey;
Settings.Secure.putString(getContentResolver(), Settings.Secure.putString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices); Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices);
// Enabling the first service enables accessibility.
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 1);
} else if (length > 0) { } else if (length > 0) {
enabledServices += ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey; enabledServices += ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey;
Settings.Secure.putString(getContentResolver(), Settings.Secure.putString(getContentResolver(),
@@ -681,6 +590,9 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
enabledServices = enabledServices.replace(preferenceKey, ""); enabledServices = enabledServices.replace(preferenceKey, "");
Settings.Secure.putString(getContentResolver(), Settings.Secure.putString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices); Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices);
// Disabling the last service disables accessibility).
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0);
} else if (index > 0) { } else if (index > 0) {
enabledServices = enabledServices.replace( enabledServices = enabledServices.replace(
ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey, ""); ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey, "");
@@ -713,18 +625,24 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private abstract static class TogglePreferenceFragment extends SettingsPreferenceFragment private abstract static class TogglePreferenceFragment extends SettingsPreferenceFragment
implements DialogInterface.OnClickListener { implements DialogInterface.OnClickListener {
private static final int DIALOG_ID_WARNING = 1; private static final int DIALOG_ID_ENABLE_WARNING = 1;
private static final int DIALOG_ID_DISABLE_WARNING = 2;
private String mPreferenceKey; private String mPreferenceKey;
private ToggleSwitch mToggleSwitch; private ToggleSwitch mToggleSwitch;
private CharSequence mWarningMessage; private CharSequence mEnableWarningTitle;
private CharSequence mEnableWarningMessage;
private CharSequence mDisableWarningTitle;
private CharSequence mDisableWarningMessage;
private Preference mSummaryPreference; private Preference mSummaryPreference;
private CharSequence mSettingsTitle; private CharSequence mSettingsTitle;
private Intent mSettingsIntent; private Intent mSettingsIntent;
private int mShownDialogId;
// TODO: Showing sub-sub fragment does not handle the activity title // TODO: Showing sub-sub fragment does not handle the activity title
// so we do it but this is wrong. Do a real fix when there is time. // so we do it but this is wrong. Do a real fix when there is time.
private CharSequence mOldActivityTitle; private CharSequence mOldActivityTitle;
@@ -789,37 +707,51 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
MenuItem menuItem = menu.add(mSettingsTitle); MenuItem menuItem = menu.add(mSettingsTitle);
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menuItem.setIntent(mSettingsIntent); menuItem.setIntent(mSettingsIntent);
} }
@Override @Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
CharSequence title = null;
CharSequence message = null;
switch (dialogId) { switch (dialogId) {
case DIALOG_ID_WARNING: case DIALOG_ID_ENABLE_WARNING:
return new AlertDialog.Builder(getActivity()) mShownDialogId = DIALOG_ID_ENABLE_WARNING;
.setTitle(android.R.string.dialog_alert_title) title = mEnableWarningTitle;
.setIcon(android.R.drawable.ic_dialog_alert) message = mEnableWarningMessage;
.setMessage(mWarningMessage) break;
.setCancelable(true) case DIALOG_ID_DISABLE_WARNING:
.setPositiveButton(android.R.string.ok, this) mShownDialogId = DIALOG_ID_DISABLE_WARNING;
.setNegativeButton(android.R.string.cancel, this) title = mDisableWarningTitle;
.create(); message = mDisableWarningMessage;
break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(message)
.setCancelable(true)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
} }
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
final boolean checked;
switch (which) { switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
// OK, we got the user consent so set checked. checked = (mShownDialogId == DIALOG_ID_ENABLE_WARNING);
mToggleSwitch.setCheckedInternal(true); mToggleSwitch.setCheckedInternal(checked);
onPreferenceToggled(mPreferenceKey, true); onPreferenceToggled(mPreferenceKey, checked);
break; break;
case DialogInterface.BUTTON_NEGATIVE: case DialogInterface.BUTTON_NEGATIVE:
onPreferenceToggled(mPreferenceKey, false); checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING);
mToggleSwitch.setCheckedInternal(checked);
onPreferenceToggled(mPreferenceKey, checked);
break; break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
@@ -832,13 +764,18 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override @Override
public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) { public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
if (checked) { if (checked) {
if (!TextUtils.isEmpty(mWarningMessage)) { if (!TextUtils.isEmpty(mEnableWarningMessage)) {
toggleSwitch.setCheckedInternal(false); toggleSwitch.setCheckedInternal(false);
showDialog(DIALOG_ID_WARNING); showDialog(DIALOG_ID_ENABLE_WARNING);
return true; return true;
} }
onPreferenceToggled(mPreferenceKey, true); onPreferenceToggled(mPreferenceKey, true);
} else { } else {
if (!TextUtils.isEmpty(mDisableWarningMessage)) {
toggleSwitch.setCheckedInternal(true);
showDialog(DIALOG_ID_DISABLE_WARNING);
return true;
}
onPreferenceToggled(mPreferenceKey, false); onPreferenceToggled(mPreferenceKey, false);
} }
return false; return false;
@@ -861,7 +798,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) { if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
mOldActivityTitle = getActivity().getTitle(); mOldActivityTitle = getActivity().getTitle();
String title = arguments.getString(EXTRA_TITLE); String title = arguments.getString(EXTRA_TITLE);
getActivity().getActionBar().setTitle(arguments.getCharSequence(EXTRA_TITLE)); getActivity().getActionBar().setTitle(title);
} }
// Summary. // Summary.
@@ -881,9 +818,21 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
} }
// Waring message. // Enable warning title.
mWarningMessage = arguments.getCharSequence( mEnableWarningTitle = arguments.getCharSequence(
AccessibilitySettings.EXTRA_WARNING_MESSAGE); AccessibilitySettings.EXTRA_ENABLE_WARNING_TITLE);
// Enable warning message.
mEnableWarningMessage = arguments.getCharSequence(
AccessibilitySettings.EXTRA_ENABLE_WARNING_MESSAGE);
// Disable warning title.
mDisableWarningTitle = arguments.getString(
AccessibilitySettings.EXTRA_DISABLE_WARNING_TITLE);
// Disable warning message.
mDisableWarningMessage = arguments.getString(
AccessibilitySettings.EXTRA_DISABLE_WARNING_MESSAGE);
} }
} }
} }