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