Home | History | Annotate | Download | only in fuelgauge
      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 
     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 
     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      */
     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 
    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 
    136     private static void showAutoBatterySaverSuggestion(Context context) {
    137         context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_AUTO_SAVER_SUGGESTION));
    138     }
    139 
    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 
    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      */
    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      */
    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      */
    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