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

Commit dd5e5e35 authored by Ruslan Tkhakokhov's avatar Ruslan Tkhakokhov
Browse files

BroadcastReceiver in UserBackupManagerService can crash system_server

Make sure mBroadcastReceiver is initialized after its dependencies,
i.e. mTransportManager.

Bug: 130408863
Test: 1) atest RunBackupFrameworksServicesRoboTests
      2) atest CtsBackupTestCases
      3) atest CtsBackupHostTestCases
      4) atest GtsBackupTestCases
      5) atest GtsBackupHostTestCases

Manual test:
1) Before fix: Add Thread.sleep() before mTransportManager is
initialized in constructor and tirgger PACKAGE_CHANGED event. Verify
broadcast receiver callback is triggered and systen_process crashes.
2) After fix: Add Thread.sleep() before mTransportManager is
initialized in constructor and tirgger PACKAGE_CHANGED event. Verify
broadcast receiver callback is not triggered.

Change-Id: If1628628176a08a2d33d020ce270de92b606d6df
parent a29d4340
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -566,10 +566,6 @@ public class UserBackupManagerService {
        // require frequent starting and stopping.
        mConstants.start();

        // Set up the various sorts of package tracking we do
        mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
        initPackageTracking();

        // Build our mapping of uid to backup client services.  This implicitly
        // schedules a backup pass on the Package Manager metadata the first
        // time anything needs to be backed up.
@@ -589,6 +585,10 @@ public class UserBackupManagerService {

        // Power management
        mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*-" + userId);

        // Set up the various sorts of package tracking we do
        mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
        initPackageTracking();
    }

    void initializeBackupEnableState() {
@@ -744,6 +744,11 @@ public class UserBackupManagerService {
        return mDataDir;
    }

    @VisibleForTesting
    BroadcastReceiver getPackageTrackingReceiver() {
        return mBroadcastReceiver;
    }

    @Nullable
    public DataChangedJournal getJournal() {
        return mJournal;
+29 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
@@ -38,6 +39,7 @@ import static org.testng.Assert.expectThrows;
import android.app.backup.BackupManager;
import android.app.backup.IBackupObserver;
import android.app.backup.ISelectBackupTransportCallback;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
@@ -48,6 +50,7 @@ import android.os.Binder;
import android.os.HandlerThread;
import android.os.PowerManager;
import android.os.PowerSaveState;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;

@@ -66,6 +69,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -1130,6 +1134,31 @@ public class UserBackupManagerServiceTest {
                                /* transportManager */ null));
    }

    /**
     * Test verifying that creating a new instance registers the broadcast receiver for package
     * tracking
     */
    @Test
    public void testCreateAndInitializeService_registersPackageTrackingReceiver() throws Exception {
        Context contextSpy = Mockito.spy(mContext);

        UserBackupManagerService service = UserBackupManagerService.createAndInitializeService(
                USER_ID,
                contextSpy,
                new Trampoline(mContext),
                mBackupThread,
                mBaseStateDir,
                mDataDir,
                mTransportManager);

        BroadcastReceiver packageTrackingReceiver = service.getPackageTrackingReceiver();
        assertThat(packageTrackingReceiver).isNotNull();

        // One call for package changes and one call for sd card events.
        verify(contextSpy, times(2)).registerReceiverAsUser(
                eq(packageTrackingReceiver), eq(UserHandle.of(USER_ID)), any(), any(), any());
    }

    private UserBackupManagerService createUserBackupManagerServiceAndRunTasks() {
        return BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks(
                USER_ID, mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager);