Merge "Added ACTION_BATTERY_LEVEL_CHANGED" into pi-dev

This commit is contained in:
Fyodor Kupolov
2018-03-10 00:14:11 +00:00
committed by Android (Google) Code Review
5 changed files with 102 additions and 10 deletions

View File

@@ -840,6 +840,7 @@ package android.content {
}
public class Intent implements java.lang.Cloneable android.os.Parcelable {
field public static final java.lang.String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED";
field public static final java.lang.String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
field public static final java.lang.String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
field public static final java.lang.String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET";
@@ -3612,6 +3613,11 @@ package android.nfc {
package android.os {
public class BatteryManager {
field public static final java.lang.String EXTRA_EVENTS = "android.os.extra.EVENTS";
field public static final java.lang.String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP";
}
public final class ConfigUpdate {
field public static final java.lang.String ACTION_UPDATE_CARRIER_PROVISIONING_URLS = "android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS";
field public static final java.lang.String ACTION_UPDATE_CT_LOGS = "android.intent.action.UPDATE_CT_LOGS";

View File

@@ -2448,6 +2448,23 @@ public class Intent implements Parcelable, Cloneable {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
/**
* Broadcast Action: Sent when the current battery level changes.
*
* It has {@link android.os.BatteryManager#EXTRA_EVENTS} that carries a list of {@link Bundle}
* instances representing individual battery level changes with associated
* extras from {@link #ACTION_BATTERY_CHANGED}.
*
* <p class="note">
* This broadcast requires {@link android.Manifest.permission#BATTERY_STATS} permission.
*
* @hide
*/
@SystemApi
public static final String ACTION_BATTERY_LEVEL_CHANGED =
"android.intent.action.BATTERY_LEVEL_CHANGED";
/**
* Broadcast Action: Indicates low battery condition on the device.
* This broadcast corresponds to the "Low battery warning" system dialog.

View File

@@ -16,6 +16,7 @@
package android.os;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.content.Intent;
@@ -138,6 +139,23 @@ public class BatteryManager {
*/
public static final String EXTRA_SEQUENCE = "seq";
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED}:
* Contains list of Bundles representing battery events
* @hide
*/
@SystemApi
public static final String EXTRA_EVENTS = "android.os.extra.EVENTS";
/**
* Extra for event in {@link android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED}:
* Long value representing time when event occurred as returned by
* {@link android.os.SystemClock#elapsedRealtime()}
* @hide
*/
@SystemApi
public static final String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP";
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = Constants.BATTERY_STATUS_UNKNOWN;
public static final int BATTERY_STATUS_CHARGING = Constants.BATTERY_STATUS_CHARGING;

View File

@@ -56,6 +56,7 @@
<protected-broadcast android:name="android.intent.action.SPLIT_CONFIGURATION_CHANGED" />
<protected-broadcast android:name="android.intent.action.LOCALE_CHANGED" />
<protected-broadcast android:name="android.intent.action.BATTERY_CHANGED" />
<protected-broadcast android:name="android.intent.action.BATTERY_LEVEL_CHANGED" />
<protected-broadcast android:name="android.intent.action.BATTERY_LOW" />
<protected-broadcast android:name="android.intent.action.BATTERY_OKAY" />
<protected-broadcast android:name="android.intent.action.ACTION_POWER_CONNECTED" />

View File

@@ -20,6 +20,7 @@ import android.app.ActivityManagerInternal;
import android.database.ContentObserver;
import android.os.BatteryStats;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -35,7 +36,6 @@ import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.hardware.health.V1_0.HealthInfo;
@@ -73,6 +73,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
@@ -117,6 +119,8 @@ public final class BatteryService extends SystemService {
private static final int BATTERY_SCALE = 100; // battery capacity is a percentage
private static final long HEALTH_HAL_WAIT_MS = 1000;
private static final long BATTERY_LEVEL_CHANGE_THROTTLE_MS = 60_000;
private static final int MAX_BATTERY_LEVELS_QUEUE_SIZE = 100;
// Used locally for determining when to make a last ditch effort to log
// discharge stats before the device dies.
@@ -178,7 +182,8 @@ public final class BatteryService extends SystemService {
private HealthServiceWrapper mHealthServiceWrapper;
private HealthHalCallback mHealthHalCallback;
private BatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
private HandlerThread mHandlerThread;
private ArrayDeque<Bundle> mBatteryLevelsEventQueue;
private long mLastBatteryLevelChangedSentMs;
public BatteryService(Context context) {
super(context);
@@ -198,6 +203,8 @@ public final class BatteryService extends SystemService {
mShutdownBatteryTemperature = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shutdownBatteryTemperature);
mBatteryLevelsEventQueue = new ArrayDeque<>();
// watch for invalid charger messages if the invalid_charger switch exists
if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
UEventObserver invalidChargerObserver = new UEventObserver() {
@@ -585,7 +592,11 @@ public final class BatteryService extends SystemService {
// We are doing this after sending the above broadcasts, so anything processing
// them will get the new sequence number at that point. (See for example how testing
// of JobScheduler's BatteryController works.)
sendIntentLocked();
sendBatteryChangedIntentLocked();
if (mLastBatteryLevel != mHealthInfo.batteryLevel) {
sendBatteryLevelChangedIntentLocked();
}
// Update the battery LED
mLed.updateLightsLocked();
@@ -610,7 +621,7 @@ public final class BatteryService extends SystemService {
}
}
private void sendIntentLocked() {
private void sendBatteryChangedIntentLocked() {
// Pack up the values and broadcast them to everyone
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -639,12 +650,51 @@ public final class BatteryService extends SystemService {
+ ", info:" + mHealthInfo.toString());
}
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
}
});
mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL));
}
private void sendBatteryLevelChangedIntentLocked() {
Bundle event = new Bundle();
long now = SystemClock.elapsedRealtime();
event.putInt(BatteryManager.EXTRA_SEQUENCE, mSequence);
event.putInt(BatteryManager.EXTRA_STATUS, mHealthInfo.batteryStatus);
event.putInt(BatteryManager.EXTRA_HEALTH, mHealthInfo.batteryHealth);
event.putBoolean(BatteryManager.EXTRA_PRESENT, mHealthInfo.batteryPresent);
event.putInt(BatteryManager.EXTRA_LEVEL, mHealthInfo.batteryLevel);
event.putBoolean(BatteryManager.EXTRA_BATTERY_LOW, mSentLowBatteryBroadcast);
event.putInt(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
event.putInt(BatteryManager.EXTRA_PLUGGED, mPlugType);
event.putInt(BatteryManager.EXTRA_VOLTAGE, mHealthInfo.batteryVoltage);
event.putLong(BatteryManager.EXTRA_EVENT_TIMESTAMP, now);
boolean queueWasEmpty = mBatteryLevelsEventQueue.isEmpty();
mBatteryLevelsEventQueue.add(event);
// Make sure queue is bounded and doesn't exceed intent payload limits
if (mBatteryLevelsEventQueue.size() > MAX_BATTERY_LEVELS_QUEUE_SIZE) {
mBatteryLevelsEventQueue.removeFirst();
}
if (queueWasEmpty) {
// send now if last event was before throttle interval, otherwise delay
long delay = now - mLastBatteryLevelChangedSentMs > BATTERY_LEVEL_CHANGE_THROTTLE_MS
? 0 : mLastBatteryLevelChangedSentMs + BATTERY_LEVEL_CHANGE_THROTTLE_MS - now;
mHandler.postDelayed(this::sendEnqueuedBatteryLevelChangedEvents, delay);
}
}
private void sendEnqueuedBatteryLevelChangedEvents() {
ArrayList<Bundle> events;
synchronized (mLock) {
events = new ArrayList<>(mBatteryLevelsEventQueue);
mBatteryLevelsEventQueue.clear();
}
final Intent intent = new Intent(Intent.ACTION_BATTERY_LEVEL_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
intent.putParcelableArrayListExtra(BatteryManager.EXTRA_EVENTS, events);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.BATTERY_STATS);
mLastBatteryLevelChangedSentMs = SystemClock.elapsedRealtime();
}
private void logBatteryStatsLocked() {