BackupManager.java revision 4b51d99a019f9b14e5698ba16e9540c179bdcd05
1a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/*
2a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Copyright (C) 2009 The Android Open Source Project
3a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate *
4a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License");
5a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * you may not use this file except in compliance with the License.
6a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * You may obtain a copy of the License at
7a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate *
8a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate *      http://www.apache.org/licenses/LICENSE-2.0
9a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate *
10a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * Unless required by applicable law or agreed to in writing, software
11a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS,
12a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * See the License for the specific language governing permissions and
14a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate * limitations under the License.
15a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */
16a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup;
18a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
19d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tateimport android.annotation.SystemApi;
20a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.content.Context;
21fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.os.Handler;
22fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.os.Message;
23a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.RemoteException;
24a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.ServiceManager;
25c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tateimport android.util.Log;
26fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromovimport android.util.Pair;
27a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
28a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/**
29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * The interface through which an application interacts with the Android backup service to
30d17da43c82c4edb97514d6138bc208eeba321636Scott Main * request backup and restore operations.
31d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Applications instantiate it using the constructor and issue calls through that instance.
325a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
335a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * When an application has made changes to data which should be backed up, a
345a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * call to {@link #dataChanged()} will notify the backup service. The system
355a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * will then schedule a backup operation to occur in the near future. Repeated
365a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * calls to {@link #dataChanged()} have no further effect until the backup
375a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation actually occurs.
385a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A backup or restore operation for your application begins when the system launches the
40d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link android.app.backup.BackupAgent} subclass you've declared in your manifest. See the
414528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * documentation for {@link android.app.backup.BackupAgent} for a detailed description
424e14a829129feee14ebe453f61a124784c870610Christopher Tate * of how the operation then proceeds.
435a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
444e14a829129feee14ebe453f61a124784c870610Christopher Tate * Several attributes affecting the operation of the backup and restore mechanism
4561fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * can be set on the <code>
4661fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * tag in your application's AndroidManifest.xml file.
48d17da43c82c4edb97514d6138bc208eeba321636Scott Main *
4961fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <div class="special reference">
5061fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <h3>Developer Guides</h3>
5161fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <p>For more information about using BackupManager, read the
5261fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/data/backup.html">Data Backup</a> developer guide.</p></div>
5361fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez *
545a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup
555a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent
565a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore
574e14a829129feee14ebe453f61a124784c870610Christopher Tate * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion
58a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */
59a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tatepublic class BackupManager {
60c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static final String TAG = "BackupManager";
61c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate
62fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    // BackupObserver status codes
63fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
64fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * Indicates that backup succeeded.
65fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
66fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
67fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
68fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
69fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int SUCCESS = 0;
70fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
71fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
72fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * Indicates that backup is either not enabled at all or
73fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * backup for the package was rejected by backup service
74fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * or backup transport,
75fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
76fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
77fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
78fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
79fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int ERROR_BACKUP_NOT_ALLOWED = -2001;
80fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
81fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
82fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * The requested app is not installed on the device.
83fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
84fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
85fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
86fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
87fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int ERROR_PACKAGE_NOT_FOUND = -2002;
88fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
89fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
90fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * The transport for some reason was not in a good state and
91fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * aborted the entire backup request. This is a transient
92fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * failure and should not be retried immediately.
93fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
94fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
95fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
96fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
97fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int ERROR_TRANSPORT_ABORTED = BackupTransport.TRANSPORT_ERROR;
98fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
99fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
100fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * Returned when the transport was unable to process the
101fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * backup request for a given package, for example if the
102fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * transport hit a transient network failure. The remaining
103fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * packages provided to {@link #requestBackup(String[], BackupObserver)}
104fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * will still be attempted.
105fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
106fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
107fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
108fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
109fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int ERROR_TRANSPORT_PACKAGE_REJECTED =
110fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            BackupTransport.TRANSPORT_PACKAGE_REJECTED;
111fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
112fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
113fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * The {@link BackupAgent} for the requested package failed for some reason
114fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * and didn't provide appropriate backup data.
115fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
116fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
117fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
118fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
119fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public static final int ERROR_AGENT_FAILURE = BackupTransport.AGENT_ERROR;
120fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
121a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    private Context mContext;
122c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static IBackupManager sService;
123a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
124c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static void checkServiceBinder() {
125c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService == null) {
126c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            sService = IBackupManager.Stub.asInterface(
127c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                    ServiceManager.getService(Context.BACKUP_SERVICE));
128c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        }
129c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    }
130043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate
131043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate    /**
132a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * Constructs a BackupManager object through which the application can
133a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * communicate with the Android backup system.
134c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate     *
135a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * @param context The {@link android.content.Context} that was provided when
136a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     *                one of your application's {@link android.app.Activity Activities}
137a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     *                was created.
138a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     */
139c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate    public BackupManager(Context context) {
140a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate        mContext = context;
141a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    }
142a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
143a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    /**
144a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * Notifies the Android backup system that your application wishes to back up
145a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * new changes to its data.  A backup operation using your application's
1464e14a829129feee14ebe453f61a124784c870610Christopher Tate     * {@link android.app.backup.BackupAgent} subclass will be scheduled when you
1474e14a829129feee14ebe453f61a124784c870610Christopher Tate     * call this method.
148a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     */
149a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    public void dataChanged() {
150c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
151c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
152c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            try {
153c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sService.dataChanged(mContext.getPackageName());
154c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            } catch (RemoteException e) {
155c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                Log.d(TAG, "dataChanged() couldn't connect");
156c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            }
157c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        }
158c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    }
159c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate
160c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    /**
161c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     * Convenience method for callers who need to indicate that some other package
1624e14a829129feee14ebe453f61a124784c870610Christopher Tate     * needs a backup pass.  This can be useful in the case of groups of packages
1634e14a829129feee14ebe453f61a124784c870610Christopher Tate     * that share a uid.
1644e14a829129feee14ebe453f61a124784c870610Christopher Tate     * <p>
165c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     * This method requires that the application hold the "android.permission.BACKUP"
1664e14a829129feee14ebe453f61a124784c870610Christopher Tate     * permission if the package named in the argument does not run under the same uid
1674e14a829129feee14ebe453f61a124784c870610Christopher Tate     * as the caller.
168d17da43c82c4edb97514d6138bc208eeba321636Scott Main     *
169d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * @param packageName The package name identifying the application to back up.
170c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     */
171c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    public static void dataChanged(String packageName) {
172c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
173c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
1748a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            try {
175c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sService.dataChanged(packageName);
1768a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            } catch (RemoteException e) {
177d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "dataChanged(pkg) couldn't connect");
1788a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            }
179a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate        }
180a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    }
1819b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate
1829b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate    /**
1839c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * Restore the calling application from backup.  The data will be restored from the
1849c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * current backup dataset if the application has stored data there, or from
1859c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * the dataset used during the last full device setup operation if the current
1869c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * backup dataset has no matching data.  If no backup data exists for this application
1879c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * in either source, a nonzero value will be returned.
1889c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     *
1899c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * <p>If this method returns zero (meaning success), the OS will attempt to retrieve
1909c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * a backed-up dataset from the remote transport, instantiate the application's
1919c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * backup agent, and pass the dataset to the agent's
1929c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()}
1939c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * method.
1949c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     *
195d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * @param observer The {@link RestoreObserver} to receive callbacks during the restore
196d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * operation. This must not be null.
197d17da43c82c4edb97514d6138bc208eeba321636Scott Main     *
1989c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * @return Zero on success; nonzero on error.
1999c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     */
2009c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    public int requestRestore(RestoreObserver observer) {
2019c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        int result = -1;
2029c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        checkServiceBinder();
2039c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        if (sService != null) {
2049c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            RestoreSession session = null;
2059c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            try {
20644ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate                IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(),
20744ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate                        null);
208f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                if (binder != null) {
209f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                    session = new RestoreSession(mContext, binder);
210f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                    result = session.restorePackage(mContext.getPackageName(), observer);
211f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                }
2129c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            } catch (RemoteException e) {
213d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "restoreSelf() unable to contact service");
2149c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            } finally {
2159c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                if (session != null) {
2169c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                    session.endRestoreSession();
2179c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                }
2189c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            }
2199c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        }
2209c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        return result;
2219c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    }
2229c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate
2232e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate    // system APIs start here
2242e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate
2259c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    /**
226e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Begin the process of restoring data from backup.  See the
2274528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate     * {@link android.app.backup.RestoreSession} class for documentation on that process.
2289c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * @hide
2299b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate     */
2302e5979236ccc06beec8b8f7f631f31bdedc79614Christopher Tate    @SystemApi
23180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    public RestoreSession beginRestoreSession() {
23280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        RestoreSession session = null;
233c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
234c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
2358a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            try {
23644ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate                // All packages, current transport
23744ab8453e1c4c46790f792a46d026fa1017d8cfeChris Tate                IRestoreSession binder = sService.beginRestoreSession(null, null);
238f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                if (binder != null) {
239f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                    session = new RestoreSession(mContext, binder);
240f5491fc1b61088843f280a6b55c1a995e2e6f939Christopher Tate                }
2418a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            } catch (RemoteException e) {
242d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "beginRestoreSession() couldn't connect");
2438a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            }
2449b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate        }
24580202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        return session;
2469b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate    }
247d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
248d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
249d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Enable/disable the backup service entirely.  When disabled, no backup
250d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * or restore operations will take place.  Data-changed notifications will
251d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * still be observed and collected, however, so that changes made while the
252d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * mechanism was disabled will still be backed up properly if it is enabled
253d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * at some point in the future.
254d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
255d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
256d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
257d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
258d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
259d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
260d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public void setBackupEnabled(boolean isEnabled) {
261d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        checkServiceBinder();
262d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
263d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
264d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                sService.setBackupEnabled(isEnabled);
265d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
266d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "setBackupEnabled() couldn't connect");
267d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
268d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
269d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
270d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
271d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
272d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Report whether the backup mechanism is currently enabled.
273d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
274d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
275d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
276d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
277d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
278d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
279d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public boolean isBackupEnabled() {
2809e079298edd022c43a960729442a53557fd16e45Christopher Tate        checkServiceBinder();
281d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
282d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
283d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                return sService.isBackupEnabled();
284d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
285d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "isBackupEnabled() couldn't connect");
286d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
287d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
288d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        return false;
289d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
290d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
291d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
292a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * Enable/disable data restore at application install time.  When enabled, app
293a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * installation will include an attempt to fetch the app's historical data from
294a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * the archival restore dataset (if any).  When disabled, no such attempt will
295a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * be made.
296a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     *
297a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
298a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     *
299a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     * @hide
300a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate     */
301a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate    @SystemApi
302a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate    public void setAutoRestore(boolean isEnabled) {
303a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate        checkServiceBinder();
304a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate        if (sService != null) {
305a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate            try {
306a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate                sService.setAutoRestore(isEnabled);
307a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate            } catch (RemoteException e) {
308a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate                Log.e(TAG, "setAutoRestore() couldn't connect");
309a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate            }
310a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate        }
311a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate    }
312a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate
313a63246d6daa02c6f3e4e78d0072d991387e14c87Christopher Tate    /**
314d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Identify the currently selected transport.  Callers must hold the
315d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * android.permission.BACKUP permission to use this method.
316d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @return The name of the currently active backup transport.  In case of
317d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *   failure or if no transport is currently active, this method returns {@code null}.
318d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
319d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
320d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
321d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
322d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public String getCurrentTransport() {
323d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        checkServiceBinder();
324d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
325d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
326d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                return sService.getCurrentTransport();
327d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
328d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "getCurrentTransport() couldn't connect");
329d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
330d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
331d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        return null;
332d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
333d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
334d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
335d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Request a list of all available backup transports' names.  Callers must
336d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * hold the android.permission.BACKUP permission to use this method.
337d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
338d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
339d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
340d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
341d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public String[] listAllTransports() {
342d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        checkServiceBinder();
343d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
344d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
345d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                return sService.listAllTransports();
346d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
347d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "listAllTransports() couldn't connect");
348d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
349d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
350d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        return null;
351d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
352d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
353d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
354d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Specify the current backup transport.  Callers must hold the
355d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * android.permission.BACKUP permission to use this method.
356d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
357d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @param transport The name of the transport to select.  This should be one
358d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *   of the names returned by {@link #listAllTransports()}.
359d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @return The name of the previously selected transport.  If the given transport
360d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *   name is not one of the currently available transports, no change is made to
361d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *   the current transport setting and the method returns null.
362d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
363d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
364d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
365d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
366d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public String selectBackupTransport(String transport) {
367d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        checkServiceBinder();
368d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
369d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
370d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                return sService.selectBackupTransport(transport);
371d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
372d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "selectBackupTransport() couldn't connect");
373d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
374d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
375d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        return null;
376d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
377d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate
378d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    /**
379d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * Schedule an immediate backup attempt for all pending key/value updates.  This
380d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * is primarily intended for transports to use when they detect a suitable
381d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * opportunity for doing a backup pass.  If there are no pending updates to
382d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * be sent, no action will be taken.  Even if some updates are pending, the
383d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * transport will still be asked to confirm via the usual requestBackupTime()
384d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * method.
385d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
386d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
387d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     *
388d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     * @hide
389d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate     */
390d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    @SystemApi
391d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    public void backupNow() {
392d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        checkServiceBinder();
393d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        if (sService != null) {
394d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            try {
395d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                sService.backupNow();
396d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            } catch (RemoteException e) {
397d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate                Log.e(TAG, "backupNow() couldn't connect");
398d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate            }
399d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate        }
400d5cf722ae62d06d1fb6a9505c6f4c403a5d14a37Christopher Tate    }
401511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate
402511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate    /**
403511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * Ask the framework which dataset, if any, the given package's data would be
404511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * restored from if we were to install it right now.
405511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     *
406511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
407511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     *
408511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * @param packageName The name of the package whose most-suitable dataset we
409511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     *     wish to look up
410511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * @return The dataset token from which a restore should be attempted, or zero if
411511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     *     no suitable data is available.
412511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     *
413511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     * @hide
414511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate     */
415511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate    @SystemApi
416511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate    public long getAvailableRestoreToken(String packageName) {
417511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate        checkServiceBinder();
418511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate        if (sService != null) {
419511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate            try {
420511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate                return sService.getAvailableRestoreToken(packageName);
421511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate            } catch (RemoteException e) {
422511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate                Log.e(TAG, "getAvailableRestoreToken() couldn't connect");
423511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate            }
424511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate        }
425511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate        return 0;
426511d02fcc37dce092e17354d53023db44817ebe6Christopher Tate    }
427fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
428fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /**
4299448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     * Ask the framework whether this app is eligible for backup.
4309448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     *
4319448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
4329448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     *
4339448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     * @param packageName The name of the package.
4349448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     * @return Whether this app is eligible for backup.
4359448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     *
4369448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     * @hide
4379448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov     */
4389448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov    @SystemApi
4399448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov    public boolean isAppEligibleForBackup(String packageName) {
4409448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov        checkServiceBinder();
4419448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov        if (sService != null) {
4429448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov            try {
4439448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov                return sService.isAppEligibleForBackup(packageName);
4449448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov            } catch (RemoteException e) {
4459448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov                Log.e(TAG, "isAppEligibleForBackup(pkg) couldn't connect");
4469448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov            }
4479448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov        }
4489448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov        return false;
4499448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov    }
4509448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov
4519448196076d5a5266b3ae7e4945216b30ee88aa7Sergey Poromov    /**
452fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * Request an immediate backup, providing an observer to which results of the backup operation
453fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * will be published. The Android backup system will decide for each package whether it will
454fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * be full app data backup or key/value-pair-based backup.
455fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
456fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * <p>If this method returns {@link BackupManager#SUCCESS}, the OS will attempt to backup all
457fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * provided packages using the remote transport.
458fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
459fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @param packages List of package names to backup.
460fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @param observer The {@link BackupObserver} to receive callbacks during the backup
461fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * operation.
462fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @return {@link BackupManager#SUCCESS} on success; nonzero on error.
463fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @exception  IllegalArgumentException on null or empty {@code packages} param.
464fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     *
465fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * @hide
466fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
467fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
468fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    public int requestBackup(String[] packages, BackupObserver observer) {
469fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        checkServiceBinder();
470fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        if (sService != null) {
471fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            try {
472fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                BackupObserverWrapper observerWrapper =
473fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                    new BackupObserverWrapper(mContext, observer);
474fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                return sService.requestBackup(packages, observerWrapper);
475fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            } catch (RemoteException e) {
476fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                Log.e(TAG, "requestBackup() couldn't connect");
477fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            }
478fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        }
479fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        return -1;
480fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    }
481fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
482fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    /*
483fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * We wrap incoming binder calls with a private class implementation that
484fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * redirects them into main-thread actions.  This serializes the backup
485fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     * progress callbacks nicely within the usual main-thread lifecycle pattern.
486fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov     */
487fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    @SystemApi
488fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    private class BackupObserverWrapper extends IBackupObserver.Stub {
489fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        final Handler mHandler;
490fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        final BackupObserver mObserver;
491fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
492fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        static final int MSG_UPDATE = 1;
493fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        static final int MSG_RESULT = 2;
494fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        static final int MSG_FINISHED = 3;
495fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
496fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        BackupObserverWrapper(Context context, BackupObserver observer) {
497fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            mHandler = new Handler(context.getMainLooper()) {
498fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                @Override
499fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                public void handleMessage(Message msg) {
500fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                    switch (msg.what) {
501fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                        case MSG_UPDATE:
502fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            Pair<String, BackupProgress> obj =
503fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                                (Pair<String, BackupProgress>) msg.obj;
504fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            mObserver.onUpdate(obj.first, obj.second);
505fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            break;
506fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                        case MSG_RESULT:
507fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            mObserver.onResult((String)msg.obj, msg.arg1);
508fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            break;
509fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                        case MSG_FINISHED:
510fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            mObserver.backupFinished(msg.arg1);
511fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            break;
512fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                        default:
513fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            Log.w(TAG, "Unknown message: " + msg);
514fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                            break;
515fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                    }
516fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                }
517fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            };
518fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            mObserver = observer;
519fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        }
520fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
521fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        // Binder calls into this object just enqueue on the main-thread handler
522fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        @Override
523fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        public void onUpdate(String currentPackage, BackupProgress backupProgress) {
524fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            mHandler.sendMessage(
525fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                mHandler.obtainMessage(MSG_UPDATE, Pair.create(currentPackage, backupProgress)));
526fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        }
527fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
528fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        @Override
529fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        public void onResult(String currentPackage, int status) {
530fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            mHandler.sendMessage(
5314b51d99a019f9b14e5698ba16e9540c179bdcd05Sergey Poromov                mHandler.obtainMessage(MSG_RESULT, status, 0, currentPackage));
532fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        }
533fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov
534fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        @Override
535fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        public void backupFinished(int status) {
536fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov            mHandler.sendMessage(
537fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov                mHandler.obtainMessage(MSG_FINISHED, status, 0));
538fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov        }
539fe06bf64d204c459699b0bf6465f9fb69208345eSergey Poromov    }
540a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate}
541