1b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato/*
2b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Copyright (C) 2009 The Android Open Source Project
3b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
4b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * you may not use this file except in compliance with the License.
6b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * You may obtain a copy of the License at
7b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
8b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato *
10b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * Unless required by applicable law or agreed to in writing, software
11b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * See the License for the specific language governing permissions and
14b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato * limitations under the License.
15b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato */
16b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
174528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tatepackage android.app.backup;
18b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
19ff31addb9b767496ba5c907513be172779eadfc5areteimport android.annotation.SystemApi;
204e14a829129feee14ebe453f61a124784c870610Christopher Tateimport android.os.ParcelFileDescriptor;
2139194c0582463be17513b9ba82802a703b10c934Robert Berry
22b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.FileDescriptor;
231cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport java.io.IOException;
24b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
25e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate/**
26d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Provides the structured interface through which a {@link BackupAgent} commits
27d17da43c82c4edb97514d6138bc208eeba321636Scott Main * information to the backup data set, via its {@link
28d17da43c82c4edb97514d6138bc208eeba321636Scott Main * BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method.  Data written for backup is presented
304e14a829129feee14ebe453f61a124784c870610Christopher Tate * as a set of "entities," key/value pairs in which each binary data record "value" is
314e14a829129feee14ebe453f61a124784c870610Christopher Tate * named with a string "key."
324e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p>
334e14a829129feee14ebe453f61a124784c870610Christopher Tate * To commit a data record to the backup transport, the agent's
34d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
35d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method first writes an "entity header" that supplies the key string for the record
364e14a829129feee14ebe453f61a124784c870610Christopher Tate * and the total size of the binary value for the record.  After the header has been
37d17da43c82c4edb97514d6138bc208eeba321636Scott Main * written, the agent then writes the binary entity value itself.  The entity value can
384e14a829129feee14ebe453f61a124784c870610Christopher Tate * be written in multiple chunks if desired, as long as the total count of bytes written
39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}.
404e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p>
414e14a829129feee14ebe453f61a124784c870610Christopher Tate * Entity key strings are considered to be unique within a given application's backup
42d17da43c82c4edb97514d6138bc208eeba321636Scott Main * data set. If a backup agent writes a new entity under an existing key string, its value will
43d17da43c82c4edb97514d6138bc208eeba321636Scott Main * replace any previous value in the transport's remote data store.  You can remove a record
44d17da43c82c4edb97514d6138bc208eeba321636Scott Main * entirely from the remote data set by writing a new entity header using the
454e14a829129feee14ebe453f61a124784c870610Christopher Tate * existing record's key, but supplying a negative <code>dataSize</code> parameter.
46d17da43c82c4edb97514d6138bc208eeba321636Scott Main * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}.
47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * <h3>Example</h3>
484e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p>
494e14a829129feee14ebe453f61a124784c870610Christopher Tate * Here is an example illustrating a way to back up the value of a String variable
504e14a829129feee14ebe453f61a124784c870610Christopher Tate * called <code>mStringToBackUp</code>:
514e14a829129feee14ebe453f61a124784c870610Christopher Tate * <pre>
524e14a829129feee14ebe453f61a124784c870610Christopher Tate * static final String MY_STRING_KEY = "storedstring";
534e14a829129feee14ebe453f61a124784c870610Christopher Tate *
544e14a829129feee14ebe453f61a124784c870610Christopher Tate * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)}
554e14a829129feee14ebe453f61a124784c870610Christopher Tate *         throws IOException {
564e14a829129feee14ebe453f61a124784c870610Christopher Tate *     ...
574e14a829129feee14ebe453f61a124784c870610Christopher Tate *     byte[] stringBytes = mStringToBackUp.getBytes();
584e14a829129feee14ebe453f61a124784c870610Christopher Tate *     data.writeEntityHeader(MY_STRING_KEY, stringBytes.length);
594e14a829129feee14ebe453f61a124784c870610Christopher Tate *     data.writeEntityData(stringBytes, stringBytes.length);
604e14a829129feee14ebe453f61a124784c870610Christopher Tate *     ...
614e14a829129feee14ebe453f61a124784c870610Christopher Tate * }</pre>
624e14a829129feee14ebe453f61a124784c870610Christopher Tate *
634e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see BackupAgent
64e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */
65b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratopublic class BackupDataOutput {
6639194c0582463be17513b9ba82802a703b10c934Robert Berry
6739194c0582463be17513b9ba82802a703b10c934Robert Berry    private final long mQuota;
6839194c0582463be17513b9ba82802a703b10c934Robert Berry    private final int mTransportFlags;
6939194c0582463be17513b9ba82802a703b10c934Robert Berry
7058b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    long mBackupWriter;
71b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
72ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    /**
73ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * Construct a BackupDataOutput purely for data-stream manipulation.  This instance will
74ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * not report usable quota information.
75ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * @hide */
76ff31addb9b767496ba5c907513be172779eadfc5arete    @SystemApi
7783248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato    public BackupDataOutput(FileDescriptor fd) {
7839194c0582463be17513b9ba82802a703b10c934Robert Berry        this(fd, /*quota=*/ -1, /*transportFlags=*/ 0);
79ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    }
80ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate
81ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    /** @hide */
82ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    @SystemApi
83ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    public BackupDataOutput(FileDescriptor fd, long quota) {
8439194c0582463be17513b9ba82802a703b10c934Robert Berry        this(fd, quota, /*transportFlags=*/ 0);
8539194c0582463be17513b9ba82802a703b10c934Robert Berry    }
8639194c0582463be17513b9ba82802a703b10c934Robert Berry
8739194c0582463be17513b9ba82802a703b10c934Robert Berry    /** @hide */
8839194c0582463be17513b9ba82802a703b10c934Robert Berry    public BackupDataOutput(FileDescriptor fd, long quota, int transportFlags) {
89d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (fd == null) throw new NullPointerException();
90ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate        mQuota = quota;
9139194c0582463be17513b9ba82802a703b10c934Robert Berry        mTransportFlags = transportFlags;
92d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        mBackupWriter = ctor(fd);
93d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (mBackupWriter == 0) {
94d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            throw new RuntimeException("Native initialization failed with fd=" + fd);
95d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
96b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato    }
97b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
98e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
99ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * Returns the quota in bytes for the application's current backup operation.  The
100ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * value can vary for each operation.
101ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     *
102ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     * @see FullBackupDataOutput#getQuota()
103ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate     */
104ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    public long getQuota() {
105ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate        return mQuota;
106ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    }
107ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate
108ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate    /**
10939194c0582463be17513b9ba82802a703b10c934Robert Berry     * Returns flags with additional information about the backup transport. For supported flags see
11039194c0582463be17513b9ba82802a703b10c934Robert Berry     * {@link android.app.backup.BackupAgent}
11139194c0582463be17513b9ba82802a703b10c934Robert Berry     *
11239194c0582463be17513b9ba82802a703b10c934Robert Berry     * @see FullBackupDataOutput#getTransportFlags()
11339194c0582463be17513b9ba82802a703b10c934Robert Berry     */
11439194c0582463be17513b9ba82802a703b10c934Robert Berry    public int getTransportFlags() {
11539194c0582463be17513b9ba82802a703b10c934Robert Berry        return mTransportFlags;
11639194c0582463be17513b9ba82802a703b10c934Robert Berry    }
11739194c0582463be17513b9ba82802a703b10c934Robert Berry
11839194c0582463be17513b9ba82802a703b10c934Robert Berry    /**
119d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * Mark the beginning of one record in the backup data stream. This must be called before
120d17da43c82c4edb97514d6138bc208eeba321636Scott Main     * {@link #writeEntityData}.
121adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate     * @param key A string key that uniquely identifies the data record within the application.
122adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate     *    Keys whose first character is \uFF00 or higher are not valid.
123e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param dataSize The size in bytes of this record's data.  Passing a dataSize
124e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *    of -1 indicates that the record under this key should be deleted.
125e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return The number of bytes written to the backup stream
126e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IOException if the write failed
127e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
1281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public int writeEntityHeader(String key, int dataSize) throws IOException {
1291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
1301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (result >= 0) {
1311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return result;
1321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
1331cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IOException("result=0x" + Integer.toHexString(result));
1341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
1351cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1361cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
137e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
138e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Write a chunk of data under the current entity to the backup transport.
139e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param data A raw data buffer to send
140e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param size The number of bytes to be sent in this chunk
141e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return the number of bytes written
142e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IOException if the write failed
143e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
1441cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public int writeEntityData(byte[] data, int size) throws IOException {
1451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        int result = writeEntityData_native(mBackupWriter, data, size);
1461cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (result >= 0) {
1471cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return result;
1481cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
1491cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IOException("result=0x" + Integer.toHexString(result));
1501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
1511cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1521cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
153fc922f115325371aaadd4e423472476303039a72Christopher Tate    /** @hide */
15406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    public void setKeyPrefix(String keyPrefix) {
15506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato        setKeyPrefix_native(mBackupWriter, keyPrefix);
15606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato    }
15706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato
158e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /** @hide */
159ff31addb9b767496ba5c907513be172779eadfc5arete    @Override
160d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    protected void finalize() throws Throwable {
161d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        try {
162d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            dtor(mBackupWriter);
163d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        } finally {
164d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            super.finalize();
165d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
166b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato    }
16706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato
16858b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    private native static long ctor(FileDescriptor fd);
16958b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    private native static void dtor(long mBackupWriter);
1701cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
17158b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    private native static int writeEntityHeader_native(long mBackupWriter, String key, int dataSize);
17258b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    private native static int writeEntityData_native(long mBackupWriter, byte[] data, int size);
17358b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat    private native static void setKeyPrefix_native(long mBackupWriter, String keyPrefix);
174b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato}
175b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
176