110523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato/*
210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * Copyright (C) 2008 The Android Open Source Project
310523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato *
410523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
510523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * you may not use this file except in compliance with the License.
610523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * You may obtain a copy of the License at
710523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato *
810523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
910523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato *
1010523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * Unless required by applicable law or agreed to in writing, software
1110523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
1210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * See the License for the specific language governing permissions and
1410523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato * limitations under the License.
1510523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato */
1610523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
1710523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratopackage com.android.systemui.power;
1810523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
1910523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.content.BroadcastReceiver;
2014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackbornimport android.content.ContentResolver;
2110523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.content.Context;
2210523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.content.Intent;
2310523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.content.IntentFilter;
2414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackbornimport android.database.ContentObserver;
254ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onoratoimport android.os.BatteryManager;
2610523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.os.Handler;
27dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandlerimport android.os.PowerManager;
28dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandlerimport android.os.SystemClock;
2914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackbornimport android.os.UserHandle;
3010523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport android.provider.Settings;
311bb480a3a4ce2ce63c5d09fa7f5cc38ec160ebf4John Spurlockimport android.util.Log;
32dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandlerimport android.util.Slog;
3310523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
3410523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratoimport com.android.systemui.SystemUI;
358de4311c51229efbe2f2d0afbf298982c5cadd96Jorim Jaggiimport com.android.systemui.statusbar.phone.PhoneStatusBar;
3610523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
37de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport java.io.FileDescriptor;
38de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport java.io.PrintWriter;
39de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport java.util.Arrays;
40de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock
4110523b4d0c99cec86647130426d470a1e02a44f6Joe Onoratopublic class PowerUI extends SystemUI {
4210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato    static final String TAG = "PowerUI";
431bb480a3a4ce2ce63c5d09fa7f5cc38ec160ebf4John Spurlock    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
4410523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
45ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private final Handler mHandler = new Handler();
463332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock    private final Receiver mReceiver = new Receiver();
474ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
483332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock    private PowerManager mPowerManager;
493332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock    private WarningsUI mWarnings;
50ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private int mBatteryLevel = 100;
51ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
52ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private int mPlugType = 0;
53ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private int mInvalidCharger = 0;
544ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
55ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private int mLowBatteryAlertCloseLevel;
56ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    private final int[] mLowBatteryReminderLevels = new int[2];
5710523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
58dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler    private long mScreenOffTime = -1;
59dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler
6010523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato    public void start() {
613332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
623332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock        mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
638de4311c51229efbe2f2d0afbf298982c5cadd96Jorim Jaggi        mWarnings = new PowerNotificationWarnings(mContext, getComponent(PhoneStatusBar.class));
64dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler
6514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        ContentObserver obs = new ContentObserver(mHandler) {
6614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            @Override
6714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            public void onChange(boolean selfChange) {
6814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                updateBatteryWarningLevels();
6914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            }
7014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        };
7114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        final ContentResolver resolver = mContext.getContentResolver();
7214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        resolver.registerContentObserver(Settings.Global.getUriFor(
7314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
7414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                false, obs, UserHandle.USER_ALL);
7514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        updateBatteryWarningLevels();
763332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock        mReceiver.init();
773332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock    }
7814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
7914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn    void updateBatteryWarningLevels() {
8014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        int critLevel = mContext.getResources().getInteger(
8114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
8214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
8314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        final ContentResolver resolver = mContext.getContentResolver();
8414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        int defWarnLevel = mContext.getResources().getInteger(
8514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                com.android.internal.R.integer.config_lowBatteryWarningLevel);
8614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        int warnLevel = Settings.Global.getInt(resolver,
8714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
8814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        if (warnLevel == 0) {
8914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            warnLevel = defWarnLevel;
9014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        }
9114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        if (warnLevel < critLevel) {
9214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            warnLevel = critLevel;
9314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        }
9414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
9514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        mLowBatteryReminderLevels[0] = warnLevel;
9614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        mLowBatteryReminderLevels[1] = critLevel;
9714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
9814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                + mContext.getResources().getInteger(
9914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                        com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
10014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn    }
10114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
1024ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato    /**
1034ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * Buckets the battery level.
1044ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     *
1054ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * The code in this function is a little weird because I couldn't comprehend
1064ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * the bucket going up when the battery level was going down. --joeo
1074ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     *
1084ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * 1 means that the battery is "ok"
1094ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * 0 means that the battery is between "ok" and what we should warn about.
1104ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     * less than 0 means that the battery is low
1114ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato     */
1124ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato    private int findBatteryLevelBucket(int level) {
1134ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        if (level >= mLowBatteryAlertCloseLevel) {
1144ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato            return 1;
1154ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        }
11614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        if (level > mLowBatteryReminderLevels[0]) {
1174ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato            return 0;
1184ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        }
1194ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        final int N = mLowBatteryReminderLevels.length;
1204ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        for (int i=N-1; i>=0; i--) {
1214ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato            if (level <= mLowBatteryReminderLevels[i]) {
1224ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                return -1-i;
1234ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato            }
1244ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        }
1254ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        throw new RuntimeException("not possible!");
1264ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato    }
1274ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
1283332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock    private final class Receiver extends BroadcastReceiver {
1293332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock
1303332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock        public void init() {
1313332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            // Register for Intent broadcasts for...
1323332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            IntentFilter filter = new IntentFilter();
1333332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1343332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            filter.addAction(Intent.ACTION_SCREEN_OFF);
1353332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            filter.addAction(Intent.ACTION_SCREEN_ON);
136ecbc5e828abaf2b10dd7a746ecff9bcfae2b0f7fJohn Spurlock            filter.addAction(Intent.ACTION_USER_SWITCHED);
1371bb480a3a4ce2ce63c5d09fa7f5cc38ec160ebf4John Spurlock            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
1383332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
1393332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock            mContext.registerReceiver(this, filter, null, mHandler);
1403332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock        }
1413332ba54ae85df14d761447d86d2aa19d448ce11John Spurlock
14210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato        @Override
14310523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato        public void onReceive(Context context, Intent intent) {
14410523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato            String action = intent.getAction();
14510523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
1464ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final int oldBatteryLevel = mBatteryLevel;
1474ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
1484ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final int oldBatteryStatus = mBatteryStatus;
1494ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
1504ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                        BatteryManager.BATTERY_STATUS_UNKNOWN);
1514ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final int oldPlugType = mPlugType;
1524ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
1534ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final int oldInvalidCharger = mInvalidCharger;
1544ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);
1554ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
1564ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final boolean plugged = mPlugType != 0;
1574ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                final boolean oldPlugged = oldPlugType != 0;
1584ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
1594ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
1604ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                int bucket = findBatteryLevelBucket(mBatteryLevel);
1614ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
1627198662bb3c81a761fdfa3038d90df68d22c0b97Daniel Sandler                if (DEBUG) {
163dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
1644ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                            + " .. " + mLowBatteryReminderLevels[0]
1654ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                            + " .. " + mLowBatteryReminderLevels[1]);
166dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
167dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
168dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
169dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
170dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
171dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
1724ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                }
1734ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
174ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
1754ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
176dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                    Slog.d(TAG, "showing invalid charger warning");
177ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    mWarnings.showInvalidChargerWarning();
1784ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                    return;
1794ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
180ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    mWarnings.dismissInvalidChargerWarning();
181ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                } else if (mWarnings.isInvalidChargerWarningShowing()) {
1824ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                    // if invalid charger is showing, don't show low battery
1834ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                    return;
1844ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                }
1854ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato
186919a68083bc0663fb908517434a42859871d0b51Jason Monk                boolean isPowerSaver = mPowerManager.isPowerSaveMode();
1874ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                if (!plugged
188919a68083bc0663fb908517434a42859871d0b51Jason Monk                        && !isPowerSaver
1894ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                        && (bucket < oldBucket || oldPlugged)
1904ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                        && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
1914ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato                        && bucket < 0) {
1927198662bb3c81a761fdfa3038d90df68d22c0b97Daniel Sandler                    // only play SFX when the dialog comes up or the bucket changes
193ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    final boolean playSound = bucket != oldBucket || oldPlugged;
194ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    mWarnings.showLowBatteryWarning(playSound);
195919a68083bc0663fb908517434a42859871d0b51Jason Monk                } else if (isPowerSaver || plugged || (bucket > oldBucket && bucket > 0)) {
196ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    mWarnings.dismissLowBatteryWarning();
197ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                } else {
198ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock                    mWarnings.updateLowBatteryWarning();
19910523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato                }
200dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
201dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                mScreenOffTime = SystemClock.elapsedRealtime();
202dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
203dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                mScreenOffTime = -1;
204ecbc5e828abaf2b10dd7a746ecff9bcfae2b0f7fJohn Spurlock            } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
205ecbc5e828abaf2b10dd7a746ecff9bcfae2b0f7fJohn Spurlock                mWarnings.userSwitched();
20610523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato            } else {
207dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                Slog.w(TAG, "unknown intent: " + intent);
20810523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato            }
20910523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato        }
21010523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato    };
21110523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
21210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2134ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mLowBatteryAlertCloseLevel=");
2144ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(mLowBatteryAlertCloseLevel);
2154ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mLowBatteryReminderLevels=");
2164ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Arrays.toString(mLowBatteryReminderLevels));
2174ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mBatteryLevel=");
2184ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Integer.toString(mBatteryLevel));
2194ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mBatteryStatus=");
2204ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Integer.toString(mBatteryStatus));
2214ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mPlugType=");
2224ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Integer.toString(mPlugType));
2234ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("mInvalidCharger=");
2244ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Integer.toString(mInvalidCharger));
225dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        pw.print("mScreenOffTime=");
226dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        pw.print(mScreenOffTime);
227dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        if (mScreenOffTime >= 0) {
228dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler            pw.print(" (");
229dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler            pw.print(SystemClock.elapsedRealtime() - mScreenOffTime);
230dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler            pw.print(" ago)");
231dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        }
232dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        pw.println();
233dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        pw.print("soundTimeout=");
234dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler        pw.println(Settings.Global.getInt(mContext.getContentResolver(),
235dea6462aab31049d1f1055314491bc33a6f16b0dDaniel Sandler                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
2364ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.print("bucket: ");
2374ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato        pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
238ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        mWarnings.dump(pw);
239ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    }
240ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock
241ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock    public interface WarningsUI {
242ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void update(int batteryLevel, int bucket, long screenOffTime);
243ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void dismissLowBatteryWarning();
244ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void showLowBatteryWarning(boolean playSound);
245ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void dismissInvalidChargerWarning();
246ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void showInvalidChargerWarning();
247ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void updateLowBatteryWarning();
248ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        boolean isInvalidChargerWarningShowing();
249ed452c5f84c2c12059a247523d768f1eb280934bJohn Spurlock        void dump(PrintWriter pw);
250ecbc5e828abaf2b10dd7a746ecff9bcfae2b0f7fJohn Spurlock        void userSwitched();
25110523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato    }
25210523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato}
25310523b4d0c99cec86647130426d470a1e02a44f6Joe Onorato
254