1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.settings.accessibility; 18 19 import android.accessibilityservice.AccessibilityServiceInfo; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.pm.ServiceInfo; 23 import android.os.UserHandle; 24 import android.view.accessibility.AccessibilityManager; 25 26 import androidx.annotation.Nullable; 27 28 import com.android.car.settings.R; 29 import com.android.internal.accessibility.util.AccessibilityUtils; 30 31 import java.util.List; 32 33 /** 34 * Hosts utility methods and constants for screen reader related settings. 35 */ 36 public class ScreenReaderUtils { 37 38 /** 39 * Returns whether the system screen reader is installed on the device. 40 */ isScreenReaderInstalled(Context context)41 static boolean isScreenReaderInstalled(Context context) { 42 return getScreenReaderServiceInfo(context) != null; 43 } 44 45 /** 46 * Returns whether the default screen reader is currently enabled on the device. 47 */ isScreenReaderEnabled(Context context)48 static boolean isScreenReaderEnabled(Context context) { 49 ComponentName screenReaderComponent = getScreenReaderComponentName(context); 50 if (screenReaderComponent == null) { 51 return false; 52 } 53 return AccessibilityUtils.getEnabledServicesFromSettings(context, 54 UserHandle.myUserId()).contains(screenReaderComponent); 55 } 56 57 /** 58 * Returns the name of the system default screen reader if it is installed. Returns an empty 59 * string if not. 60 */ 61 @Nullable getScreenReaderName(Context context)62 static CharSequence getScreenReaderName(Context context) { 63 AccessibilityServiceInfo serviceInfo = getScreenReaderServiceInfo(context); 64 if (serviceInfo == null) { 65 return ""; 66 } 67 68 return serviceInfo.getResolveInfo().loadLabel(context.getPackageManager()); 69 } 70 71 /** 72 * Returns the description of the system default screen reader if it is installed. Returns an 73 * empty string if not. 74 */ getScreenReaderDescription(Context context)75 static CharSequence getScreenReaderDescription(Context context) { 76 AccessibilityServiceInfo serviceInfo = getScreenReaderServiceInfo(context); 77 if (serviceInfo == null) { 78 return ""; 79 } 80 81 String description = serviceInfo.loadDescription(context.getPackageManager()); 82 return description != null ? description : ""; 83 } 84 85 /** 86 * Returns the settings activity ComponentName of the system default screen reader if the screen 87 * reader is installed and a settings activity exists. Returns {@code null} otherwise. 88 */ 89 @Nullable getScreenReaderSettingsActivity(Context context)90 static ComponentName getScreenReaderSettingsActivity(Context context) { 91 AccessibilityServiceInfo serviceInfo = getScreenReaderServiceInfo(context); 92 if (serviceInfo == null) { 93 return null; 94 } 95 96 String settingsActivity = serviceInfo.getSettingsActivityName(); 97 if (settingsActivity == null || settingsActivity.isEmpty()) { 98 return null; 99 } 100 101 return new ComponentName(getScreenReaderComponentName(context).getPackageName(), 102 settingsActivity); 103 } 104 105 /** 106 * Sets the screen reader enabled state. This should only be called if the screen reader is 107 * installed. 108 */ setScreenReaderEnabled(Context context, boolean enabled)109 static void setScreenReaderEnabled(Context context, boolean enabled) { 110 ComponentName screenReaderComponent = getScreenReaderComponentName(context); 111 if (screenReaderComponent == null) { 112 return; 113 } 114 115 AccessibilityUtils.setAccessibilityServiceState(context, 116 getScreenReaderComponentName(context), enabled, 117 UserHandle.myUserId()); 118 } 119 getScreenReaderComponentName(Context context)120 private static ComponentName getScreenReaderComponentName(Context context) { 121 return ComponentName.unflattenFromString( 122 context.getString(R.string.config_default_screen_reader)); 123 } 124 125 @Nullable getScreenReaderServiceInfo(Context context)126 private static AccessibilityServiceInfo getScreenReaderServiceInfo(Context context) { 127 AccessibilityManager accessibilityManager = context.getSystemService( 128 AccessibilityManager.class); 129 if (accessibilityManager == null) { 130 return null; 131 } 132 133 List<AccessibilityServiceInfo> accessibilityServices = 134 accessibilityManager.getInstalledAccessibilityServiceList(); 135 if (accessibilityServices == null) { 136 return null; 137 } 138 139 ComponentName screenReaderComponent = getScreenReaderComponentName(context); 140 if (screenReaderComponent == null) { 141 return null; 142 } 143 144 for (AccessibilityServiceInfo info : accessibilityServices) { 145 ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; 146 if (screenReaderComponent.getPackageName().equals(serviceInfo.packageName) 147 && screenReaderComponent.getClassName().equals(serviceInfo.name)) { 148 return info; 149 } 150 } 151 152 return null; 153 } 154 155 } 156