PerformInitializeTask.java revision 387267eafebaed8abe031efcb6d6379292503d48
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.server.backup.internal; 18 19import static com.android.server.backup.RefactoredBackupManagerService.TAG; 20 21import android.app.AlarmManager; 22import android.app.backup.BackupTransport; 23import android.app.backup.IBackupObserver; 24import android.os.RemoteException; 25import android.os.SystemClock; 26import android.util.EventLog; 27import android.util.Slog; 28 29import com.android.internal.backup.IBackupTransport; 30import com.android.server.EventLogTags; 31import com.android.server.backup.RefactoredBackupManagerService; 32 33import java.io.File; 34 35public class PerformInitializeTask implements Runnable { 36 37 private RefactoredBackupManagerService backupManagerService; 38 String[] mQueue; 39 IBackupObserver mObserver; 40 41 public PerformInitializeTask(RefactoredBackupManagerService backupManagerService, 42 String[] transportNames, IBackupObserver observer) { 43 this.backupManagerService = backupManagerService; 44 mQueue = transportNames; 45 mObserver = observer; 46 } 47 48 private void notifyResult(String target, int status) { 49 try { 50 if (mObserver != null) { 51 mObserver.onResult(target, status); 52 } 53 } catch (RemoteException ignored) { 54 mObserver = null; // don't try again 55 } 56 } 57 58 private void notifyFinished(int status) { 59 try { 60 if (mObserver != null) { 61 mObserver.backupFinished(status); 62 } 63 } catch (RemoteException ignored) { 64 mObserver = null; 65 } 66 } 67 68 public void run() { 69 // mWakelock is *acquired* when execution begins here 70 int result = BackupTransport.TRANSPORT_OK; 71 try { 72 for (String transportName : mQueue) { 73 IBackupTransport transport = 74 backupManagerService.getTransportManager().getTransportBinder( 75 transportName); 76 if (transport == null) { 77 Slog.e(TAG, "Requested init for " + transportName + " but not found"); 78 continue; 79 } 80 81 Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName); 82 String transportDirName = transport.transportDirName(); 83 EventLog.writeEvent(EventLogTags.BACKUP_START, transportDirName); 84 long startRealtime = SystemClock.elapsedRealtime(); 85 int status = transport.initializeDevice(); 86 87 if (status == BackupTransport.TRANSPORT_OK) { 88 status = transport.finishBackup(); 89 } 90 91 // Okay, the wipe really happened. Clean up our local bookkeeping. 92 if (status == BackupTransport.TRANSPORT_OK) { 93 Slog.i(TAG, "Device init successful"); 94 int millis = (int) (SystemClock.elapsedRealtime() - startRealtime); 95 EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE); 96 backupManagerService 97 .resetBackupState(new File(backupManagerService.getBaseStateDir(), 98 transportDirName)); 99 EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis); 100 synchronized (backupManagerService.getQueueLock()) { 101 backupManagerService.recordInitPendingLocked(false, transportName); 102 } 103 notifyResult(transportName, BackupTransport.TRANSPORT_OK); 104 } else { 105 // If this didn't work, requeue this one and try again 106 // after a suitable interval 107 Slog.e(TAG, "Transport error in initializeDevice()"); 108 EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)"); 109 synchronized (backupManagerService.getQueueLock()) { 110 backupManagerService.recordInitPendingLocked(true, transportName); 111 } 112 notifyResult(transportName, status); 113 result = status; 114 115 // do this via another alarm to make sure of the wakelock states 116 long delay = transport.requestBackupTime(); 117 Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay); 118 backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP, 119 System.currentTimeMillis() + delay, 120 backupManagerService.getRunInitIntent()); 121 } 122 } 123 } catch (Exception e) { 124 Slog.e(TAG, "Unexpected error performing init", e); 125 result = BackupTransport.TRANSPORT_ERROR; 126 } finally { 127 // Done; release the wakelock 128 notifyFinished(result); 129 backupManagerService.getWakelock().release(); 130 } 131 } 132} 133