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 EventLog.writeEvent(EventLogTags.BACKUP_START, transport.transportDirName()); 83 long startRealtime = SystemClock.elapsedRealtime(); 84 int status = transport.initializeDevice(); 85 86 if (status == BackupTransport.TRANSPORT_OK) { 87 status = transport.finishBackup(); 88 } 89 90 // Okay, the wipe really happened. Clean up our local bookkeeping. 91 if (status == BackupTransport.TRANSPORT_OK) { 92 Slog.i(TAG, "Device init successful"); 93 int millis = (int) (SystemClock.elapsedRealtime() - startRealtime); 94 EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE); 95 backupManagerService 96 .resetBackupState(new File(backupManagerService.getBaseStateDir(), 97 transport.transportDirName())); 98 EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis); 99 synchronized (backupManagerService.getQueueLock()) { 100 backupManagerService.recordInitPendingLocked(false, transportName); 101 } 102 notifyResult(transportName, BackupTransport.TRANSPORT_OK); 103 } else { 104 // If this didn't work, requeue this one and try again 105 // after a suitable interval 106 Slog.e(TAG, "Transport error in initializeDevice()"); 107 EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)"); 108 synchronized (backupManagerService.getQueueLock()) { 109 backupManagerService.recordInitPendingLocked(true, transportName); 110 } 111 notifyResult(transportName, status); 112 result = status; 113 114 // do this via another alarm to make sure of the wakelock states 115 long delay = transport.requestBackupTime(); 116 Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay); 117 backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP, 118 System.currentTimeMillis() + delay, 119 backupManagerService.getRunInitIntent()); 120 } 121 } 122 } catch (Exception e) { 123 Slog.e(TAG, "Unexpected error performing init", e); 124 result = BackupTransport.TRANSPORT_ERROR; 125 } finally { 126 // Done; release the wakelock 127 notifyFinished(result); 128 backupManagerService.getWakelock().release(); 129 } 130 } 131} 132