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.
5 package org.chromium.content.browser;
7 import android.content.BroadcastReceiver;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.content.IntentFilter;
11 import android.os.BatteryManager;
12 import android.util.Log;
14 import com.google.common.annotations.VisibleForTesting;
16 import org.chromium.base.CalledByNative;
17 import org.chromium.base.JNINamespace;
20 * Android implementation of the battery status APIs.
22 @JNINamespace("content")
23 class BatteryStatusManager {
25 private static final String TAG = "BatteryStatusManager";
27 // A reference to the application context in order to acquire the SensorService.
28 private final Context mAppContext;
29 private final IntentFilter mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
30 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
32 public void onReceive(Context context, Intent intent) {
33 BatteryStatusManager.this.onReceive(intent);
37 // Non-zero if and only if we're listening for events.
38 // To avoid race conditions on the C++ side, access must be synchronized.
39 private long mNativePtr;
40 // The lock to access the mNativePtr.
41 private final Object mNativePtrLock = new Object();
43 private boolean mEnabled = false;
45 protected BatteryStatusManager(Context context) {
46 mAppContext = context.getApplicationContext();
50 static BatteryStatusManager getInstance(Context appContext) {
51 return new BatteryStatusManager(appContext);
55 * Start listening for intents
56 * @return True on success.
59 boolean start(long nativePtr) {
60 synchronized (mNativePtrLock) {
61 if (!mEnabled && mAppContext.registerReceiver(mReceiver, mFilter) != null) {
63 mNativePtr = nativePtr;
71 * Stop listening to intents.
75 synchronized (mNativePtrLock) {
77 mAppContext.unregisterReceiver(mReceiver);
85 void onReceive(Intent intent) {
86 if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
87 Log.e(TAG, "Unexpected intent.");
91 int current = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
92 int max = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
93 double level = (double)current / (double)max;
95 int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
96 // by default assume a battery is present
97 boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
98 boolean charging = (present && status == BatteryManager.BATTERY_STATUS_DISCHARGING)
101 //TODO(timvolodine) : add proper projection for chargingTime, dischargingTime.
102 double chargingTime = (!present || status == BatteryManager.BATTERY_STATUS_FULL)
103 ? 0 : Double.POSITIVE_INFINITY;
104 double dischargingTime = Double.POSITIVE_INFINITY;
106 gotBatteryStatus(charging, chargingTime, dischargingTime, level);
109 protected void gotBatteryStatus(boolean charging, double chargingTime,
110 double dischargingTime, double level) {
111 synchronized (mNativePtrLock) {
112 if (mNativePtr != 0) {
113 nativeGotBatteryStatus(mNativePtr, charging, chargingTime, dischargingTime, level);
120 * see content/browser/battery_status/battery_status_manager_android.cc
122 private native void nativeGotBatteryStatus(long nativeBatteryStatusManagerAndroid,
123 boolean charging, double chargingTime, double dischargingTime, double level);