blob: 6c61d9d190a50e19055adf9a52f815b40355ed5d [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build;
import android.os.PowerManager;
import org.jni_zero.CalledByNative;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.base.compat.ApiHelperForQ;
/**
* Integrates native PowerMonitor with the java side.
*/
@JNINamespace("base::android")
public class PowerMonitor {
private static PowerMonitor sInstance;
private boolean mIsBatteryPower;
public static void createForTests() {
// Applications will create this once the JNI side has been fully wired up both sides. For
// tests, we just need native -> java, that is, we don't need to notify java -> native on
// creation.
sInstance = new PowerMonitor();
}
/**
* Create a PowerMonitor instance if none exists.
*/
public static void create() {
ThreadUtils.assertOnUiThread();
if (sInstance != null) return;
Context context = ContextUtils.getApplicationContext();
sInstance = new PowerMonitor();
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatusIntent =
ContextUtils.registerProtectedBroadcastReceiver(context, null, ifilter);
if (batteryStatusIntent != null) {
// Default to 0, which the EXTRA_PLUGGED docs indicate means "on battery power". There
// is no symbolic constant. Nonzero values indicate we have some external power source.
int chargePlug = batteryStatusIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
// If we're not plugged, assume we're running on battery power.
onBatteryChargingChanged(chargePlug == 0);
}
IntentFilter powerConnectedFilter = new IntentFilter();
powerConnectedFilter.addAction(Intent.ACTION_POWER_CONNECTED);
powerConnectedFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
ContextUtils.registerProtectedBroadcastReceiver(context, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
PowerMonitor.onBatteryChargingChanged(
intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED));
}
}, powerConnectedFilter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
PowerManager powerManager =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (powerManager != null) {
PowerMonitorForQ.addThermalStatusListener(powerManager);
}
}
}
private PowerMonitor() {
}
private static void onBatteryChargingChanged(boolean isBatteryPower) {
assert sInstance != null;
sInstance.mIsBatteryPower = isBatteryPower;
PowerMonitorJni.get().onBatteryChargingChanged();
}
@CalledByNative
private static boolean isBatteryPower() {
// Creation of the PowerMonitor can be deferred based on the browser startup path. If the
// battery power is requested prior to the browser triggering the creation, force it to be
// created now.
if (sInstance == null) create();
return sInstance.mIsBatteryPower;
}
@CalledByNative
private static int getRemainingBatteryCapacity() {
// Creation of the PowerMonitor can be deferred based on the browser startup path. If the
// battery power is requested prior to the browser triggering the creation, force it to be
// created now.
if (sInstance == null) create();
return getRemainingBatteryCapacityImpl();
}
private static int getRemainingBatteryCapacityImpl() {
return ((BatteryManager) ContextUtils.getApplicationContext().getSystemService(
Context.BATTERY_SERVICE))
.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER);
}
@CalledByNative
private static int getCurrentThermalStatus() {
// Return invalid code that will get mapped to unknown in the native library.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return -1;
// Creation of the PowerMonitor can be deferred based on the browser startup path. If the
// battery power is requested prior to the browser triggering the creation, force it to be
// created now.
if (sInstance == null) create();
PowerManager powerManager =
(PowerManager) ContextUtils.getApplicationContext().getSystemService(
Context.POWER_SERVICE);
if (powerManager == null) return -1;
return ApiHelperForQ.getCurrentThermalStatus(powerManager);
}
@NativeMethods
interface Natives {
void onBatteryChargingChanged();
void onThermalStatusChanged(int thermalStatus);
}
}