Home | History | Annotate | Download | only in accessibility
      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.settings.accessibility;
     18 
     19 import android.accessibilityservice.AccessibilityServiceInfo;
     20 import android.content.ComponentName;
     21 import android.content.Context;
     22 import android.content.res.Resources;
     23 import android.os.Bundle;
     24 import android.provider.SearchIndexableResource;
     25 import android.provider.Settings;
     26 import android.support.v7.preference.Preference;
     27 import android.text.TextUtils;
     28 import android.view.View;
     29 import android.view.accessibility.AccessibilityManager;
     30 
     31 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     32 import com.android.settings.R;
     33 import com.android.settings.SettingsPreferenceFragment;
     34 import com.android.settings.search.BaseSearchIndexProvider;
     35 import com.android.settings.search.Indexable;
     36 
     37 import java.util.Arrays;
     38 import java.util.Collections;
     39 import java.util.List;
     40 
     41 public final class MagnificationPreferenceFragment extends SettingsPreferenceFragment implements
     42         Indexable {
     43 
     44     // Settings App preference keys
     45     private static final String PREFERENCE_TITLE_KEY = "magnification_preference_screen_title";
     46     private static final String MAGNIFICATION_GESTURES_PREFERENCE_SCREEN_KEY =
     47             "screen_magnification_gestures_preference_screen";
     48     private static final String MAGNIFICATION_NAVBAR_PREFERENCE_SCREEN_KEY =
     49             "screen_magnification_navbar_preference_screen";
     50 
     51     // Pseudo ComponentName used to represent navbar magnification in Settings.Secure.
     52     private static final String MAGNIFICATION_COMPONENT_ID =
     53             "com.android.server.accessibility.MagnificationController";
     54 
     55     private Preference mMagnificationGesturesPreference;
     56     private Preference mMagnificationNavbarPreference;
     57 
     58     private boolean mLaunchedFromSuw = false;
     59 
     60     @Override
     61     public void onCreatePreferences(Bundle bundle, String s) {
     62         addPreferencesFromResource(R.xml.accessibility_magnification_settings);
     63         mMagnificationGesturesPreference = findPreference(
     64                 MAGNIFICATION_GESTURES_PREFERENCE_SCREEN_KEY);
     65         mMagnificationNavbarPreference = findPreference(MAGNIFICATION_NAVBAR_PREFERENCE_SCREEN_KEY);
     66     }
     67 
     68     @Override
     69     protected int getHelpResource() {
     70         return R.string.help_url_magnification;
     71     }
     72 
     73     @Override
     74     public void onViewCreated(View view, Bundle savedInstanceState) {
     75         super.onViewCreated(view, savedInstanceState);
     76 
     77         final Bundle args = getArguments();
     78         if ((args != null) && args.containsKey(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW)) {
     79             mLaunchedFromSuw = args.getBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW);
     80         }
     81     }
     82 
     83     @Override
     84     public void onResume() {
     85         super.onResume();
     86         getActivity().setTitle(R.string.accessibility_screen_magnification_title);
     87         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
     88                 mMagnificationGesturesPreference);
     89         updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
     90                 mMagnificationNavbarPreference);
     91     }
     92 
     93     @Override
     94     public int getMetricsCategory() {
     95         return MetricsEvent.ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS;
     96     }
     97 
     98     @Override
     99     public boolean onPreferenceTreeClick(Preference preference) {
    100         if (mLaunchedFromSuw) {
    101             // If invoked from SUW, redirect to fragment instrumented for Vision Settings metrics
    102             preference.setFragment(
    103                     ToggleScreenMagnificationPreferenceFragmentForSetupWizard.class.getName());
    104         }
    105         if (mMagnificationGesturesPreference == preference) {
    106             handleMagnificationGesturesPreferenceScreenClick();
    107             super.onPreferenceTreeClick(mMagnificationGesturesPreference);
    108             return true;
    109         } else if (mMagnificationNavbarPreference == preference) {
    110             handleMagnificationNavbarPreferenceScreenClick();
    111             super.onPreferenceTreeClick(mMagnificationNavbarPreference);
    112             return true;
    113         }
    114         return super.onPreferenceTreeClick(preference);
    115     }
    116 
    117     private void updateFeatureSummary(String prefKey, Preference pref) {
    118         if (!mLaunchedFromSuw) {
    119             final boolean enabled = Settings.Secure.getInt(getContentResolver(), prefKey, 0) == 1;
    120             pref.setSummary(enabled ? R.string.accessibility_feature_state_on
    121                     : R.string.accessibility_feature_state_off);
    122         } else {
    123             if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(prefKey)) {
    124                 pref.setSummary(R.string.accessibility_screen_magnification_short_summary);
    125             } else if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED.equals(
    126                     prefKey)) {
    127                 pref.setSummary(R.string.accessibility_screen_magnification_navbar_short_summary);
    128             }
    129         }
    130     }
    131 
    132     private void handleMagnificationGesturesPreferenceScreenClick() {
    133         Bundle extras = mMagnificationGesturesPreference.getExtras();
    134         populateMagnificationGesturesPreferenceExtras(extras, getContext());
    135         extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mLaunchedFromSuw);
    136     }
    137 
    138     private void handleMagnificationNavbarPreferenceScreenClick() {
    139         Bundle extras = mMagnificationNavbarPreference.getExtras();
    140         extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY,
    141                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
    142         extras.putString(AccessibilitySettings.EXTRA_TITLE, getString(
    143                 R.string.accessibility_screen_magnification_navbar_title));
    144         extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY,
    145                 getActivity().getResources().getText(
    146                         R.string.accessibility_screen_magnification_navbar_summary));
    147         extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
    148                 Settings.Secure.getInt(getContentResolver(),
    149                         Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0)
    150                         == 1);
    151         extras.putBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW, mLaunchedFromSuw);
    152     }
    153 
    154     static CharSequence getConfigurationWarningStringForSecureSettingsKey(String key,
    155             Context context) {
    156         if (!Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED.equals(key)) {
    157             return null;
    158         }
    159         if (Settings.Secure.getInt(context.getContentResolver(),
    160                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 0) {
    161             return null;
    162         }
    163         final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
    164                 Context.ACCESSIBILITY_SERVICE);
    165         final String assignedId = Settings.Secure.getString(context.getContentResolver(),
    166                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
    167         if (!TextUtils.isEmpty(assignedId) && !MAGNIFICATION_COMPONENT_ID.equals(assignedId)) {
    168             final ComponentName assignedComponentName = ComponentName.unflattenFromString(
    169                     assignedId);
    170             final List<AccessibilityServiceInfo> activeServices =
    171                     am.getEnabledAccessibilityServiceList(
    172                             AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
    173             final int serviceCount = activeServices.size();
    174             for (int i = 0; i < serviceCount; i++) {
    175                 final AccessibilityServiceInfo info = activeServices.get(i);
    176                 if (info.getComponentName().equals(assignedComponentName)) {
    177                     final CharSequence assignedServiceName = info.getResolveInfo().loadLabel(
    178                             context.getPackageManager());
    179                     return context.getString(
    180                             R.string.accessibility_screen_magnification_navbar_configuration_warning,
    181                             assignedServiceName);
    182                 }
    183             }
    184         }
    185         return null;
    186     }
    187 
    188     static void populateMagnificationGesturesPreferenceExtras(Bundle extras, Context context) {
    189         extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY,
    190                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
    191         extras.putString(AccessibilitySettings.EXTRA_TITLE, context.getString(
    192                 R.string.accessibility_screen_magnification_gestures_title));
    193         extras.putCharSequence(AccessibilitySettings.EXTRA_SUMMARY, context.getResources().getText(
    194                 R.string.accessibility_screen_magnification_summary));
    195         extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED,
    196                 Settings.Secure.getInt(context.getContentResolver(),
    197                         Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1);
    198         extras.putInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID,
    199                 R.raw.accessibility_screen_magnification);
    200     }
    201 
    202     /**
    203      * @return {@code true} if this fragment should be shown, {@code false} otherwise. This
    204      * fragment is shown in the case that more than one magnification mode is available.
    205      */
    206     static boolean isApplicable(Resources res) {
    207         return res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
    208     }
    209 
    210     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    211             new BaseSearchIndexProvider() {
    212                 @Override
    213                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
    214                         boolean enabled) {
    215                     if (isApplicable(context.getResources())) {
    216                         final SearchIndexableResource sir = new SearchIndexableResource(context);
    217                         sir.xmlResId = R.xml.accessibility_magnification_settings;
    218                         return Arrays.asList(sir);
    219                     } else {
    220                         return Collections.emptyList();
    221                     }
    222                 }
    223 
    224                 @Override
    225                 public List<String> getNonIndexableKeys(Context context) {
    226                     List<String> keys = super.getNonIndexableKeys(context);
    227                     keys.add(PREFERENCE_TITLE_KEY);
    228                     return keys;
    229                 }
    230             };
    231 }
    232