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.dream;
18 
19 import static com.android.settings.dream.DreamMainSwitchPreferenceController.MAIN_SWITCH_PREF_KEY;
20 import static com.android.settingslib.dream.DreamBackend.EITHER;
21 import static com.android.settingslib.dream.DreamBackend.NEVER;
22 import static com.android.settingslib.dream.DreamBackend.WHILE_CHARGING;
23 import static com.android.settingslib.dream.DreamBackend.WHILE_DOCKED;
24 
25 import android.app.settings.SettingsEnums;
26 import android.content.Context;
27 import android.os.Bundle;
28 import android.service.dreams.DreamService;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.widget.Button;
33 import android.widget.CompoundButton;
34 import android.widget.CompoundButton.OnCheckedChangeListener;
35 
36 import androidx.annotation.VisibleForTesting;
37 import androidx.preference.Preference;
38 import androidx.recyclerview.widget.RecyclerView;
39 
40 import com.android.settings.R;
41 import com.android.settings.Utils;
42 import com.android.settings.dashboard.DashboardFragment;
43 import com.android.settings.search.BaseSearchIndexProvider;
44 import com.android.settingslib.core.AbstractPreferenceController;
45 import com.android.settingslib.dream.DreamBackend;
46 import com.android.settingslib.dream.DreamBackend.WhenToDream;
47 import com.android.settingslib.search.SearchIndexable;
48 import com.android.settingslib.widget.MainSwitchPreference;
49 
50 import java.util.ArrayList;
51 import java.util.List;
52 
53 @SearchIndexable
54 public class DreamSettings extends DashboardFragment implements OnCheckedChangeListener {
55 
56     private static final String TAG = "DreamSettings";
57     static final String WHILE_CHARGING_ONLY = "while_charging_only";
58     static final String WHILE_DOCKED_ONLY = "while_docked_only";
59     static final String EITHER_CHARGING_OR_DOCKED = "either_charging_or_docked";
60     static final String NEVER_DREAM = "never";
61 
62     private MainSwitchPreference mMainSwitchPreference;
63     private Button mPreviewButton;
64     private Preference mComplicationsTogglePreference;
65     private Preference mHomeControllerTogglePreference;
66     private RecyclerView mRecyclerView;
67 
68     private DreamPickerController mDreamPickerController;
69     private DreamHomeControlsPreferenceController mDreamHomeControlsPreferenceController;
70 
71     private final DreamPickerController.Callback mCallback =
72             this::updateComplicationsToggleVisibility;
73 
74     @WhenToDream
getSettingFromPrefKey(String key)75     static int getSettingFromPrefKey(String key) {
76         switch (key) {
77             case WHILE_CHARGING_ONLY:
78                 return WHILE_CHARGING;
79             case WHILE_DOCKED_ONLY:
80                 return WHILE_DOCKED;
81             case EITHER_CHARGING_OR_DOCKED:
82                 return EITHER;
83             case NEVER_DREAM:
84             default:
85                 return NEVER;
86         }
87     }
88 
getKeyFromSetting(@henToDream int dreamSetting)89     static String getKeyFromSetting(@WhenToDream int dreamSetting) {
90         switch (dreamSetting) {
91             case WHILE_CHARGING:
92                 return WHILE_CHARGING_ONLY;
93             case WHILE_DOCKED:
94                 return WHILE_DOCKED_ONLY;
95             case EITHER:
96                 return EITHER_CHARGING_OR_DOCKED;
97             case NEVER:
98             default:
99                 return NEVER_DREAM;
100         }
101     }
102 
getDreamSettingDescriptionResId(@henToDream int dreamSetting, boolean enabledOnBattery)103     static int getDreamSettingDescriptionResId(@WhenToDream int dreamSetting,
104             boolean enabledOnBattery) {
105         switch (dreamSetting) {
106             case WHILE_CHARGING:
107                 return R.string.screensaver_settings_summary_sleep;
108             case WHILE_DOCKED:
109                 return enabledOnBattery ? R.string.screensaver_settings_summary_dock
110                         : R.string.screensaver_settings_summary_dock_and_charging;
111             case EITHER:
112                 return R.string.screensaver_settings_summary_either_long;
113             case NEVER:
114             default:
115                 return R.string.screensaver_settings_summary_never;
116         }
117     }
118 
119     @Override
getMetricsCategory()120     public int getMetricsCategory() {
121         return SettingsEnums.DREAM;
122     }
123 
124     @Override
getPreferenceScreenResId()125     protected int getPreferenceScreenResId() {
126         return R.xml.dream_fragment_overview;
127     }
128 
129     @Override
getHelpResource()130     public int getHelpResource() {
131         return R.string.help_url_screen_saver;
132     }
133 
134     @Override
getLogTag()135     protected String getLogTag() {
136         return TAG;
137     }
138 
139     @Override
createPreferenceControllers(Context context)140     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
141         final List<AbstractPreferenceController> controllers = new ArrayList<>();
142         if (mDreamPickerController == null) {
143             mDreamPickerController = new DreamPickerController(context);
144         }
145         if (mDreamHomeControlsPreferenceController == null) {
146             mDreamHomeControlsPreferenceController = new DreamHomeControlsPreferenceController(
147                     context, DreamBackend.getInstance(getContext()));
148         }
149         controllers.add(mDreamPickerController);
150         controllers.add(mDreamHomeControlsPreferenceController);
151         controllers.add(new WhenToDreamPreferenceController(context));
152         return controllers;
153     }
154 
getSummaryTextWithDreamName(Context context)155     public static CharSequence getSummaryTextWithDreamName(Context context) {
156         DreamBackend backend = DreamBackend.getInstance(context);
157         return getSummaryTextFromBackend(backend, context);
158     }
159 
160     @VisibleForTesting
getSummaryTextFromBackend(DreamBackend backend, Context context)161     static CharSequence getSummaryTextFromBackend(DreamBackend backend, Context context) {
162         if (backend.isEnabled()) {
163             return context.getString(R.string.screensaver_settings_summary_on,
164                     backend.getActiveDreamName());
165         } else {
166             return context.getString(R.string.screensaver_settings_summary_off);
167         }
168     }
169 
170     @VisibleForTesting
setDreamPickerController(DreamPickerController dreamPickerController)171     void setDreamPickerController(DreamPickerController dreamPickerController) {
172         mDreamPickerController = dreamPickerController;
173     }
174 
175     @VisibleForTesting
setDreamHomeControlsPreferenceController(DreamHomeControlsPreferenceController dreamHomeControlsPreferenceController)176     void setDreamHomeControlsPreferenceController(DreamHomeControlsPreferenceController
177             dreamHomeControlsPreferenceController) {
178         mDreamHomeControlsPreferenceController = dreamHomeControlsPreferenceController;
179     }
180 
setAllPreferencesEnabled(boolean isEnabled)181     private void setAllPreferencesEnabled(boolean isEnabled) {
182         getPreferenceControllers().forEach(controllers -> {
183             controllers.forEach(controller -> {
184                 final String prefKey = controller.getPreferenceKey();
185                 if (prefKey.equals(MAIN_SWITCH_PREF_KEY)) {
186                     return;
187                 }
188                 if (prefKey.equals(DreamHomeControlsPreferenceController.PREF_KEY)) {
189                     return;
190                 }
191                 final Preference pref = findPreference(prefKey);
192                 if (pref != null) {
193                     pref.setEnabled(isEnabled);
194                     controller.updateState(pref);
195                 }
196             });
197         });
198         updateComplicationsToggleVisibility();
199     }
200 
201     @Override
onCreate(Bundle icicle)202     public void onCreate(Bundle icicle) {
203         super.onCreate(icicle);
204 
205         final DreamBackend dreamBackend = DreamBackend.getInstance(getContext());
206 
207         mComplicationsTogglePreference = findPreference(
208                 DreamComplicationPreferenceController.PREF_KEY);
209 
210         mHomeControllerTogglePreference = findPreference(
211                 DreamHomeControlsPreferenceController.PREF_KEY
212         );
213 
214         mMainSwitchPreference = findPreference(MAIN_SWITCH_PREF_KEY);
215         if (mMainSwitchPreference != null) {
216             mMainSwitchPreference.addOnSwitchChangeListener(this);
217         }
218 
219         setAllPreferencesEnabled(dreamBackend.isEnabled());
220 
221         if (mDreamPickerController != null) {
222             mDreamPickerController.addCallback(mCallback);
223         }
224     }
225 
226     @Override
onDestroy()227     public void onDestroy() {
228         if (mDreamPickerController != null) {
229             mDreamPickerController.removeCallback(mCallback);
230         }
231 
232         super.onDestroy();
233     }
234 
235     @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle bundle)236     public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
237             Bundle bundle) {
238         final DreamBackend dreamBackend = DreamBackend.getInstance(getContext());
239 
240         final ViewGroup root = getActivity().findViewById(android.R.id.content);
241         mPreviewButton = (Button) getActivity().getLayoutInflater().inflate(
242                 R.layout.dream_preview_button, root, false);
243         mPreviewButton.setVisibility(dreamBackend.isEnabled() ? View.VISIBLE : View.GONE);
244         root.addView(mPreviewButton);
245         mPreviewButton.setOnClickListener(v -> dreamBackend.preview(dreamBackend.getActiveDream()));
246 
247         mRecyclerView = super.onCreateRecyclerView(inflater, parent, bundle);
248         mRecyclerView.setFocusable(false);
249         updatePaddingForPreviewButton();
250         return mRecyclerView;
251     }
252 
updateComplicationsToggleVisibility()253     private void updateComplicationsToggleVisibility() {
254         if (mDreamPickerController == null) {
255             return;
256         }
257         final DreamBackend.DreamInfo activeDream = mDreamPickerController.getActiveDreamInfo();
258 
259         final DreamBackend dreamBackend = DreamBackend.getInstance(getContext());
260 
261 
262         if (mComplicationsTogglePreference != null) {
263             mComplicationsTogglePreference.setVisible(
264                     activeDream != null && activeDream.supportsComplications);
265         }
266 
267         if (mHomeControllerTogglePreference != null) {
268             boolean isEnabled = dreamBackend.isEnabled()
269                                 && (activeDream == null
270                                 || (activeDream.dreamCategory
271                                 & DreamService.DREAM_CATEGORY_HOME_PANEL) == 0)
272                                 && mDreamHomeControlsPreferenceController
273                                     .getAvailabilityStatus()
274                                     == mDreamHomeControlsPreferenceController.AVAILABLE;
275             mHomeControllerTogglePreference.setEnabled(isEnabled);
276         }
277     }
278 
updatePaddingForPreviewButton()279     private void updatePaddingForPreviewButton() {
280         mPreviewButton.post(() -> {
281             mRecyclerView.setPadding(0, 0, 0, mPreviewButton.getMeasuredHeight());
282         });
283     }
284 
285     @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)286     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
287         setAllPreferencesEnabled(isChecked);
288         mPreviewButton.setVisibility(isChecked ? View.VISIBLE : View.GONE);
289         updatePaddingForPreviewButton();
290     }
291 
292     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
293             new SearchIndexProvider(R.xml.dream_fragment_overview);
294 
295     static class SearchIndexProvider extends BaseSearchIndexProvider {
SearchIndexProvider(int xmlRes)296         SearchIndexProvider(int xmlRes) {
297             super(xmlRes);
298         }
299 
300         @Override
isPageSearchEnabled(Context context)301         protected boolean isPageSearchEnabled(Context context) {
302             return Utils.areDreamsAvailableToCurrentUser(context);
303         }
304     }
305 }
306 
307