| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package com.android.tv.settings.device.display.daydream; |
| |
| import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; |
| |
| import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_CLASSIC; |
| import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_TWO_PANEL; |
| import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_VENDOR; |
| import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_X; |
| import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected; |
| |
| import android.app.tvsettings.TvSettingsEnums; |
| import android.content.BroadcastReceiver; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.os.Bundle; |
| import android.os.UserManager; |
| import android.provider.Settings; |
| import android.text.format.DateUtils; |
| import android.util.ArrayMap; |
| import android.util.Log; |
| |
| import androidx.annotation.Keep; |
| import androidx.preference.ListPreference; |
| import androidx.preference.Preference; |
| |
| import com.android.settingslib.dream.DreamBackend; |
| import com.android.tv.settings.R; |
| import com.android.tv.settings.RestrictedPreferenceAdapter; |
| import com.android.tv.settings.SettingsPreferenceFragment; |
| import com.android.tv.settings.library.util.SliceUtils; |
| import com.android.tv.settings.overlay.FlavorUtils; |
| import com.android.tv.twopanelsettings.slices.SlicePreference; |
| |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| |
| /** |
| * The screen saver screen in TV settings. |
| */ |
| @Keep |
| public class DaydreamFragment extends SettingsPreferenceFragment |
| implements Preference.OnPreferenceChangeListener { |
| |
| private static final String TAG = "DaydreamFragment"; |
| |
| private static final String KEY_ACTIVE_DREAM = "activeDream"; |
| private static final String KEY_DREAM_TIME = "dreamTime"; |
| private static final String KEY_DREAM_NOW = "dreamNow"; |
| private static final String KEY_AMBIENT_SETTINGS = "ambient_settings"; |
| |
| private static final String DREAM_COMPONENT_NONE = "NONE"; |
| private static final String PACKAGE_SCHEME = "package"; |
| |
| private static final int DEFAULT_DREAM_TIME_MS = (int) (30 * DateUtils.MINUTE_IN_MILLIS); |
| |
| private final PackageReceiver mPackageReceiver = new PackageReceiver(); |
| |
| private DreamBackend mBackend; |
| private final Map<String, DreamBackend.DreamInfo> mDreamInfos = new ArrayMap<>(); |
| |
| private RestrictedPreferenceAdapter<ListPreference> mActiveDreamPref; |
| private RestrictedPreferenceAdapter<ListPreference> mDreamTimePref; |
| |
| public static DaydreamFragment newInstance() { |
| return new DaydreamFragment(); |
| } |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| mBackend = new DreamBackend(getActivity()); |
| super.onCreate(savedInstanceState); |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| refreshFromBackend(); |
| |
| // listen for package changes |
| IntentFilter filter = new IntentFilter(); |
| filter.addAction(Intent.ACTION_PACKAGE_ADDED); |
| filter.addAction(Intent.ACTION_PACKAGE_CHANGED); |
| filter.addAction(Intent.ACTION_PACKAGE_REMOVED); |
| filter.addAction(Intent.ACTION_PACKAGE_REPLACED); |
| filter.addDataScheme(PACKAGE_SCHEME); |
| getActivity().registerReceiver(mPackageReceiver, filter); |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| |
| getActivity().unregisterReceiver(mPackageReceiver); |
| } |
| |
| |
| private int getPreferenceScreenResId() { |
| switch (FlavorUtils.getFlavor(getContext())) { |
| case FLAVOR_CLASSIC: |
| case FLAVOR_TWO_PANEL: |
| return R.xml.daydream; |
| case FLAVOR_X: |
| case FLAVOR_VENDOR: |
| return R.xml.daydream_x; |
| default: |
| return R.xml.daydream; |
| } |
| } |
| |
| @Override |
| public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { |
| setPreferencesFromResource(getPreferenceScreenResId(), null); |
| final String userRestriction = UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT; |
| |
| final ListPreference activeDreamPref = (ListPreference) findPreference(KEY_ACTIVE_DREAM); |
| refreshActiveDreamPref(); |
| if (activeDreamPref != null) { |
| activeDreamPref.setOnPreferenceChangeListener(this); |
| mActiveDreamPref = RestrictedPreferenceAdapter.adapt(activeDreamPref, userRestriction); |
| } |
| |
| final ListPreference dreamTimePref = (ListPreference) findPreference(KEY_DREAM_TIME); |
| if (dreamTimePref != null) { |
| dreamTimePref.setValue(Integer.toString(getDreamTime())); |
| dreamTimePref.setOnPreferenceChangeListener(this); |
| mDreamTimePref = RestrictedPreferenceAdapter.adapt(dreamTimePref, userRestriction); |
| } |
| |
| final Preference dreamNowPref = findPreference(KEY_DREAM_NOW); |
| dreamNowPref.setEnabled(mBackend.isEnabled()); |
| |
| updateAmbientSettings(); |
| } |
| |
| private void refreshActiveDreamPref() { |
| if (mActiveDreamPref == null) { |
| return; |
| } |
| |
| final List<DreamBackend.DreamInfo> infos = mBackend.getDreamInfos(); |
| final CharSequence[] dreamEntries = new CharSequence[infos.size() + 1]; |
| final CharSequence[] dreamEntryValues = new CharSequence[infos.size() + 1]; |
| refreshDreamInfoMap(infos, dreamEntries, dreamEntryValues); |
| final ComponentName currentDreamComponent = mBackend.getActiveDream(); |
| |
| mActiveDreamPref.updatePreference(activeDreamPref -> { |
| activeDreamPref.setEntries(dreamEntries); |
| activeDreamPref.setEntryValues(dreamEntryValues); |
| activeDreamPref.setValue(mBackend.isEnabled() && currentDreamComponent != null |
| ? currentDreamComponent.toShortString() : DREAM_COMPONENT_NONE); |
| }); |
| } |
| |
| private void refreshDreamInfoMap(List<DreamBackend.DreamInfo> infos, |
| CharSequence[] listEntries, CharSequence[] listEntryValues) { |
| mDreamInfos.clear(); |
| listEntries[0] = getString(R.string.device_daydreams_none); |
| listEntryValues[0] = DREAM_COMPONENT_NONE; |
| int index = 1; |
| for (final DreamBackend.DreamInfo info : infos) { |
| final String componentNameString = info.componentName.toShortString(); |
| mDreamInfos.put(componentNameString, info); |
| listEntries[index] = info.caption; |
| listEntryValues[index] = componentNameString; |
| index++; |
| } |
| } |
| |
| @Override |
| public boolean onPreferenceChange(Preference preference, Object newValue) { |
| switch (preference.getKey()) { |
| case KEY_ACTIVE_DREAM: |
| logEntrySelected(TvSettingsEnums.PREFERENCES_SCREENSAVER_CHOOSER); |
| setActiveDream((String) newValue); |
| break; |
| case KEY_DREAM_TIME: |
| final int sleepTimeout = Integer.parseInt((String) newValue); |
| if (getSleepTimeoutEntryId(sleepTimeout) != -1) { |
| logEntrySelected(getSleepTimeoutEntryId(sleepTimeout)); |
| } |
| setDreamTime(sleepTimeout); |
| break; |
| } |
| return true; |
| } |
| |
| private void setActiveDream(String componentNameString) { |
| final DreamBackend.DreamInfo dreamInfo = mDreamInfos.get(componentNameString); |
| if (dreamInfo != null) { |
| if (dreamInfo.settingsComponentName != null) { |
| startActivity(new Intent().setComponent(dreamInfo.settingsComponentName)); |
| } |
| if (!mBackend.isEnabled()) { |
| mBackend.setEnabled(true); |
| } |
| if (!Objects.equals(mBackend.getActiveDream(), dreamInfo.componentName)) { |
| mBackend.setActiveDream(dreamInfo.componentName); |
| } |
| } else { |
| if (mBackend.isEnabled()) { |
| mBackend.setActiveDream(null); |
| mBackend.setEnabled(false); |
| } |
| } |
| } |
| |
| private int getDreamTime() { |
| return Settings.System.getInt(getActivity().getContentResolver(), SCREEN_OFF_TIMEOUT, |
| DEFAULT_DREAM_TIME_MS); |
| } |
| |
| private void setDreamTime(int ms) { |
| Settings.System.putInt(getActivity().getContentResolver(), SCREEN_OFF_TIMEOUT, ms); |
| } |
| |
| @Override |
| public boolean onPreferenceTreeClick(Preference preference) { |
| switch (preference.getKey()) { |
| case KEY_DREAM_NOW: |
| logEntrySelected(TvSettingsEnums.PREFERENCES_SCREENSAVER_START_NOW); |
| mBackend.startDreaming(); |
| return true; |
| default: |
| return super.onPreferenceTreeClick(preference); |
| } |
| } |
| |
| private void refreshFromBackend() { |
| if (getActivity() == null) { |
| Log.d(TAG, "No activity, not refreshing"); |
| return; |
| } |
| |
| refreshActiveDreamPref(); |
| if (mDreamTimePref != null) { |
| mDreamTimePref.updatePreference( |
| dreamTimePref -> dreamTimePref.setValue(Integer.toString(getDreamTime()))); |
| } |
| |
| final Preference dreamNowPref = findPreference(KEY_DREAM_NOW); |
| if (dreamNowPref != null) { |
| dreamNowPref.setEnabled(mBackend.isEnabled()); |
| } |
| } |
| |
| private class PackageReceiver extends BroadcastReceiver { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| refreshFromBackend(); |
| } |
| } |
| |
| // Map @array/sleep_timeout_entries to defined log enum |
| private int getSleepTimeoutEntryId(int sleepTimeout) { |
| switch(sleepTimeout) { |
| case 300000: |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER_START_DELAY_5M; |
| case 900000: |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER_START_DELAY_15M; |
| case 1800000: |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER_START_DELAY_30M; |
| case 3600000: |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER_START_DELAY_1H; |
| case 7200000: |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER_START_DELAY_2H; |
| default: |
| return -1; |
| } |
| } |
| |
| private void updateAmbientSettings() { |
| final SlicePreference ambientSlicePref = findPreference(KEY_AMBIENT_SETTINGS); |
| if (ambientSlicePref != null) { |
| if (SliceUtils.isSliceProviderValid(getContext(), ambientSlicePref.getUri())) { |
| ambientSlicePref.setVisible(true); |
| } |
| } |
| } |
| |
| @Override |
| protected int getPageId() { |
| return TvSettingsEnums.PREFERENCES_SCREENSAVER; |
| } |
| } |