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

Commit 46bc34d2 authored by Harshit Mahajan's avatar Harshit Mahajan
Browse files

Adding BroadcastReceiver for REBOOT and SHUTDOWN

Instead of calling writeNow() from PackageManagerService, we can
register a BroadcastReceiver for REBOOT and SHUTDOWN

Bug: 338468233
Test: atest PackageWatchdogTest; verified that broadcast is received.
Flag: android.crashrecovery.flags.refactor_crashrecovery
Change-Id: I2c4f3f0863fb1fed91f89969d7fde24a4ea7196c
parent b92f17c6
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -16,13 +16,18 @@

package com.android.server;

import static android.content.Intent.ACTION_REBOOT;
import static android.content.Intent.ACTION_SHUTDOWN;
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
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.VersionedPackage;
@@ -2001,6 +2006,31 @@ public class PackageWatchdog {
                }
            }
        }
    }

    /**
     * Register broadcast receiver for shutdown.
     * We would save the observer state to persist across boots.
     *
     * @hide
     */
    public void registerShutdownBroadcastReceiver() {
        BroadcastReceiver shutdownEventReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // Only write if intent is relevant to device reboot or shutdown.
                String intentAction = intent.getAction();
                if (ACTION_REBOOT.equals(intentAction)
                        || ACTION_SHUTDOWN.equals(intentAction)) {
                    writeNow();
                }
            }
        };

        // Setup receiver for device reboots or shutdowns.
        IntentFilter filter = new IntentFilter(ACTION_REBOOT);
        filter.addAction(ACTION_SHUTDOWN);
        mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null,
                /* run on main thread */ null);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public class CrashRecoveryModule {
        @Override
        public void onStart() {
            RescueParty.registerHealthObserver(mSystemContext);
            mPackageWatchdog.registerShutdownBroadcastReceiver();
            mPackageWatchdog.noteBoot();
        }

+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.crashrecovery.flags.Flags.refactorCrashrecovery;
import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
@@ -3037,7 +3038,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mCompilerStats.writeNow();
        mDexManager.writePackageDexUsageNow();
        mDynamicCodeLogger.writeNow();
        if (!refactorCrashrecovery()) {
            PackageWatchdog.getInstance(mContext).writeNow();
        }

        synchronized (mLock) {
            mPackageUsage.writeNow(mSettings.getPackagesLocked());
+2 −0
Original line number Diff line number Diff line
@@ -84,8 +84,10 @@ public class CrashRecoveryModuleTest {
    @Test
    public void testLifecycleServiceStart() {
        mLifecycle.onStart();
        doNothing().when(mPackageWatchdog).registerShutdownBroadcastReceiver();

        verify(mPackageWatchdog, times(1)).noteBoot();
        verify(mPackageWatchdog, times(1)).registerShutdownBroadcastReceiver();
        ExtendedMockito.verify(() -> RescueParty.registerHealthObserver(any()),
                Mockito.times(1));
    }
+18 −0
Original line number Diff line number Diff line
@@ -23,9 +23,12 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -33,6 +36,7 @@ import static org.mockito.Mockito.when;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
@@ -116,6 +120,7 @@ public class PackageWatchdogTest {
    private ConnectivityModuleConnector mConnectivityModuleConnector;
    @Mock
    private PackageManager mMockPackageManager;
    @Mock Intent mMockIntent;
    // Mock only sysprop apis
    private PackageWatchdog.BootThreshold mSpyBootThreshold;
    @Captor
@@ -1669,6 +1674,19 @@ public class PackageWatchdogTest {
                PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS);
    }

    /**
     * Tests device config changes are propagated correctly.
     */
    @Test
    public void testRegisterShutdownBroadcastReceiver() {
        PackageWatchdog watchdog = createWatchdog();
        doReturn(mMockIntent).when(mSpyContext)
                .registerReceiverForAllUsers(any(), any(), any(), any());

        watchdog.registerShutdownBroadcastReceiver();
        verify(mSpyContext).registerReceiverForAllUsers(any(), any(), eq(null), eq(null));
    }

    private void adoptShellPermissions(String... permissions) {
        InstrumentationRegistry
                .getInstrumentation()