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

Commit 59c766b9 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Send only the latest battery change events." into main

parents 49cfa63d a7502ea9
Loading
Loading
Loading
Loading
+135 −34
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import static com.android.server.health.Utils.copyV1Battery;

import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -67,6 +68,7 @@ import android.util.proto.ProtoOutputStream;

import com.android.internal.app.IBatteryStats;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.DumpUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.health.HealthServiceWrapper;
@@ -207,18 +209,18 @@ public final class BatteryService extends SystemService {
    private final CopyOnWriteArraySet<BatteryManagerInternal.ChargingPolicyChangeListener>
            mChargingPolicyChangeListeners = new CopyOnWriteArraySet<>();

    private Bundle mBatteryChangedOptions = BroadcastOptions.makeBasic()
    private static final Bundle BATTERY_CHANGED_OPTIONS = BroadcastOptions.makeBasic()
            .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
            .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
            .toBundle();
    /** Used for both connected/disconnected, so match using key */
    private Bundle mPowerOptions = BroadcastOptions.makeBasic()
    private static final Bundle POWER_OPTIONS = BroadcastOptions.makeBasic()
            .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
            .setDeliveryGroupMatchingKey("android", Intent.ACTION_POWER_CONNECTED)
            .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
            .toBundle();
    /** Used for both low/okay, so match using key */
    private Bundle mBatteryOptions = BroadcastOptions.makeBasic()
    private static final Bundle BATTERY_OPTIONS = BroadcastOptions.makeBasic()
            .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
            .setDeliveryGroupMatchingKey("android", Intent.ACTION_BATTERY_OKAY)
            .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
@@ -226,11 +228,60 @@ public final class BatteryService extends SystemService {

    private MetricsLogger mMetricsLogger;

    private static final int MSG_BROADCAST_BATTERY_CHANGED = 1;
    private static final int MSG_BROADCAST_POWER_CONNECTION_CHANGED = 2;
    private static final int MSG_BROADCAST_BATTERY_LOW_OKAY = 3;

    private final Handler.Callback mLocalCallback = msg -> {
        switch (msg.what) {
            case MSG_BROADCAST_BATTERY_CHANGED: {
                final SomeArgs args = (SomeArgs) msg.obj;
                final Context context;
                final Intent intent;
                try {
                    context = (Context) args.arg1;
                    intent = (Intent) args.arg2;
                } finally {
                    args.recycle();
                }
                broadcastBatteryChangedIntent(context, intent, BATTERY_CHANGED_OPTIONS);
                return true;
            }
            case MSG_BROADCAST_POWER_CONNECTION_CHANGED: {
                final SomeArgs args = (SomeArgs) msg.obj;
                final Context context;
                final Intent intent;
                try {
                    context = (Context) args.arg1;
                    intent = (Intent) args.arg2;
                } finally {
                    args.recycle();
                }
                sendBroadcastToAllUsers(context, intent, POWER_OPTIONS);
                return true;
            }
            case MSG_BROADCAST_BATTERY_LOW_OKAY: {
                final SomeArgs args = (SomeArgs) msg.obj;
                final Context context;
                final Intent intent;
                try {
                    context = (Context) args.arg1;
                    intent = (Intent) args.arg2;
                } finally {
                    args.recycle();
                }
                sendBroadcastToAllUsers(context, intent, BATTERY_OPTIONS);
                return true;
            }
        }
        return false;
    };

    public BatteryService(Context context) {
        super(context);

        mContext = context;
        mHandler = new Handler(true /*async*/);
        mHandler = new Handler(mLocalCallback, true /*async*/);
        mLed = new Led(context, getLocalService(LightsManager.class));
        mBatteryStats = BatteryStatsService.getService();
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -660,53 +711,89 @@ public final class BatteryService extends SystemService {
                final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
                if (com.android.server.flags.Flags.consolidateBatteryChangeEvents()) {
                    mHandler.removeMessages(MSG_BROADCAST_POWER_CONNECTION_CHANGED);
                    final SomeArgs args = SomeArgs.obtain();
                    args.arg1 = mContext;
                    args.arg2 = statusIntent;
                    mHandler.obtainMessage(MSG_BROADCAST_POWER_CONNECTION_CHANGED, args)
                            .sendToTarget();
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL, null,
                                mPowerOptions);
                                    POWER_OPTIONS);
                        }
                    });
                }
            }
            else if (mPlugType == 0 && mLastPlugType != 0) {
                final Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
                if (com.android.server.flags.Flags.consolidateBatteryChangeEvents()) {
                    mHandler.removeMessages(MSG_BROADCAST_POWER_CONNECTION_CHANGED);
                    final SomeArgs args = SomeArgs.obtain();
                    args.arg1 = mContext;
                    args.arg2 = statusIntent;
                    mHandler.obtainMessage(MSG_BROADCAST_POWER_CONNECTION_CHANGED, args)
                            .sendToTarget();
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL, null,
                                mPowerOptions);
                                    POWER_OPTIONS);
                        }
                    });
                }
            }

            if (shouldSendBatteryLowLocked()) {
                mSentLowBatteryBroadcast = true;
                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
                if (com.android.server.flags.Flags.consolidateBatteryChangeEvents()) {
                    mHandler.removeMessages(MSG_BROADCAST_BATTERY_LOW_OKAY);
                    final SomeArgs args = SomeArgs.obtain();
                    args.arg1 = mContext;
                    args.arg2 = statusIntent;
                    mHandler.obtainMessage(MSG_BROADCAST_BATTERY_LOW_OKAY, args)
                            .sendToTarget();
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL, null,
                                mBatteryOptions);
                                    BATTERY_OPTIONS);
                        }
                    });
                }
            } else if (mSentLowBatteryBroadcast &&
                    mHealthInfo.batteryLevel >= mLowBatteryCloseWarningLevel) {
                mSentLowBatteryBroadcast = false;
                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
                if (com.android.server.flags.Flags.consolidateBatteryChangeEvents()) {
                    mHandler.removeMessages(MSG_BROADCAST_BATTERY_LOW_OKAY);
                    final SomeArgs args = SomeArgs.obtain();
                    args.arg1 = mContext;
                    args.arg2 = statusIntent;
                    mHandler.obtainMessage(MSG_BROADCAST_BATTERY_LOW_OKAY, args)
                            .sendToTarget();
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL, null,
                                mBatteryOptions);
                                    BATTERY_OPTIONS);
                        }
                    });
                }
            }

            // 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
@@ -777,8 +864,16 @@ public final class BatteryService extends SystemService {
                    + ", info:" + mHealthInfo.toString());
        }

        if (com.android.server.flags.Flags.consolidateBatteryChangeEvents()) {
            mHandler.removeMessages(MSG_BROADCAST_BATTERY_CHANGED);
            final SomeArgs args = SomeArgs.obtain();
            args.arg1 = mContext;
            args.arg2 = intent;
            mHandler.obtainMessage(MSG_BROADCAST_BATTERY_CHANGED, args).sendToTarget();
        } else {
            mHandler.post(() -> broadcastBatteryChangedIntent(mContext,
                intent, mBatteryChangedOptions));
                    intent, BATTERY_CHANGED_OPTIONS));
        }
    }

    private static void broadcastBatteryChangedIntent(Context context, Intent intent,
@@ -1307,6 +1402,12 @@ public final class BatteryService extends SystemService {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    @SuppressLint("AndroidFrameworkRequiresPermission")
    private static void sendBroadcastToAllUsers(Context context, Intent intent,
            Bundle options) {
        context.sendBroadcastAsUser(intent, UserHandle.ALL, null, options);
    }

    private final class Led {
        // must match: config_notificationsBatteryLowBehavior in config.xml
        static final int LOW_BATTERY_BEHAVIOR_DEFAULT = 0;
+11 −0
Original line number Diff line number Diff line
@@ -45,3 +45,14 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    namespace: "backstage_power"
    name: "consolidate_battery_change_events"
    description: "Optimize battery status updates by delivering only the most recent battery information"
    bug: "361334584"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}