Loading services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java +27 −25 Original line number Diff line number Diff line Loading @@ -1086,15 +1086,14 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter } /** * Maintain persistent state around whether need to do an initialize operation. * Must be called with the queue lock held. * Maintain persistent state around whether need to do an initialize operation. This will lock * on {@link #getQueueLock()}. */ @GuardedBy("mQueueLock") public void recordInitPendingLocked( public void recordInitPending( boolean isPending, String transportName, String transportDirName) { synchronized (mQueueLock) { if (MORE_DEBUG) { Slog.i(TAG, "recordInitPendingLocked: " + isPending + " on transport " + transportName); Slog.i(TAG, "recordInitPending(" + isPending + ") on transport " + transportName); } File stateDir = new File(mBaseStateDir, transportDirName); Loading @@ -1116,6 +1115,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter mPendingInits.remove(transportName); } } } // Reset all of our bookkeeping, in response to having been told that // the backend data has been wiped [due to idle expiry, for example], Loading Loading @@ -2321,7 +2321,9 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter final long oldId = Binder.clearCallingIdentity(); try { mWakelock.acquire(); mBackupHandler.post(new PerformInitializeTask(this, transportNames, observer)); OnTaskFinishedListener listener = caller -> mWakelock.release(); mBackupHandler.post( new PerformInitializeTask(this, transportNames, observer, listener)); } finally { Binder.restoreCallingIdentity(oldId); } Loading Loading @@ -2812,7 +2814,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter // build the set of transports for which we are posting an init for (int i = 0; i < transportNames.size(); i++) { recordInitPendingLocked( recordInitPending( true, transportNames.get(i), transportDirNames.get(i)); Loading services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java +67 −26 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.backup.internal; import static com.android.server.backup.RefactoredBackupManagerService.TAG; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.backup.BackupTransport; import android.app.backup.IBackupObserver; Loading @@ -26,23 +27,63 @@ import android.os.SystemClock; import android.util.EventLog; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.backup.IBackupTransport; import com.android.server.EventLogTags; import com.android.server.backup.RefactoredBackupManagerService; import com.android.server.backup.TransportManager; import com.android.server.backup.transport.TransportClient; import java.io.File; import java.util.ArrayList; import java.util.List; /** * Attempts to call {@link BackupTransport#initializeDevice()} followed by * {@link BackupTransport#finishBackup()} for the transport names passed in with the intent of * wiping backup data from the transport. * * If the transport returns error, it will record the operation as pending and schedule it to run in * a future time according to {@link BackupTransport#requestBackupTime()}. The result status * reported to observers will be the last unsuccessful status reported by the transports. If every * operation was successful then it's {@link BackupTransport#TRANSPORT_OK}. */ public class PerformInitializeTask implements Runnable { private final RefactoredBackupManagerService mBackupManagerService; private final TransportManager mTransportManager; private final String[] mQueue; private final File mBaseStateDir; private final OnTaskFinishedListener mListener; @Nullable private IBackupObserver mObserver; private RefactoredBackupManagerService backupManagerService; String[] mQueue; IBackupObserver mObserver; public PerformInitializeTask( RefactoredBackupManagerService backupManagerService, String[] transportNames, @Nullable IBackupObserver observer, OnTaskFinishedListener listener) { this( backupManagerService, backupManagerService.getTransportManager(), transportNames, observer, listener, backupManagerService.getBaseStateDir()); } public PerformInitializeTask(RefactoredBackupManagerService backupManagerService, String[] transportNames, IBackupObserver observer) { this.backupManagerService = backupManagerService; @VisibleForTesting PerformInitializeTask( RefactoredBackupManagerService backupManagerService, TransportManager transportManager, String[] transportNames, @Nullable IBackupObserver observer, OnTaskFinishedListener listener, File baseStateDir) { mBackupManagerService = backupManagerService; mTransportManager = transportManager; mQueue = transportNames; mObserver = observer; mListener = listener; mBaseStateDir = baseStateDir; } private void notifyResult(String target, int status) { Loading @@ -67,21 +108,25 @@ public class PerformInitializeTask implements Runnable { public void run() { // mWakelock is *acquired* when execution begins here String callerLogString = "PerformInitializeTask.run()"; List<TransportClient> transportClientsToDisposeOf = new ArrayList<>(mQueue.length); int result = BackupTransport.TRANSPORT_OK; try { for (String transportName : mQueue) { IBackupTransport transport = backupManagerService.getTransportManager().getTransportBinder( transportName); if (transport == null) { TransportClient transportClient = mTransportManager.getTransportClient(transportName, callerLogString); if (transportClient == null) { Slog.e(TAG, "Requested init for " + transportName + " but not found"); continue; } transportClientsToDisposeOf.add(transportClient); Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName); String transportDirName = transport.transportDirName(); String transportDirName = transportClient.getTransportDirName(); EventLog.writeEvent(EventLogTags.BACKUP_START, transportDirName); long startRealtime = SystemClock.elapsedRealtime(); IBackupTransport transport = transportClient.connectOrThrow(callerLogString); int status = transport.initializeDevice(); if (status == BackupTransport.TRANSPORT_OK) { Loading @@ -93,42 +138,38 @@ public class PerformInitializeTask implements Runnable { Slog.i(TAG, "Device init successful"); int millis = (int) (SystemClock.elapsedRealtime() - startRealtime); EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE); backupManagerService .resetBackupState(new File(backupManagerService.getBaseStateDir(), transportDirName)); File stateFileDir = new File(mBaseStateDir, transportDirName); mBackupManagerService.resetBackupState(stateFileDir); EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis); synchronized (backupManagerService.getQueueLock()) { backupManagerService.recordInitPendingLocked( false, transportName, transportDirName); } mBackupManagerService.recordInitPending(false, transportName, transportDirName); notifyResult(transportName, BackupTransport.TRANSPORT_OK); } else { // If this didn't work, requeue this one and try again // after a suitable interval Slog.e(TAG, "Transport error in initializeDevice()"); EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)"); synchronized (backupManagerService.getQueueLock()) { backupManagerService.recordInitPendingLocked( true, transportName, transportDirName); } mBackupManagerService.recordInitPending(true, transportName, transportDirName); notifyResult(transportName, status); result = status; // do this via another alarm to make sure of the wakelock states long delay = transport.requestBackupTime(); Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay); backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP, mBackupManagerService.getAlarmManager().set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, backupManagerService.getRunInitIntent()); mBackupManagerService.getRunInitIntent()); } } } catch (Exception e) { Slog.e(TAG, "Unexpected error performing init", e); result = BackupTransport.TRANSPORT_ERROR; } finally { // Done; release the wakelock for (TransportClient transportClient : transportClientsToDisposeOf) { mTransportManager.disposeOfTransportClient(transportClient, callerLogString); } notifyFinished(result); backupManagerService.getWakelock().release(); mListener.onFinished(callerLogString); } } } services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java +18 −14 Original line number Diff line number Diff line Loading @@ -23,37 +23,41 @@ import static com.android.server.backup.RefactoredBackupManagerService.TAG; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.PowerManager; import android.util.ArraySet; import android.util.Slog; import com.android.server.backup.RefactoredBackupManagerService; public class RunInitializeReceiver extends BroadcastReceiver { private RefactoredBackupManagerService backupManagerService; private final RefactoredBackupManagerService mBackupManagerService; public RunInitializeReceiver(RefactoredBackupManagerService backupManagerService) { this.backupManagerService = backupManagerService; mBackupManagerService = backupManagerService; } public void onReceive(Context context, Intent intent) { if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) { synchronized (backupManagerService.getQueueLock()) { final ArraySet<String> pendingInits = backupManagerService.getPendingInits(); synchronized (mBackupManagerService.getQueueLock()) { final ArraySet<String> pendingInits = mBackupManagerService.getPendingInits(); if (DEBUG) { Slog.v(TAG, "Running a device init; " + pendingInits.size() + " pending"); } if (pendingInits.size() > 0) { final String[] transports = pendingInits.toArray(new String[pendingInits.size()]); PerformInitializeTask initTask = new PerformInitializeTask(backupManagerService, transports, null); // Acquire the wakelock and pass it to the init thread. it will // be released once init concludes. backupManagerService.clearPendingInits(); backupManagerService.getWakelock().acquire(); backupManagerService.getBackupHandler().post(initTask); final String[] transports = pendingInits.toArray(new String[pendingInits.size()]); mBackupManagerService.clearPendingInits(); PowerManager.WakeLock wakelock = mBackupManagerService.getWakelock(); wakelock.acquire(); OnTaskFinishedListener listener = caller -> wakelock.release(); Runnable task = new PerformInitializeTask( mBackupManagerService, transports, null, listener); mBackupManagerService.getBackupHandler().post(task); } } } Loading services/robotests/src/com/android/server/backup/TransportManagerTest.java +0 −3 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.backup; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.robolectric.shadow.api.Shadow.extract; Loading Loading @@ -58,7 +56,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowPackageManager; import org.testng.Assert.ThrowingRunnable; import java.util.ArrayList; import java.util.Arrays; Loading services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java 0 → 100644 +411 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java +27 −25 Original line number Diff line number Diff line Loading @@ -1086,15 +1086,14 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter } /** * Maintain persistent state around whether need to do an initialize operation. * Must be called with the queue lock held. * Maintain persistent state around whether need to do an initialize operation. This will lock * on {@link #getQueueLock()}. */ @GuardedBy("mQueueLock") public void recordInitPendingLocked( public void recordInitPending( boolean isPending, String transportName, String transportDirName) { synchronized (mQueueLock) { if (MORE_DEBUG) { Slog.i(TAG, "recordInitPendingLocked: " + isPending + " on transport " + transportName); Slog.i(TAG, "recordInitPending(" + isPending + ") on transport " + transportName); } File stateDir = new File(mBaseStateDir, transportDirName); Loading @@ -1116,6 +1115,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter mPendingInits.remove(transportName); } } } // Reset all of our bookkeeping, in response to having been told that // the backend data has been wiped [due to idle expiry, for example], Loading Loading @@ -2321,7 +2321,9 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter final long oldId = Binder.clearCallingIdentity(); try { mWakelock.acquire(); mBackupHandler.post(new PerformInitializeTask(this, transportNames, observer)); OnTaskFinishedListener listener = caller -> mWakelock.release(); mBackupHandler.post( new PerformInitializeTask(this, transportNames, observer, listener)); } finally { Binder.restoreCallingIdentity(oldId); } Loading Loading @@ -2812,7 +2814,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter // build the set of transports for which we are posting an init for (int i = 0; i < transportNames.size(); i++) { recordInitPendingLocked( recordInitPending( true, transportNames.get(i), transportDirNames.get(i)); Loading
services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java +67 −26 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.backup.internal; import static com.android.server.backup.RefactoredBackupManagerService.TAG; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.backup.BackupTransport; import android.app.backup.IBackupObserver; Loading @@ -26,23 +27,63 @@ import android.os.SystemClock; import android.util.EventLog; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.backup.IBackupTransport; import com.android.server.EventLogTags; import com.android.server.backup.RefactoredBackupManagerService; import com.android.server.backup.TransportManager; import com.android.server.backup.transport.TransportClient; import java.io.File; import java.util.ArrayList; import java.util.List; /** * Attempts to call {@link BackupTransport#initializeDevice()} followed by * {@link BackupTransport#finishBackup()} for the transport names passed in with the intent of * wiping backup data from the transport. * * If the transport returns error, it will record the operation as pending and schedule it to run in * a future time according to {@link BackupTransport#requestBackupTime()}. The result status * reported to observers will be the last unsuccessful status reported by the transports. If every * operation was successful then it's {@link BackupTransport#TRANSPORT_OK}. */ public class PerformInitializeTask implements Runnable { private final RefactoredBackupManagerService mBackupManagerService; private final TransportManager mTransportManager; private final String[] mQueue; private final File mBaseStateDir; private final OnTaskFinishedListener mListener; @Nullable private IBackupObserver mObserver; private RefactoredBackupManagerService backupManagerService; String[] mQueue; IBackupObserver mObserver; public PerformInitializeTask( RefactoredBackupManagerService backupManagerService, String[] transportNames, @Nullable IBackupObserver observer, OnTaskFinishedListener listener) { this( backupManagerService, backupManagerService.getTransportManager(), transportNames, observer, listener, backupManagerService.getBaseStateDir()); } public PerformInitializeTask(RefactoredBackupManagerService backupManagerService, String[] transportNames, IBackupObserver observer) { this.backupManagerService = backupManagerService; @VisibleForTesting PerformInitializeTask( RefactoredBackupManagerService backupManagerService, TransportManager transportManager, String[] transportNames, @Nullable IBackupObserver observer, OnTaskFinishedListener listener, File baseStateDir) { mBackupManagerService = backupManagerService; mTransportManager = transportManager; mQueue = transportNames; mObserver = observer; mListener = listener; mBaseStateDir = baseStateDir; } private void notifyResult(String target, int status) { Loading @@ -67,21 +108,25 @@ public class PerformInitializeTask implements Runnable { public void run() { // mWakelock is *acquired* when execution begins here String callerLogString = "PerformInitializeTask.run()"; List<TransportClient> transportClientsToDisposeOf = new ArrayList<>(mQueue.length); int result = BackupTransport.TRANSPORT_OK; try { for (String transportName : mQueue) { IBackupTransport transport = backupManagerService.getTransportManager().getTransportBinder( transportName); if (transport == null) { TransportClient transportClient = mTransportManager.getTransportClient(transportName, callerLogString); if (transportClient == null) { Slog.e(TAG, "Requested init for " + transportName + " but not found"); continue; } transportClientsToDisposeOf.add(transportClient); Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName); String transportDirName = transport.transportDirName(); String transportDirName = transportClient.getTransportDirName(); EventLog.writeEvent(EventLogTags.BACKUP_START, transportDirName); long startRealtime = SystemClock.elapsedRealtime(); IBackupTransport transport = transportClient.connectOrThrow(callerLogString); int status = transport.initializeDevice(); if (status == BackupTransport.TRANSPORT_OK) { Loading @@ -93,42 +138,38 @@ public class PerformInitializeTask implements Runnable { Slog.i(TAG, "Device init successful"); int millis = (int) (SystemClock.elapsedRealtime() - startRealtime); EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE); backupManagerService .resetBackupState(new File(backupManagerService.getBaseStateDir(), transportDirName)); File stateFileDir = new File(mBaseStateDir, transportDirName); mBackupManagerService.resetBackupState(stateFileDir); EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis); synchronized (backupManagerService.getQueueLock()) { backupManagerService.recordInitPendingLocked( false, transportName, transportDirName); } mBackupManagerService.recordInitPending(false, transportName, transportDirName); notifyResult(transportName, BackupTransport.TRANSPORT_OK); } else { // If this didn't work, requeue this one and try again // after a suitable interval Slog.e(TAG, "Transport error in initializeDevice()"); EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)"); synchronized (backupManagerService.getQueueLock()) { backupManagerService.recordInitPendingLocked( true, transportName, transportDirName); } mBackupManagerService.recordInitPending(true, transportName, transportDirName); notifyResult(transportName, status); result = status; // do this via another alarm to make sure of the wakelock states long delay = transport.requestBackupTime(); Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay); backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP, mBackupManagerService.getAlarmManager().set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, backupManagerService.getRunInitIntent()); mBackupManagerService.getRunInitIntent()); } } } catch (Exception e) { Slog.e(TAG, "Unexpected error performing init", e); result = BackupTransport.TRANSPORT_ERROR; } finally { // Done; release the wakelock for (TransportClient transportClient : transportClientsToDisposeOf) { mTransportManager.disposeOfTransportClient(transportClient, callerLogString); } notifyFinished(result); backupManagerService.getWakelock().release(); mListener.onFinished(callerLogString); } } }
services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java +18 −14 Original line number Diff line number Diff line Loading @@ -23,37 +23,41 @@ import static com.android.server.backup.RefactoredBackupManagerService.TAG; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.PowerManager; import android.util.ArraySet; import android.util.Slog; import com.android.server.backup.RefactoredBackupManagerService; public class RunInitializeReceiver extends BroadcastReceiver { private RefactoredBackupManagerService backupManagerService; private final RefactoredBackupManagerService mBackupManagerService; public RunInitializeReceiver(RefactoredBackupManagerService backupManagerService) { this.backupManagerService = backupManagerService; mBackupManagerService = backupManagerService; } public void onReceive(Context context, Intent intent) { if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) { synchronized (backupManagerService.getQueueLock()) { final ArraySet<String> pendingInits = backupManagerService.getPendingInits(); synchronized (mBackupManagerService.getQueueLock()) { final ArraySet<String> pendingInits = mBackupManagerService.getPendingInits(); if (DEBUG) { Slog.v(TAG, "Running a device init; " + pendingInits.size() + " pending"); } if (pendingInits.size() > 0) { final String[] transports = pendingInits.toArray(new String[pendingInits.size()]); PerformInitializeTask initTask = new PerformInitializeTask(backupManagerService, transports, null); // Acquire the wakelock and pass it to the init thread. it will // be released once init concludes. backupManagerService.clearPendingInits(); backupManagerService.getWakelock().acquire(); backupManagerService.getBackupHandler().post(initTask); final String[] transports = pendingInits.toArray(new String[pendingInits.size()]); mBackupManagerService.clearPendingInits(); PowerManager.WakeLock wakelock = mBackupManagerService.getWakelock(); wakelock.acquire(); OnTaskFinishedListener listener = caller -> wakelock.release(); Runnable task = new PerformInitializeTask( mBackupManagerService, transports, null, listener); mBackupManagerService.getBackupHandler().post(task); } } } Loading
services/robotests/src/com/android/server/backup/TransportManagerTest.java +0 −3 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.backup; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.robolectric.shadow.api.Shadow.extract; Loading Loading @@ -58,7 +56,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowPackageManager; import org.testng.Assert.ThrowingRunnable; import java.util.ArrayList; import java.util.Arrays; Loading
services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java 0 → 100644 +411 −0 File added.Preview size limit exceeded, changes collapsed. Show changes