1 /*
2  * Copyright (C) 2019 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.help;
18 
19 import static android.content.Context.ACCESSIBILITY_SERVICE;
20 
21 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_CLASSIC;
22 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_TWO_PANEL;
23 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_VENDOR;
24 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_X;
25 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected;
26 
27 import android.app.tvsettings.TvSettingsEnums;
28 import android.content.ComponentName;
29 import android.content.pm.ResolveInfo;
30 import android.os.Bundle;
31 import android.text.TextUtils;
32 import android.view.accessibility.AccessibilityManager;
33 
34 import androidx.annotation.Keep;
35 import androidx.leanback.widget.VerticalGridView;
36 import androidx.preference.Preference;
37 
38 import com.android.settingslib.accessibility.AccessibilityUtils;
39 import com.android.tv.settings.MainFragment;
40 import com.android.tv.settings.R;
41 import com.android.tv.settings.SettingsPreferenceFragment;
42 import com.android.tv.settings.overlay.FlavorUtils;
43 
44 import java.util.Set;
45 
46 /**
47  * The "Help & feedback" screen in TV settings.
48  */
49 @Keep
50 public class HelpFragment extends SettingsPreferenceFragment {
51 
52     private static final String KEY_SEND_FEEDBACK = "feedback";
53     private static final String KEY_HELP = "help_center";
54     private static final String TALKBACK_SERVICE_NAME = ".TalkBackService";
55 
getPreferenceScreenResId()56     private int getPreferenceScreenResId() {
57         switch (FlavorUtils.getFlavor(getContext())) {
58             case FLAVOR_CLASSIC:
59             case FLAVOR_TWO_PANEL:
60                 return R.xml.help_and_feedback;
61             case FLAVOR_X:
62             case FLAVOR_VENDOR:
63                 return R.xml.help_and_feedback_x;
64             default:
65                 return R.xml.help_and_feedback;
66         }
67     }
68 
69     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)70     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
71         setPreferencesFromResource(getPreferenceScreenResId(), null);
72 
73         final Preference sendFeedbackPref = findPreference(KEY_SEND_FEEDBACK);
74         if (sendFeedbackPref != null) {
75             sendFeedbackPref.setVisible(!FlavorUtils.getFeatureFactory(getContext())
76                     .getBasicModeFeatureProvider().isBasicMode(getContext()));
77         }
78 
79         final Preference helpPref = findPreference(KEY_HELP);
80         if (helpPref != null) {
81             final ResolveInfo info = MainFragment.systemIntentIsHandled(getActivity(),
82                     helpPref.getIntent());
83             helpPref.setVisible(info != null);
84         }
85     }
86 
87     @Override
onPreferenceTreeClick(Preference preference)88     public boolean onPreferenceTreeClick(Preference preference) {
89         // Workaround to only allow click when the input focus and a11y focus are on the same item.
90         // This should only apply when the TalkBack service is on since other a11y services may not
91         // utilize a11y focus (ex. Switch Access).
92         VerticalGridView listView = (VerticalGridView) getListView();
93         if (!listView.getChildAt(listView.getSelectedPosition()).isAccessibilityFocused()
94                 && isTalkBackEnabled()) {
95             return true;
96         }
97         switch (preference.getKey()) {
98             case KEY_SEND_FEEDBACK:
99                 logEntrySelected(TvSettingsEnums.FEEDBACK_SEND);
100                 return super.onPreferenceTreeClick(preference);
101             case KEY_HELP:
102                 FlavorUtils.getFeatureFactory(getActivity()).getSupportFeatureProvider()
103                         .startSupport(getActivity());
104                 return true;
105             default:
106                 return super.onPreferenceTreeClick(preference);
107         }
108     }
109 
110 
isTalkBackEnabled()111     private boolean isTalkBackEnabled() {
112         AccessibilityManager am =
113                 (AccessibilityManager) getContext().getSystemService(ACCESSIBILITY_SERVICE);
114         boolean isAccessibilityEnabled = am.isEnabled();
115 
116         if (isAccessibilityEnabled) {
117             final Set<ComponentName> enabledServices =
118                     AccessibilityUtils.getEnabledServicesFromSettings(getActivity());
119 
120             for (final ComponentName componentName : enabledServices) {
121                 if (TextUtils.equals(componentName.getShortClassName(), TALKBACK_SERVICE_NAME)) {
122                     return true;
123                 }
124             }
125         }
126         return false;
127     }
128 
129     @Override
getPageId()130     protected int getPageId() {
131         return TvSettingsEnums.FEEDBACK;
132     }
133 }
134