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 package com.android.settings.fuelgauge; 17 18 import android.content.Context; 19 import android.database.ContentObserver; 20 import android.os.Handler; 21 import android.os.PowerManager; 22 import android.provider.Settings; 23 import android.support.annotation.VisibleForTesting; 24 import android.support.v7.preference.Preference; 25 import android.support.v7.preference.PreferenceScreen; 26 import com.android.settings.R; 27 import com.android.settings.Utils; 28 import com.android.settings.core.PreferenceControllerMixin; 29 import com.android.settings.dashboard.conditional.BatterySaverCondition; 30 import com.android.settings.dashboard.conditional.ConditionManager; 31 import com.android.settings.widget.MasterSwitchPreference; 32 import com.android.settingslib.core.AbstractPreferenceController; 33 import com.android.settingslib.core.lifecycle.Lifecycle; 34 import com.android.settingslib.core.lifecycle.LifecycleObserver; 35 import com.android.settingslib.core.lifecycle.events.OnStart; 36 import com.android.settingslib.core.lifecycle.events.OnStop; 37 38 import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGING; 39 40 public class BatterySaverController extends AbstractPreferenceController 41 implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener, 42 LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener { 43 private static final String KEY_BATTERY_SAVER = "battery_saver_summary"; 44 private final BatterySaverReceiver mBatteryStateChangeReceiver; 45 private final PowerManager mPowerManager; 46 private MasterSwitchPreference mBatterySaverPref; 47 48 public BatterySaverController(Context context, Lifecycle lifecycle) { 49 super(context); 50 51 lifecycle.addObserver(this); 52 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 53 mBatteryStateChangeReceiver = new BatterySaverReceiver(context); 54 mBatteryStateChangeReceiver.setBatterySaverListener(this); 55 } 56 57 @Override 58 public boolean isAvailable() { 59 return true; 60 } 61 62 @Override 63 public String getPreferenceKey() { 64 return KEY_BATTERY_SAVER; 65 } 66 67 @Override 68 public void displayPreference(PreferenceScreen screen) { 69 super.displayPreference(screen); 70 mBatterySaverPref = (MasterSwitchPreference) screen.findPreference(KEY_BATTERY_SAVER); 71 } 72 73 @Override 74 public void updateState(Preference preference) { 75 mBatterySaverPref.setChecked(mPowerManager.isPowerSaveMode()); 76 updateSummary(); 77 } 78 79 @Override 80 public boolean onPreferenceChange(Preference preference, Object newValue) { 81 final boolean saverOn = (Boolean) newValue; 82 if (saverOn != mPowerManager.isPowerSaveMode() 83 && !mPowerManager.setPowerSaveMode(saverOn)) { 84 // Do nothing if power save mode doesn't set correctly 85 return false; 86 } 87 88 refreshConditionManager(); 89 updateSummary(); 90 return true; 91 } 92 93 @Override 94 public void onStart() { 95 mContext.getContentResolver().registerContentObserver( 96 Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL) 97 , true, mObserver); 98 99 mBatteryStateChangeReceiver.setListening(true); 100 } 101 102 @Override 103 public void onStop() { 104 mContext.getContentResolver().unregisterContentObserver(mObserver); 105 mBatteryStateChangeReceiver.setListening(false); 106 } 107 108 @VisibleForTesting 109 void refreshConditionManager() { 110 ConditionManager.get(mContext).getCondition(BatterySaverCondition.class).refreshState(); 111 } 112 113 private void updateSummary() { 114 final boolean mode = mPowerManager.isPowerSaveMode(); 115 final int format = mode ? R.string.battery_saver_on_summary 116 : R.string.battery_saver_off_summary; 117 final int percent = Settings.Global.getInt(mContext.getContentResolver(), 118 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); 119 final int percentFormat = percent > 0 ? R.string.battery_saver_desc_turn_on_auto_pct 120 : R.string.battery_saver_desc_turn_on_auto_never; 121 122 final String summary = mContext.getString(format, mContext.getString(percentFormat, 123 Utils.formatPercentage(percent))); 124 125 mBatterySaverPref.setSummary(summary); 126 } 127 128 private final ContentObserver mObserver = new ContentObserver(new Handler()) { 129 @Override 130 public void onChange(boolean selfChange) { 131 updateSummary(); 132 } 133 }; 134 135 @Override 136 public void onPowerSaveModeChanged() { 137 mBatterySaverPref.setChecked(mPowerManager.isPowerSaveMode()); 138 updateSummary(); 139 } 140 141 @Override 142 public void onBatteryChanged(boolean pluggedIn) { 143 mBatterySaverPref.setSwitchEnabled(!pluggedIn); 144 } 145 } 146