19c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt/* 29c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * Copyright (C) 2017 The Android Open Source Project 39c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * 49c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * Licensed under the Apache License, Version 2.0 (the "License"); 59c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * you may not use this file except in compliance with the License. 69c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * You may obtain a copy of the License at 79c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * 89c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * http://www.apache.org/licenses/LICENSE-2.0 99c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * 109c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * Unless required by applicable law or agreed to in writing, software 119c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * distributed under the License is distributed on an "AS IS" BASIS, 129c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * See the License for the specific language governing permissions and 149c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt * limitations under the License. 159c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt */ 169c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 179c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtpackage com.android.settings.accessibility; 189c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 19bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardtimport android.accessibilityservice.AccessibilityServiceInfo; 20bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardtimport android.content.ComponentName; 21a92271c26d6cc17529747dad02491078f6914abahjchangliaoimport android.content.ContentResolver; 229c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport android.content.Context; 23875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardtimport android.content.res.Resources; 249c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport android.os.Bundle; 259c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport android.provider.SearchIndexableResource; 269c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport android.provider.Settings; 27a92271c26d6cc17529747dad02491078f6914abahjchangliaoimport android.support.annotation.VisibleForTesting; 289c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport android.support.v7.preference.Preference; 29bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardtimport android.text.TextUtils; 30bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardtimport android.view.accessibility.AccessibilityManager; 319c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 329c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 339c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport com.android.settings.R; 340cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhangimport com.android.settings.dashboard.DashboardFragment; 359c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport com.android.settings.search.BaseSearchIndexProvider; 369c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport com.android.settings.search.Indexable; 3717ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsaiimport com.android.settings.search.actionbar.SearchMenuController; 3817ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsaiimport com.android.settings.support.actionbar.HelpResourceProvider; 399c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 409c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport java.util.Arrays; 419c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardtimport java.util.List; 429c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 43807506b1668b8438a138e1485f27e74de6a3d06crafftsaipublic final class MagnificationPreferenceFragment extends DashboardFragment { 44a92271c26d6cc17529747dad02491078f6914abahjchangliao @VisibleForTesting 45a92271c26d6cc17529747dad02491078f6914abahjchangliao static final int ON = 1; 46a92271c26d6cc17529747dad02491078f6914abahjchangliao @VisibleForTesting 47a92271c26d6cc17529747dad02491078f6914abahjchangliao static final int OFF = 0; 48807506b1668b8438a138e1485f27e74de6a3d06crafftsai 49807506b1668b8438a138e1485f27e74de6a3d06crafftsai private static final String TAG = "MagnificationPreferenceFragment"; 509c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 519c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt // Settings App preference keys 526ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze private static final String PREFERENCE_TITLE_KEY = "magnification_preference_screen_title"; 539c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 54bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt // Pseudo ComponentName used to represent navbar magnification in Settings.Secure. 55bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt private static final String MAGNIFICATION_COMPONENT_ID = 56bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt "com.android.server.accessibility.MagnificationController"; 57bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt 589c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt private boolean mLaunchedFromSuw = false; 599c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 609c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt @Override 61807506b1668b8438a138e1485f27e74de6a3d06crafftsai public int getMetricsCategory() { 62807506b1668b8438a138e1485f27e74de6a3d06crafftsai return MetricsEvent.ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS; 63807506b1668b8438a138e1485f27e74de6a3d06crafftsai } 64807506b1668b8438a138e1485f27e74de6a3d06crafftsai 65807506b1668b8438a138e1485f27e74de6a3d06crafftsai @Override 66807506b1668b8438a138e1485f27e74de6a3d06crafftsai protected String getLogTag() { 67807506b1668b8438a138e1485f27e74de6a3d06crafftsai return TAG; 689c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 699c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 709c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt @Override 71e0b0e9f9025038d72f8129606cc1f432afcb54e0Fan Zhang public int getHelpResource() { 72179645eecd1a2321e7dd8992678b47799e60f9e6Fan Zhang return R.string.help_url_magnification; 73179645eecd1a2321e7dd8992678b47799e60f9e6Fan Zhang } 74179645eecd1a2321e7dd8992678b47799e60f9e6Fan Zhang 75179645eecd1a2321e7dd8992678b47799e60f9e6Fan Zhang @Override 76807506b1668b8438a138e1485f27e74de6a3d06crafftsai protected int getPreferenceScreenResId() { 77807506b1668b8438a138e1485f27e74de6a3d06crafftsai return R.xml.accessibility_magnification_settings; 78807506b1668b8438a138e1485f27e74de6a3d06crafftsai } 799c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 80807506b1668b8438a138e1485f27e74de6a3d06crafftsai @Override 81807506b1668b8438a138e1485f27e74de6a3d06crafftsai public void onAttach(Context context) { 82807506b1668b8438a138e1485f27e74de6a3d06crafftsai super.onAttach(context); 839c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt final Bundle args = getArguments(); 849c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt if ((args != null) && args.containsKey(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW)) { 859c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt mLaunchedFromSuw = args.getBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW); 869c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 87807506b1668b8438a138e1485f27e74de6a3d06crafftsai use(MagnificationGesturesPreferenceController.class) 88807506b1668b8438a138e1485f27e74de6a3d06crafftsai .setIsFromSUW(mLaunchedFromSuw); 89807506b1668b8438a138e1485f27e74de6a3d06crafftsai use(MagnificationNavbarPreferenceController.class) 90807506b1668b8438a138e1485f27e74de6a3d06crafftsai .setIsFromSUW(mLaunchedFromSuw); 919c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 929c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 939c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt @Override 949c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt public boolean onPreferenceTreeClick(Preference preference) { 959c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt if (mLaunchedFromSuw) { 969c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt // If invoked from SUW, redirect to fragment instrumented for Vision Settings metrics 979c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt preference.setFragment( 989c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt ToggleScreenMagnificationPreferenceFragmentForSetupWizard.class.getName()); 9917ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsai Bundle args = preference.getExtras(); 10017ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsai // Copy from AccessibilitySettingsForSetupWizardActivity, hide search and help menu 10117ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsai args.putInt(HelpResourceProvider.HELP_URI_RESOURCE_KEY, 0); 10217ebdcf6e66f4388c74a4d104486e22ee5ad8d40rafftsai args.putBoolean(SearchMenuController.NEED_SEARCH_ICON_IN_ACTION_BAR, false); 1039c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 1049c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt return super.onPreferenceTreeClick(preference); 1059c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 1069c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 107bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt static CharSequence getConfigurationWarningStringForSecureSettingsKey(String key, 108bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt Context context) { 109bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt if (!Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED.equals(key)) { 110bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt return null; 111bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt } 112bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt if (Settings.Secure.getInt(context.getContentResolver(), 113bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 0) { 114bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt return null; 115bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt } 116bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final AccessibilityManager am = (AccessibilityManager) context.getSystemService( 117bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt Context.ACCESSIBILITY_SERVICE); 118bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final String assignedId = Settings.Secure.getString(context.getContentResolver(), 119bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT); 120bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt if (!TextUtils.isEmpty(assignedId) && !MAGNIFICATION_COMPONENT_ID.equals(assignedId)) { 121bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final ComponentName assignedComponentName = ComponentName.unflattenFromString( 122bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt assignedId); 123bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final List<AccessibilityServiceInfo> activeServices = 124bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt am.getEnabledAccessibilityServiceList( 125bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt AccessibilityServiceInfo.FEEDBACK_ALL_MASK); 126bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final int serviceCount = activeServices.size(); 127bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt for (int i = 0; i < serviceCount; i++) { 128bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final AccessibilityServiceInfo info = activeServices.get(i); 129bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt if (info.getComponentName().equals(assignedComponentName)) { 130bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt final CharSequence assignedServiceName = info.getResolveInfo().loadLabel( 131bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt context.getPackageManager()); 132bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt return context.getString( 133bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt R.string.accessibility_screen_magnification_navbar_configuration_warning, 134bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt assignedServiceName); 135bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt } 1369c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 1379c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 138bc3827d7172955d58c4569fe003eb0d9ee46db1dCasey Burkhardt return null; 1399c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 1409c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt 141a92271c26d6cc17529747dad02491078f6914abahjchangliao static boolean isChecked(ContentResolver contentResolver, String settingsKey) { 142a92271c26d6cc17529747dad02491078f6914abahjchangliao return Settings.Secure.getInt(contentResolver, settingsKey, OFF) == ON; 143a92271c26d6cc17529747dad02491078f6914abahjchangliao } 144a92271c26d6cc17529747dad02491078f6914abahjchangliao 145a92271c26d6cc17529747dad02491078f6914abahjchangliao static boolean setChecked(ContentResolver contentResolver, String settingsKey, 146a92271c26d6cc17529747dad02491078f6914abahjchangliao boolean isChecked) { 147a92271c26d6cc17529747dad02491078f6914abahjchangliao return Settings.Secure.putInt(contentResolver, settingsKey, isChecked ? ON : OFF); 148a92271c26d6cc17529747dad02491078f6914abahjchangliao } 149a92271c26d6cc17529747dad02491078f6914abahjchangliao 150875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt /** 151875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt * @return {@code true} if this fragment should be shown, {@code false} otherwise. This 152875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt * fragment is shown in the case that more than one magnification mode is available. 153875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt */ 154875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt static boolean isApplicable(Resources res) { 155875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt return res.getBoolean(com.android.internal.R.bool.config_showNavigationBar); 156875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt } 157875d3b24715c6e36df0f63985d210a4e6280038aCasey Burkhardt 1589c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 1599c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt new BaseSearchIndexProvider() { 1609c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt @Override 1619c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, 1629c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt boolean enabled) { 1630cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang final SearchIndexableResource sir = new SearchIndexableResource(context); 1640cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang sir.xmlResId = R.xml.accessibility_magnification_settings; 1650cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang return Arrays.asList(sir); 1660cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang } 1670cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang 1680cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang @Override 1690cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang protected boolean isPageSearchEnabled(Context context) { 1700cd2ccfe3062237036cbdacfeb542f80d8ee6e52Fan Zhang return isApplicable(context.getResources()); 1719c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt } 1726ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze 1736ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze @Override 1746ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze public List<String> getNonIndexableKeys(Context context) { 1756ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze List<String> keys = super.getNonIndexableKeys(context); 1766ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze keys.add(PREFERENCE_TITLE_KEY); 1776ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze return keys; 1786ad584877575b4904b9f180c399cf9661be7fd28Matthew Fritze } 1799c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt }; 1809c7143c3e45362e540d1ca99340c65475307455aCasey Burkhardt} 181