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