Polish of the accessibility settings.

Change-Id: Ifb32ec6745e566cf7ffafe20019b68d95661b45d
This commit is contained in:
Svetoslav Ganov
2011-07-27 14:54:52 -07:00
parent bb33bdcef7
commit 1a97fa13d0
5 changed files with 528 additions and 189 deletions

View File

@@ -2681,9 +2681,8 @@ found in the list of installed applications.</string>
<!-- Title for accessibility preference to enable touch exploration mode. [CHAR LIMIT=35] --> <!-- Title for accessibility preference to enable touch exploration mode. [CHAR LIMIT=35] -->
<string name="accessibility_touch_exploration_title">Explore by touch</string> <string name="accessibility_touch_exploration_title">Explore by touch</string>
<!-- Summary for accessibility of the touch exploration mode. [CHAR LIMIT=NONE] --> <!-- Summary for accessibility of the touch exploration mode. [CHAR LIMIT=NONE] -->
<string name="accessibility_touch_exploration_summary" >Allows exploring screen content and interacting with the device.\n\n <string name="accessibility_touch_exploration_summary" >When Explore by Touch is turned on,
Touch the screen to receive feedback of the content under your finger.\n\n Tap on the last explored location to activate.\n\n you can hear or see descriptions of what\'s under your finger.\n\n This feature is for low-vision users.</string>
Use two fingers to drag. </string>
<!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] --> <!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
<string name="accessibility_long_press_timeout_title">Touch &amp; hold delay</string> <string name="accessibility_long_press_timeout_title">Touch &amp; hold delay</string>
<!-- Title for accessibility preference to install accessibility scripts from Google. [CHAR LIMIT=35] --> <!-- Title for accessibility preference to install accessibility scripts from Google. [CHAR LIMIT=35] -->
@@ -2710,31 +2709,37 @@ found in the list of installed applications.</string>
<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, <!-- Warning message about security implications of enabling an accessibility service,
displayed as a dialog message when the user selects to enable an accessibility service. [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">This accessibility service may be able to collect <string name="accessibility_service_security_warning">
all the text you type, including personal data credit card numbers except passwords. <xliff:g id="accessibility_service_name">%1$s</xliff:g> can
It may also log your user interface interactions. It comes from the application collect all of the text you type, except passwords. This includes personal data such as credit card
<xliff:g id="accessibility_service_name">%1$s</xliff:g>. Use this accessibility service?</string> numbers. It can also collect data about your interactions with the device.</string>
<!-- Warning about disabling accessibility displayed as a dialog message when the user <!-- 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] -->
<string name="accessibility_disable_warning_title">Turn accessibility off?</string>
<!-- Summary for a warning about disabling accessibility displayed as a dialog message when the user
selects to disable accessibility. This avoids accidental disabling. [CHAR LIMIT=NONE] --> selects to disable accessibility. This avoids accidental disabling. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_disable_warning">Disable accessibility?</string> <string name="accessibility_disable_warning_summary">Touching OK will stop spoken
descriptions and all other accessibility features you\'ve been using.</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 related applications found <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 do not have any accessibility-related <string name="accessibility_service_no_apps_message">You don\'t have accessibility
applications installed.\n\nYou can download a screen reader for your device from Android applications installed. Do you want to download a screen reader from the Android Market?</string>
Market.\n\nClick "OK" to install the screen reader.</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">Some applications can ask Google <string name="accessibility_script_injection_security_warning">Do you want applications to install
to download scripts to your device that make their content more accessible. Are you sure you scripts from Google that will make their content more accessible?</string>
want to allow Google to install accessibility scripts on your device?</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">Enabling explore by touch <string name="accessibility_touch_exploration_warning">Enabling explore by touch
changes the interation model. Enable explore by touch?</string> changes how the devices respons to touch. Enable explore by touch?</string>
<!-- Default description for an accessiiblity serivice if the latter doesn't provide one. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_default_description">This accessibility service has no
description.\n\nAccessibility services provide various types of feedback when you interact
with the device. </string>
<!-- App Fuel Gauge strings --> <!-- App Fuel Gauge strings -->
<skip /> <skip />

View File

@@ -30,12 +30,12 @@
<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="false"/> android:persistent="true"/>
<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="false"> android:persistent="true">
</CheckBoxPreference> </CheckBoxPreference>
<PreferenceScreen <PreferenceScreen
@@ -55,10 +55,15 @@
android:entryValues="@array/long_press_timeout_selector_values" android:entryValues="@array/long_press_timeout_selector_values"
android:persistent="true" /> android:persistent="true" />
<Preference <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:persistent="false" /> android:dialogTitle="@android:string/dialog_alert_title"
android:dialogIcon="@android:drawable/ic_dialog_alert"
android:dialogMessage="@string/accessibility_script_injection_security_warning"
android:positiveButtonText="@string/accessibility_script_injection_button_allow"
android:negativeButtonText="@string/accessibility_script_injection_button_disallow"
android:persistent="true" />
</PreferenceCategory> </PreferenceCategory>

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.DialogPreference;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
/**
* Preference for enabling accessibility script injection. It displays a warning
* dialog before enabling the preference.
*/
public class AccessibilityEnableScriptInjectionPreference extends DialogPreference {
private boolean mInjectionAllowed;
private boolean mSendClickAccessibilityEvent;
public AccessibilityEnableScriptInjectionPreference(Context context, AttributeSet attrs) {
super(context, attrs);
updateSummary();
}
public void setInjectionAllowed(boolean injectionAllowed) {
if (mInjectionAllowed != injectionAllowed) {
mInjectionAllowed = injectionAllowed;
persistBoolean(injectionAllowed);
updateSummary();
}
}
public boolean isInjectionAllowed() {
return mInjectionAllowed;
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
View summaryView = view.findViewById(com.android.internal.R.id.summary);
sendAccessibilityEvent(summaryView);
}
private void sendAccessibilityEvent(View view) {
// Since the view is still not attached we create, populate,
// and send the event directly since we do not know when it
// will be attached and posting commands is not as clean.
AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getContext());
if (mSendClickAccessibilityEvent && accessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
view.onInitializeAccessibilityEvent(event);
view.dispatchPopulateAccessibilityEvent(event);
accessibilityManager.sendAccessibilityEvent(event);
}
mSendClickAccessibilityEvent = false;
}
@Override
protected void onClick() {
if (isInjectionAllowed()) {
setInjectionAllowed(false);
// Update the system setting only upon user action.
setSystemSetting(false);
mSendClickAccessibilityEvent = true;
} else {
super.onClick();
mSendClickAccessibilityEvent = false;
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getBoolean(index, false);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setInjectionAllowed(restoreValue
? getPersistedBoolean(mInjectionAllowed)
: (Boolean) defaultValue);
}
@Override
protected void onDialogClosed(boolean result) {
setInjectionAllowed(result);
if (result) {
// Update the system setting only upon user action.
setSystemSetting(true);
}
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
return superState;
}
SavedState myState = new SavedState(superState);
myState.mInjectionAllowed = mInjectionAllowed;
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setInjectionAllowed(myState.mInjectionAllowed);
}
private void updateSummary() {
setSummary(mInjectionAllowed
? getContext().getString(R.string.accessibility_script_injection_allowed)
: getContext().getString(R.string.accessibility_script_injection_disallowed));
}
private void setSystemSetting(boolean enabled) {
Settings.Secure.putInt(getContext().getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0);
}
private static class SavedState extends BaseSavedState {
private boolean mInjectionAllowed;
public SavedState(Parcel source) {
super(source);
mInjectionAllowed = (source.readInt() == 1);
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
super.writeToParcel(parcel, flags);
parcel.writeInt(mInjectionAllowed ? 1 : 0);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("all")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@@ -26,6 +26,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri; import android.net.Uri;
@@ -37,6 +38,7 @@ import android.os.SystemProperties;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.provider.Settings; import android.provider.Settings;
@@ -49,6 +51,7 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
@@ -73,6 +76,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private static final float LARGE_FONT_SCALE = 1.3f; private static final float LARGE_FONT_SCALE = 1.3f;
private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market";
// Timeout before we update the services if packages are added/removed since // Timeout before we update the services if packages are added/removed since
// the AccessibilityManagerService has to do that processing first to generate // the AccessibilityManagerService has to do that processing first to generate
// the AccessibilityServiceInfo we need for proper presentation. // the AccessibilityServiceInfo we need for proper presentation.
@@ -80,8 +85,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':'; private static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
private static final String KEY_ACCESSIBILITY_TUTORIAL_LAUNCHED_ONCE =
"key_accessibility_tutorial_launched_once";
private static final String KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE =
"key_install_accessibility_service_offered_once";
// Preference categories // Preference categories
private static final String SERVICES_CATEGORY = "services_category"; private static final String SERVICES_CATEGORY = "services_category";
private static final String SYSTEM_CATEGORY = "system_category";
// Preferences // Preferences
private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference"; private static final String TOGGLE_LARGE_TEXT_PREFERENCE = "toggle_large_text_preference";
@@ -95,18 +107,17 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"toggle_script_injection_preference"; "toggle_script_injection_preference";
// Extras passed to sub-fragments. // Extras passed to sub-fragments.
static final String EXTRA_PREFERENCE_KEY = "preference_key"; private static final String EXTRA_PREFERENCE_KEY = "preference_key";
static final String EXTRA_CHECKED = "checked"; private static final String EXTRA_CHECKED = "checked";
static final String EXTRA_TITLE = "title"; private static final String EXTRA_TITLE = "title";
static final String EXTRA_SUMMARY = "summary"; private static final String EXTRA_SUMMARY = "summary";
static final String EXTRA_WARNING_MESSAGE = "warning_message"; private static final String EXTRA_WARNING_MESSAGE = "warning_message";
static final String EXTRA_SETTINGS_TITLE = "settings_title"; private static final String EXTRA_SETTINGS_TITLE = "settings_title";
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_DISABLE_ACCESSIBILITY = 1;
private static final int DIALOG_ID_ENABLE_SCRIPT_INJECTION = 2; private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 2;
private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 3;
// Auxiliary members. // Auxiliary members.
private final SimpleStringSplitter mStringColonSplitter = private final SimpleStringSplitter mStringColonSplitter =
@@ -123,7 +134,7 @@ 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(); updateServicesPreferences(mToggleAccessibilitySwitch.isChecked());
} }
}; };
@@ -131,103 +142,96 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private ToggleSwitch mToggleAccessibilitySwitch; private ToggleSwitch mToggleAccessibilitySwitch;
private PreferenceCategory mServicesCategory; private PreferenceCategory mServicesCategory;
private PreferenceCategory mSystemsCategory;
private CheckBoxPreference mToggleLargeTextPreference; private CheckBoxPreference mToggleLargeTextPreference;
private CheckBoxPreference mTogglePowerButtonEndsCallPreference; private CheckBoxPreference mTogglePowerButtonEndsCallPreference;
private Preference mTouchExplorationEnabledPreference; private Preference mToggleTouchExplorationPreference;
private ListPreference mSelectLongPressTimeoutPreference; private ListPreference mSelectLongPressTimeoutPreference;
private Preference mToggleScriptInjectionPreference; private AccessibilityEnableScriptInjectionPreference mToggleScriptInjectionPreference;
private int mLongPressTimeoutDefault;
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
addPreferencesFromResource(R.xml.accessibility_settings); addPreferencesFromResource(R.xml.accessibility_settings);
installToggleAccessibilitySwitch(); initializeAllPreferences();
findPreferences();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
updateServicesPreferences(); final boolean accessibilityEnabled = mToggleAccessibilitySwitch.isChecked();
updateSystemPreferences(); updateAllPreferences(accessibilityEnabled);
updatePreferencesForAccessibilityState(); if (accessibilityEnabled) {
offerInstallAccessibilitySerivceOnce();
}
mSettingsPackageMonitor.register(getActivity(), false); mSettingsPackageMonitor.register(getActivity(), false);
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause();
mSettingsPackageMonitor.unregister(); mSettingsPackageMonitor.unregister();
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) {
final int intValue = Integer.parseInt((String) newValue); String stringValue = (String) newValue;
Settings.Secure.putInt(getContentResolver(), Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, intValue); Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue));
mSelectLongPressTimeoutPreference.setSummary( mSelectLongPressTimeoutPreference.setSummary(
mLongPressTimeoutValuetoTitleMap.get(String.valueOf(intValue))); mLongPressTimeoutValuetoTitleMap.get(stringValue));
return true; return true;
} }
return false; return false;
} }
private void updatePreferencesForAccessibilityState() {
final boolean accessibilityEnabled = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1);
mServicesCategory.setEnabled(accessibilityEnabled);
mTouchExplorationEnabledPreference.setEnabled(accessibilityEnabled);
mToggleScriptInjectionPreference.setEnabled(accessibilityEnabled);
}
@Override @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
final String key = preference.getKey(); final String key = preference.getKey();
if (mToggleLargeTextPreference == preference) { if (mToggleLargeTextPreference == preference) {
handleToggleLargeTextPreference((CheckBoxPreference) preference); handleToggleLargeTextPreferenceClick();
return true; return true;
} else if (mTogglePowerButtonEndsCallPreference == preference) { } else if (mTogglePowerButtonEndsCallPreference == preference) {
handleTogglePowerButtonEndsCallPreference((CheckBoxPreference) preference); handleTogglePowerButtonEndsCallPreferenceClick();
return true;
} else if (mToggleScriptInjectionPreference == preference) {
handleToggleAccessibilityScriptInjectionPreference(preference);
return true; return true;
} }
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
private void handleTogglePowerButtonEndsCallPreference(CheckBoxPreference preference) { private void handleToggleLargeTextPreferenceClick() {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
(preference.isChecked() ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
: Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
}
private void handleToggleLargeTextPreference(CheckBoxPreference preference) {
try { try {
mCurConfig.fontScale = preference.isChecked() ? LARGE_FONT_SCALE : 1; mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig); ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
} catch (RemoteException e) { } catch (RemoteException re) {
/* ignore */ /* ignore */
} }
} }
private void handleToggleAccessibilityScriptInjectionPreference(Preference preference) { private void handleTogglePowerButtonEndsCallPreferenceClick() {
String allowed = getString(R.string.accessibility_script_injection_disallowed); Settings.Secure.putInt(getContentResolver(),
if (preference.getSummary().equals(allowed)) { Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
// set right enabled state since the user may press back. (mTogglePowerButtonEndsCallPreference.isChecked()
showDialog(DIALOG_ID_ENABLE_SCRIPT_INJECTION); ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
} else { : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0);
mToggleScriptInjectionPreference.setSummary(
getString(R.string.accessibility_script_injection_disallowed));
}
} }
private void installToggleAccessibilitySwitch() { private void addToggleAccessibilitySwitch() {
mToggleAccessibilitySwitch = createActionBarToggleSwitch(getActivity()); mToggleAccessibilitySwitch = createAndAddActionBarToggleSwitch(getActivity());
final boolean checked = (Settings.Secure.getInt(getContentResolver(), final boolean checked = (Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1); Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1);
mToggleAccessibilitySwitch.setChecked(checked); mToggleAccessibilitySwitch.setChecked(checked);
@@ -236,34 +240,126 @@ 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) {
toggleSwitch.setCheckedNoBeforeCheckedChangeListener(true); toggleSwitch.setCheckedInternal(true);
showDialog(DIALOG_ID_DISABLE_ACCESSIBILITY); showDialog(DIALOG_ID_DISABLE_ACCESSIBILITY);
return true; return true;
} }
Settings.Secure.putInt(getContentResolver(), Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 1); Settings.Secure.ACCESSIBILITY_ENABLED, 1);
updatePreferencesForAccessibilityState(); updateAllPreferences(true);
offerInstallAccessibilitySerivceOnce();
return false; return false;
} }
}); });
} }
private void findPreferences() { public void removeToggleAccessibilitySwitch() {
mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY); getActivity().getActionBar().setCustomView(null);
mToggleLargeTextPreference = (CheckBoxPreference) findPreference(
TOGGLE_LARGE_TEXT_PREFERENCE);
mTogglePowerButtonEndsCallPreference = (CheckBoxPreference) findPreference(
TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
mTouchExplorationEnabledPreference = findPreference(TOGGLE_TOUCH_EXPLORATION_PREFERENCE);
mSelectLongPressTimeoutPreference = (ListPreference) findPreference(
SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
mToggleScriptInjectionPreference = findPreference(TOGGLE_SCRIPT_INJECTION_PREFERENCE);
mToggleScriptInjectionPreference.setOnPreferenceChangeListener(this);
} }
private void updateServicesPreferences() { 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);
mSystemsCategory = (PreferenceCategory) findPreference(SYSTEM_CATEGORY);
// Large text.
mToggleLargeTextPreference =
(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.
mTogglePowerButtonEndsCallPreference =
(CheckBoxPreference) findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
&& 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);
}
// Touch exploration enabled.
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.
mSelectLongPressTimeoutPreference =
(ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
if (mLongPressTimeoutValuetoTitleMap.size() == 0) {
String[] timeoutValues = getResources().getStringArray(
R.array.long_press_timeout_selector_values);
mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]);
String[] timeoutTitles = getResources().getStringArray(
R.array.long_press_timeout_selector_titles);
final int timeoutValueCount = timeoutValues.length;
for (int i = 0; i < timeoutValueCount; 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.
mToggleScriptInjectionPreference = (AccessibilityEnableScriptInjectionPreference)
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) {
updateServicesPreferences(accessibilityEnabled);
updateSystemPreferences(accessibilityEnabled);
}
private void updateServicesPreferences(boolean accessibilityEnabled) {
// 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
// the global accessibility state to decided whether it is enabled.
// Generate.
mServicesCategory.removeAll(); mServicesCategory.removeAll();
AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity()); AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getActivity());
@@ -271,17 +367,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
List<AccessibilityServiceInfo> installedServices = List<AccessibilityServiceInfo> installedServices =
accessibilityManager.getInstalledAccessibilityServiceList(); accessibilityManager.getInstalledAccessibilityServiceList();
if (installedServices.isEmpty() && accessibilityManager.isEnabled()) {
// no service and accessibility is enabled => disable
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 0);
mToggleAccessibilitySwitch.setChecked(false);
mToggleAccessibilitySwitch.setEnabled(false);
// Notify user that they do not have any accessibility
// services installed and direct them to Market to get TalkBack.
showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
return;
}
Set<ComponentName> enabledComponentNames = new HashSet<ComponentName>(); Set<ComponentName> enabledComponentNames = new HashSet<ComponentName>();
String settingValue = Settings.Secure.getString(getContentResolver(), String settingValue = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
@@ -317,12 +402,19 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
preference.setOrder(i); preference.setOrder(i);
preference.setFragment(ToggleAccessibilityServiceFragment.class.getName()); preference.setFragment(ToggleAccessibilityServiceFragment.class.getName());
preference.setPersistent(true);
Bundle extras = preference.getExtras(); Bundle extras = preference.getExtras();
extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey()); extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
extras.putBoolean(EXTRA_CHECKED, enabled); extras.putBoolean(EXTRA_CHECKED, enabled);
extras.putString(EXTRA_TITLE, title); extras.putString(EXTRA_TITLE, title);
extras.putString(EXTRA_SUMMARY, info.getDescription());
String description = info.getDescription();
if (TextUtils.isEmpty(description)) {
description = getString(R.string.accessibility_service_default_description);
}
extras.putString(EXTRA_SUMMARY, description);
extras.putString(EXTRA_WARNING_MESSAGE, getString( extras.putString(EXTRA_WARNING_MESSAGE, getString(
R.string.accessibility_service_security_warning, R.string.accessibility_service_security_warning,
info.getResolveInfo().loadLabel(getPackageManager()))); info.getResolveInfo().loadLabel(getPackageManager())));
@@ -338,69 +430,99 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
mServicesCategory.addPreference(preference); mServicesCategory.addPreference(preference);
} }
// Update enabled state.
mServicesCategory.setEnabled(accessibilityEnabled);
} }
public void updateSystemPreferences() { private void updateSystemPreferences(boolean accessibilityEnabled) {
// 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.
// Large text. // Large text.
mToggleLargeTextPreference.setEnabled(accessibilityEnabled);
if (accessibilityEnabled) {
mCurConfig.fontScale =
mToggleLargeTextPreference.isChecked() ? LARGE_FONT_SCALE : 1;
} else {
mCurConfig.fontScale = 1;
}
try { try {
mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration()); ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
} catch (RemoteException re) { } catch (RemoteException re) {
/* ignore */ /* ignore */
} }
mToggleLargeTextPreference.setChecked(Float.compare(mCurConfig.fontScale,
LARGE_FONT_SCALE) == 0);
// Power button ends call. // Power button ends calls.
if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) if (mTogglePowerButtonEndsCallPreference != null) {
&& Utils.isVoiceCapable(getActivity())) { mTogglePowerButtonEndsCallPreference.setEnabled(accessibilityEnabled);
final int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(), final int powerButtonEndsCall;
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, if (accessibilityEnabled) {
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); powerButtonEndsCall = mTogglePowerButtonEndsCallPreference.isChecked()
final boolean powerButtonEndsCall = ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
(incallPowerBehavior == Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP); : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall); } else {
} else { powerButtonEndsCall = Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
getPreferenceScreen().removePreference(mTogglePowerButtonEndsCallPreference); }
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
powerButtonEndsCall);
} }
// 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) {
mTouchExplorationEnabledPreference.setSummary( mToggleTouchExplorationPreference.setSummary(
getString(R.string.accessibility_service_state_on)); getString(R.string.accessibility_service_state_on));
mTouchExplorationEnabledPreference.getExtras().putBoolean(EXTRA_CHECKED, true); mToggleTouchExplorationPreference.getExtras().putBoolean(EXTRA_CHECKED, true);
} else { } else {
mTouchExplorationEnabledPreference.setSummary( mToggleTouchExplorationPreference.setSummary(
getString(R.string.accessibility_service_state_off)); getString(R.string.accessibility_service_state_off));
mTouchExplorationEnabledPreference.getExtras().putBoolean(EXTRA_CHECKED, false); mToggleTouchExplorationPreference.getExtras().putBoolean(EXTRA_CHECKED, false);
} }
// Long press timeout. // Long press timeout.
if (mLongPressTimeoutValuetoTitleMap.isEmpty()) { mSelectLongPressTimeoutPreference.setEnabled(accessibilityEnabled);
String[] timeoutValues = getResources().getStringArray( final int longPressTimeout;
R.array.long_press_timeout_selector_values); if (accessibilityEnabled) {
String[] timeoutTitles = getResources().getStringArray( longPressTimeout = Integer.parseInt(mSelectLongPressTimeoutPreference.getValue());
R.array.long_press_timeout_selector_titles); } else {
final int timeoutValueCount = timeoutValues.length; longPressTimeout = mLongPressTimeoutDefault;
for (int i = 0;i < timeoutValueCount; i++) {
mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i], timeoutTitles[i]);
}
} }
String longPressTimeout = String.valueOf(Settings.Secure.getInt(getContentResolver(), Settings.Secure.putInt(getContentResolver(), Settings.Secure.LONG_PRESS_TIMEOUT,
Settings.Secure.LONG_PRESS_TIMEOUT, 0)); longPressTimeout);
mSelectLongPressTimeoutPreference.setSummary( String value = mSelectLongPressTimeoutPreference.getValue();
mLongPressTimeoutValuetoTitleMap.get(longPressTimeout)); mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
// Script injection. // Script injection.
final boolean scriptInjectionAllowed = (Settings.Secure.getInt(getContentResolver(), mToggleScriptInjectionPreference.setEnabled(accessibilityEnabled);
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1); final boolean scriptInjectionAllowed;
if (scriptInjectionAllowed) { if (accessibilityEnabled) {
mToggleScriptInjectionPreference.setSummary( scriptInjectionAllowed = mToggleScriptInjectionPreference.isInjectionAllowed();
getString(R.string.accessibility_script_injection_allowed));
} else { } else {
mToggleScriptInjectionPreference.setSummary( scriptInjectionAllowed = false;
getString(R.string.accessibility_script_injection_disallowed)); }
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
scriptInjectionAllowed ? 1 : 0);
}
private void offerInstallAccessibilitySerivceOnce() {
if (mServicesCategory.getPreferenceCount() > 0) {
return;
}
SharedPreferences preferences = getActivity().getPreferences(Context.MODE_PRIVATE);
final boolean offerInstallService = !preferences.getBoolean(
KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE, false);
if (offerInstallService) {
preferences.edit().putBoolean(KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE,
true).commit();
// Notify user that they do not have any accessibility
// services installed and direct them to Market to get TalkBack.
showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
} }
} }
@@ -409,48 +531,29 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
switch (dialogId) { switch (dialogId) {
case DIALOG_ID_DISABLE_ACCESSIBILITY: case DIALOG_ID_DISABLE_ACCESSIBILITY:
return (new AlertDialog.Builder(getActivity())) return (new AlertDialog.Builder(getActivity()))
.setTitle(android.R.string.dialog_alert_title) .setTitle(R.string.accessibility_disable_warning_title)
.setIcon(android.R.drawable.ic_dialog_alert) .setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(getResources(). .setMessage(getResources().
getString(R.string.accessibility_service_disable_warning)) getString(R.string.accessibility_disable_warning_summary))
.setCancelable(true) .setCancelable(true)
.setPositiveButton(android.R.string.ok, .setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0); Settings.Secure.ACCESSIBILITY_ENABLED, 0);
mToggleAccessibilitySwitch.setCheckedNoBeforeCheckedChangeListener( mToggleAccessibilitySwitch.setCheckedInternal(
false); false);
updatePreferencesForAccessibilityState(); updateAllPreferences(false);
} }
}) })
.setNegativeButton(android.R.string.cancel, .setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mToggleAccessibilitySwitch.setCheckedNoBeforeCheckedChangeListener( mToggleAccessibilitySwitch.setCheckedInternal(
true); true);
} }
}) })
.create(); .create();
case DIALOG_ID_ENABLE_SCRIPT_INJECTION:
return new AlertDialog.Builder(getActivity())
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(getActivity().getString(
R.string.accessibility_script_injection_security_warning))
.setCancelable(true)
.setPositiveButton(R.string.accessibility_script_injection_button_allow,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1);
mToggleScriptInjectionPreference.setSummary(
getString(R.string.accessibility_script_injection_allowed));
}
})
.setNegativeButton(R.string.accessibility_script_injection_button_disallow, null)
.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)
@@ -461,9 +564,10 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
// dismiss the dialog before launching the activity otherwise // dismiss the dialog before launching the activity otherwise
// the dialog removal occurs after onSaveInstanceState which // the dialog removal occurs after onSaveInstanceState which
// triggers an exception // triggers an exception
dialog.dismiss(); removeDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
String screenreaderMarketLink = SystemProperties.get( String screenreaderMarketLink = SystemProperties.get(
"ro.screenreader.market", DEFAULT_SCREENREADER_MARKET_LINK); SYSTEM_PROPERTY_MARKET_URL,
DEFAULT_SCREENREADER_MARKET_LINK);
Uri marketUri = Uri.parse(screenreaderMarketLink); Uri marketUri = Uri.parse(screenreaderMarketLink);
Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri); Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
startActivity(marketIntent); startActivity(marketIntent);
@@ -503,7 +607,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
} }
private static ToggleSwitch createActionBarToggleSwitch(Activity activity) { private static ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) {
ToggleSwitch toggleSwitch = new ToggleSwitch(activity); ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
final int padding = activity.getResources().getDimensionPixelSize( final int padding = activity.getResources().getDimensionPixelSize(
R.dimen.action_bar_switch_padding); R.dimen.action_bar_switch_padding);
@@ -542,7 +646,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
super.setChecked(checked); super.setChecked(checked);
} }
public void setCheckedNoBeforeCheckedChangeListener(boolean checked) { public void setCheckedInternal(boolean checked) {
super.setChecked(checked); super.setChecked(checked);
} }
} }
@@ -590,6 +694,17 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
public void onPreferenceToggled(String preferenceKey, boolean enabled) { public void onPreferenceToggled(String preferenceKey, boolean enabled) {
Settings.Secure.putInt(getContentResolver(), Settings.Secure.putInt(getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0); Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0);
if (enabled) {
SharedPreferences preferences = getActivity().getPreferences(Context.MODE_PRIVATE);
final boolean launchAccessibilityTutorial = !preferences.getBoolean(
KEY_ACCESSIBILITY_TUTORIAL_LAUNCHED_ONCE, false);
if (launchAccessibilityTutorial) {
preferences.edit().putBoolean(KEY_ACCESSIBILITY_TUTORIAL_LAUNCHED_ONCE,
true).commit();
Intent intent = new Intent(AccessibilityTutorialActivity.ACTION);
getActivity().startActivity(intent);
}
}
} }
} }
@@ -608,14 +723,9 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private CharSequence mSettingsTitle; private CharSequence mSettingsTitle;
private Intent mSettingsIntent; private Intent mSettingsIntent;
@Override // TODO: Showing sub-sub fragment does not handle the activity title
public void onActivityCreated(Bundle savedInstanceState) { // so we do it but this is wrong. Do a real fix when there is time.
installActionBarToggleSwitch(); private CharSequence mOldActivityTitle;
processArguments();
getListView().setDivider(null);
getListView().setEnabled(false);
super.onActivityCreated(savedInstanceState);
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -629,6 +739,22 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
super.onBindView(view); super.onBindView(view);
TextView summaryView = (TextView) view.findViewById(R.id.summary); TextView summaryView = (TextView) view.findViewById(R.id.summary);
summaryView.setText(getSummary()); summaryView.setText(getSummary());
sendAccessibilityEvent(summaryView);
}
private void sendAccessibilityEvent(View view) {
// Since the view is still not attached we create, populate,
// and send the event directly since we do not know when it
// will be attached and posting commands is not as clean.
AccessibilityManager accessibilityManager =
AccessibilityManager.getInstance(getActivity());
if (accessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
view.onInitializeAccessibilityEvent(event);
view.dispatchPopulateAccessibilityEvent(event);
accessibilityManager.sendAccessibilityEvent(event);
}
} }
}; };
mSummaryPreference.setPersistent(false); mSummaryPreference.setPersistent(false);
@@ -636,13 +762,31 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
preferenceScreen.addPreference(mSummaryPreference); preferenceScreen.addPreference(mSummaryPreference);
} }
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
installActionBarToggleSwitch();
processArguments();
getListView().setDivider(null);
getListView().setEnabled(false);
}
@Override
public void onDestroyView() {
getActivity().getActionBar().setCustomView(null);
if (mOldActivityTitle != null) {
getActivity().getActionBar().setTitle(mOldActivityTitle);
}
super.onDestroyView();
}
public abstract void onPreferenceToggled(String preferenceKey, boolean value); public abstract void onPreferenceToggled(String preferenceKey, boolean value);
@Override @Override
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_ALWAYS); menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menuItem.setIntent(mSettingsIntent); menuItem.setIntent(mSettingsIntent);
} }
@@ -668,7 +812,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
switch (which) { switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
// OK, we got the user consent so set checked. // OK, we got the user consent so set checked.
mToggleSwitch.setCheckedNoBeforeCheckedChangeListener(true); mToggleSwitch.setCheckedInternal(true);
onPreferenceToggled(mPreferenceKey, true); onPreferenceToggled(mPreferenceKey, true);
break; break;
case DialogInterface.BUTTON_NEGATIVE: case DialogInterface.BUTTON_NEGATIVE:
@@ -680,13 +824,13 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
private void installActionBarToggleSwitch() { private void installActionBarToggleSwitch() {
mToggleSwitch = createActionBarToggleSwitch(getActivity()); mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity());
mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() { mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
@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(mWarningMessage)) {
toggleSwitch.setCheckedNoBeforeCheckedChangeListener(false); toggleSwitch.setCheckedInternal(false);
showDialog(DIALOG_ID_WARNING); showDialog(DIALOG_ID_WARNING);
return true; return true;
} }
@@ -707,11 +851,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
// Enabled. // Enabled.
final boolean enabled = arguments.getBoolean(EXTRA_CHECKED); final boolean enabled = arguments.getBoolean(EXTRA_CHECKED);
mToggleSwitch.setCheckedNoBeforeCheckedChangeListener(enabled); mToggleSwitch.setCheckedInternal(enabled);
// Title. // Title.
String title = arguments.getString(EXTRA_TITLE); PreferenceActivity activity = (PreferenceActivity) getActivity();
getActivity().getActionBar().setTitle(arguments.getCharSequence(EXTRA_TITLE)); if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
mOldActivityTitle = getActivity().getTitle();
String title = arguments.getString(EXTRA_TITLE);
getActivity().getActionBar().setTitle(arguments.getCharSequence(EXTRA_TITLE));
}
// Summary. // Summary.
String summary = arguments.getString(EXTRA_SUMMARY); String summary = arguments.getString(EXTRA_SUMMARY);

View File

@@ -47,6 +47,8 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ViewAnimator; import android.widget.ViewAnimator;
import com.android.settings.R;
import java.util.List; import java.util.List;
/** /**
@@ -54,6 +56,10 @@ import java.util.List;
* available in Touch Exploration. * available in Touch Exploration.
*/ */
public class AccessibilityTutorialActivity extends Activity { public class AccessibilityTutorialActivity extends Activity {
/** Intent action for launching this activity. */
public static final String ACTION = "android.settings.ACCESSIBILITY_TUTORIAL";
/** Instance state saving constant for the active module. */ /** Instance state saving constant for the active module. */
private static final String KEY_ACTIVE_MODULE = "active_module"; private static final String KEY_ACTIVE_MODULE = "active_module";