BatteryStatusManager.java revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 com.google.common.annotations.VisibleForTesting;
15
16import org.chromium.base.CalledByNative;
17import org.chromium.base.JNINamespace;
18
19/**
20 * Android implementation of the battery status APIs.
21 */
22@JNINamespace("content")
23class BatteryStatusManager {
24
25    private static final String TAG = "BatteryStatusManager";
26
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() {
31        @Override
32        public void onReceive(Context context, Intent intent) {
33            BatteryStatusManager.this.onReceive(intent);
34        }
35    };
36
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();
42
43    private boolean mEnabled = false;
44
45    protected BatteryStatusManager(Context context) {
46        mAppContext = context.getApplicationContext();
47    }
48
49    @CalledByNative
50    static BatteryStatusManager getInstance(Context appContext) {
51        return new BatteryStatusManager(appContext);
52    }
53
54    /**
55     * Start listening for intents
56     * @return True on success.
57     */
58    @CalledByNative
59    boolean start(long nativePtr) {
60        synchronized (mNativePtrLock) {
61            if (!mEnabled && mAppContext.registerReceiver(mReceiver, mFilter) != null) {
62                // success
63                mNativePtr = nativePtr;
64                mEnabled = true;
65            }
66        }
67        return mEnabled;
68    }
69
70    /**
71     * Stop listening to intents.
72     */
73    @CalledByNative
74    void stop() {
75        synchronized (mNativePtrLock) {
76            if (mEnabled) {
77                mAppContext.unregisterReceiver(mReceiver);
78                mNativePtr = 0;
79                mEnabled = false;
80            }
81        }
82    }
83
84    @VisibleForTesting
85    void onReceive(Intent intent) {
86       if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
87           Log.e(TAG, "Unexpected intent.");
88           return;
89       }
90
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;
94
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)
99               ? false : true;
100
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;
105
106       gotBatteryStatus(charging, chargingTime, dischargingTime, level);
107    }
108
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);
114            }
115        }
116    }
117
118    /**
119     * Native JNI call
120     * see content/browser/battery_status/battery_status_manager.cc
121     */
122    private native void nativeGotBatteryStatus(long nativeBatteryStatusManager,
123            boolean charging, double chargingTime, double dischargingTime, double level);
124}
125