BatteryStatusManager.java revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.content.BroadcastReceiver;
8import android.content.Context;
9import android.content.Intent;
10import android.content.IntentFilter;
11import android.os.BatteryManager;
12import android.util.Log;
13
14import org.chromium.base.CalledByNative;
15import org.chromium.base.JNINamespace;
16
17/**
18 * Android implementation of the battery status APIs.
19 */
20@JNINamespace("content")
21class BatteryStatusManager extends BroadcastReceiver {
22
23    private static final String TAG = "BatteryStatusManager";
24
25    // A reference to the application context in order to acquire the SensorService.
26    private final Context mAppContext;
27    private final IntentFilter mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
28
29    // Non-zero if and only if we're listening for events.
30    // To avoid race conditions on the C++ side, access must be synchronized.
31    private long mNativePtr;
32    // The lock to access the mNativePtr.
33    private final Object mNativePtrLock = new Object();
34
35    private boolean mEnabled = false;
36
37    protected BatteryStatusManager(Context context) {
38        mAppContext = context.getApplicationContext();
39    }
40
41    @CalledByNative
42    static BatteryStatusManager getInstance(Context appContext) {
43        return new BatteryStatusManager(appContext);
44    }
45
46    /**
47     * Start listening for intents
48     * @return True on success.
49     */
50    @CalledByNative
51    boolean start(long nativePtr) {
52        synchronized (mNativePtrLock) {
53            if (!mEnabled && mAppContext.registerReceiver(this, mFilter) != null) {
54                // success
55                mNativePtr = nativePtr;
56                mEnabled = true;
57            }
58        }
59        return mEnabled;
60    }
61
62    /**
63     * Stop listening to intents.
64     */
65    @CalledByNative
66    void stop() {
67        synchronized (mNativePtrLock) {
68            if (mEnabled) {
69                mAppContext.unregisterReceiver(this);
70                mNativePtr = 0;
71                mEnabled = false;
72            }
73        }
74    }
75
76    @Override
77    public void onReceive(Context context, Intent intent) {
78       if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
79           Log.e(TAG, "Unexpected intent.");
80           return;
81       }
82
83       int current = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
84       int max = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
85       double level = (double)current / (double)max;
86
87       int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
88       // by default assume a battery is present
89       boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
90       boolean charging = (present && status == BatteryManager.BATTERY_STATUS_DISCHARGING)
91               ? false : true;
92
93       //TODO(timvolodine) : add proper projection for chargingTime, dischargingTime.
94       double chargingTime = (!present || status == BatteryManager.BATTERY_STATUS_FULL)
95               ? 0 : Double.POSITIVE_INFINITY;
96       double dischargingTime = Double.POSITIVE_INFINITY;
97
98       gotBatteryStatus(charging, chargingTime, dischargingTime, level);
99    }
100
101    protected void gotBatteryStatus(boolean charging, double chargingTime,
102            double dischargingTime, double level) {
103        synchronized (mNativePtrLock) {
104            if (mNativePtr != 0) {
105                nativeGotBatteryStatus(mNativePtr, charging, chargingTime, dischargingTime, level);
106            }
107        }
108    }
109
110    /**
111     * Native JNI call
112     * see content/browser/battery_status/battery_status_manager_android.cc
113     */
114    private native void nativeGotBatteryStatus(long nativeBatteryStatusManagerAndroid,
115            boolean charging, double chargingTime, double dischargingTime, double level);
116}
117