summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/AccessibilitySettings.java
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2011-09-20 11:10:44 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2011-09-20 12:16:13 -0700
commit232d031a13244e8a2a9a56909e9cdaa2b35f6e00 (patch)
tree7e1c74e3acfd1cbe28a03f7d20d0f11d8800e5d2 /src/com/android/settings/AccessibilitySettings.java
parent1e596f303520d211aebc87dfc0c08108efe80921 (diff)
downloadpackages_apps_settings-232d031a13244e8a2a9a56909e9cdaa2b35f6e00.zip
packages_apps_settings-232d031a13244e8a2a9a56909e9cdaa2b35f6e00.tar.gz
packages_apps_settings-232d031a13244e8a2a9a56909e9cdaa2b35f6e00.tar.bz2
Accessibility settings get into state not allowing to enable accessibility.
If the setting for enabled accessibility serivces contains a service that is not installed on the device the system gets into a state that does not allow enabling accessibility. This state is not recoverable. bug:5343351 Change-Id: I6127ae00f7a16b190cfe43b68b8e71d49b10911e
Diffstat (limited to 'src/com/android/settings/AccessibilitySettings.java')
-rw-r--r--src/com/android/settings/AccessibilitySettings.java128
1 files changed, 85 insertions, 43 deletions
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index 3718ced..3de275b 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.net.Uri;
@@ -82,7 +83,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
// Timeout before we update the services if packages are added/removed since
// the AccessibilityManagerService has to do that processing first to generate
// the AccessibilityServiceInfo we need for proper presentation.
- private static final long DELAY_UPDATE_SERVICES_PREFERENCES_MILLIS = 1000;
+ private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
private static final String ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ":";
@@ -125,9 +126,12 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
// Auxiliary members.
- private final SimpleStringSplitter mStringColonSplitter =
+ private final static SimpleStringSplitter sStringColonSplitter =
new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR.charAt(0));
+ private static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>();
+ private static final Set<ComponentName> sEnabledServices = new HashSet<ComponentName>();
+
private final Map<String, String> mLongPressTimeoutValuetoTitleMap =
new HashMap<String, String>();
@@ -139,6 +143,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
+ loadInstalledServices();
updateServicesPreferences();
}
};
@@ -167,6 +172,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
@Override
public void onResume() {
super.onResume();
+ loadInstalledServices();
updateAllPreferences();
if (mServicesCategory.getPreference(0) == mNoServicesMessagePreference) {
offerInstallAccessibilitySerivceOnce();
@@ -296,7 +302,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
String settingValue = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null) {
- SimpleStringSplitter splitter = mStringColonSplitter;
+ SimpleStringSplitter splitter = sStringColonSplitter;
splitter.setString(settingValue);
while (splitter.hasNext()) {
enabledComponentNames.add(ComponentName.unflattenFromString(splitter.next()));
@@ -493,30 +499,46 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
}
}
+ private void loadInstalledServices() {
+ List<AccessibilityServiceInfo> installedServiceInfos =
+ AccessibilityManager.getInstance(getActivity())
+ .getInstalledAccessibilityServiceList();
+ Set<ComponentName> installedServices = sInstalledServices;
+ installedServices.clear();
+ final int installedServiceInfoCount = installedServiceInfos.size();
+ for (int i = 0; i < installedServiceInfoCount; i++) {
+ ResolveInfo resolveInfo = installedServiceInfos.get(i).getResolveInfo();
+ ComponentName installedService = new ComponentName(
+ resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name);
+ installedServices.add(installedService);
+ }
+ }
+
private class SettingsPackageMonitor extends PackageMonitor {
@Override
public void onPackageAdded(String packageName, int uid) {
Message message = mHandler.obtainMessage();
- mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_PREFERENCES_MILLIS);
+ mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
}
@Override
public void onPackageAppeared(String packageName, int reason) {
Message message = mHandler.obtainMessage();
- mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_PREFERENCES_MILLIS);
+ mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
}
@Override
public void onPackageDisappeared(String packageName, int reason) {
Message message = mHandler.obtainMessage();
- mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_PREFERENCES_MILLIS);
+ mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
}
@Override
public void onPackageRemoved(String packageName, int uid) {
Message message = mHandler.obtainMessage();
- mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_PREFERENCES_MILLIS);
+ mHandler.sendMessageDelayed(message, DELAY_UPDATE_SERVICES_MILLIS);
}
}
@@ -567,49 +589,69 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
public static class ToggleAccessibilityServiceFragment extends TogglePreferenceFragment {
@Override
public void onPreferenceToggled(String preferenceKey, boolean enabled) {
- String enabledServices = Settings.Secure.getString(getContentResolver(),
+ String enabledServicesSetting = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
- if (enabledServices == null) {
- enabledServices = "";
+ if (enabledServicesSetting == null) {
+ enabledServicesSetting = "";
}
- // Due to a legacy bug we can get an enabled services value ending with a
- // separator. Make sure to catch and fix that before handling.
- if (enabledServices.endsWith(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR)) {
- enabledServices = enabledServices.substring(0, enabledServices.length() - 1);
+
+ // Parse the enabled services.
+ Set<ComponentName> enabledServices = sEnabledServices;
+ enabledServices.clear();
+ SimpleStringSplitter colonSplitter = sStringColonSplitter;
+ colonSplitter.setString(enabledServicesSetting);
+ while (colonSplitter.hasNext()) {
+ String componentNameString = colonSplitter.next();
+ ComponentName enabledService = ComponentName.unflattenFromString(
+ componentNameString);
+ if (enabledService != null) {
+ enabledServices.add(enabledService);
+ }
}
- final int length = enabledServices.length();
+
+ // Determine enabled services and accessibility state.
+ ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey);
+ final boolean accessibilityEnabled;
if (enabled) {
- if (enabledServices.contains(preferenceKey)) {
- return;
- }
- if (length == 0) {
- enabledServices += preferenceKey;
- Settings.Secure.putString(getContentResolver(),
- 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) {
- enabledServices += ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey;
- Settings.Secure.putString(getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices);
- }
+ // Enabling at least one service enables accessibility.
+ accessibilityEnabled = true;
+ enabledServices.add(toggledService);
} else {
- final int index = enabledServices.indexOf(preferenceKey);
- if (index == 0) {
- enabledServices = enabledServices.replace(preferenceKey, "");
- Settings.Secure.putString(getContentResolver(),
- 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) {
- enabledServices = enabledServices.replace(
- ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR + preferenceKey, "");
- Settings.Secure.putString(getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices);
+ // Check how many enabled and installed services are present.
+ int enabledAndInstalledServiceCount = 0;
+ Set<ComponentName> installedServices = sInstalledServices;
+ for (ComponentName enabledService : enabledServices) {
+ if (installedServices.contains(enabledService)) {
+ enabledAndInstalledServiceCount++;
+ }
}
+ // Disabling the last service disables accessibility.
+ accessibilityEnabled = enabledAndInstalledServiceCount > 1
+ || (enabledAndInstalledServiceCount == 1
+ && !installedServices.contains(toggledService));
+ enabledServices.remove(toggledService);
+ }
+
+ // Update the enabled services setting.
+ StringBuilder enabledServicesBuilder = new StringBuilder();
+ // Keep the enabled services even if they are not installed since we have
+ // no way to know whether the application restore process has completed.
+ // In general the system should be responsible for the clean up not settings.
+ for (ComponentName enabledService : enabledServices) {
+ enabledServicesBuilder.append(enabledService.flattenToString());
+ enabledServicesBuilder.append(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
}
+ final int enabledServicesBuilderLength = enabledServicesBuilder.length();
+ if (enabledServicesBuilderLength > 0) {
+ enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1);
+ }
+ Settings.Secure.putString(getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ enabledServicesBuilder.toString());
+
+ // Update accessibility enabled.
+ Settings.Secure.putInt(getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0);
}
}