• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.tv.settings;
2 
3 import android.app.tvsettings.TvSettingsEnums;
4 import android.content.ActivityNotFoundException;
5 import android.content.ComponentName;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.service.settings.suggestions.Suggestion;
9 import android.util.Log;
10 
11 import androidx.annotation.VisibleForTesting;
12 import androidx.preference.Preference;
13 import androidx.preference.PreferenceCategory;
14 import androidx.preference.SwitchPreference;
15 
16 import com.android.settingslib.core.AbstractPreferenceController;
17 import com.android.settingslib.suggestions.SuggestionControllerMixinCompat;
18 import com.android.settingslib.utils.IconCache;
19 import com.android.tv.settings.HotwordSwitchController.HotwordStateListener;
20 import com.android.tv.settings.R;
21 import com.android.tv.settings.overlay.FlavorUtils;
22 import com.android.tv.settings.suggestions.SuggestionPreference;
23 import com.android.tv.settings.system.SecurityFragment;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected;
29 
30 public class SuggestionQuickSettingPrefsContainer  {
31     @VisibleForTesting static final String KEY_QUICK_SETTINGS = "quick_settings";
32     private static final String TAG = "SuggestionQuickSettingPrefsContainer";
33     private static final String KEY_SUGGESTIONS_LIST = "suggestions";
34     @VisibleForTesting PreferenceCategory mSuggestionsList;
35     IconCache mIconCache;
36     private SuggestionControllerMixinCompat mSuggestionControllerMixin;
37     /** Controllers for the Quick Settings section. */
38     private List<AbstractPreferenceController> mPreferenceControllers;
39 
40     private HotwordSwitchController mHotwordSwitchController;
41     private TakeBugReportController mTakeBugReportController;
42     private PreferenceCategory mQuickSettingsList;
43     private SwitchPreference mHotwordSwitch;
44     private Preference mTakeBugReportPreference;
45     private MainFragment mainFragment;
46 
SuggestionQuickSettingPrefsContainer(MainFragment mainFragment)47     SuggestionQuickSettingPrefsContainer(MainFragment mainFragment) {
48         this.mainFragment = mainFragment;
49     }
50 
onCreate()51     void onCreate() {
52         mIconCache = new IconCache(mainFragment.getContext());
53         if (!isRestricted()) {
54             ComponentName componentName = new ComponentName("com.android.settings.intelligence",
55                     "com.android.settings.intelligence.suggestions.SuggestionService");
56             mSuggestionControllerMixin =
57                     new SuggestionControllerMixinCompat(mainFragment.getContext(),
58                     mainFragment, mainFragment.getSettingsLifecycle(), componentName);
59         }
60     }
61 
onDestroy()62     void onDestroy() {
63         if (mHotwordSwitchController != null) {
64             mHotwordSwitchController.unregister();
65         }
66     }
67 
showOrHideQuickSettings()68     void showOrHideQuickSettings() {
69         if (shouldShowQuickSettings()) {
70             showQuickSettings();
71         } else {
72             hideQuickSettings();
73         }
74     }
75 
onCreatePreferences()76     void onCreatePreferences() {
77         if (mHotwordSwitchController != null) {
78             mHotwordSwitchController.init(mainFragment);
79         }
80     }
81 
onSuggestionReady(List<Suggestion> data)82     void onSuggestionReady(List<Suggestion> data) {
83         // Suggestion category is handled differently in basic mode
84         if (data == null || data.size() == 0
85                 || FlavorUtils.getFeatureFactory(mainFragment.getContext())
86                 .getBasicModeFeatureProvider()
87                 .isBasicMode(mainFragment.getContext())) {
88             if (mSuggestionsList != null) {
89                 mainFragment.getPreferenceScreen().removePreference(mSuggestionsList);
90                 mSuggestionsList = null;
91             }
92             return;
93         }
94 
95         if (mSuggestionsList == null) {
96             mSuggestionsList = new PreferenceCategory(
97                     mainFragment.getPreferenceManager().getContext());
98             mSuggestionsList.setKey(KEY_SUGGESTIONS_LIST);
99             mSuggestionsList.setTitle(R.string.header_category_suggestions);
100             mSuggestionsList.setOrder(0); // always at top
101             mainFragment.getPreferenceScreen().addPreference(mSuggestionsList);
102         }
103         updateSuggestionList(data);
104     }
105 
106     @VisibleForTesting
updateSuggestionList(List<Suggestion> suggestions)107     void updateSuggestionList(List<Suggestion> suggestions) {
108         // Remove suggestions that are not in the new list.
109         for (int i = 0; i < mSuggestionsList.getPreferenceCount(); i++) {
110             SuggestionPreference pref = (SuggestionPreference) mSuggestionsList.getPreference(i);
111             boolean isInNewSuggestionList = false;
112             for (Suggestion suggestion : suggestions) {
113                 if (pref.getId().equals(suggestion.getId())) {
114                     isInNewSuggestionList = true;
115                     break;
116                 }
117             }
118             if (!isInNewSuggestionList) {
119                 mSuggestionsList.removePreference(pref);
120             }
121         }
122 
123         // Add suggestions that are not in the old list and update the existing suggestions.
124         for (Suggestion suggestion : suggestions) {
125             Preference curPref = mainFragment.findPreference(
126                     SuggestionPreference.SUGGESTION_PREFERENCE_KEY + suggestion.getId());
127             if (curPref == null) {
128                 SuggestionPreference newSuggPref =
129                         new SuggestionPreference(suggestion,
130                                 mainFragment.getPreferenceManager().getContext(),
131                                 mSuggestionControllerMixin, mainFragment);
132                 newSuggPref.setIcon(mIconCache.getIcon(suggestion.getIcon()));
133                 newSuggPref.setTitle(suggestion.getTitle());
134                 newSuggPref.setSummary(suggestion.getSummary());
135                 mSuggestionsList.addPreference(newSuggPref);
136             } else {
137                 // Even though the id of suggestion might not change, the details could change.
138                 // So we need to update icon, title and summary for the suggestions.
139                 curPref.setIcon(mIconCache.getIcon(suggestion.getIcon()));
140                 curPref.setTitle(suggestion.getTitle());
141                 curPref.setSummary(suggestion.getSummary());
142             }
143         }
144     }
145 
isRestricted()146     boolean isRestricted() {
147         return SecurityFragment.isRestrictedProfileInEffect(mainFragment.getContext());
148     }
149 
onSuggestionClosed(Preference preference)150     void onSuggestionClosed(Preference preference) {
151         if (mSuggestionsList == null || mSuggestionsList.getPreferenceCount() == 0) {
152             return;
153         } else if (mSuggestionsList.getPreferenceCount() == 1) {
154             mainFragment.getPreferenceScreen().removePreference(mSuggestionsList);
155         } else {
156             mSuggestionsList.removePreference(preference);
157         }
158     }
159 
onHotwordStateChanged()160     void onHotwordStateChanged() {
161         if (mHotwordSwitch != null) {
162             mHotwordSwitchController.updateState(mHotwordSwitch);
163         }
164         showOrHideQuickSettings();
165     }
166 
onHotwordEnable()167     void onHotwordEnable() {
168         try {
169             Intent intent = new Intent(HotwordSwitchController.ACTION_HOTWORD_ENABLE);
170             intent.setPackage(HotwordSwitchController.ASSISTANT_PGK_NAME);
171             mainFragment.startActivityForResult(intent, 0);
172         } catch (ActivityNotFoundException e) {
173             Log.w(TAG, "Unable to find hotwording activity.", e);
174         }
175     }
176 
onHotwordDisable()177     void onHotwordDisable() {
178         try {
179             Intent intent = new Intent(HotwordSwitchController.ACTION_HOTWORD_DISABLE);
180             intent.setPackage(HotwordSwitchController.ASSISTANT_PGK_NAME);
181             mainFragment.startActivityForResult(intent, 0);
182         } catch (ActivityNotFoundException e) {
183             Log.w(TAG, "Unable to find hotwording activity.", e);
184         }
185     }
186 
quickSettingsEnabled()187     private boolean quickSettingsEnabled() {
188         return mainFragment.getContext().getResources().getBoolean(
189                 R.bool.config_quick_settings_enabled);
190     }
191 
192     /** @return true if there is at least one available item in quick settings. */
shouldShowQuickSettings()193     private boolean shouldShowQuickSettings() {
194         for (AbstractPreferenceController controller : mPreferenceControllers) {
195             if (controller.isAvailable()) {
196                 return true;
197             }
198         }
199         return false;
200     }
201 
202 
203     /** Creates the quick settings category and its children. */
showQuickSettings()204     private void showQuickSettings() {
205         if (mQuickSettingsList != null) {
206             return;
207         }
208         mQuickSettingsList = new PreferenceCategory(
209                 mainFragment.getPreferenceManager().getContext());
210         mQuickSettingsList.setKey(KEY_QUICK_SETTINGS);
211         mQuickSettingsList.setTitle(R.string.header_category_quick_settings);
212         mQuickSettingsList.setOrder(1); // at top, but below suggested settings
213         mainFragment.getPreferenceScreen().addPreference(mQuickSettingsList);
214         if (mHotwordSwitchController != null && mHotwordSwitchController.isAvailable()) {
215             mHotwordSwitch = new SwitchPreference(
216                     mainFragment.getPreferenceManager().getContext());
217             mHotwordSwitch.setKey(HotwordSwitchController.KEY_HOTWORD_SWITCH);
218             mHotwordSwitch.setOnPreferenceClickListener(preference -> {
219                 logEntrySelected(TvSettingsEnums.QUICK_SETTINGS);
220                 return false;
221             });
222             mHotwordSwitchController.updateState(mHotwordSwitch);
223             mQuickSettingsList.addPreference(mHotwordSwitch);
224         }
225         if (mTakeBugReportController != null && mTakeBugReportController.isAvailable()) {
226             mTakeBugReportPreference = new Preference(
227                     mainFragment.getPreferenceManager().getContext());
228             mTakeBugReportPreference.setKey(TakeBugReportController.KEY_TAKE_BUG_REPORT);
229             mTakeBugReportPreference.setOnPreferenceClickListener(preference -> {
230                 logEntrySelected(TvSettingsEnums.QUICK_SETTINGS);
231                 return false;
232             });
233             mTakeBugReportController.updateState(mTakeBugReportPreference);
234             mQuickSettingsList.addPreference(mTakeBugReportPreference);
235         }
236     }
237 
238     /** Removes the quick settings category and all its children. */
hideQuickSettings()239     private void hideQuickSettings() {
240         Preference quickSettingsPref = mainFragment.findPreference(KEY_QUICK_SETTINGS);
241         if (quickSettingsPref == null) {
242             return;
243         }
244         mQuickSettingsList.removeAll();
245         mainFragment.getPreferenceScreen().removePreference(mQuickSettingsList);
246         mQuickSettingsList = null;
247     }
248 
onCreatePreferenceControllers(Context context)249     List<AbstractPreferenceController> onCreatePreferenceControllers(Context context) {
250         mPreferenceControllers = new ArrayList<>(2);
251         if (quickSettingsEnabled()) {
252             mHotwordSwitchController = new HotwordSwitchController(context);
253             mTakeBugReportController = new TakeBugReportController(context);
254             mPreferenceControllers.add(mHotwordSwitchController);
255             mPreferenceControllers.add(mTakeBugReportController);
256         }
257         return mPreferenceControllers;
258     }
259 
260 }
261