1 /* 2 * Copyright (C) 2015 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.systemui.qs.tiles; 17 18 import android.content.Intent; 19 import android.os.Handler; 20 import android.os.Looper; 21 import android.provider.Settings; 22 import android.provider.Settings.Secure; 23 import android.service.quicksettings.Tile; 24 import android.view.View; 25 import android.widget.Switch; 26 27 import androidx.annotation.Nullable; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.internal.logging.MetricsLogger; 31 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 32 import com.android.systemui.R; 33 import com.android.systemui.dagger.qualifiers.Background; 34 import com.android.systemui.dagger.qualifiers.Main; 35 import com.android.systemui.plugins.ActivityStarter; 36 import com.android.systemui.plugins.FalsingManager; 37 import com.android.systemui.plugins.qs.QSTile.BooleanState; 38 import com.android.systemui.plugins.statusbar.StatusBarStateController; 39 import com.android.systemui.qs.QSHost; 40 import com.android.systemui.qs.QsEventLogger; 41 import com.android.systemui.qs.SettingObserver; 42 import com.android.systemui.qs.logging.QSLogger; 43 import com.android.systemui.qs.tileimpl.QSTileImpl; 44 import com.android.systemui.statusbar.policy.BatteryController; 45 import com.android.systemui.util.settings.SecureSettings; 46 47 import javax.inject.Inject; 48 49 public class BatterySaverTile extends QSTileImpl<BooleanState> implements 50 BatteryController.BatteryStateChangeCallback { 51 52 public static final String TILE_SPEC = "battery"; 53 54 private final BatteryController mBatteryController; 55 @VisibleForTesting 56 protected final SettingObserver mSetting; 57 58 private int mLevel; 59 private boolean mPowerSave; 60 private boolean mCharging; 61 private boolean mPluggedIn; 62 63 @Inject BatterySaverTile( QSHost host, QsEventLogger uiEventLogger, @Background Looper backgroundLooper, @Main Handler mainHandler, FalsingManager falsingManager, MetricsLogger metricsLogger, StatusBarStateController statusBarStateController, ActivityStarter activityStarter, QSLogger qsLogger, BatteryController batteryController, SecureSettings secureSettings )64 public BatterySaverTile( 65 QSHost host, 66 QsEventLogger uiEventLogger, 67 @Background Looper backgroundLooper, 68 @Main Handler mainHandler, 69 FalsingManager falsingManager, 70 MetricsLogger metricsLogger, 71 StatusBarStateController statusBarStateController, 72 ActivityStarter activityStarter, 73 QSLogger qsLogger, 74 BatteryController batteryController, 75 SecureSettings secureSettings 76 ) { 77 super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, 78 statusBarStateController, activityStarter, qsLogger); 79 mBatteryController = batteryController; 80 mBatteryController.observe(getLifecycle(), this); 81 int currentUser = host.getUserContext().getUserId(); 82 mSetting = new SettingObserver( 83 secureSettings, 84 mHandler, 85 Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 86 currentUser 87 ) { 88 @Override 89 protected void handleValueChanged(int value, boolean observedChange) { 90 // mHandler is the background handler so calling this is OK 91 handleRefreshState(null); 92 } 93 }; 94 } 95 96 @Override newTileState()97 public BooleanState newTileState() { 98 return new BooleanState(); 99 } 100 101 @Override handleDestroy()102 protected void handleDestroy() { 103 super.handleDestroy(); 104 mSetting.setListening(false); 105 } 106 107 @Override handleUserSwitch(int newUserId)108 protected void handleUserSwitch(int newUserId) { 109 mSetting.setUserId(newUserId); 110 } 111 112 @Override getMetricsCategory()113 public int getMetricsCategory() { 114 return MetricsEvent.QS_BATTERY_TILE; 115 } 116 117 @Override handleSetListening(boolean listening)118 public void handleSetListening(boolean listening) { 119 super.handleSetListening(listening); 120 mSetting.setListening(listening); 121 if (!listening) { 122 // If we stopped listening, it means that the tile is not visible. In that case, we 123 // don't need to save the view anymore 124 mBatteryController.clearLastPowerSaverStartView(); 125 } 126 } 127 128 @Override getLongClickIntent()129 public Intent getLongClickIntent() { 130 return new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS); 131 } 132 133 @Override handleClick(@ullable View view)134 protected void handleClick(@Nullable View view) { 135 if (getState().state == Tile.STATE_UNAVAILABLE) { 136 return; 137 } 138 mBatteryController.setPowerSaveMode(!mPowerSave, view); 139 } 140 141 @Override getTileLabel()142 public CharSequence getTileLabel() { 143 return mContext.getString(R.string.battery_detail_switch_title); 144 } 145 146 @Override handleUpdateState(BooleanState state, Object arg)147 protected void handleUpdateState(BooleanState state, Object arg) { 148 state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE 149 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; 150 state.icon = ResourceIcon.get(mPowerSave 151 ? R.drawable.qs_battery_saver_icon_on 152 : R.drawable.qs_battery_saver_icon_off); 153 state.label = mContext.getString(R.string.battery_detail_switch_title); 154 state.secondaryLabel = ""; 155 state.contentDescription = state.label; 156 state.value = mPowerSave; 157 state.expandedAccessibilityClassName = Switch.class.getName(); 158 } 159 160 @Override onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging)161 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 162 mLevel = level; 163 mPluggedIn = pluggedIn; 164 mCharging = charging; 165 refreshState(level); 166 } 167 168 @Override onPowerSaveChanged(boolean isPowerSave)169 public void onPowerSaveChanged(boolean isPowerSave) { 170 mPowerSave = isPowerSave; 171 refreshState(null); 172 } 173 } 174