1 |
1 |
/* |
2 |
2 |
* Copyright (C) 2009 The Android Open Source Project |
3 |
3 |
* |
4 |
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
5 |
* you may not use this file except in compliance with the License. |
6 |
6 |
* You may obtain a copy of the License at |
7 |
7 |
* |
8 |
8 |
* http://www.apache.org/licenses/LICENSE-2.0 |
9 |
9 |
* |
10 |
10 |
* Unless required by applicable law or agreed to in writing, software
|
11 |
11 |
* distributed under the License is distributed on an "AS IS" BASIS, |
12 |
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
|
13 |
13 |
* See the License for the specific language governing permissions and
|
14 |
14 |
* limitations under the License. |
15 |
15 |
*/ |
16 |
16 |
|
17 |
17 |
package com.android.settings.accessibility; |
18 |
18 |
|
19 |
19 |
import android.accessibilityservice.AccessibilityServiceInfo; |
|
20 |
import android.app.Activity; |
20 |
21 |
import android.app.ActivityManagerNative; |
21 |
22 |
import android.app.admin.DevicePolicyManager; |
22 |
23 |
import android.content.ComponentName; |
23 |
24 |
import android.content.Context; |
|
25 |
import android.content.Intent; |
24 |
26 |
import android.content.pm.PackageManager; |
25 |
27 |
import android.content.pm.ResolveInfo; |
26 |
28 |
import android.content.pm.ServiceInfo; |
27 |
29 |
import android.content.res.Configuration; |
28 |
30 |
import android.net.Uri; |
29 |
31 |
import android.os.Bundle; |
30 |
32 |
import android.os.Handler; |
31 |
33 |
import android.os.RemoteException; |
32 |
34 |
import android.os.UserHandle; |
33 |
35 |
import android.preference.ListPreference; |
34 |
36 |
import android.preference.Preference; |
35 |
37 |
import android.preference.PreferenceCategory; |
36 |
38 |
import android.preference.PreferenceScreen; |
37 |
39 |
import android.preference.SwitchPreference; |
38 |
40 |
import android.provider.SearchIndexableResource; |
39 |
41 |
import android.provider.Settings; |
40 |
42 |
import android.text.TextUtils; |
41 |
43 |
import android.text.TextUtils.SimpleStringSplitter; |
42 |
44 |
import android.view.KeyCharacterMap; |
43 |
45 |
import android.view.KeyEvent; |
44 |
46 |
import android.view.accessibility.AccessibilityManager; |
45 |
47 |
import com.android.internal.content.PackageMonitor; |
46 |
48 |
import com.android.internal.logging.MetricsLogger; |
47 |
49 |
import com.android.internal.view.RotationPolicy; |
48 |
50 |
import com.android.internal.view.RotationPolicy.RotationPolicyListener;
|
49 |
51 |
import com.android.settings.DialogCreatable; |
50 |
52 |
import com.android.settings.R; |
51 |
53 |
import com.android.settings.SettingsPreferenceFragment; |
52 |
54 |
import com.android.settings.Utils; |
53 |
55 |
import com.android.settings.search.BaseSearchIndexProvider; |
54 |
56 |
import com.android.settings.search.Indexable; |
55 |
57 |
import com.android.settings.search.SearchIndexableRaw; |
56 |
58 |
|
57 |
59 |
import java.util.ArrayList; |
58 |
60 |
import java.util.HashMap; |
59 |
61 |
import java.util.HashSet; |
60 |
62 |
import java.util.List; |
61 |
63 |
import java.util.Map; |
62 |
64 |
import java.util.Set; |
63 |
65 |
|
64 |
66 |
/** |
65 |
67 |
* Activity with the accessibility settings. |
66 |
68 |
*/ |
67 |
69 |
public class AccessibilitySettings extends SettingsPreferenceFragment
implements DialogCreatable,
|
68 |
70 |
Preference.OnPreferenceChangeListener, Indexable { |
69 |
71 |
|
70 |
72 |
private static final float LARGE_FONT_SCALE = 1.3f; |
71 |
73 |
|
72 |
74 |
static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':'; |
73 |
75 |
|
74 |
76 |
// Preference categories |
75 |
77 |
private static final String SERVICES_CATEGORY = "services_category"; |
76 |
78 |
private static final String SYSTEM_CATEGORY = "system_category"; |
77 |
79 |
|
78 |
80 |
// Preferences |
|
81 |
private static final String TOGGLE_ENHANCE_NAVIGATION_BAR_PREFERENCE =
|
|
82 |
"toggle_enhance_navigation_bar_preference"; |
79 |
83 |
private static final String TOGGLE_LARGE_TEXT_PREFERENCE = |
80 |
84 |
"toggle_large_text_preference"; |
81 |
85 |
private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE = |
82 |
86 |
"toggle_high_text_contrast_preference"; |
83 |
87 |
private static final String TOGGLE_INVERSION_PREFERENCE = |
84 |
88 |
"toggle_inversion_preference"; |
85 |
89 |
private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
|
86 |
90 |
"toggle_power_button_ends_call_preference"; |
87 |
91 |
private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE = |
88 |
92 |
"toggle_lock_screen_rotation_preference"; |
89 |
93 |
private static final String TOGGLE_SPEAK_PASSWORD_PREFERENCE = |
90 |
94 |
"toggle_speak_password_preference"; |
91 |
95 |
private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE = |
92 |
96 |
"select_long_press_timeout_preference"; |
93 |
97 |
private static final String
ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
|
94 |
98 |
"enable_global_gesture_preference_screen"; |
95 |
99 |
private static final String CAPTIONING_PREFERENCE_SCREEN = |
96 |
100 |
"captioning_preference_screen"; |
97 |
101 |
private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
|
98 |
102 |
"screen_magnification_preference_screen"; |
99 |
103 |
private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = |
100 |
104 |
"daltonizer_preference_screen"; |
101 |
105 |
|
102 |
106 |
// Extras passed to sub-fragments. |
103 |
107 |
static final String EXTRA_PREFERENCE_KEY = "preference_key"; |
104 |
108 |
static final String EXTRA_CHECKED = "checked"; |
105 |
109 |
static final String EXTRA_TITLE = "title"; |
106 |
110 |
static final String EXTRA_SUMMARY = "summary"; |
107 |
111 |
static final String EXTRA_SETTINGS_TITLE = "settings_title"; |
108 |
112 |
static final String EXTRA_COMPONENT_NAME = "component_name"; |
109 |
113 |
static final String EXTRA_SETTINGS_COMPONENT_NAME =
"settings_component_name";
|
110 |
114 |
|
111 |
115 |
// Timeout before we update the services if packages are added/removed
|
112 |
116 |
// since the AccessibilityManagerService has to do that processing
first
|
113 |
117 |
// to generate the AccessibilityServiceInfo we need for proper |
114 |
118 |
// presentation. |
115 |
119 |
private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000; |
116 |
120 |
|
117 |
121 |
// Auxiliary members. |
118 |
122 |
final static SimpleStringSplitter sStringColonSplitter = |
119 |
123 |
new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR); |
120 |
124 |
|
121 |
125 |
static final Set<ComponentName> sInstalledServices = new HashSet<ComponentName>(); |
122 |
126 |
|
123 |
127 |
private final Map<String, String> mLongPressTimeoutValuetoTitleMap
=
|
124 |
128 |
new HashMap<String, String>(); |
125 |
129 |
|
126 |
130 |
private final Configuration mCurConfig = new Configuration(); |
127 |
131 |
|
128 |
132 |
private final Handler mHandler = new Handler(); |
129 |
133 |
|
|
134 |
private Context mContext; |
|
135 |
|
130 |
136 |
private final Runnable mUpdateRunnable = new Runnable() { |
131 |
137 |
@Override |
132 |
138 |
public void run() { |
133 |
139 |
loadInstalledServices(); |
134 |
140 |
updateServicesPreferences(); |
135 |
141 |
} |
136 |
142 |
}; |
137 |
143 |
|
138 |
144 |
private final PackageMonitor mSettingsPackageMonitor = new
PackageMonitor() {
|
139 |
145 |
@Override |
140 |
146 |
public void onPackageAdded(String packageName, int uid) { |
141 |
147 |
sendUpdate(); |
142 |
148 |
} |
143 |
149 |
|
144 |
150 |
@Override |
145 |
151 |
public void onPackageAppeared(String packageName, int reason) { |
146 |
152 |
sendUpdate(); |
147 |
153 |
} |
148 |
154 |
|
149 |
155 |
@Override |
150 |
156 |
public void onPackageDisappeared(String packageName, int reason) { |
151 |
157 |
sendUpdate(); |
152 |
158 |
} |
153 |
159 |
|
154 |
160 |
@Override |
155 |
161 |
public void onPackageRemoved(String packageName, int uid) { |
156 |
162 |
sendUpdate(); |
157 |
163 |
} |
158 |
164 |
|
159 |
165 |
private void sendUpdate() { |
160 |
166 |
mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_SERVICES_MILLIS); |
161 |
167 |
} |
162 |
168 |
}; |
163 |
169 |
|
164 |
170 |
private final SettingsContentObserver mSettingsContentObserver = |
165 |
171 |
new SettingsContentObserver(mHandler) { |
166 |
172 |
@Override |
167 |
173 |
public void onChange(boolean selfChange, Uri uri) { |
168 |
174 |
loadInstalledServices(); |
169 |
175 |
updateServicesPreferences(); |
170 |
176 |
} |
171 |
177 |
}; |
172 |
178 |
|
173 |
179 |
private final RotationPolicyListener mRotationPolicyListener = new
RotationPolicyListener() {
|
174 |
180 |
@Override |
175 |
181 |
public void onChange() { |
176 |
182 |
updateLockScreenRotationCheckbox(); |
177 |
183 |
} |
178 |
184 |
}; |
179 |
185 |
|
180 |
186 |
// Preference controls. |
181 |
187 |
private PreferenceCategory mServicesCategory; |
182 |
188 |
private PreferenceCategory mSystemsCategory; |
183 |
189 |
|
184 |
190 |
private SwitchPreference mToggleLargeTextPreference; |
185 |
191 |
private SwitchPreference mToggleHighTextContrastPreference; |
186 |
192 |
private SwitchPreference mTogglePowerButtonEndsCallPreference; |
187 |
193 |
private SwitchPreference mToggleLockScreenRotationPreference; |
|
194 |
private SwitchPreference mToggleEnhanceNavigationBarPreference; |
188 |
195 |
private SwitchPreference mToggleSpeakPasswordPreference; |
189 |
196 |
private ListPreference mSelectLongPressTimeoutPreference; |
190 |
197 |
private Preference mNoServicesMessagePreference; |
191 |
198 |
private PreferenceScreen mCaptioningPreferenceScreen; |
192 |
199 |
private PreferenceScreen mDisplayMagnificationPreferenceScreen; |
193 |
200 |
private PreferenceScreen mGlobalGesturePreferenceScreen; |
194 |
201 |
private PreferenceScreen mDisplayDaltonizerPreferenceScreen; |
195 |
202 |
private SwitchPreference mToggleInversionPreference; |
196 |
203 |
|
197 |
204 |
private int mLongPressTimeoutDefault; |
198 |
205 |
|
199 |
206 |
private DevicePolicyManager mDpm; |
200 |
207 |
|
201 |
208 |
@Override |
202 |
209 |
protected int getMetricsCategory() { |
203 |
210 |
return MetricsLogger.ACCESSIBILITY; |
204 |
211 |
} |
205 |
212 |
|
206 |
213 |
@Override |
207 |
214 |
protected int getHelpResource() { |
208 |
215 |
return R.string.help_uri_accessibility; |
209 |
216 |
} |
210 |
217 |
|
211 |
218 |
@Override |
212 |
219 |
public void onCreate(Bundle icicle) { |
213 |
220 |
super.onCreate(icicle); |
214 |
221 |
addPreferencesFromResource(R.xml.accessibility_settings); |
215 |
222 |
initializeAllPreferences(); |
216 |
223 |
mDpm = (DevicePolicyManager) (getActivity() |
217 |
224 |
.getSystemService(Context.DEVICE_POLICY_SERVICE)); |
218 |
225 |
} |
219 |
226 |
|
220 |
227 |
@Override |
221 |
228 |
public void onResume() { |
222 |
229 |
super.onResume(); |
223 |
230 |
loadInstalledServices(); |
224 |
231 |
updateAllPreferences(); |
225 |
232 |
|
226 |
233 |
mSettingsPackageMonitor.register(getActivity(),
getActivity().getMainLooper(), false);
|
227 |
234 |
mSettingsContentObserver.register(getContentResolver()); |
228 |
235 |
if (RotationPolicy.isRotationSupported(getActivity())) { |
229 |
236 |
RotationPolicy.registerRotationPolicyListener(getActivity(), |
230 |
237 |
mRotationPolicyListener); |
231 |
238 |
} |
232 |
239 |
} |
233 |
240 |
|
234 |
241 |
@Override |
235 |
242 |
public void onPause() { |
236 |
243 |
mSettingsPackageMonitor.unregister(); |
237 |
244 |
mSettingsContentObserver.unregister(getContentResolver()); |
238 |
245 |
if (RotationPolicy.isRotationSupported(getActivity())) { |
239 |
246 |
RotationPolicy.unregisterRotationPolicyListener(getActivity(), |
240 |
247 |
mRotationPolicyListener); |
241 |
248 |
} |
242 |
249 |
super.onPause(); |
243 |
250 |
} |
244 |
251 |
|
245 |
252 |
@Override |
246 |
253 |
public boolean onPreferenceChange(Preference preference, Object newValue)
{
|
247 |
254 |
if (mSelectLongPressTimeoutPreference == preference) { |
248 |
255 |
handleLongPressTimeoutPreferenceChange((String) newValue); |
249 |
256 |
return true; |
250 |
257 |
} else if (mToggleInversionPreference == preference) { |
251 |
258 |
handleToggleInversionPreferenceChange((Boolean) newValue); |
252 |
259 |
return true; |
|
260 |
}else if (mToggleEnhanceNavigationBarPreference == preference){ |
|
261 |
handleToggleEnhanceNavigationBarPreferenceChange((Boolean) newValue);
|
|
262 |
return true; |
253 |
263 |
} |
254 |
264 |
return false; |
255 |
265 |
} |
256 |
266 |
|
257 |
267 |
private void handleLongPressTimeoutPreferenceChange(String stringValue)
{
|
258 |
268 |
Settings.Secure.putInt(getContentResolver(), |
259 |
269 |
Settings.Secure.LONG_PRESS_TIMEOUT, Integer.parseInt(stringValue)); |
260 |
270 |
mSelectLongPressTimeoutPreference.setSummary( |
261 |
271 |
mLongPressTimeoutValuetoTitleMap.get(stringValue)); |
262 |
272 |
} |
263 |
273 |
|
264 |
274 |
private void handleToggleInversionPreferenceChange(boolean checked) {
|
265 |
275 |
Settings.Secure.putInt(getContentResolver(), |
266 |
276 |
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, (checked ? 1 :
0));
|
267 |
277 |
} |
268 |
278 |
|
|
279 |
private void handleToggleEnhanceNavigationBarPreferenceChange(boolean
checked) {
|
|
280 |
Settings.Secure.putInt(getContentResolver(), |
|
281 |
Settings.Secure.ACCESSIBILITY_ENHANCE_NAVIGATION_BAR, (checked ? 1 :
0));
|
|
282 |
if(!checked){ |
|
283 |
//开始发送广播 |
|
284 |
Intent intent = new Intent(); |
|
285 |
intent.setAction("LYD_SHOW_NAVIGATION_BAR"); |
|
286 |
mContext.sendBroadcast(intent); |
|
287 |
} |
|
288 |
} |
|
289 |
|
269 |
290 |
@Override |
270 |
291 |
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
|
271 |
292 |
if (mToggleLargeTextPreference == preference) { |
272 |
293 |
handleToggleLargeTextPreferenceClick(); |
273 |
294 |
return true; |
274 |
295 |
} else if (mToggleHighTextContrastPreference == preference) { |
275 |
296 |
handleToggleTextContrastPreferenceClick(); |
276 |
297 |
return true; |
277 |
298 |
} else if (mTogglePowerButtonEndsCallPreference == preference) { |
278 |
299 |
handleTogglePowerButtonEndsCallPreferenceClick(); |
279 |
300 |
return true; |
280 |
301 |
} else if (mToggleLockScreenRotationPreference == preference) { |
281 |
302 |
handleLockScreenRotationPreferenceClick(); |
|
303 |
return true; |
|
304 |
} else if (mToggleEnhanceNavigationBarPreference == preference) { |
|
305 |
handleToggleEnhanceNavigationBarPreferenceClick(); |
282 |
306 |
return true; |
283 |
307 |
} else if (mToggleSpeakPasswordPreference == preference) { |
284 |
308 |
handleToggleSpeakPasswordPreferenceClick(); |
285 |
309 |
return true; |
286 |
310 |
} else if (mGlobalGesturePreferenceScreen == preference) { |
287 |
311 |
handleToggleEnableAccessibilityGesturePreferenceClick(); |
288 |
312 |
return true; |
289 |
313 |
} else if (mDisplayMagnificationPreferenceScreen == preference) { |
290 |
314 |
handleDisplayMagnificationPreferenceScreenClick(); |
291 |
315 |
return true; |
292 |
316 |
} |
293 |
317 |
return super.onPreferenceTreeClick(preferenceScreen, preference); |
294 |
318 |
} |
295 |
319 |
|
296 |
320 |
private void handleToggleLargeTextPreferenceClick() { |
297 |
321 |
try { |
298 |
322 |
mCurConfig.fontScale = mToggleLargeTextPreference.isChecked() ?
LARGE_FONT_SCALE : 1;
|
299 |
323 |
ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
|
300 |
324 |
} catch (RemoteException re) { |
301 |
325 |
/* ignore */ |
302 |
326 |
} |
303 |
327 |
} |
304 |
328 |
|
305 |
329 |
private void handleToggleTextContrastPreferenceClick() { |
306 |
330 |
Settings.Secure.putInt(getContentResolver(), |
307 |
331 |
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, |
308 |
332 |
(mToggleHighTextContrastPreference.isChecked() ? 1 : 0)); |
309 |
333 |
} |
310 |
334 |
|
311 |
335 |
private void handleTogglePowerButtonEndsCallPreferenceClick() { |
312 |
336 |
Settings.Secure.putInt(getContentResolver(), |
313 |
337 |
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, |
314 |
338 |
(mTogglePowerButtonEndsCallPreference.isChecked() |
315 |
339 |
? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP |
316 |
340 |
: Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF)); |
317 |
341 |
} |
318 |
342 |
|
319 |
343 |
private void handleLockScreenRotationPreferenceClick() { |
320 |
344 |
RotationPolicy.setRotationLockForAccessibility(getActivity(), |
321 |
345 |
!mToggleLockScreenRotationPreference.isChecked()); |
|
346 |
} |
|
347 |
|
|
348 |
private void handleToggleEnhanceNavigationBarPreferenceClick() { |
|
349 |
Settings.Secure.putInt(getContentResolver(), |
|
350 |
Settings.Secure.ACCESSIBILITY_ENHANCE_NAVIGATION_BAR, |
|
351 |
mToggleEnhanceNavigationBarPreference.isChecked() ? 1 : 0); |
322 |
352 |
} |
323 |
353 |
|
324 |
354 |
private void handleToggleSpeakPasswordPreferenceClick() { |
325 |
355 |
Settings.Secure.putInt(getContentResolver(), |
326 |
356 |
Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, |
327 |
357 |
mToggleSpeakPasswordPreference.isChecked() ? 1 : 0); |
328 |
358 |
} |
329 |
359 |
|
330 |
360 |
private void handleToggleEnableAccessibilityGesturePreferenceClick() {
|
331 |
361 |
Bundle extras = mGlobalGesturePreferenceScreen.getExtras(); |
332 |
362 |
extras.putString(EXTRA_TITLE, getString( |
333 |
363 |
R.string.accessibility_global_gesture_preference_title)); |
334 |
364 |
extras.putString(EXTRA_SUMMARY, getString( |
335 |
365 |
R.string.accessibility_global_gesture_preference_description)); |
336 |
366 |
extras.putBoolean(EXTRA_CHECKED,
Settings.Global.getInt(getContentResolver(),
|
337 |
367 |
Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1);
|
338 |
368 |
super.onPreferenceTreeClick(mGlobalGesturePreferenceScreen, |
339 |
369 |
mGlobalGesturePreferenceScreen); |
340 |
370 |
} |
341 |
371 |
|
342 |
372 |
private void handleDisplayMagnificationPreferenceScreenClick() { |
343 |
373 |
Bundle extras = mDisplayMagnificationPreferenceScreen.getExtras(); |
344 |
374 |
extras.putString(EXTRA_TITLE, getString( |
345 |
375 |
R.string.accessibility_screen_magnification_title)); |
346 |
376 |
extras.putCharSequence(EXTRA_SUMMARY,
getActivity().getResources().getText(
|
347 |
377 |
R.string.accessibility_screen_magnification_summary)); |
348 |
378 |
extras.putBoolean(EXTRA_CHECKED,
Settings.Secure.getInt(getContentResolver(),
|
349 |
379 |
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
|
350 |
380 |
super.onPreferenceTreeClick(mDisplayMagnificationPreferenceScreen, |
351 |
381 |
mDisplayMagnificationPreferenceScreen); |
352 |
382 |
} |
353 |
383 |
|
354 |
384 |
private void initializeAllPreferences() { |
355 |
385 |
mServicesCategory = (PreferenceCategory)
findPreference(SERVICES_CATEGORY);
|
356 |
386 |
mSystemsCategory = (PreferenceCategory)
findPreference(SYSTEM_CATEGORY);
|
357 |
387 |
|
358 |
388 |
// Large text. |
359 |
389 |
mToggleLargeTextPreference = |
360 |
390 |
(SwitchPreference) findPreference(TOGGLE_LARGE_TEXT_PREFERENCE); |
361 |
391 |
|
362 |
392 |
// Text contrast. |
363 |
393 |
mToggleHighTextContrastPreference = |
364 |
394 |
(SwitchPreference)
findPreference(TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE);
|
365 |
395 |
|
366 |
396 |
// Display inversion. |
367 |
397 |
mToggleInversionPreference = (SwitchPreference)
findPreference(TOGGLE_INVERSION_PREFERENCE);
|
368 |
398 |
mToggleInversionPreference.setOnPreferenceChangeListener(this); |
369 |
399 |
|
370 |
400 |
// Power button ends calls. |
371 |
401 |
mTogglePowerButtonEndsCallPreference = |
372 |
402 |
(SwitchPreference)
findPreference(TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE);
|
373 |
403 |
if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) |
374 |
404 |
|| !Utils.isVoiceCapable(getActivity())) { |
375 |
405 |
mSystemsCategory.removePreference(mTogglePowerButtonEndsCallPreference);
|
376 |
406 |
} |
377 |
407 |
|
378 |
408 |
// Lock screen rotation. |
379 |
409 |
mToggleLockScreenRotationPreference = |
380 |
410 |
(SwitchPreference)
findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE);
|
381 |
411 |
if (!RotationPolicy.isRotationSupported(getActivity())) { |
382 |
412 |
mSystemsCategory.removePreference(mToggleLockScreenRotationPreference);
|
383 |
413 |
} |
|
414 |
|
|
415 |
// enhance navigation bar. |
|
416 |
mToggleEnhanceNavigationBarPreference = |
|
417 |
(SwitchPreference)
findPreference(TOGGLE_ENHANCE_NAVIGATION_BAR_PREFERENCE);
|
|
418 |
mToggleEnhanceNavigationBarPreference.setOnPreferenceChangeListener(this);
|
384 |
419 |
|
385 |
420 |
// Speak passwords. |
386 |
421 |
mToggleSpeakPasswordPreference = |
387 |
422 |
(SwitchPreference) findPreference(TOGGLE_SPEAK_PASSWORD_PREFERENCE); |
388 |
423 |
|
389 |
424 |
// Long press timeout. |
390 |
425 |
mSelectLongPressTimeoutPreference = |
391 |
426 |
(ListPreference) findPreference(SELECT_LONG_PRESS_TIMEOUT_PREFERENCE);
|
392 |
427 |
mSelectLongPressTimeoutPreference.setOnPreferenceChangeListener(this);
|
393 |
428 |
if (mLongPressTimeoutValuetoTitleMap.size() == 0) { |
394 |
429 |
String[] timeoutValues = getResources().getStringArray( |
395 |
430 |
R.array.long_press_timeout_selector_values); |
396 |
431 |
mLongPressTimeoutDefault = Integer.parseInt(timeoutValues[0]); |
397 |
432 |
String[] timeoutTitles = getResources().getStringArray( |
398 |
433 |
R.array.long_press_timeout_selector_titles); |
399 |
434 |
final int timeoutValueCount = timeoutValues.length; |
400 |
435 |
for (int i = 0; i < timeoutValueCount; i++) { |
401 |
436 |
mLongPressTimeoutValuetoTitleMap.put(timeoutValues[i],
timeoutTitles[i]);
|
402 |
437 |
} |
403 |
438 |
} |
404 |
439 |
|
405 |
440 |
// Captioning. |
406 |
441 |
mCaptioningPreferenceScreen = (PreferenceScreen) findPreference( |
407 |
442 |
CAPTIONING_PREFERENCE_SCREEN); |
408 |
443 |
|
409 |
444 |
// Display magnification. |
410 |
445 |
mDisplayMagnificationPreferenceScreen = (PreferenceScreen)
findPreference(
|
411 |
446 |
DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN); |
412 |
447 |
|
413 |
448 |
// Display color adjustments. |
414 |
449 |
mDisplayDaltonizerPreferenceScreen = (PreferenceScreen) findPreference(
|
415 |
450 |
DISPLAY_DALTONIZER_PREFERENCE_SCREEN); |
416 |
451 |
|
417 |
452 |
// Global gesture. |
418 |
453 |
mGlobalGesturePreferenceScreen = |
419 |
454 |
(PreferenceScreen)
findPreference(ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN);
|
420 |
455 |
final int longPressOnPowerBehavior =
getActivity().getResources().getInteger(
|
421 |
456 |
com.android.internal.R.integer.config_longPressOnPowerBehavior); |
422 |
457 |
final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; |
423 |
458 |
if (!KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) |
424 |
459 |
|| longPressOnPowerBehavior != LONG_PRESS_POWER_GLOBAL_ACTIONS) { |
425 |
460 |
// Remove accessibility shortcut if power key is not present |
426 |
461 |
// nor long press power does not show global actions menu. |
427 |
462 |
mSystemsCategory.removePreference(mGlobalGesturePreferenceScreen); |
428 |
463 |
} |
429 |
464 |
} |
430 |
465 |
|
431 |
466 |
private void updateAllPreferences() { |
432 |
467 |
updateServicesPreferences(); |
433 |
468 |
updateSystemPreferences(); |
434 |
469 |
} |
435 |
470 |
|
436 |
471 |
private void updateServicesPreferences() { |
437 |
472 |
// Since services category is auto generated we have to do a pass |
438 |
473 |
// to generate it since services can come and go and then based on |
439 |
474 |
// the global accessibility state to decided whether it is enabled. |
440 |
475 |
|
441 |
476 |
// Generate. |
442 |
477 |
mServicesCategory.removeAll(); |
443 |
478 |
|
444 |
479 |
AccessibilityManager accessibilityManager =
AccessibilityManager.getInstance(getActivity());
|
445 |
480 |
|
446 |
481 |
List<AccessibilityServiceInfo> installedServices = |
447 |
482 |
accessibilityManager.getInstalledAccessibilityServiceList(); |
448 |
483 |
Set<ComponentName> enabledServices =
AccessibilityUtils.getEnabledServicesFromSettings(
|
449 |
484 |
getActivity()); |
450 |
485 |
List<String> permittedServices =
mDpm.getPermittedAccessibilityServices(
|
451 |
486 |
UserHandle.myUserId()); |
452 |
487 |
final boolean accessibilityEnabled =
Settings.Secure.getInt(getContentResolver(),
|
453 |
488 |
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; |
454 |
489 |
|
455 |
490 |
for (int i = 0, count = installedServices.size(); i < count; ++i) {
|
456 |
491 |
AccessibilityServiceInfo info = installedServices.get(i); |
457 |
492 |
|
458 |
493 |
PreferenceScreen preference =
getPreferenceManager().createPreferenceScreen(
|
459 |
494 |
getActivity()); |
460 |
495 |
String title =
info.getResolveInfo().loadLabel(getPackageManager()).toString();
|
461 |
496 |
|
462 |
497 |
ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; |
463 |
498 |
ComponentName componentName = new
ComponentName(serviceInfo.packageName,
|
464 |
499 |
serviceInfo.name); |
465 |
500 |
|
466 |
501 |
preference.setKey(componentName.flattenToString()); |
467 |
502 |
|
468 |
503 |
preference.setTitle(title); |
469 |
504 |
final boolean serviceEnabled = accessibilityEnabled |
470 |
505 |
&& enabledServices.contains(componentName);
|
471 |
506 |
String serviceEnabledString; |
472 |
507 |
if (serviceEnabled) { |
473 |
508 |
serviceEnabledString =
getString(R.string.accessibility_feature_state_on);
|
474 |
509 |
} else { |
475 |
510 |
serviceEnabledString =
getString(R.string.accessibility_feature_state_off);
|
476 |
511 |
} |
477 |
512 |
|
478 |
513 |
// Disable all accessibility services that are not permitted. |
479 |
514 |
String packageName = serviceInfo.packageName; |
480 |
515 |
boolean serviceAllowed = |
481 |
516 |
permittedServices == null || permittedServices.contains(packageName);
|
482 |
517 |
preference.setEnabled(serviceAllowed || serviceEnabled); |
483 |
518 |
|
484 |
519 |
String summaryString; |
485 |
520 |
if (serviceAllowed) { |
486 |
521 |
summaryString = serviceEnabledString; |
487 |
522 |
} else { |
488 |
523 |
summaryString =
getString(R.string.accessibility_feature_or_input_method_not_allowed);
|
489 |
524 |
} |
490 |
525 |
preference.setSummary(summaryString); |
491 |
526 |
|
492 |
527 |
preference.setOrder(i); |
493 |
528 |
preference.setFragment(ToggleAccessibilityServicePreferenceFragment.class.getName());
|
494 |
529 |
preference.setPersistent(true); |
495 |
530 |
|
496 |
531 |
Bundle extras = preference.getExtras(); |
497 |
532 |
extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey()); |
498 |
533 |
extras.putBoolean(EXTRA_CHECKED, serviceEnabled); |
499 |
534 |
extras.putString(EXTRA_TITLE, title); |
500 |
535 |
|
501 |
536 |
String description = info.loadDescription(getPackageManager()); |
502 |
537 |
if (TextUtils.isEmpty(description)) { |
503 |
538 |
description =
getString(R.string.accessibility_service_default_description);
|
504 |
539 |
} |
505 |
540 |
extras.putString(EXTRA_SUMMARY, description); |
506 |
541 |
|
507 |
542 |
String settingsClassName = info.getSettingsActivityName(); |
508 |
543 |
if (!TextUtils.isEmpty(settingsClassName)) { |
509 |
544 |
extras.putString(EXTRA_SETTINGS_TITLE, |
510 |
545 |
getString(R.string.accessibility_menu_item_settings)); |
511 |
546 |
extras.putString(EXTRA_SETTINGS_COMPONENT_NAME, |
512 |
547 |
new ComponentName(info.getResolveInfo().serviceInfo.packageName, |
513 |
548 |
settingsClassName).flattenToString()); |
514 |
549 |
} |
515 |
550 |
|
516 |
551 |
extras.putParcelable(EXTRA_COMPONENT_NAME, componentName); |
517 |
552 |
|
518 |
553 |
mServicesCategory.addPreference(preference); |
519 |
554 |
} |
520 |
555 |
|
521 |
556 |
if (mServicesCategory.getPreferenceCount() == 0) { |
522 |
557 |
if (mNoServicesMessagePreference == null) { |
523 |
558 |
mNoServicesMessagePreference = new Preference(getActivity()); |
524 |
559 |
mNoServicesMessagePreference.setPersistent(false); |
525 |
560 |
mNoServicesMessagePreference.setLayoutResource( |
526 |
561 |
R.layout.text_description_preference); |
527 |
562 |
mNoServicesMessagePreference.setSelectable(false); |
528 |
563 |
mNoServicesMessagePreference.setSummary( |
529 |
564 |
getString(R.string.accessibility_no_services_installed)); |
530 |
565 |
} |
531 |
566 |
mServicesCategory.addPreference(mNoServicesMessagePreference); |
532 |
567 |
} |
533 |
568 |
} |
534 |
569 |
|
535 |
570 |
private void updateSystemPreferences() { |
536 |
571 |
// Large text. |
537 |
572 |
try { |
538 |
573 |
mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
|
539 |
574 |
} catch (RemoteException re) { |
540 |
575 |
/* ignore */ |
541 |
576 |
} |
542 |
577 |
mToggleLargeTextPreference.setChecked(mCurConfig.fontScale ==
LARGE_FONT_SCALE);
|
543 |
578 |
|
544 |
579 |
mToggleHighTextContrastPreference.setChecked( |
545 |
580 |
Settings.Secure.getInt(getContentResolver(), |
546 |
581 |
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0) == 1); |
547 |
582 |
|
548 |
583 |
// If the quick setting is enabled, the preference MUST be enabled. |
549 |
584 |
mToggleInversionPreference.setChecked(Settings.Secure.getInt(getContentResolver(),
|
550 |
585 |
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0) == 1); |
551 |
586 |
|
552 |
587 |
// Power button ends calls. |
553 |
588 |
if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER) |
554 |
589 |
&& Utils.isVoiceCapable(getActivity())) { |
555 |
590 |
final int incallPowerBehavior =
Settings.Secure.getInt(getContentResolver(),
|
556 |
591 |
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, |
557 |
592 |
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); |
558 |
593 |
final boolean powerButtonEndsCall = |
559 |
594 |
(incallPowerBehavior ==
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP);
|
560 |
595 |
mTogglePowerButtonEndsCallPreference.setChecked(powerButtonEndsCall);
|
561 |
596 |
} |
562 |
597 |
|
563 |
598 |
// Auto-rotate screen |
564 |
599 |
updateLockScreenRotationCheckbox(); |
565 |
600 |
|
|
601 |
// Enhance navigation bar. |
|
602 |
final boolean enhanceNaviagtionBarEnabled =
Settings.Secure.getInt(getContentResolver(),
|
|
603 |
Settings.Secure.ACCESSIBILITY_ENHANCE_NAVIGATION_BAR, 0) != 0; |
|
604 |
mToggleEnhanceNavigationBarPreference.setChecked(enhanceNaviagtionBarEnabled);
|
|
605 |
|
566 |
606 |
// Speak passwords. |
567 |
607 |
final boolean speakPasswordEnabled =
Settings.Secure.getInt(getContentResolver(),
|
568 |
608 |
Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0; |
569 |
609 |
mToggleSpeakPasswordPreference.setChecked(speakPasswordEnabled); |
570 |
610 |
|
571 |
611 |
// Long press timeout. |
572 |
612 |
final int longPressTimeout =
Settings.Secure.getInt(getContentResolver(),
|
573 |
613 |
Settings.Secure.LONG_PRESS_TIMEOUT, mLongPressTimeoutDefault); |
574 |
614 |
String value = String.valueOf(longPressTimeout); |
575 |
615 |
mSelectLongPressTimeoutPreference.setValue(value); |
576 |
616 |
mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
|
577 |
617 |
|
578 |
618 |
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
|
579 |
619 |
mCaptioningPreferenceScreen); |
580 |
620 |
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
|
581 |
621 |
mDisplayMagnificationPreferenceScreen); |
582 |
622 |
updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
|
583 |
623 |
mDisplayDaltonizerPreferenceScreen); |
584 |
624 |
|
585 |
625 |
// Global gesture |
586 |
626 |
final boolean globalGestureEnabled =
Settings.Global.getInt(getContentResolver(),
|
587 |
627 |
Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
|
588 |
628 |
if (globalGestureEnabled) { |
589 |
629 |
mGlobalGesturePreferenceScreen.setSummary( |
590 |
630 |
R.string.accessibility_global_gesture_preference_summary_on); |
591 |
631 |
} else { |
592 |
632 |
mGlobalGesturePreferenceScreen.setSummary( |
593 |
633 |
R.string.accessibility_global_gesture_preference_summary_off); |
594 |
634 |
} |
595 |
635 |
} |
596 |
636 |
|
597 |
637 |
private void updateFeatureSummary(String prefKey, Preference pref) { |
598 |
638 |
final boolean enabled = Settings.Secure.getInt(getContentResolver(),
prefKey, 0) == 1;
|
599 |
639 |
pref.setSummary(enabled ? R.string.accessibility_feature_state_on |
600 |
640 |
: R.string.accessibility_feature_state_off); |
601 |
641 |
} |
602 |
642 |
|
603 |
643 |
private void updateLockScreenRotationCheckbox() { |
604 |
644 |
Context context = getActivity(); |
605 |
645 |
if (context != null) { |
606 |
646 |
mToggleLockScreenRotationPreference.setChecked( |
607 |
647 |
!RotationPolicy.isRotationLocked(context)); |
608 |
648 |
} |
609 |
649 |
} |
610 |
650 |
|
611 |
651 |
private void loadInstalledServices() { |
612 |
652 |
Set<ComponentName> installedServices = sInstalledServices; |
613 |
653 |
installedServices.clear(); |
614 |
654 |
|
615 |
655 |
List<AccessibilityServiceInfo> installedServiceInfos = |
616 |
656 |
AccessibilityManager.getInstance(getActivity()) |
617 |
657 |
.getInstalledAccessibilityServiceList(); |
618 |
658 |
if (installedServiceInfos == null) { |
619 |
659 |
return; |
620 |
660 |
} |
621 |
661 |
|
622 |
662 |
final int installedServiceInfoCount = installedServiceInfos.size(); |
623 |
663 |
for (int i = 0; i < installedServiceInfoCount; i++) { |
624 |
664 |
ResolveInfo resolveInfo =
installedServiceInfos.get(i).getResolveInfo();
|
625 |
665 |
ComponentName installedService = new ComponentName( |
626 |
666 |
resolveInfo.serviceInfo.packageName, |
627 |
667 |
resolveInfo.serviceInfo.name); |
628 |
668 |
installedServices.add(installedService); |
629 |
669 |
} |
630 |
670 |
} |
631 |
671 |
|
632 |
672 |
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = |
633 |
673 |
new BaseSearchIndexProvider() { |
634 |
674 |
@Override |
635 |
675 |
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
boolean enabled) {
|
636 |
676 |
List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>(); |
637 |
677 |
|
638 |
678 |
PackageManager packageManager = context.getPackageManager(); |
639 |
679 |
AccessibilityManager accessibilityManager = (AccessibilityManager) |
640 |
680 |
context.getSystemService(Context.ACCESSIBILITY_SERVICE); |
641 |
681 |
|
642 |
682 |
String screenTitle = context.getResources().getString( |
643 |
683 |
R.string.accessibility_services_title); |
644 |
684 |
|
645 |
685 |
// Indexing all services, regardless if enabled. |
646 |
686 |
List<AccessibilityServiceInfo> services = accessibilityManager |
647 |
687 |
.getInstalledAccessibilityServiceList(); |
648 |
688 |
final int serviceCount = services.size(); |
649 |
689 |
for (int i = 0; i < serviceCount; i++) { |
650 |
690 |
AccessibilityServiceInfo service = services.get(i); |
651 |
691 |
if (service == null || service.getResolveInfo() == null) { |
652 |
692 |
continue; |
653 |
693 |
} |
654 |
694 |
|
655 |
695 |
ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo; |
656 |
696 |
ComponentName componentName = new
ComponentName(serviceInfo.packageName,
|
657 |
697 |
serviceInfo.name); |
658 |
698 |
|
659 |
699 |
SearchIndexableRaw indexable = new SearchIndexableRaw(context); |
660 |
700 |
indexable.key = componentName.flattenToString(); |
661 |
701 |
indexable.title =
service.getResolveInfo().loadLabel(packageManager).toString();
|
662 |
702 |
indexable.summaryOn =
context.getString(R.string.accessibility_feature_state_on);
|
663 |
703 |
indexable.summaryOff =
context.getString(R.string.accessibility_feature_state_off);
|
664 |
704 |
indexable.screenTitle = screenTitle; |
665 |
705 |
indexables.add(indexable); |
666 |
706 |
} |
667 |
707 |
|
668 |
708 |
return indexables; |
669 |
709 |
} |
670 |
710 |
|
671 |
711 |
@Override |
672 |
712 |
public List<SearchIndexableResource> getXmlResourcesToIndex(Context
context,
|
673 |
713 |
boolean enabled) { |
674 |
714 |
List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>(); |
675 |
715 |
SearchIndexableResource indexable = new
SearchIndexableResource(context);
|
676 |
716 |
indexable.xmlResId = R.xml.accessibility_settings; |
677 |
717 |
indexables.add(indexable); |
678 |
718 |
return indexables; |
679 |
719 |
} |
680 |
720 |
}; |
|
721 |
|
|
722 |
@Override |
|
723 |
public void onAttach(Activity activity) { |
|
724 |
super.onAttach(activity); |
|
725 |
mContext = activity; |
|
726 |
} |
681 |
727 |
} |
682 |
728 |
|