Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 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 | |
| 17 | package com.android.server.backup.internal; |
| 18 | |
Annie Meng | 384230f | 2018-11-28 10:58:08 +0000 | [diff] [blame] | 19 | import static com.android.server.backup.BackupManagerService.DEBUG; |
| 20 | import static com.android.server.backup.BackupManagerService.MORE_DEBUG; |
| 21 | import static com.android.server.backup.BackupManagerService.TAG; |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 22 | |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 23 | import android.app.backup.RestoreSet; |
| 24 | import android.content.Intent; |
| 25 | import android.os.Handler; |
| 26 | import android.os.Looper; |
| 27 | import android.os.Message; |
| 28 | import android.os.RemoteException; |
| 29 | import android.os.UserHandle; |
| 30 | import android.util.EventLog; |
| 31 | import android.util.Pair; |
| 32 | import android.util.Slog; |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 33 | |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 34 | import com.android.internal.backup.IBackupTransport; |
Annie Meng | a1e8fd6 | 2018-03-15 14:45:46 +0000 | [diff] [blame] | 35 | import com.android.internal.util.Preconditions; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 36 | import com.android.server.EventLogTags; |
Annie Meng | a1e8fd6 | 2018-03-15 14:45:46 +0000 | [diff] [blame] | 37 | import com.android.server.backup.BackupAgentTimeoutParameters; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 38 | import com.android.server.backup.BackupRestoreTask; |
Robert Berry | c31a839 | 2017-07-14 14:19:21 +0100 | [diff] [blame] | 39 | import com.android.server.backup.DataChangedJournal; |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 40 | import com.android.server.backup.TransportManager; |
Annie Meng | 813716b | 2018-11-20 14:08:21 +0000 | [diff] [blame] | 41 | import com.android.server.backup.UserBackupManagerService; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 42 | import com.android.server.backup.fullbackup.PerformAdbBackupTask; |
| 43 | import com.android.server.backup.fullbackup.PerformFullTransportBackupTask; |
Bernardo Rufino | 75f73f0 | 2018-08-02 09:39:39 +0100 | [diff] [blame] | 44 | import com.android.server.backup.keyvalue.BackupRequest; |
| 45 | import com.android.server.backup.keyvalue.KeyValueBackupTask; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 46 | import com.android.server.backup.params.AdbBackupParams; |
| 47 | import com.android.server.backup.params.AdbParams; |
| 48 | import com.android.server.backup.params.AdbRestoreParams; |
| 49 | import com.android.server.backup.params.BackupParams; |
| 50 | import com.android.server.backup.params.ClearParams; |
| 51 | import com.android.server.backup.params.ClearRetryParams; |
| 52 | import com.android.server.backup.params.RestoreGetSetsParams; |
| 53 | import com.android.server.backup.params.RestoreParams; |
| 54 | import com.android.server.backup.restore.PerformAdbRestoreTask; |
| 55 | import com.android.server.backup.restore.PerformUnifiedRestoreTask; |
Bernardo Rufino | 2d87f45 | 2018-06-22 11:47:49 +0100 | [diff] [blame] | 56 | import com.android.server.backup.transport.TransportClient; |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 57 | |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 58 | import java.util.ArrayList; |
| 59 | import java.util.Collections; |
Bernardo Rufino | e80f270 | 2018-08-10 17:06:15 +0100 | [diff] [blame] | 60 | import java.util.List; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 61 | |
| 62 | /** |
| 63 | * Asynchronous backup/restore handler thread. |
| 64 | */ |
| 65 | public class BackupHandler extends Handler { |
| 66 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 67 | public static final int MSG_RUN_BACKUP = 1; |
| 68 | public static final int MSG_RUN_ADB_BACKUP = 2; |
| 69 | public static final int MSG_RUN_RESTORE = 3; |
| 70 | public static final int MSG_RUN_CLEAR = 4; |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 71 | public static final int MSG_RUN_GET_RESTORE_SETS = 6; |
| 72 | public static final int MSG_RESTORE_SESSION_TIMEOUT = 8; |
| 73 | public static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9; |
| 74 | public static final int MSG_RUN_ADB_RESTORE = 10; |
| 75 | public static final int MSG_RETRY_INIT = 11; |
| 76 | public static final int MSG_RETRY_CLEAR = 12; |
| 77 | public static final int MSG_WIDGET_BROADCAST = 13; |
| 78 | public static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14; |
| 79 | public static final int MSG_REQUEST_BACKUP = 15; |
| 80 | public static final int MSG_SCHEDULE_BACKUP_PACKAGE = 16; |
| 81 | public static final int MSG_BACKUP_OPERATION_TIMEOUT = 17; |
| 82 | public static final int MSG_RESTORE_OPERATION_TIMEOUT = 18; |
| 83 | // backup task state machine tick |
| 84 | public static final int MSG_BACKUP_RESTORE_STEP = 20; |
| 85 | public static final int MSG_OP_COMPLETE = 21; |
| 86 | |
Annie Meng | 813716b | 2018-11-20 14:08:21 +0000 | [diff] [blame] | 87 | private final UserBackupManagerService backupManagerService; |
Annie Meng | a1e8fd6 | 2018-03-15 14:45:46 +0000 | [diff] [blame] | 88 | private final BackupAgentTimeoutParameters mAgentTimeoutParameters; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 89 | |
Annie Meng | 813716b | 2018-11-20 14:08:21 +0000 | [diff] [blame] | 90 | public BackupHandler(UserBackupManagerService backupManagerService, Looper looper) { |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 91 | super(looper); |
| 92 | this.backupManagerService = backupManagerService; |
Annie Meng | a1e8fd6 | 2018-03-15 14:45:46 +0000 | [diff] [blame] | 93 | mAgentTimeoutParameters = Preconditions.checkNotNull( |
| 94 | backupManagerService.getAgentTimeoutParameters(), |
| 95 | "Timeout parameters cannot be null"); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 96 | } |
| 97 | |
| 98 | public void handleMessage(Message msg) { |
| 99 | |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 100 | TransportManager transportManager = backupManagerService.getTransportManager(); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 101 | switch (msg.what) { |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 102 | case MSG_RUN_BACKUP: { |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 103 | backupManagerService.setLastBackupPass(System.currentTimeMillis()); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 104 | |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 105 | String callerLogString = "BH/MSG_RUN_BACKUP"; |
| 106 | TransportClient transportClient = |
| 107 | transportManager.getCurrentTransportClient(callerLogString); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 108 | IBackupTransport transport = |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 109 | transportClient != null |
| 110 | ? transportClient.connect(callerLogString) |
| 111 | : null; |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 112 | if (transport == null) { |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 113 | if (transportClient != null) { |
| 114 | transportManager |
| 115 | .disposeOfTransportClient(transportClient, callerLogString); |
| 116 | } |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 117 | Slog.v(TAG, "Backup requested but no transport available"); |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 118 | synchronized (backupManagerService.getQueueLock()) { |
| 119 | backupManagerService.setBackupRunning(false); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 120 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 121 | backupManagerService.getWakelock().release(); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 122 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 123 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 124 | |
Bernardo Rufino | e80f270 | 2018-08-10 17:06:15 +0100 | [diff] [blame] | 125 | // Snapshot the pending-backup set and work on that. |
| 126 | List<String> queue = new ArrayList<>(); |
Robert Berry | c31a839 | 2017-07-14 14:19:21 +0100 | [diff] [blame] | 127 | DataChangedJournal oldJournal = backupManagerService.getJournal(); |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 128 | synchronized (backupManagerService.getQueueLock()) { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 129 | // Do we have any work to do? Construct the work queue |
| 130 | // then release the synchronization lock to actually run |
| 131 | // the backup. |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 132 | if (backupManagerService.getPendingBackups().size() > 0) { |
| 133 | for (BackupRequest b : backupManagerService.getPendingBackups().values()) { |
Bernardo Rufino | e80f270 | 2018-08-10 17:06:15 +0100 | [diff] [blame] | 134 | queue.add(b.packageName); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 135 | } |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 136 | if (DEBUG) { |
| 137 | Slog.v(TAG, "clearing pending backups"); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 138 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 139 | backupManagerService.getPendingBackups().clear(); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 140 | |
| 141 | // Start a new backup-queue journal file too |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 142 | backupManagerService.setJournal(null); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 143 | |
| 144 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 145 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 146 | |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 147 | // At this point, we have started a new journal file, and the old |
| 148 | // file identity is being passed to the backup processing task. |
| 149 | // When it completes successfully, that old journal file will be |
| 150 | // deleted. If we crash prior to that, the old journal is parsed |
| 151 | // at next boot and the journaled requests fulfilled. |
| 152 | boolean staged = true; |
| 153 | if (queue.size() > 0) { |
| 154 | // Spin up a backup state sequence and set it running |
| 155 | try { |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 156 | OnTaskFinishedListener listener = |
| 157 | caller -> |
| 158 | transportManager |
| 159 | .disposeOfTransportClient(transportClient, caller); |
Bernardo Rufino | cc714c1 | 2018-08-02 08:39:45 +0100 | [diff] [blame] | 160 | KeyValueBackupTask.start( |
Bernardo Rufino | 2d87f45 | 2018-06-22 11:47:49 +0100 | [diff] [blame] | 161 | backupManagerService, |
| 162 | transportClient, |
| 163 | transport.transportDirName(), |
| 164 | queue, |
| 165 | oldJournal, |
| 166 | /* observer */ null, |
| 167 | /* monitor */ null, |
| 168 | listener, |
| 169 | Collections.emptyList(), |
| 170 | /* userInitiated */ false, |
| 171 | /* nonIncremental */ false); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 172 | } catch (Exception e) { |
| 173 | // unable to ask the transport its dir name -- transient failure, since |
| 174 | // the above check succeeded. Try again next time. |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 175 | Slog.e(TAG, "Transport became unavailable attempting backup" |
| 176 | + " or error initializing backup task", e); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 177 | staged = false; |
| 178 | } |
| 179 | } else { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 180 | Slog.v(TAG, "Backup requested but nothing pending"); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 181 | staged = false; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 182 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 183 | |
| 184 | if (!staged) { |
Bernardo Rufino | af547f4 | 2017-11-13 15:49:41 +0000 | [diff] [blame] | 185 | transportManager.disposeOfTransportClient(transportClient, callerLogString); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 186 | // if we didn't actually hand off the wakelock, rewind until next time |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 187 | synchronized (backupManagerService.getQueueLock()) { |
| 188 | backupManagerService.setBackupRunning(false); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 189 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 190 | backupManagerService.getWakelock().release(); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 191 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 192 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 193 | } |
| 194 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 195 | case MSG_BACKUP_RESTORE_STEP: { |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 196 | try { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 197 | BackupRestoreTask task = (BackupRestoreTask) msg.obj; |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 198 | if (MORE_DEBUG) { |
| 199 | Slog.v(TAG, "Got next step for " + task + ", executing"); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 200 | } |
| 201 | task.execute(); |
| 202 | } catch (ClassCastException e) { |
Bernardo Rufino | 998fdaa | 2017-12-05 17:27:45 +0000 | [diff] [blame] | 203 | Slog.e(TAG, "Invalid backup/restore task in flight, obj=" + msg.obj); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 204 | } |
| 205 | break; |
| 206 | } |
| 207 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 208 | case MSG_OP_COMPLETE: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 209 | try { |
| 210 | Pair<BackupRestoreTask, Long> taskWithResult = |
| 211 | (Pair<BackupRestoreTask, Long>) msg.obj; |
| 212 | taskWithResult.first.operationComplete(taskWithResult.second); |
| 213 | } catch (ClassCastException e) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 214 | Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 215 | } |
| 216 | break; |
| 217 | } |
| 218 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 219 | case MSG_RUN_ADB_BACKUP: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 220 | // TODO: refactor full backup to be a looper-based state machine |
| 221 | // similar to normal backup/restore. |
| 222 | AdbBackupParams params = (AdbBackupParams) msg.obj; |
| 223 | PerformAdbBackupTask task = new PerformAdbBackupTask(backupManagerService, |
| 224 | params.fd, |
| 225 | params.observer, params.includeApks, params.includeObbs, |
| 226 | params.includeShared, params.doWidgets, params.curPassword, |
| 227 | params.encryptPassword, params.allApps, params.includeSystem, |
| 228 | params.doCompress, params.includeKeyValue, params.packages, params.latch); |
| 229 | (new Thread(task, "adb-backup")).start(); |
| 230 | break; |
| 231 | } |
| 232 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 233 | case MSG_RUN_FULL_TRANSPORT_BACKUP: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 234 | PerformFullTransportBackupTask task = (PerformFullTransportBackupTask) msg.obj; |
| 235 | (new Thread(task, "transport-backup")).start(); |
| 236 | break; |
| 237 | } |
| 238 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 239 | case MSG_RUN_RESTORE: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 240 | RestoreParams params = (RestoreParams) msg.obj; |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 241 | Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 242 | |
Bernardo Rufino | 998fdaa | 2017-12-05 17:27:45 +0000 | [diff] [blame] | 243 | PerformUnifiedRestoreTask task = |
| 244 | new PerformUnifiedRestoreTask( |
| 245 | backupManagerService, |
| 246 | params.transportClient, |
| 247 | params.observer, |
| 248 | params.monitor, |
| 249 | params.token, |
| 250 | params.packageInfo, |
| 251 | params.pmToken, |
| 252 | params.isSystemRestore, |
| 253 | params.filterSet, |
| 254 | params.listener); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 255 | |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 256 | synchronized (backupManagerService.getPendingRestores()) { |
| 257 | if (backupManagerService.isRestoreInProgress()) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 258 | if (DEBUG) { |
| 259 | Slog.d(TAG, "Restore in progress, queueing."); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 260 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 261 | backupManagerService.getPendingRestores().add(task); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 262 | // This task will be picked up and executed when the the currently running |
| 263 | // restore task finishes. |
| 264 | } else { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 265 | if (DEBUG) { |
| 266 | Slog.d(TAG, "Starting restore."); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 267 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 268 | backupManagerService.setRestoreInProgress(true); |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 269 | Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 270 | sendMessage(restoreMsg); |
| 271 | } |
| 272 | } |
| 273 | break; |
| 274 | } |
| 275 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 276 | case MSG_RUN_ADB_RESTORE: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 277 | // TODO: refactor full restore to be a looper-based state machine |
| 278 | // similar to normal backup/restore. |
| 279 | AdbRestoreParams params = (AdbRestoreParams) msg.obj; |
| 280 | PerformAdbRestoreTask task = new PerformAdbRestoreTask(backupManagerService, |
| 281 | params.fd, |
| 282 | params.curPassword, params.encryptPassword, |
| 283 | params.observer, params.latch); |
| 284 | (new Thread(task, "adb-restore")).start(); |
| 285 | break; |
| 286 | } |
| 287 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 288 | case MSG_RUN_CLEAR: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 289 | ClearParams params = (ClearParams) msg.obj; |
Bernardo Rufino | f93a091 | 2017-12-04 14:11:24 +0000 | [diff] [blame] | 290 | Runnable task = |
| 291 | new PerformClearTask( |
| 292 | backupManagerService, |
| 293 | params.transportClient, |
| 294 | params.packageInfo, |
| 295 | params.listener); |
| 296 | task.run(); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 297 | break; |
| 298 | } |
| 299 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 300 | case MSG_RETRY_CLEAR: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 301 | // reenqueues if the transport remains unavailable |
| 302 | ClearRetryParams params = (ClearRetryParams) msg.obj; |
| 303 | backupManagerService.clearBackupData(params.transportName, params.packageName); |
| 304 | break; |
| 305 | } |
| 306 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 307 | case MSG_RUN_GET_RESTORE_SETS: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 308 | // Like other async operations, this is entered with the wakelock held |
| 309 | RestoreSet[] sets = null; |
| 310 | RestoreGetSetsParams params = (RestoreGetSetsParams) msg.obj; |
Bernardo Rufino | 998fdaa | 2017-12-05 17:27:45 +0000 | [diff] [blame] | 311 | String callerLogString = "BH/MSG_RUN_GET_RESTORE_SETS"; |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 312 | try { |
Bernardo Rufino | 998fdaa | 2017-12-05 17:27:45 +0000 | [diff] [blame] | 313 | IBackupTransport transport = |
| 314 | params.transportClient.connectOrThrow(callerLogString); |
| 315 | sets = transport.getAvailableRestoreSets(); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 316 | // cache the result in the active session |
| 317 | synchronized (params.session) { |
Bernardo Rufino | 12b6baf | 2018-02-26 14:07:01 +0000 | [diff] [blame] | 318 | params.session.setRestoreSets(sets); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 319 | } |
| 320 | if (sets == null) { |
| 321 | EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); |
| 322 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 323 | } catch (Exception e) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 324 | Slog.e(TAG, "Error from transport getting set list: " + e.getMessage()); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 325 | } finally { |
| 326 | if (params.observer != null) { |
| 327 | try { |
| 328 | params.observer.restoreSetsAvailable(sets); |
| 329 | } catch (RemoteException re) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 330 | Slog.e(TAG, "Unable to report listing to observer"); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 331 | } catch (Exception e) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 332 | Slog.e(TAG, "Restore observer threw: " + e.getMessage()); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 333 | } |
| 334 | } |
| 335 | |
| 336 | // Done: reset the session timeout clock |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 337 | removeMessages(MSG_RESTORE_SESSION_TIMEOUT); |
Annie Meng | a1e8fd6 | 2018-03-15 14:45:46 +0000 | [diff] [blame] | 338 | sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, |
| 339 | mAgentTimeoutParameters.getRestoreAgentTimeoutMillis()); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 340 | |
Bernardo Rufino | 998fdaa | 2017-12-05 17:27:45 +0000 | [diff] [blame] | 341 | params.listener.onFinished(callerLogString); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 342 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 343 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 344 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 345 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 346 | case MSG_BACKUP_OPERATION_TIMEOUT: |
| 347 | case MSG_RESTORE_OPERATION_TIMEOUT: { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 348 | Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1)); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 349 | backupManagerService.handleCancel(msg.arg1, false); |
| 350 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 351 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 352 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 353 | case MSG_RESTORE_SESSION_TIMEOUT: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 354 | synchronized (backupManagerService) { |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 355 | if (backupManagerService.getActiveRestoreSession() != null) { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 356 | // Client app left the restore session dangling. We know that it |
| 357 | // can't be in the middle of an actual restore operation because |
| 358 | // the timeout is suspended while a restore is in progress. Clean |
| 359 | // up now. |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 360 | Slog.w(TAG, "Restore session timed out; aborting"); |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 361 | backupManagerService.getActiveRestoreSession().markTimedOut(); |
| 362 | post(backupManagerService.getActiveRestoreSession().new EndRestoreRunnable( |
| 363 | backupManagerService, |
| 364 | backupManagerService.getActiveRestoreSession())); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 365 | } |
| 366 | } |
| 367 | break; |
| 368 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 369 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 370 | case MSG_FULL_CONFIRMATION_TIMEOUT: { |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 371 | synchronized (backupManagerService.getAdbBackupRestoreConfirmations()) { |
| 372 | AdbParams params = backupManagerService.getAdbBackupRestoreConfirmations().get( |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 373 | msg.arg1); |
| 374 | if (params != null) { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 375 | Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation"); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 376 | |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 377 | // Release the waiter; timeout == completion |
| 378 | backupManagerService.signalAdbBackupRestoreCompletion(params); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 379 | |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 380 | // Remove the token from the set |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 381 | backupManagerService.getAdbBackupRestoreConfirmations().delete(msg.arg1); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 382 | |
| 383 | // Report a timeout to the observer, if any |
| 384 | if (params.observer != null) { |
| 385 | try { |
| 386 | params.observer.onTimeout(); |
| 387 | } catch (RemoteException e) { |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 388 | /* don't care if the app has gone away */ |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 389 | } |
| 390 | } |
| 391 | } else { |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 392 | Slog.d(TAG, "couldn't find params for token " + msg.arg1); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 393 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 394 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 395 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 396 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 397 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 398 | case MSG_WIDGET_BROADCAST: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 399 | final Intent intent = (Intent) msg.obj; |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 400 | backupManagerService.getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 401 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 402 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 403 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 404 | case MSG_REQUEST_BACKUP: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 405 | BackupParams params = (BackupParams) msg.obj; |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 406 | if (MORE_DEBUG) { |
| 407 | Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 408 | } |
Artem Iglikov | d6c00c7 | 2017-04-24 12:03:42 +0100 | [diff] [blame] | 409 | backupManagerService.setBackupRunning(true); |
| 410 | backupManagerService.getWakelock().acquire(); |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 411 | |
Bernardo Rufino | cc714c1 | 2018-08-02 08:39:45 +0100 | [diff] [blame] | 412 | KeyValueBackupTask.start( |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 413 | backupManagerService, |
Bernardo Rufino | 2d87f45 | 2018-06-22 11:47:49 +0100 | [diff] [blame] | 414 | params.transportClient, |
| 415 | params.dirName, |
Bernardo Rufino | e80f270 | 2018-08-10 17:06:15 +0100 | [diff] [blame] | 416 | params.kvPackages, |
Bernardo Rufino | 2d87f45 | 2018-06-22 11:47:49 +0100 | [diff] [blame] | 417 | /* dataChangedJournal */ null, |
| 418 | params.observer, |
| 419 | params.monitor, |
| 420 | params.listener, |
| 421 | params.fullPackages, |
| 422 | /* userInitiated */ true, |
| 423 | params.nonIncrementalBackup); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 424 | break; |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 425 | } |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 426 | |
Artem Iglikov | c2a3d0f | 2017-04-28 13:16:47 +0100 | [diff] [blame] | 427 | case MSG_SCHEDULE_BACKUP_PACKAGE: { |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 428 | String pkgName = (String) msg.obj; |
Artem Iglikov | dbe6832 | 2017-05-09 11:00:03 +0100 | [diff] [blame] | 429 | if (MORE_DEBUG) { |
| 430 | Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName); |
Artem Iglikov | 21510f0 | 2017-04-18 14:53:06 +0100 | [diff] [blame] | 431 | } |
| 432 | backupManagerService.dataChangedImpl(pkgName); |
| 433 | break; |
| 434 | } |
Artem Iglikov | f251e35 | 2017-04-07 12:48:54 +0100 | [diff] [blame] | 435 | } |
| 436 | } |
| 437 | } |