Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04782e27 authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by Android (Google) Code Review
Browse files

Merge "Added ACTION_BATTERY_LEVEL_CHANGED" into pi-dev

parents 911ac7b7 70e75430
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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";
+17 −0
Original line number Diff line number Diff line
@@ -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.
+18 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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" />
+60 −10
Original line number Diff line number Diff line
@@ -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() {