1 /*
2  * Copyright (C) 2018 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.fuelgauge.batterysaver;
18 
19 import static com.android.settingslib.fuelgauge.BatterySaverUtils.KEY_NO_SCHEDULE;
20 import static com.android.settingslib.fuelgauge.BatterySaverUtils.KEY_PERCENTAGE;
21 
22 import android.app.settings.SettingsEnums;
23 import android.content.Context;
24 import android.database.ContentObserver;
25 import android.graphics.Color;
26 import android.graphics.drawable.ColorDrawable;
27 import android.graphics.drawable.Drawable;
28 import android.net.Uri;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.provider.Settings;
33 import android.view.View;
34 
35 import androidx.annotation.NonNull;
36 import androidx.annotation.Nullable;
37 import androidx.annotation.VisibleForTesting;
38 import androidx.preference.PreferenceScreen;
39 
40 import com.android.settings.R;
41 import com.android.settings.overlay.FeatureFactory;
42 import com.android.settings.widget.RadioButtonPickerFragment;
43 import com.android.settingslib.fuelgauge.BatterySaverUtils;
44 import com.android.settingslib.widget.CandidateInfo;
45 import com.android.settingslib.widget.SelectorWithWidgetPreference;
46 
47 import com.google.common.collect.Lists;
48 
49 import java.util.List;
50 
51 /**
52  * Fragment that allows users to customize their automatic battery saver mode settings. <br>
53  * <br>
54  * Location: Settings > Battery > Battery Saver > Set a Schedule <br>
55  * See {@link BatterySaverSchedulePreferenceController} for the controller that manages navigation
56  * to this screen from "Settings > Battery > Battery Saver" and the summary. <br>
57  * See {@link BatterySaverScheduleRadioButtonsController} & {@link
58  * BatterySaverScheduleSeekBarController} for the controller that manages user interactions in this
59  * screen.
60  */
61 public class BatterySaverScheduleSettings extends RadioButtonPickerFragment {
62 
63     public BatterySaverScheduleRadioButtonsController mRadioButtonController;
64     @VisibleForTesting Context mContext;
65     private int mSaverPercentage;
66     private String mSaverScheduleKey;
67     private BatterySaverScheduleSeekBarController mSeekBarController;
68 
69     @VisibleForTesting
70     final ContentObserver mSettingsObserver =
71             new ContentObserver(new Handler()) {
72                 @Override
73                 public void onChange(boolean selfChange, Uri uri) {
74                     getPreferenceScreen().removeAll();
75                     updateCandidates();
76                 }
77             };
78 
79     @Override
getPreferenceScreenResId()80     protected int getPreferenceScreenResId() {
81         return R.xml.battery_saver_schedule_settings;
82     }
83 
84     @Override
onAttach(Context context)85     public void onAttach(Context context) {
86         super.onAttach(context);
87         mSeekBarController = new BatterySaverScheduleSeekBarController(context);
88         mRadioButtonController =
89                 new BatterySaverScheduleRadioButtonsController(context, mSeekBarController);
90         mContext = context;
91     }
92 
93     @Override
onResume()94     public void onResume() {
95         super.onResume();
96         mContext.getContentResolver()
97                 .registerContentObserver(
98                         Settings.Secure.getUriFor(Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED),
99                         false,
100                         mSettingsObserver);
101         mSaverScheduleKey = BatterySaverUtils.getBatterySaverScheduleKey(mContext);
102         mSaverPercentage = getSaverPercentage();
103     }
104 
105     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)106     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
107         super.onViewCreated(view, savedInstanceState);
108         setDivider(new ColorDrawable(Color.TRANSPARENT));
109         setDividerHeight(0);
110     }
111 
112     @Override
onCreate(Bundle savedInstanceState)113     public void onCreate(Bundle savedInstanceState) {
114         super.onCreate(savedInstanceState);
115     }
116 
117     @Override
onPause()118     public void onPause() {
119         mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
120         AsyncTask.execute(() -> logPowerSaver());
121         super.onPause();
122     }
123 
124     @Override
getCandidates()125     protected List<? extends CandidateInfo> getCandidates() {
126         Context context = getContext();
127         List<CandidateInfo> candidates = Lists.newArrayList();
128         candidates.add(
129                 new BatterySaverScheduleCandidateInfo(
130                         context.getText(R.string.battery_saver_auto_no_schedule),
131                         /* summary */ null,
132                         KEY_NO_SCHEDULE,
133                         /* enabled */ true));
134         BatterySaverUtils.revertScheduleToNoneIfNeeded(context);
135         candidates.add(
136                 new BatterySaverScheduleCandidateInfo(
137                         context.getText(R.string.battery_saver_auto_percentage),
138                         /* summary */ null,
139                         KEY_PERCENTAGE,
140                         /* enabled */ true));
141 
142         return candidates;
143     }
144 
145     @Override
bindPreferenceExtra( SelectorWithWidgetPreference pref, String key, CandidateInfo info, String defaultKey, String systemDefaultKey)146     public void bindPreferenceExtra(
147             SelectorWithWidgetPreference pref,
148             String key,
149             CandidateInfo info,
150             String defaultKey,
151             String systemDefaultKey) {
152         final BatterySaverScheduleCandidateInfo candidateInfo =
153                 (BatterySaverScheduleCandidateInfo) info;
154         final CharSequence summary = candidateInfo.getSummary();
155         if (summary != null) {
156             pref.setSummary(summary);
157             pref.setAppendixVisibility(View.GONE);
158         }
159     }
160 
161     @Override
addStaticPreferences(PreferenceScreen screen)162     protected void addStaticPreferences(PreferenceScreen screen) {
163         mSeekBarController.updateSeekBar();
164         mSeekBarController.addToScreen(screen);
165     }
166 
167     @Override
getDefaultKey()168     protected String getDefaultKey() {
169         return BatterySaverUtils.getBatterySaverScheduleKey(mContext);
170     }
171 
172     @Override
setDefaultKey(String key)173     protected boolean setDefaultKey(String key) {
174         return mRadioButtonController.setDefaultKey(key);
175     }
176 
177     @Override
getMetricsCategory()178     public int getMetricsCategory() {
179         return SettingsEnums.FUELGAUGE_BATTERY_SAVER_SCHEDULE;
180     }
181 
logPowerSaver()182     private void logPowerSaver() {
183         final int currentSaverPercentage = getSaverPercentage();
184         final String currentSaverScheduleKey =
185                 BatterySaverUtils.getBatterySaverScheduleKey(mContext);
186         if (mSaverScheduleKey.equals(currentSaverScheduleKey)
187                 && mSaverPercentage == currentSaverPercentage) {
188             return;
189         }
190         FeatureFactory.getFeatureFactory()
191                 .getMetricsFeatureProvider()
192                 .action(
193                         SettingsEnums.FUELGAUGE_BATTERY_SAVER,
194                         SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE,
195                         SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE,
196                         currentSaverScheduleKey,
197                         currentSaverPercentage);
198     }
199 
getSaverPercentage()200     private int getSaverPercentage() {
201         return Settings.Global.getInt(
202                 mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1);
203     }
204 
205     static class BatterySaverScheduleCandidateInfo extends CandidateInfo {
206 
207         private final CharSequence mLabel;
208         private final CharSequence mSummary;
209         private final String mKey;
210 
BatterySaverScheduleCandidateInfo( CharSequence label, CharSequence summary, String key, boolean enabled)211         BatterySaverScheduleCandidateInfo(
212                 CharSequence label, CharSequence summary, String key, boolean enabled) {
213             super(enabled);
214             mLabel = label;
215             mKey = key;
216             mSummary = summary;
217         }
218 
219         @Override
loadLabel()220         public CharSequence loadLabel() {
221             return mLabel;
222         }
223 
224         @Override
loadIcon()225         public Drawable loadIcon() {
226             return null;
227         }
228 
229         @Override
getKey()230         public String getKey() {
231             return mKey;
232         }
233 
getSummary()234         public CharSequence getSummary() {
235             return mSummary;
236         }
237     }
238 }
239