1f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov/*
2f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * Copyright (C) 2017 The Android Open Source Project
3f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov *
4f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * Licensed under the Apache License, Version 2.0 (the "License");
5f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * you may not use this file except in compliance with the License.
6f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * You may obtain a copy of the License at
7f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov *
8f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov *      http://www.apache.org/licenses/LICENSE-2.0
9f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov *
10f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * Unless required by applicable law or agreed to in writing, software
11f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * distributed under the License is distributed on an "AS IS" BASIS,
12f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * See the License for the specific language governing permissions and
14f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * limitations under the License
15f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov */
16f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
17f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovpackage com.android.server.backup.internal;
18f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
19dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikovimport static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
20dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikovimport static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
21dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikovimport static com.android.server.backup.RefactoredBackupManagerService.TAG;
22dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikovimport static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
23dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov
24f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.app.AlarmManager;
25f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.app.backup.RestoreSet;
26f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.content.Intent;
27f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.os.Handler;
28f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.os.Looper;
29f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.os.Message;
30f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.os.RemoteException;
31f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.os.UserHandle;
32f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.util.EventLog;
33f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.util.Pair;
34f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport android.util.Slog;
3521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
36f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.internal.backup.IBackupTransport;
37f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.EventLogTags;
38f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.BackupRestoreTask;
39c31a839fd3ecc91807d735884d09fcbaf62e9244Robert Berryimport com.android.server.backup.DataChangedJournal;
40f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.RefactoredBackupManagerService;
41f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.fullbackup.PerformAdbBackupTask;
42f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
43f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.AdbBackupParams;
44f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.AdbParams;
45f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.AdbRestoreParams;
46f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.BackupParams;
47f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.ClearParams;
48f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.ClearRetryParams;
49f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.RestoreGetSetsParams;
50f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.params.RestoreParams;
51f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.restore.PerformAdbRestoreTask;
52f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport com.android.server.backup.restore.PerformUnifiedRestoreTask;
5321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
54f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport java.io.File;
55f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport java.util.ArrayList;
56f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport java.util.Collections;
57f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovimport java.util.HashSet;
58f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
59f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov/**
60f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov * Asynchronous backup/restore handler thread.
61f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov */
62f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikovpublic class BackupHandler extends Handler {
63f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
64c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_BACKUP = 1;
65c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_ADB_BACKUP = 2;
66c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_RESTORE = 3;
67c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_CLEAR = 4;
68c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_GET_RESTORE_SETS = 6;
69c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RESTORE_SESSION_TIMEOUT = 8;
70c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
71c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_ADB_RESTORE = 10;
72c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RETRY_INIT = 11;
73c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RETRY_CLEAR = 12;
74c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_WIDGET_BROADCAST = 13;
75c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14;
76c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_REQUEST_BACKUP = 15;
77c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_SCHEDULE_BACKUP_PACKAGE = 16;
78c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_BACKUP_OPERATION_TIMEOUT = 17;
79c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_RESTORE_OPERATION_TIMEOUT = 18;
80c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    // backup task state machine tick
81c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_BACKUP_RESTORE_STEP = 20;
82c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov    public static final int MSG_OP_COMPLETE = 21;
83c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov
84f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov    private RefactoredBackupManagerService backupManagerService;
85f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
86f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov    public BackupHandler(
8721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov            RefactoredBackupManagerService backupManagerService, Looper looper) {
88f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov        super(looper);
89f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov        this.backupManagerService = backupManagerService;
90f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov    }
91f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
92f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov    public void handleMessage(Message msg) {
93f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
94f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov        switch (msg.what) {
95c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_BACKUP: {
96d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                backupManagerService.setLastBackupPass(System.currentTimeMillis());
9721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
9821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                IBackupTransport transport =
99d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.getTransportManager().getCurrentTransportBinder();
10021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                if (transport == null) {
101dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.v(TAG, "Backup requested but no transport available");
102d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    synchronized (backupManagerService.getQueueLock()) {
103d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.setBackupRunning(false);
10421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
105d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    backupManagerService.getWakelock().release();
10621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    break;
107f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                }
10821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
10921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // snapshot the pending-backup set and work on that
11021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                ArrayList<BackupRequest> queue = new ArrayList<>();
111c31a839fd3ecc91807d735884d09fcbaf62e9244Robert Berry                DataChangedJournal oldJournal = backupManagerService.getJournal();
112d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                synchronized (backupManagerService.getQueueLock()) {
11321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // Do we have any work to do?  Construct the work queue
11421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // then release the synchronization lock to actually run
11521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // the backup.
116d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    if (backupManagerService.getPendingBackups().size() > 0) {
117d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        for (BackupRequest b : backupManagerService.getPendingBackups().values()) {
11821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            queue.add(b);
11921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
120dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        if (DEBUG) {
121dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                            Slog.v(TAG, "clearing pending backups");
12221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
123d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.getPendingBackups().clear();
12421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
12521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // Start a new backup-queue journal file too
126d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.setJournal(null);
12721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
12821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
129f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                }
130f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
13121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // At this point, we have started a new journal file, and the old
13221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // file identity is being passed to the backup processing task.
13321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // When it completes successfully, that old journal file will be
13421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // deleted.  If we crash prior to that, the old journal is parsed
13521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // at next boot and the journaled requests fulfilled.
13621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                boolean staged = true;
13721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                if (queue.size() > 0) {
13821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // Spin up a backup state sequence and set it running
13921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    try {
14021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        String dirName = transport.transportDirName();
14121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        PerformBackupTask pbt = new PerformBackupTask(
14221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                                backupManagerService, transport, dirName, queue,
14321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                                oldJournal, null, null, Collections.<String>emptyList(), false,
14421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                                false /* nonIncremental */);
145c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov                        Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
14621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        sendMessage(pbtMessage);
14721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    } catch (Exception e) {
14821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // unable to ask the transport its dir name -- transient failure, since
14921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // the above check succeeded.  Try again next time.
150dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        Slog.e(TAG, "Transport became unavailable attempting backup"
151dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                                + " or error initializing backup task", e);
15221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        staged = false;
15321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
15421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                } else {
155dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.v(TAG, "Backup requested but nothing pending");
15621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    staged = false;
15721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
158f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
15921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                if (!staged) {
16021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // if we didn't actually hand off the wakelock, rewind until next time
161d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    synchronized (backupManagerService.getQueueLock()) {
162d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.setBackupRunning(false);
16321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
164d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    backupManagerService.getWakelock().release();
16521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
16621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
167f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
168f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
169c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_BACKUP_RESTORE_STEP: {
17021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                try {
17121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    BackupRestoreTask task = (BackupRestoreTask) msg.obj;
172dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    if (MORE_DEBUG) {
173dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        Slog.v(TAG, "Got next step for " + task + ", executing");
17421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
17521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    task.execute();
17621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                } catch (ClassCastException e) {
177dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.e(TAG, "Invalid backup task in flight, obj=" + msg.obj);
17821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
17921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
180f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
181f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
182c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_OP_COMPLETE: {
18321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                try {
18421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    Pair<BackupRestoreTask, Long> taskWithResult =
18521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            (Pair<BackupRestoreTask, Long>) msg.obj;
18621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    taskWithResult.first.operationComplete(taskWithResult.second);
18721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                } catch (ClassCastException e) {
188dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
18921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
19021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
191f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
19221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
193c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_ADB_BACKUP: {
19421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // TODO: refactor full backup to be a looper-based state machine
19521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // similar to normal backup/restore.
19621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                AdbBackupParams params = (AdbBackupParams) msg.obj;
19721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                PerformAdbBackupTask task = new PerformAdbBackupTask(backupManagerService,
19821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.fd,
19921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.observer, params.includeApks, params.includeObbs,
20021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.includeShared, params.doWidgets, params.curPassword,
20121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.encryptPassword, params.allApps, params.includeSystem,
20221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.doCompress, params.includeKeyValue, params.packages, params.latch);
20321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                (new Thread(task, "adb-backup")).start();
20421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
205f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
20621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
207c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_FULL_TRANSPORT_BACKUP: {
20821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                PerformFullTransportBackupTask task = (PerformFullTransportBackupTask) msg.obj;
20921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                (new Thread(task, "transport-backup")).start();
21021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
211f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
21221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
213c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_RESTORE: {
21421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                RestoreParams params = (RestoreParams) msg.obj;
215dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
21621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
21721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(backupManagerService,
21821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.transport,
21921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.observer, params.monitor, params.token, params.pkgInfo,
22021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.pmToken, params.isSystemRestore, params.filterSet);
22121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
222d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                synchronized (backupManagerService.getPendingRestores()) {
223d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    if (backupManagerService.isRestoreInProgress()) {
224dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        if (DEBUG) {
225dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                            Slog.d(TAG, "Restore in progress, queueing.");
22621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
227d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.getPendingRestores().add(task);
22821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // This task will be picked up and executed when the the currently running
22921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // restore task finishes.
23021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    } else {
231dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        if (DEBUG) {
232dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                            Slog.d(TAG, "Starting restore.");
23321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
234d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.setRestoreInProgress(true);
235c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov                        Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
23621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        sendMessage(restoreMsg);
23721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
238f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                }
23921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
24021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov            }
24121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
242c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_ADB_RESTORE: {
24321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // TODO: refactor full restore to be a looper-based state machine
24421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // similar to normal backup/restore.
24521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                AdbRestoreParams params = (AdbRestoreParams) msg.obj;
24621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                PerformAdbRestoreTask task = new PerformAdbRestoreTask(backupManagerService,
24721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.fd,
24821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.curPassword, params.encryptPassword,
24921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.observer, params.latch);
25021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                (new Thread(task, "adb-restore")).start();
25121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
25221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov            }
25321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
254c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_CLEAR: {
25521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                ClearParams params = (ClearParams) msg.obj;
25621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                (new PerformClearTask(backupManagerService, params.transport,
25721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.packageInfo)).run();
25821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
259f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
26021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
261c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RETRY_CLEAR: {
26221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // reenqueues if the transport remains unavailable
26321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                ClearRetryParams params = (ClearRetryParams) msg.obj;
26421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                backupManagerService.clearBackupData(params.transportName, params.packageName);
26521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
266f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
267f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
268c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RETRY_INIT: {
269d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                synchronized (backupManagerService.getQueueLock()) {
27021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    backupManagerService.recordInitPendingLocked(msg.arg1 != 0, (String) msg.obj);
271d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
27221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            System.currentTimeMillis(),
273d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                            backupManagerService.getRunInitIntent());
27421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
27521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
276f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
27721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
278c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RUN_GET_RESTORE_SETS: {
27921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                // Like other async operations, this is entered with the wakelock held
28021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                RestoreSet[] sets = null;
28121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                RestoreGetSetsParams params = (RestoreGetSetsParams) msg.obj;
282f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                try {
28321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    sets = params.transport.getAvailableRestoreSets();
28421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // cache the result in the active session
28521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    synchronized (params.session) {
28621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.session.mRestoreSets = sets;
28721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
28821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    if (sets == null) {
28921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
29021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
291f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                } catch (Exception e) {
292dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.e(TAG, "Error from transport getting set list: " + e.getMessage());
29321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                } finally {
29421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    if (params.observer != null) {
29521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        try {
29621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            params.observer.restoreSetsAvailable(sets);
29721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        } catch (RemoteException re) {
298dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                            Slog.e(TAG, "Unable to report listing to observer");
29921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        } catch (Exception e) {
300dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                            Slog.e(TAG, "Restore observer threw: " + e.getMessage());
30121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
30221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
30321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
30421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    // Done: reset the session timeout clock
305c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov                    removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
306dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
30721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
308d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    backupManagerService.getWakelock().release();
309f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                }
31021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
31121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov            }
312f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov
313c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_BACKUP_OPERATION_TIMEOUT:
314c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RESTORE_OPERATION_TIMEOUT: {
315dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1));
31621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                backupManagerService.handleCancel(msg.arg1, false);
31721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
318f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
31921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
320c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_RESTORE_SESSION_TIMEOUT: {
32121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                synchronized (backupManagerService) {
322d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    if (backupManagerService.getActiveRestoreSession() != null) {
32321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // Client app left the restore session dangling.  We know that it
32421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // can't be in the middle of an actual restore operation because
32521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // the timeout is suspended while a restore is in progress.  Clean
32621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // up now.
327dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        Slog.w(TAG, "Restore session timed out; aborting");
328d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.getActiveRestoreSession().markTimedOut();
329d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        post(backupManagerService.getActiveRestoreSession().new EndRestoreRunnable(
330d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                                backupManagerService,
331d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                                backupManagerService.getActiveRestoreSession()));
33221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
33321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
33421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
335f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
33621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
337c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_FULL_CONFIRMATION_TIMEOUT: {
338d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                synchronized (backupManagerService.getAdbBackupRestoreConfirmations()) {
339d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                    AdbParams params = backupManagerService.getAdbBackupRestoreConfirmations().get(
34021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            msg.arg1);
34121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    if (params != null) {
342dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation");
34321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
34421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // Release the waiter; timeout == completion
34521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        backupManagerService.signalAdbBackupRestoreCompletion(params);
34621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
34721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // Remove the token from the set
348d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                        backupManagerService.getAdbBackupRestoreConfirmations().delete(msg.arg1);
34921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
35021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        // Report a timeout to the observer, if any
35121510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        if (params.observer != null) {
35221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            try {
35321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                                params.observer.onTimeout();
35421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            } catch (RemoteException e) {
355f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                            /* don't care if the app has gone away */
35621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                            }
35721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        }
35821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    } else {
359dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                        Slog.d(TAG, "couldn't find params for token " + msg.arg1);
36021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    }
361f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov                }
36221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
363f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
36421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
365c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_WIDGET_BROADCAST: {
36621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                final Intent intent = (Intent) msg.obj;
367d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                backupManagerService.getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
36821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
369f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
37021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
371c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_REQUEST_BACKUP: {
37221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                BackupParams params = (BackupParams) msg.obj;
373dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                if (MORE_DEBUG) {
374dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer);
37521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
37621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                ArrayList<BackupRequest> kvQueue = new ArrayList<>();
37721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                for (String packageName : params.kvPackages) {
37821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                    kvQueue.add(new BackupRequest(packageName));
37921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
380d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                backupManagerService.setBackupRunning(true);
381d6c00c711000aa70db51f46b48a86c2884e91b15Artem Iglikov                backupManagerService.getWakelock().acquire();
38221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
38321510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                PerformBackupTask pbt = new PerformBackupTask(
38421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        backupManagerService,
38521510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.transport, params.dirName,
38621510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        kvQueue, null, params.observer, params.monitor, params.fullPackages, true,
38721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                        params.nonIncrementalBackup);
388c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov                Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
38921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                sendMessage(pbtMessage);
39021510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
391f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
39221510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov
393c2a3d0fb3a25dd3f8171d24e1815da1f7f749e13Artem Iglikov            case MSG_SCHEDULE_BACKUP_PACKAGE: {
39421510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                String pkgName = (String) msg.obj;
395dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                if (MORE_DEBUG) {
396dbe68324801cfd45d0d1116c9da983b8ebe651aeArtem Iglikov                    Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
39721510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                }
39821510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                backupManagerService.dataChangedImpl(pkgName);
39921510f0b7571f0689dc48c4f8fdbafea883cbdd0Artem Iglikov                break;
400f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov            }
401f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov        }
402f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov    }
403f251e3509838e3fbc62ccdba9d4cfd0527f67acdArtem Iglikov}
404