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.settingslib.fuelgauge; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.PowerManager; 23 import android.provider.Settings.Global; 24 import android.provider.Settings.Secure; 25 import android.util.KeyValueListParser; 26 import android.util.Log; 27 import android.util.Slog; 28 29 /** 30 * Utilities related to battery saver. 31 */ 32 public class BatterySaverUtils { 33 private static final String TAG = "BatterySaverUtils"; 34 BatterySaverUtils()35 private BatterySaverUtils() { 36 } 37 38 private static final boolean DEBUG = false; 39 40 private static final String SYSUI_PACKAGE = "com.android.systemui"; 41 42 /** Broadcast action for SystemUI to show the battery saver confirmation dialog. */ 43 public static final String ACTION_SHOW_START_SAVER_CONFIRMATION = "PNW.startSaverConfirmation"; 44 45 /** 46 * Broadcast action for SystemUI to show the notification that suggests turning on 47 * automatic battery saver. 48 */ 49 public static final String ACTION_SHOW_AUTO_SAVER_SUGGESTION 50 = "PNW.autoSaverSuggestion"; 51 52 private static class Parameters { 53 private final Context mContext; 54 55 /** 56 * We show the auto battery saver suggestion notification when the user manually enables 57 * battery saver for the START_NTH time through the END_NTH time. 58 * (We won't show it for END_NTH + 1 time and after.) 59 */ 60 private static final int AUTO_SAVER_SUGGESTION_START_NTH = 4; 61 private static final int AUTO_SAVER_SUGGESTION_END_NTH = 8; 62 63 public final int startNth; 64 public final int endNth; 65 Parameters(Context context)66 public Parameters(Context context) { 67 mContext = context; 68 69 final String newValue = Global.getString(mContext.getContentResolver(), 70 Global.LOW_POWER_MODE_SUGGESTION_PARAMS); 71 final KeyValueListParser parser = new KeyValueListParser(','); 72 try { 73 parser.setString(newValue); 74 } catch (IllegalArgumentException e) { 75 Slog.wtf(TAG, "Bad constants: " + newValue); 76 } 77 startNth = parser.getInt("start_nth", AUTO_SAVER_SUGGESTION_START_NTH); 78 endNth = parser.getInt("end_nth", AUTO_SAVER_SUGGESTION_END_NTH); 79 } 80 } 81 82 /** 83 * Enable / disable battery saver by user request. 84 * - If it's the first time and needFirstTimeWarning, show the first time dialog. 85 * - If it's 4th time through 8th time, show the schedule suggestion notification. 86 * 87 * @param enable true to disable battery saver. 88 * 89 * @return true if the request succeeded. 90 */ setPowerSaveMode(Context context, boolean enable, boolean needFirstTimeWarning)91 public static synchronized boolean setPowerSaveMode(Context context, 92 boolean enable, boolean needFirstTimeWarning) { 93 if (DEBUG) { 94 Log.d(TAG, "Battery saver turning " + (enable ? "ON" : "OFF")); 95 } 96 final ContentResolver cr = context.getContentResolver(); 97 98 if (enable && needFirstTimeWarning && maybeShowBatterySaverConfirmation(context)) { 99 return false; 100 } 101 if (enable && !needFirstTimeWarning) { 102 setBatterySaverConfirmationAcknowledged(context); 103 } 104 105 if (context.getSystemService(PowerManager.class).setPowerSaveMode(enable)) { 106 if (enable) { 107 final int count = 108 Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1; 109 Secure.putInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, count); 110 111 final Parameters parameters = new Parameters(context); 112 113 if ((count >= parameters.startNth) 114 && (count <= parameters.endNth) 115 && Global.getInt(cr, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) == 0 116 && Secure.getInt(cr, 117 Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0) == 0) { 118 showAutoBatterySaverSuggestion(context); 119 } 120 } 121 122 return true; 123 } 124 return false; 125 } 126 maybeShowBatterySaverConfirmation(Context context)127 private static boolean maybeShowBatterySaverConfirmation(Context context) { 128 if (Secure.getInt(context.getContentResolver(), 129 Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) { 130 return false; // Already shown. 131 } 132 context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_START_SAVER_CONFIRMATION)); 133 return true; 134 } 135 showAutoBatterySaverSuggestion(Context context)136 private static void showAutoBatterySaverSuggestion(Context context) { 137 context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_AUTO_SAVER_SUGGESTION)); 138 } 139 getSystemUiBroadcast(String action)140 private static Intent getSystemUiBroadcast(String action) { 141 final Intent i = new Intent(action); 142 i.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); 143 i.setPackage(SYSUI_PACKAGE); 144 return i; 145 } 146 setBatterySaverConfirmationAcknowledged(Context context)147 private static void setBatterySaverConfirmationAcknowledged(Context context) { 148 Secure.putInt(context.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1); 149 } 150 151 /** 152 * Don't show the automatic battery suggestion notification in the future. 153 */ suppressAutoBatterySaver(Context context)154 public static void suppressAutoBatterySaver(Context context) { 155 Secure.putInt(context.getContentResolver(), 156 Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 1); 157 } 158 159 /** 160 * Set the automatic battery saver trigger level to {@code level}. 161 */ setAutoBatterySaverTriggerLevel(Context context, int level)162 public static void setAutoBatterySaverTriggerLevel(Context context, int level) { 163 if (level > 0) { 164 suppressAutoBatterySaver(context); 165 } 166 Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level); 167 } 168 169 /** 170 * Set the automatic battery saver trigger level to {@code level}, but only when 171 * automatic battery saver isn't enabled yet. 172 */ ensureAutoBatterySaver(Context context, int level)173 public static void ensureAutoBatterySaver(Context context, int level) { 174 if (Global.getInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) 175 == 0) { 176 setAutoBatterySaverTriggerLevel(context, level); 177 } 178 } 179 } 180