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

Commit 0daa76ed authored by Hui Yu's avatar Hui Yu
Browse files

Exempt some broadcasts from FGS start restriction.

1. Exempt broadcasts ACTION_TIMEZONE_CHANGED, ACTION_TIME_CHANGED, ACTION_LOCALE_CHANGED
from FGS start restriction.
2. Add test case AlarmManagerServiceTest#setTimeZoneImpl.

Bug: 184111171
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
Change-Id: I80ce830d1bd98d69f35fdc6bcc041de173083fba
parent a7c3e113
Loading
Loading
Loading
Loading
+24 −1
Original line number Original line Diff line number Diff line
@@ -236,7 +236,21 @@ public class PowerExemptionManager {
     * @hide
     * @hide
     */
     */
    public static final int REASON_BLUETOOTH_BROADCAST = 203;
    public static final int REASON_BLUETOOTH_BROADCAST = 203;

    /**
     * Broadcast {@link android.content.Intent#ACTION_TIMEZONE_CHANGED}
     * @hide
     */
    public static final int REASON_TIMEZONE_CHANGED = 204;
    /**
     * Broadcast {@link android.content.Intent#ACTION_TIME_CHANGED}
     * @hide
     */
    public static final int REASON_TIME_CHANGED = 205;
    /**
     * Broadcast {@link android.content.Intent#ACTION_LOCALE_CHANGED}
     * @hide
     */
    public static final int REASON_LOCALE_CHANGED = 206;
    /* Reason code range 300-399 are reserved for other internal reasons */
    /* Reason code range 300-399 are reserved for other internal reasons */
    /**
    /**
     * Device idle system allow list, including EXCEPT-IDLE
     * Device idle system allow list, including EXCEPT-IDLE
@@ -369,6 +383,9 @@ public class PowerExemptionManager {
            REASON_PRE_BOOT_COMPLETED,
            REASON_PRE_BOOT_COMPLETED,
            REASON_LOCKED_BOOT_COMPLETED,
            REASON_LOCKED_BOOT_COMPLETED,
            REASON_BLUETOOTH_BROADCAST,
            REASON_BLUETOOTH_BROADCAST,
            REASON_TIMEZONE_CHANGED,
            REASON_TIME_CHANGED,
            REASON_LOCALE_CHANGED,
            REASON_SYSTEM_ALLOW_LISTED,
            REASON_SYSTEM_ALLOW_LISTED,
            REASON_ALARM_MANAGER_ALARM_CLOCK,
            REASON_ALARM_MANAGER_ALARM_CLOCK,
            REASON_ALARM_MANAGER_WHILE_IDLE,
            REASON_ALARM_MANAGER_WHILE_IDLE,
@@ -641,6 +658,12 @@ public class PowerExemptionManager {
                return "LOCKED_BOOT_COMPLETED";
                return "LOCKED_BOOT_COMPLETED";
            case REASON_BLUETOOTH_BROADCAST:
            case REASON_BLUETOOTH_BROADCAST:
                return "BLUETOOTH_BROADCAST";
                return "BLUETOOTH_BROADCAST";
            case REASON_TIMEZONE_CHANGED:
                return "TIMEZONE_CHANGED";
            case REASON_TIME_CHANGED:
                return "TIME_CHANGED";
            case REASON_LOCALE_CHANGED:
                return "LOCALE_CHANGED";
            case REASON_SYSTEM_ALLOW_LISTED:
            case REASON_SYSTEM_ALLOW_LISTED:
                return "SYSTEM_ALLOW_LISTED";
                return "SYSTEM_ALLOW_LISTED";
            case REASON_ALARM_MANAGER_ALARM_CLOCK:
            case REASON_ALARM_MANAGER_ALARM_CLOCK:
+15 −3
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.app.AlarmManager.INTERVAL_HOUR;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE;
import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
@@ -81,6 +82,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.ParcelableException;
import android.os.ParcelableException;
import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
@@ -293,6 +295,7 @@ public class AlarmManagerService extends SystemService {


    BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic();
    BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic();
    BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic();
    BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic();
    BroadcastOptions mOptsTimeBroadcast = BroadcastOptions.makeBasic();


    // TODO(b/172085676): Move inside alarm store.
    // TODO(b/172085676): Move inside alarm store.
    private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
    private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
@@ -1745,7 +1748,12 @@ public class AlarmManagerService extends SystemService {
                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
            intent.putExtra(Intent.EXTRA_TIMEZONE, zone.getID());
            intent.putExtra(Intent.EXTRA_TIMEZONE, zone.getID());
            getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
            mOptsTimeBroadcast.setTemporaryAppAllowlist(
                    mActivityManagerInternal.getBootTimeTempAllowListDuration(),
                    TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                    PowerExemptionManager.REASON_TIMEZONE_CHANGED, "");
            getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                    null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
        }
        }
    }
    }


@@ -3899,8 +3907,12 @@ public class AlarmManagerService extends SystemService {
                                | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                                | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                        getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
                        mOptsTimeBroadcast.setTemporaryAppAllowlist(

                                mActivityManagerInternal.getBootTimeTempAllowListDuration(),
                                TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                                PowerExemptionManager.REASON_TIME_CHANGED, "");
                        getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                                null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
                        // The world has changed on us, so we need to re-evaluate alarms
                        // The world has changed on us, so we need to re-evaluate alarms
                        // regardless of whether the kernel has told us one went off.
                        // regardless of whether the kernel has told us one went off.
                        result |= IS_WAKEUP_MASK;
                        result |= IS_WAKEUP_MASK;
+5 −1
Original line number Original line Diff line number Diff line
@@ -15831,8 +15831,12 @@ public class ActivityManagerService extends IActivityManager.Stub
                    if (initLocale || !mProcessesReady) {
                    if (initLocale || !mProcessesReady) {
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    }
                    }
                    final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
                    bOptions.setTemporaryAppAllowlist(mInternal.getBootTimeTempAllowListDuration(),
                            TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                            PowerExemptionManager.REASON_LOCALE_CHANGED, "");
                    broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null,
                    broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null,
                            null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                            null, OP_NONE, bOptions.toBundle(), false, false, MY_PID, SYSTEM_UID,
                            Binder.getCallingUid(), Binder.getCallingPid(),
                            Binder.getCallingUid(), Binder.getCallingPid(),
                            UserHandle.USER_ALL);
                            UserHandle.USER_ALL);
                }
                }
+21 −0
Original line number Original line Diff line number Diff line
@@ -127,9 +127,11 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig;
@@ -367,6 +369,7 @@ public class AlarmManagerServiceTest {
                .mockStatic(MetricsHelper.class)
                .mockStatic(MetricsHelper.class)
                .mockStatic(Settings.Global.class)
                .mockStatic(Settings.Global.class)
                .mockStatic(ServiceManager.class)
                .mockStatic(ServiceManager.class)
                .mockStatic(SystemProperties.class)
                .spyStatic(UserHandle.class)
                .spyStatic(UserHandle.class)
                .strictness(Strictness.WARN)
                .strictness(Strictness.WARN)
                .startMocking();
                .startMocking();
@@ -2536,6 +2539,24 @@ public class AlarmManagerServiceTest {
        verify(() -> MetricsHelper.pushAlarmBatchDelivered(10, 5));
        verify(() -> MetricsHelper.pushAlarmBatchDelivered(10, 5));
    }
    }


    @Test
    public void setTimeZoneImpl() {
        final long durationMs = 20000L;
        when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
        mService.setTimeZoneImpl("UTC");
        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(mMockContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
                isNull(), bundleCaptor.capture());
        assertEquals(Intent.ACTION_TIMEZONE_CHANGED, intentCaptor.getValue().getAction());
        final BroadcastOptions bOptions = new BroadcastOptions(bundleCaptor.getValue());
        assertEquals(durationMs, bOptions.getTemporaryAppAllowlistDuration());
        assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                bOptions.getTemporaryAppAllowlistType());
        assertEquals(PowerExemptionManager.REASON_TIMEZONE_CHANGED,
                bOptions.getTemporaryAppAllowlistReasonCode());
    }

    @After
    @After
    public void tearDown() {
    public void tearDown() {
        if (mMockingSession != null) {
        if (mMockingSession != null) {