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

Commit 43f09107 authored by Chandan Nath's avatar Chandan Nath Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE Add stop method to backup handler thread." into qt-r1-dev

parents c2f168ec 842369a8
Loading
Loading
Loading
Loading
+55 −8
Original line number Diff line number Diff line
@@ -166,6 +166,52 @@ import java.util.concurrent.atomic.AtomicInteger;

/** System service that performs backup/restore operations. */
public class UserBackupManagerService {
    /** Wrapper over {@link PowerManager.WakeLock} to prevent double-free exceptions on release()
     * after quit().
     * */
    public static class BackupWakeLock {
        private final PowerManager.WakeLock mPowerManagerWakeLock;
        private boolean mHasQuit = false;

        public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock) {
            mPowerManagerWakeLock = powerManagerWakeLock;
        }

        /** Acquires the {@link PowerManager.WakeLock} if hasn't been quit. */
        public synchronized void acquire() {
            if (mHasQuit) {
                Slog.v(TAG, "Ignore wakelock acquire after quit:" + mPowerManagerWakeLock.getTag());
                return;
            }
            mPowerManagerWakeLock.acquire();
        }

        /** Releases the {@link PowerManager.WakeLock} if hasn't been quit. */
        public synchronized void release() {
            if (mHasQuit) {
                Slog.v(TAG, "Ignore wakelock release after quit:" + mPowerManagerWakeLock.getTag());
                return;
            }
            mPowerManagerWakeLock.release();
        }

        /**
         * Returns true if the {@link PowerManager.WakeLock} has been acquired but not yet released.
         */
        public synchronized boolean isHeld() {
            return mPowerManagerWakeLock.isHeld();
        }

        /** Release the {@link PowerManager.WakeLock} till it isn't held. */
        public synchronized void quit() {
            while (mPowerManagerWakeLock.isHeld()) {
                Slog.v(TAG, "Releasing wakelock:" + mPowerManagerWakeLock.getTag());
                mPowerManagerWakeLock.release();
            }
            mHasQuit = true;
        }
    }

    // Persistently track the need to do a full init.
    private static final String INIT_SENTINEL_FILE_NAME = "_need_init_";

@@ -252,7 +298,6 @@ public class UserBackupManagerService {
    private final @UserIdInt int mUserId;
    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
    private final TransportManager mTransportManager;
    private final HandlerThread mUserBackupThread;

    private final Context mContext;
    private final PackageManager mPackageManager;
@@ -263,7 +308,7 @@ public class UserBackupManagerService {
    private final AlarmManager mAlarmManager;
    private final IStorageManager mStorageManager;
    private final BackupManagerConstants mConstants;
    private final PowerManager.WakeLock mWakelock;
    private final BackupWakeLock mWakelock;
    private final BackupHandler mBackupHandler;

    private final IBackupManager mBackupManagerBinder;
@@ -487,8 +532,7 @@ public class UserBackupManagerService {
        mAgentTimeoutParameters.start();

        checkNotNull(userBackupThread, "userBackupThread cannot be null");
        mUserBackupThread = userBackupThread;
        mBackupHandler = new BackupHandler(this, userBackupThread.getLooper());
        mBackupHandler = new BackupHandler(this, userBackupThread);

        // Set up our bookkeeping
        final ContentResolver resolver = context.getContentResolver();
@@ -588,7 +632,10 @@ public class UserBackupManagerService {
        mBackupHandler.postDelayed(this::parseLeftoverJournals, INITIALIZATION_DELAY_MILLIS);

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

        // Set up the various sorts of package tracking we do
        mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
@@ -608,7 +655,7 @@ public class UserBackupManagerService {
        mContext.unregisterReceiver(mRunBackupReceiver);
        mContext.unregisterReceiver(mRunInitReceiver);
        mContext.unregisterReceiver(mPackageTrackingReceiver);
        mUserBackupThread.quit();
        mBackupHandler.stop();
    }

    public @UserIdInt int getUserId() {
@@ -668,7 +715,7 @@ public class UserBackupManagerService {
        mSetupComplete = setupComplete;
    }

    public PowerManager.WakeLock getWakelock() {
    public BackupWakeLock getWakelock() {
        return mWakelock;
    }

@@ -679,7 +726,7 @@ public class UserBackupManagerService {
    @VisibleForTesting
    public void setWorkSource(@Nullable WorkSource workSource) {
        // TODO: This is for testing, unfortunately WakeLock is final and WorkSource is not exposed
        mWakelock.setWorkSource(workSource);
        mWakelock.mPowerManagerWakeLock.setWorkSource(workSource);
    }

    public Handler getBackupHandler() {
+31 −3
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import static com.android.server.backup.BackupManagerService.TAG;
import android.app.backup.RestoreSet;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -83,19 +83,47 @@ public class BackupHandler extends Handler {
    // backup task state machine tick
    public static final int MSG_BACKUP_RESTORE_STEP = 20;
    public static final int MSG_OP_COMPLETE = 21;
    // Release the wakelock. This is used to ensure we don't hold it after
    // a user is removed. This will also terminate the looper thread.
    public static final int MSG_STOP = 22;

    private final UserBackupManagerService backupManagerService;
    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;

    public BackupHandler(UserBackupManagerService backupManagerService, Looper looper) {
        super(looper);
    private final HandlerThread mBackupThread;
    private volatile boolean mIsStopping = false;

    public BackupHandler(
            UserBackupManagerService backupManagerService, HandlerThread backupThread) {
        super(backupThread.getLooper());
        mBackupThread = backupThread;
        this.backupManagerService = backupManagerService;
        mAgentTimeoutParameters = Preconditions.checkNotNull(
                backupManagerService.getAgentTimeoutParameters(),
                "Timeout parameters cannot be null");
    }

    /**
     * Put the BackupHandler into a stopping state where the remaining messages on the queue will be
     * silently dropped and the {@link WakeLock} held by the {@link UserBackupManagerService} will
     * then be released.
     */
    public void stop() {
        mIsStopping = true;
        sendMessage(obtainMessage(BackupHandler.MSG_STOP));
    }

    public void handleMessage(Message msg) {
        if (msg.what == MSG_STOP) {
            Slog.v(TAG, "Stopping backup handler");
            backupManagerService.getWakelock().quit();
            mBackupThread.quitSafely();
        }

        if (mIsStopping) {
            // If we're finishing all other types of messages should be ignored
            return;
        }

        TransportManager transportManager = backupManagerService.getTransportManager();
        switch (msg.what) {
+2 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import static com.android.server.backup.UserBackupManagerService.RUN_INITIALIZE_
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Slog;

import com.android.server.backup.UserBackupManagerService;
@@ -57,7 +56,8 @@ public class RunInitializeReceiver extends BroadcastReceiver {

                mUserBackupManagerService.clearPendingInits();

                PowerManager.WakeLock wakelock = mUserBackupManagerService.getWakelock();
                UserBackupManagerService.BackupWakeLock wakelock =
                        mUserBackupManagerService.getWakelock();
                wakelock.acquire();
                OnTaskFinishedListener listener = caller -> wakelock.release();

+2 −3
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.util.Slog;

import com.android.server.backup.TransportManager;
@@ -110,7 +109,7 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
            // comes in.
            mBackupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);

            PowerManager.WakeLock wakelock = mBackupManagerService.getWakelock();
            UserBackupManagerService.BackupWakeLock wakelock = mBackupManagerService.getWakelock();
            wakelock.acquire();

            // Prevent lambda from leaking 'this'
@@ -392,7 +391,7 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
        Handler backupHandler = mBackupManagerService.getBackupHandler();
        backupHandler.removeMessages(MSG_RESTORE_SESSION_TIMEOUT);

        PowerManager.WakeLock wakelock = mBackupManagerService.getWakelock();
        UserBackupManagerService.BackupWakeLock wakelock = mBackupManagerService.getWakelock();
        wakelock.acquire();
        if (MORE_DEBUG) {
            Slog.d(TAG, callerLogString);
+1 −2
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
@@ -184,7 +183,7 @@ public class KeyValueBackupTaskTest {
    private TransportData mTransport;
    private ShadowLooper mShadowBackupLooper;
    private Handler mBackupHandler;
    private PowerManager.WakeLock mWakeLock;
    private UserBackupManagerService.BackupWakeLock mWakeLock;
    private KeyValueBackupReporter mReporter;
    private PackageManager mPackageManager;
    private ShadowPackageManager mShadowPackageManager;
Loading