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

Commit 5f9a1d65 authored by Robert Horvath's avatar Robert Horvath Committed by David Zhao
Browse files

Send LowPowerStandby broadcasts also to receivers holding permission

In addition to registered receivers, also send the Low Power Standby
broadcasts to any receiver (manifest or registered) if its package is
holding the permission MANAGE_LOW_POWER_STANDBY.
Privileged apps may have to react to MANAGE_LOW_POWER_STANDBY, and they
should not have to be running at all times to do so.

Bug: 274427730
Test: atest LowPowerStandbyControllerTest
Change-Id: Id7667c0dee4177870f0520055991e9af63a17532
parent 7ab7a215
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.os;

import android.annotation.FlaggedApi;
import android.Manifest.permission;
import android.annotation.CallbackExecutor;
import android.annotation.CurrentTimeMillisLong;
@@ -3103,7 +3102,8 @@ public final class PowerManager {

    /**
     * Intent that is broadcast when Low Power Standby is enabled or disabled.
     * This broadcast is only sent to registered receivers.
     * This broadcast is only sent to registered receivers and receivers holding
     * {@code android.permission.MANAGE_LOW_POWER_STANDBY}.
     *
     * @see #isLowPowerStandbyEnabled()
     */
@@ -3113,7 +3113,8 @@ public final class PowerManager {

    /**
     * Intent that is broadcast when Low Power Standby policy is changed.
     * This broadcast is only sent to registered receivers.
     * This broadcast is only sent to registered receivers and receivers holding
     * {@code android.permission.MANAGE_LOW_POWER_STANDBY}.
     *
     * @see #isExemptFromLowPowerStandby()
     * @see #isAllowedInLowPowerStandby(int)
@@ -3125,7 +3126,6 @@ public final class PowerManager {

    /**
     * Intent that is broadcast when Low Power Standby exempt ports change.
     * This broadcast is only sent to registered receivers.
     *
     * @see #getActiveLowPowerStandbyPorts
     * @hide
+29 −8
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
@@ -146,6 +147,7 @@ public class LowPowerStandbyController {
            this::onStandbyTimeoutExpired;
    private final LowPowerStandbyControllerInternal mLocalService = new LocalService();
    private final SparseIntArray mUidAllowedReasons = new SparseIntArray();
    private final List<String> mLowPowerStandbyManagingPackages = new ArrayList<>();
    private final List<StandbyPortsLock> mStandbyPortLocks = new ArrayList<>();

    @GuardedBy("mLock")
@@ -370,6 +372,14 @@ public class LowPowerStandbyController {
                return;
            }

            List<PackageInfo> manageLowPowerStandbyPackages = mContext.getPackageManager()
                    .getPackagesHoldingPermissions(new String[]{
                            Manifest.permission.MANAGE_LOW_POWER_STANDBY
                    }, PackageManager.MATCH_SYSTEM_ONLY);
            for (PackageInfo packageInfo : manageLowPowerStandbyPackages) {
                mLowPowerStandbyManagingPackages.add(packageInfo.packageName);
            }

            mAlarmManager = mContext.getSystemService(AlarmManager.class);
            mPowerManager = mContext.getSystemService(PowerManager.class);
            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -756,9 +766,7 @@ public class LowPowerStandbyController {
            Slog.d(TAG, "notifyEnabledChangedLocked, mIsEnabled=" + mIsEnabled);
        }

        final Intent intent = new Intent(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
        sendExplicitBroadcast(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
    }

    @GuardedBy("mLock")
@@ -772,10 +780,7 @@ public class LowPowerStandbyController {
            Slog.d(TAG, "notifyPolicyChanged, policy=" + policy);
        }

        final Intent intent = new Intent(
                PowerManager.ACTION_LOW_POWER_STANDBY_POLICY_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
        sendExplicitBroadcast(PowerManager.ACTION_LOW_POWER_STANDBY_POLICY_CHANGED);
    }

    private void onStandbyTimeoutExpired() {
@@ -787,6 +792,22 @@ public class LowPowerStandbyController {
        }
    }

    private void sendExplicitBroadcast(String intentType) {
        final Intent intent = new Intent(intentType);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);

        // Send explicit broadcast to holders of MANAGE_LOW_POWER_STANDBY
        final Intent privilegedIntent = new Intent(intentType);
        privilegedIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        for (String packageName : mLowPowerStandbyManagingPackages) {
            final Intent explicitIntent = new Intent(privilegedIntent);
            explicitIntent.setPackage(packageName);
            mContext.sendBroadcastAsUser(explicitIntent, UserHandle.ALL,
                    Manifest.permission.MANAGE_LOW_POWER_STANDBY);
        }
    }

    @GuardedBy("mLock")
    private void enqueueNotifyActiveChangedLocked() {
        final Message msg = mHandler.obtainMessage(MSG_NOTIFY_ACTIVE_CHANGED, mIsActive);
@@ -1360,7 +1381,7 @@ public class LowPowerStandbyController {
        }

        final Intent intent = new Intent(PowerManager.ACTION_LOW_POWER_STANDBY_PORTS_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                Manifest.permission.MANAGE_LOW_POWER_STANDBY);
    }