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.ContentResolver;
20 import android.content.Context;
21 import android.net.Uri;
22 import android.os.Handler;
23 import android.os.Looper;
24 import android.os.PowerManager;
25 import android.provider.SettingsSlicesContract;
26 import android.widget.Switch;
27 
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.settings.R;
31 import com.android.settings.core.TogglePreferenceController;
32 import com.android.settings.fuelgauge.BatterySaverReceiver;
33 import com.android.settingslib.core.lifecycle.LifecycleObserver;
34 import com.android.settingslib.core.lifecycle.events.OnStart;
35 import com.android.settingslib.core.lifecycle.events.OnStop;
36 import com.android.settingslib.fuelgauge.BatterySaverUtils;
37 import com.android.settingslib.widget.MainSwitchPreference;
38 import com.android.settingslib.widget.OnMainSwitchChangeListener;
39 
40 
41 /**
42  * Controller to update the battery saver button
43  */
44 public class BatterySaverButtonPreferenceController extends
45         TogglePreferenceController implements OnMainSwitchChangeListener, LifecycleObserver,
46         OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
47     private static final long SWITCH_ANIMATION_DURATION = 350L;
48 
49     private final BatterySaverReceiver mBatterySaverReceiver;
50     private final PowerManager mPowerManager;
51 
52     private Handler mHandler;
53     private MainSwitchPreference mPreference;
54 
BatterySaverButtonPreferenceController(Context context, String key)55     public BatterySaverButtonPreferenceController(Context context, String key) {
56         super(context, key);
57         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
58         mBatterySaverReceiver = new BatterySaverReceiver(context);
59         mBatterySaverReceiver.setBatterySaverListener(this);
60         mHandler = new Handler(Looper.getMainLooper());
61     }
62 
63     @Override
getAvailabilityStatus()64     public int getAvailabilityStatus() {
65         return AVAILABLE;
66     }
67 
68     @Override
isPublicSlice()69     public boolean isPublicSlice() {
70         return true;
71     }
72 
73     @Override
getSliceUri()74     public Uri getSliceUri() {
75         return new Uri.Builder()
76                 .scheme(ContentResolver.SCHEME_CONTENT)
77                 .authority(SettingsSlicesContract.AUTHORITY)
78                 .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
79                 .appendPath(SettingsSlicesContract.KEY_BATTERY_SAVER)
80                 .build();
81     }
82 
83     @Override
onStart()84     public void onStart() {
85         mBatterySaverReceiver.setListening(true);
86     }
87 
88     @Override
onStop()89     public void onStop() {
90         mBatterySaverReceiver.setListening(false);
91         mHandler.removeCallbacksAndMessages(null /* token */);
92     }
93 
94     @Override
displayPreference(PreferenceScreen screen)95     public void displayPreference(PreferenceScreen screen) {
96         super.displayPreference(screen);
97         mPreference = screen.findPreference(getPreferenceKey());
98         mPreference.setTitle(mContext.getString(R.string.battery_saver_master_switch_title));
99         mPreference.addOnSwitchChangeListener(this);
100         mPreference.updateStatus(isChecked());
101     }
102 
103     @Override
onSwitchChanged(Switch switchView, boolean isChecked)104     public void onSwitchChanged(Switch switchView, boolean isChecked) {
105         setChecked(isChecked);
106     }
107 
108     @Override
isChecked()109     public boolean isChecked() {
110         return mPowerManager.isPowerSaveMode();
111     }
112 
113     @Override
setChecked(boolean stateOn)114     public boolean setChecked(boolean stateOn) {
115         // This screen already shows a warning, so we don't need another warning.
116         mPreference.updateStatus(isChecked());
117         return BatterySaverUtils.setPowerSaveMode(mContext, stateOn,
118                 false /* needFirstTimeWarning */);
119     }
120 
121     @Override
getSliceHighlightMenuRes()122     public int getSliceHighlightMenuRes() {
123         return R.string.menu_key_battery;
124     }
125 
126     @Override
onPowerSaveModeChanged()127     public void onPowerSaveModeChanged() {
128         mHandler.postDelayed(() -> onPowerSaveModeChangedInternal(),
129                 SWITCH_ANIMATION_DURATION);
130     }
131 
onPowerSaveModeChangedInternal()132     private void onPowerSaveModeChangedInternal() {
133         final boolean isChecked = isChecked();
134         if (mPreference != null && mPreference.isChecked() != isChecked) {
135             mPreference.setChecked(isChecked);
136         }
137     }
138 
139     @Override
onBatteryChanged(boolean pluggedIn)140     public void onBatteryChanged(boolean pluggedIn) {
141         if (mPreference != null) {
142             mPreference.setEnabled(!pluggedIn);
143         }
144     }
145 }
146