1 /*
2  * Copyright (C) 2017 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.tv.settings.accessibility;
18 
19 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted;
20 
21 import android.accessibilityservice.AccessibilityServiceInfo;
22 import android.app.tvsettings.TvSettingsEnums;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.SharedPreferences;
26 import android.content.pm.PackageManager;
27 import android.os.Bundle;
28 import android.os.UserHandle;
29 import android.provider.Settings;
30 import android.text.TextUtils;
31 import android.view.accessibility.AccessibilityManager;
32 
33 import androidx.annotation.Keep;
34 import androidx.preference.Preference;
35 import androidx.preference.TwoStatePreference;
36 
37 import com.android.settingslib.accessibility.AccessibilityUtils;
38 import com.android.tv.settings.R;
39 import com.android.tv.settings.SettingsPreferenceFragment;
40 
41 import java.util.List;
42 
43 /**
44  * Fragment for configuring the accessibility shortcut
45  */
46 @Keep
47 public class AccessibilityShortcutFragment extends SettingsPreferenceFragment {
48     private static final String KEY_ENABLE = "enable";
49     private static final String KEY_SERVICE = "service";
50     private static final String ACCESSIBILITY_SHORTCUT_STORE = "accessibility_shortcut";
51     private static final String LAST_SHORTCUT_SERVICE = "last_shortcut_service";
52 
53     private SharedPreferences mSharedPref;
54     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)55     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
56         setPreferencesFromResource(R.xml.accessibility_shortcut, null);
57 
58         final TwoStatePreference enablePref = findPreference(KEY_ENABLE);
59         final String currentService = getCurrentService(getContext());
60         enablePref.setOnPreferenceChangeListener((preference, newValue) -> {
61             logToggleInteracted(TvSettingsEnums.SYSTEM_A11Y_SHORTCUT_ON_OFF, (Boolean) newValue);
62             setAccessibilityShortcutEnabled((Boolean) newValue);
63             return true;
64         });
65         String enabledComponents = Settings.Secure.getString(getContext().getContentResolver(),
66                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
67         mSharedPref = getContext().getSharedPreferences(
68                 ACCESSIBILITY_SHORTCUT_STORE, Context.MODE_PRIVATE);
69         boolean shortcutEnabled = !TextUtils.isEmpty(enabledComponents)
70                 || TextUtils.isEmpty(getLastShortcutService());
71         enablePref.setChecked(shortcutEnabled);
72         setAccessibilityShortcutEnabled(shortcutEnabled);
73     }
74 
75     @Override
onResume()76     public void onResume() {
77         super.onResume();
78         updateServicePrefSummary();
79     }
80 
updateServicePrefSummary()81     private void updateServicePrefSummary() {
82         final Preference servicePref = findPreference(KEY_SERVICE);
83         final List<AccessibilityServiceInfo> installedServices = getContext()
84                 .getSystemService(AccessibilityManager.class)
85                 .getInstalledAccessibilityServiceList();
86         final PackageManager packageManager = getContext().getPackageManager();
87         final String currentService = getCurrentService(getContext());
88         for (AccessibilityServiceInfo service : installedServices) {
89             final String serviceString = service.getComponentName().flattenToString();
90             if (TextUtils.equals(currentService, serviceString)) {
91                 if (servicePref != null) {
92                     servicePref.setSummary(service.getResolveInfo().loadLabel(packageManager));
93                 }
94                 putLastShortcutService(currentService);
95             }
96         }
97     }
setAccessibilityShortcutEnabled(boolean enabled)98     private void setAccessibilityShortcutEnabled(boolean enabled) {
99         if (enabled) {
100             String updatedComponent = getLastShortcutService();
101             if (!TextUtils.isEmpty(updatedComponent)) {
102                 Settings.Secure.putString(getContext().getContentResolver(),
103                         Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, updatedComponent);
104                 updateServicePrefSummary();
105             }
106         } else {
107             Settings.Secure.putString(getContext().getContentResolver(),
108                     Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "");
109             final Preference servicePref = findPreference(KEY_SERVICE);
110             servicePref.setSummary(null);
111         }
112         final Preference servicePref = findPreference(KEY_SERVICE);
113         servicePref.setEnabled(enabled);
114     }
115 
getCurrentService(Context context)116     static String getCurrentService(Context context) {
117         String shortcutServiceString = AccessibilityUtils
118                 .getShortcutTargetServiceComponentNameString(context, UserHandle.myUserId());
119         if (shortcutServiceString != null) {
120             ComponentName shortcutName = ComponentName.unflattenFromString(shortcutServiceString);
121             if (shortcutName != null) {
122                 return shortcutName.flattenToString();
123             }
124         }
125         return null;
126     }
127 
128     @Override
getPageId()129     protected int getPageId() {
130         return TvSettingsEnums.SYSTEM_A11Y_SHORTCUT;
131     }
132 
getLastShortcutService()133     private String getLastShortcutService() {
134         return mSharedPref.getString(LAST_SHORTCUT_SERVICE, "");
135     }
136 
putLastShortcutService(String s)137     private void putLastShortcutService(String s) {
138         mSharedPref.edit().putString(LAST_SHORTCUT_SERVICE, s).apply();
139     }
140 }
141