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
194528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.RestoreSession;
204528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IBackupManager;
214528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.IRestoreSession;
22a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.content.Context;
23a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.RemoteException;
24a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tateimport android.os.ServiceManager;
25c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tateimport android.util.Log;
26a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
27a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate/**
28d17da43c82c4edb97514d6138bc208eeba321636Scott Main * The interface through which an application interacts with the Android backup service to
29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * request backup and restore operations.
30d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Applications instantiate it using the constructor and issue calls through that instance.
315a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
325a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * When an application has made changes to data which should be backed up, a
335a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * call to {@link #dataChanged()} will notify the backup service. The system
345a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * will then schedule a backup operation to occur in the near future. Repeated
355a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * calls to {@link #dataChanged()} have no further effect until the backup
365a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * operation actually occurs.
375a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
38d17da43c82c4edb97514d6138bc208eeba321636Scott Main * A backup or restore operation for your application begins when the system launches the
39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link android.app.backup.BackupAgent} subclass you've declared in your manifest. See the
404528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate * documentation for {@link android.app.backup.BackupAgent} for a detailed description
414e14a829129feee14ebe453f61a124784c870610Christopher Tate * of how the operation then proceeds.
425a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * <p>
434e14a829129feee14ebe453f61a124784c870610Christopher Tate * Several attributes affecting the operation of the backup and restore mechanism
44d17da43c82c4edb97514d6138bc208eeba321636Scott Main * can be set on the <code><a
45d17da43c82c4edb97514d6138bc208eeba321636Scott Main * href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
46d17da43c82c4edb97514d6138bc208eeba321636Scott Main * tag in your application's AndroidManifest.xml file.
47d17da43c82c4edb97514d6138bc208eeba321636Scott Main *
485a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup
495a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent
505a20ea16d7e5b70dc7bad8700f54170e4f220d12Kenny Root * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore
514e14a829129feee14ebe453f61a124784c870610Christopher Tate * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion
52a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate */
53a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tatepublic class BackupManager {
54c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static final String TAG = "BackupManager";
55c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate
56a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    private Context mContext;
57c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static IBackupManager sService;
58a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
59c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    private static void checkServiceBinder() {
60c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService == null) {
61c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            sService = IBackupManager.Stub.asInterface(
62c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                    ServiceManager.getService(Context.BACKUP_SERVICE));
63c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        }
64c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    }
65043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate
66043dadc7516d20c3b3ccbcb20c53aaeef076a237Christopher Tate    /**
67a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * Constructs a BackupManager object through which the application can
68a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * communicate with the Android backup system.
69c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate     *
70a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * @param context The {@link android.content.Context} that was provided when
71a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     *                one of your application's {@link android.app.Activity Activities}
72a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     *                was created.
73a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     */
74c114eb55b442981e2ea0a8989aa6ed458fc418e4Christopher Tate    public BackupManager(Context context) {
75a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate        mContext = context;
76a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    }
77a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate
78a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    /**
79a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * Notifies the Android backup system that your application wishes to back up
80a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     * new changes to its data.  A backup operation using your application's
814e14a829129feee14ebe453f61a124784c870610Christopher Tate     * {@link android.app.backup.BackupAgent} subclass will be scheduled when you
824e14a829129feee14ebe453f61a124784c870610Christopher Tate     * call this method.
83a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate     */
84a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    public void dataChanged() {
85c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
86c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
87c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            try {
88c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sService.dataChanged(mContext.getPackageName());
89c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            } catch (RemoteException e) {
90c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                Log.d(TAG, "dataChanged() couldn't connect");
91c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate            }
92c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        }
93c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    }
94c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate
95c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    /**
96c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     * Convenience method for callers who need to indicate that some other package
974e14a829129feee14ebe453f61a124784c870610Christopher Tate     * needs a backup pass.  This can be useful in the case of groups of packages
984e14a829129feee14ebe453f61a124784c870610Christopher Tate     * that share a uid.
994e14a829129feee14ebe453f61a124784c870610Christopher Tate     * <p>
100c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     * This method requires that the application hold the "android.permission.BACKUP"
1014e14a829129feee14ebe453f61a124784c870610Christopher Tate     * permission if the package named in the argument does not run under the same uid
1024e14a829129feee14ebe453f61a124784c870610Christopher Tate     * as the caller.
103d17da43c82c4edb97514d6138bc208eeba321636Scott Main     *
104d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * @param packageName The package name identifying the application to back up.
105c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate     */
106c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    public static void dataChanged(String packageName) {
107c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
108c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
1098a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            try {
110c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sService.dataChanged(packageName);
1118a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            } catch (RemoteException e) {
112c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                Log.d(TAG, "dataChanged(pkg) couldn't connect");
1138a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            }
114a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate        }
115a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate    }
1169b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate
1179b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate    /**
1189c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * Restore the calling application from backup.  The data will be restored from the
1199c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * current backup dataset if the application has stored data there, or from
1209c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * the dataset used during the last full device setup operation if the current
1219c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * backup dataset has no matching data.  If no backup data exists for this application
1229c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * in either source, a nonzero value will be returned.
1239c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     *
1249c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * <p>If this method returns zero (meaning success), the OS will attempt to retrieve
1259c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * a backed-up dataset from the remote transport, instantiate the application's
1269c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * backup agent, and pass the dataset to the agent's
1279c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()}
1289c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * method.
1299c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     *
130d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * @param observer The {@link RestoreObserver} to receive callbacks during the restore
131d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * operation. This must not be null.
132d17da43c82c4edb97514d6138bc208eeba321636Scott Main     *
1339c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * @return Zero on success; nonzero on error.
1349c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     */
1359c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    public int requestRestore(RestoreObserver observer) {
1369c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        int result = -1;
1379c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        checkServiceBinder();
1389c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        if (sService != null) {
1399c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            RestoreSession session = null;
1409c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            try {
1419c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                String transport = sService.getCurrentTransport();
1429c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                IRestoreSession binder = sService.beginRestoreSession(transport);
1439c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                session = new RestoreSession(mContext, binder);
1449c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                result = session.restorePackage(mContext.getPackageName(), observer);
1459c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            } catch (RemoteException e) {
1469c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                Log.w(TAG, "restoreSelf() unable to contact service");
1479c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            } finally {
1489c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                if (session != null) {
1499c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                    session.endRestoreSession();
1509c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate                }
1519c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate            }
1529c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        }
1539c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate        return result;
1549c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    }
1559c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate
1569c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate    /**
157e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Begin the process of restoring data from backup.  See the
1584528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate     * {@link android.app.backup.RestoreSession} class for documentation on that process.
1599c3cee9824026764275e4d84ba9b5d9fdc5da690Christopher Tate     * @hide
1609b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate     */
16180202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate    public RestoreSession beginRestoreSession() {
16280202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        RestoreSession session = null;
163c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        checkServiceBinder();
164c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate        if (sService != null) {
1658a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            try {
16680202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate                String transport = sService.getCurrentTransport();
16780202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate                IRestoreSession binder = sService.beginRestoreSession(transport);
16880202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate                session = new RestoreSession(mContext, binder);
1698a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            } catch (RemoteException e) {
170e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate                Log.w(TAG, "beginRestoreSession() couldn't connect");
1718a27f923eb9dbbe3c2d0184e82d9f1a98f1e4cdcChristopher Tate            }
1729b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate        }
17380202c8cb8c8e4ab507079e79b864c61a8eeeee9Christopher Tate        return session;
1749b3905c4a25f2d785ce7535d1f2e1540b46bb561Christopher Tate    }
175a8bf815c6153290b173f34b071dddb0a0034a115Christopher Tate}
176