OSDN Git Service

API: make "what's the quota?" an operation on the backup data sinks
[android-x86/frameworks-base.git] / core / java / android / app / backup / BackupDataOutput.java
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.app.backup;
18
19 import android.annotation.SystemApi;
20 import android.os.ParcelFileDescriptor;
21 import java.io.FileDescriptor;
22 import java.io.IOException;
23
24 /**
25  * Provides the structured interface through which a {@link BackupAgent} commits
26  * information to the backup data set, via its {@link
27  * BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
28  * onBackup()} method.  Data written for backup is presented
29  * as a set of "entities," key/value pairs in which each binary data record "value" is
30  * named with a string "key."
31  * <p>
32  * To commit a data record to the backup transport, the agent's
33  * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
34  * onBackup()} method first writes an "entity header" that supplies the key string for the record
35  * and the total size of the binary value for the record.  After the header has been
36  * written, the agent then writes the binary entity value itself.  The entity value can
37  * be written in multiple chunks if desired, as long as the total count of bytes written
38  * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}.
39  * <p>
40  * Entity key strings are considered to be unique within a given application's backup
41  * data set. If a backup agent writes a new entity under an existing key string, its value will
42  * replace any previous value in the transport's remote data store.  You can remove a record
43  * entirely from the remote data set by writing a new entity header using the
44  * existing record's key, but supplying a negative <code>dataSize</code> parameter.
45  * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}.
46  * <h3>Example</h3>
47  * <p>
48  * Here is an example illustrating a way to back up the value of a String variable
49  * called <code>mStringToBackUp</code>:
50  * <pre>
51  * static final String MY_STRING_KEY = "storedstring";
52  *
53  * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)}
54  *         throws IOException {
55  *     ...
56  *     byte[] stringBytes = mStringToBackUp.getBytes();
57  *     data.writeEntityHeader(MY_STRING_KEY, stringBytes.length);
58  *     data.writeEntityData(stringBytes, stringBytes.length);
59  *     ...
60  * }</pre>
61  *
62  * @see BackupAgent
63  */
64 public class BackupDataOutput {
65     final long mQuota;
66     long mBackupWriter;
67
68     /**
69      * Construct a BackupDataOutput purely for data-stream manipulation.  This instance will
70      * not report usable quota information.
71      * @hide */
72     @SystemApi
73     public BackupDataOutput(FileDescriptor fd) {
74         this(fd, -1);
75     }
76
77     /** @hide */
78     @SystemApi
79     public BackupDataOutput(FileDescriptor fd, long quota) {
80         if (fd == null) throw new NullPointerException();
81         mQuota = quota;
82         mBackupWriter = ctor(fd);
83         if (mBackupWriter == 0) {
84             throw new RuntimeException("Native initialization failed with fd=" + fd);
85         }
86     }
87
88     /**
89      * Returns the quota in bytes for the application's current backup operation.  The
90      * value can vary for each operation.
91      *
92      * @see FullBackupDataOutput#getQuota()
93      */
94     public long getQuota() {
95         return mQuota;
96     }
97
98     /**
99      * Mark the beginning of one record in the backup data stream. This must be called before
100      * {@link #writeEntityData}.
101      * @param key A string key that uniquely identifies the data record within the application.
102      *    Keys whose first character is \uFF00 or higher are not valid.
103      * @param dataSize The size in bytes of this record's data.  Passing a dataSize
104      *    of -1 indicates that the record under this key should be deleted.
105      * @return The number of bytes written to the backup stream
106      * @throws IOException if the write failed
107      */
108     public int writeEntityHeader(String key, int dataSize) throws IOException {
109         int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
110         if (result >= 0) {
111             return result;
112         } else {
113             throw new IOException("result=0x" + Integer.toHexString(result));
114         }
115     }
116
117     /**
118      * Write a chunk of data under the current entity to the backup transport.
119      * @param data A raw data buffer to send
120      * @param size The number of bytes to be sent in this chunk
121      * @return the number of bytes written
122      * @throws IOException if the write failed
123      */
124     public int writeEntityData(byte[] data, int size) throws IOException {
125         int result = writeEntityData_native(mBackupWriter, data, size);
126         if (result >= 0) {
127             return result;
128         } else {
129             throw new IOException("result=0x" + Integer.toHexString(result));
130         }
131     }
132
133     /** @hide */
134     public void setKeyPrefix(String keyPrefix) {
135         setKeyPrefix_native(mBackupWriter, keyPrefix);
136     }
137
138     /** @hide */
139     @Override
140     protected void finalize() throws Throwable {
141         try {
142             dtor(mBackupWriter);
143         } finally {
144             super.finalize();
145         }
146     }
147
148     private native static long ctor(FileDescriptor fd);
149     private native static void dtor(long mBackupWriter);
150
151     private native static int writeEntityHeader_native(long mBackupWriter, String key, int dataSize);
152     private native static int writeEntityData_native(long mBackupWriter, byte[] data, int size);
153     private native static void setKeyPrefix_native(long mBackupWriter, String keyPrefix);
154 }
155