diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index c44a796082b6f..14eb084ce4c61 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -231,4 +231,113 @@
No defaults set
+
+
+ Text-to-speech settings
+
+ Text-to-speech output
+
+ Speech rate
+
+ Speed at which the text is spoken
+
+ Language
+
+ Use system language
+
+ Language not selected
+
+ Sets the language-specific voice for the spoken text
+
+ Listen to an example
+
+ Play a short demonstration of speech synthesis
+
+ Install voice data
+
+ Install the voice data required for speech synthesis
+
+ This speech synthesis engine may be able to collect
+ all the text that will be spoken, including personal data like passwords and credit
+ card numbers. It comes from the %s engine.
+ Enable the use of this speech synthesis engine?
+
+ This language requires a working network connection for text-to-speech output.
+
+ This is an example of speech synthesis
+
+ Default language status
+
+ %1$s is fully supported
+
+ %1$s requires network connection
+
+ %1$s is not supported
+
+ Checking…
+
+ Settings for %s
+
+ Launch engine settings
+
+ Preferred engine
+
+ General
+
+
+
+ - Very slow
+ - Slow
+ - Normal
+ - Fast
+ - Faster
+ - Very fast
+ - Rapid
+ - Very rapid
+ - Fastest
+
+
+
+ - 60
+ - 80
+ - 100
+ - 150
+ - 200
+ - 250
+ - 300
+ - 350
+ - 400
+
+
+
+
+ - This is an example of speech synthesis in English.
+ - Voici un échantillon de synthèse vocale en français.
+ - Dies ist ein Beispiel für Sprachsynthese in Deutsch.
+ - Questo è un esempio di sintesi vocale in italiano.
+ - Este es un ejemplo de síntesis de voz en español.
+ - 이것은 한국어 음성 합성의 예입니다.
+
+
+
+ - eng
+ - fra
+ - deu
+ - ita
+ - spa
+ - kor
+
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
index cf17ea5ebf1a8..99bd4ad1d3dc2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
@@ -16,15 +16,20 @@
package com.android.settingslib.accessibility;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArraySet;
+import android.view.accessibility.AccessibilityManager;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -45,7 +50,7 @@ public class AccessibilityUtils {
return Collections.emptySet();
}
- final Set enabledServices = new HashSet();
+ final Set enabledServices = new HashSet<>();
final TextUtils.SimpleStringSplitter colonSplitter = sStringColonSplitter;
colonSplitter.setString(enabledServicesSetting);
@@ -71,4 +76,79 @@ public class AccessibilityUtils {
final Context langContext = context.createConfigurationContext(config);
return langContext.getText(resId);
}
+
+ public static void setAccessibilityServiceState(Context context, ComponentName toggledService,
+ boolean enabled) {
+ // Parse the enabled services.
+ Set enabledServices = AccessibilityUtils.getEnabledServicesFromSettings(
+ context);
+
+ if (enabledServices.isEmpty()) {
+ enabledServices = new ArraySet<>(1);
+ }
+
+ // Determine enabled services and accessibility state.
+ boolean accessibilityEnabled = false;
+ if (enabled) {
+ enabledServices.add(toggledService);
+ // Enabling at least one service enables accessibility.
+ accessibilityEnabled = true;
+ } else {
+ enabledServices.remove(toggledService);
+ // Check how many enabled and installed services are present.
+ Set installedServices = getInstalledServices(context);
+ for (ComponentName enabledService : enabledServices) {
+ if (installedServices.contains(enabledService)) {
+ // Disabling the last service disables accessibility.
+ accessibilityEnabled = true;
+ break;
+ }
+ }
+ }
+
+ // 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(
+ AccessibilityUtils.ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
+ }
+ final int enabledServicesBuilderLength = enabledServicesBuilder.length();
+ if (enabledServicesBuilderLength > 0) {
+ enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1);
+ }
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ enabledServicesBuilder.toString());
+
+ // Update accessibility enabled.
+ Settings.Secure.putInt(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0);
+ }
+
+ private static Set getInstalledServices(Context context) {
+ final Set installedServices = new HashSet<>();
+ installedServices.clear();
+
+ final List installedServiceInfos =
+ AccessibilityManager.getInstance(context)
+ .getInstalledAccessibilityServiceList();
+ if (installedServiceInfos == null) {
+ return installedServices;
+ }
+
+ for (final AccessibilityServiceInfo info : installedServiceInfos) {
+ final ResolveInfo resolveInfo = info.getResolveInfo();
+ final ComponentName installedService = new ComponentName(
+ resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name);
+ installedServices.add(installedService);
+ }
+ return installedServices;
+ }
+
}