blob: 22668b6533ab3dd32374a0e8d2148ed0cb4b606f [file] [log] [blame]
Joe Onoratob1a7ffe2009-05-06 18:06:21 -07001/*
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
Christopher Tate45281862010-03-05 15:46:30 -080017package android.app.backup;
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070018
Christopher Tate4e14a822010-04-08 12:54:23 -070019import android.os.ParcelFileDescriptor;
20
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070021import java.io.FileDescriptor;
Joe Onorato1cf58742009-06-12 11:06:24 -070022import java.io.IOException;
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070023
Christopher Tatee28290e2010-02-16 15:22:26 -080024/**
Scott Maind17da432010-04-29 21:42:58 -070025 * 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
Christopher Tate4e14a822010-04-08 12:54:23 -070029 * 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
Scott Maind17da432010-04-29 21:42:58 -070033 * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
34 * onBackup()} method first writes an "entity header" that supplies the key string for the record
Christopher Tate4e14a822010-04-08 12:54:23 -070035 * and the total size of the binary value for the record. After the header has been
Scott Maind17da432010-04-29 21:42:58 -070036 * written, the agent then writes the binary entity value itself. The entity value can
Christopher Tate4e14a822010-04-08 12:54:23 -070037 * be written in multiple chunks if desired, as long as the total count of bytes written
Scott Maind17da432010-04-29 21:42:58 -070038 * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}.
Christopher Tate4e14a822010-04-08 12:54:23 -070039 * <p>
40 * Entity key strings are considered to be unique within a given application's backup
Scott Maind17da432010-04-29 21:42:58 -070041 * 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
Christopher Tate4e14a822010-04-08 12:54:23 -070044 * existing record's key, but supplying a negative <code>dataSize</code> parameter.
Scott Maind17da432010-04-29 21:42:58 -070045 * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}.
46 * <h3>Example</h3>
Christopher Tate4e14a822010-04-08 12:54:23 -070047 * <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
Christopher Tatee28290e2010-02-16 15:22:26 -080063 */
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070064public class BackupDataOutput {
Joe Onoratod2110db2009-05-19 13:41:21 -070065 int mBackupWriter;
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070066
Christopher Tatee28290e2010-02-16 15:22:26 -080067 /** @hide */
Joe Onorato83248c42009-06-17 17:55:20 -070068 public BackupDataOutput(FileDescriptor fd) {
Joe Onoratod2110db2009-05-19 13:41:21 -070069 if (fd == null) throw new NullPointerException();
70 mBackupWriter = ctor(fd);
71 if (mBackupWriter == 0) {
72 throw new RuntimeException("Native initialization failed with fd=" + fd);
73 }
Joe Onoratob1a7ffe2009-05-06 18:06:21 -070074 }
75
Christopher Tatee28290e2010-02-16 15:22:26 -080076 /**
Scott Maind17da432010-04-29 21:42:58 -070077 * Mark the beginning of one record in the backup data stream. This must be called before
78 * {@link #writeEntityData}.
79 * @param key A string key that uniquely identifies the data record within the application
Christopher Tatee28290e2010-02-16 15:22:26 -080080 * @param dataSize The size in bytes of this record's data. Passing a dataSize
81 * of -1 indicates that the record under this key should be deleted.
82 * @return The number of bytes written to the backup stream
83 * @throws IOException if the write failed
84 */
Joe Onorato1cf58742009-06-12 11:06:24 -070085 public int writeEntityHeader(String key, int dataSize) throws IOException {
86 int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
87 if (result >= 0) {
88 return result;
89 } else {
90 throw new IOException("result=0x" + Integer.toHexString(result));
91 }
92 }
93
Christopher Tatee28290e2010-02-16 15:22:26 -080094 /**
95 * Write a chunk of data under the current entity to the backup transport.
96 * @param data A raw data buffer to send
97 * @param size The number of bytes to be sent in this chunk
98 * @return the number of bytes written
99 * @throws IOException if the write failed
100 */
Joe Onorato1cf58742009-06-12 11:06:24 -0700101 public int writeEntityData(byte[] data, int size) throws IOException {
102 int result = writeEntityData_native(mBackupWriter, data, size);
103 if (result >= 0) {
104 return result;
105 } else {
106 throw new IOException("result=0x" + Integer.toHexString(result));
107 }
108 }
109
Christopher Tatefc922f112010-04-09 13:05:16 -0700110 /** @hide */
Joe Onorato06290a42009-06-18 20:10:37 -0700111 public void setKeyPrefix(String keyPrefix) {
112 setKeyPrefix_native(mBackupWriter, keyPrefix);
113 }
114
Christopher Tatee28290e2010-02-16 15:22:26 -0800115 /** @hide */
Joe Onoratod2110db2009-05-19 13:41:21 -0700116 protected void finalize() throws Throwable {
117 try {
118 dtor(mBackupWriter);
119 } finally {
120 super.finalize();
121 }
Joe Onoratob1a7ffe2009-05-06 18:06:21 -0700122 }
Joe Onorato06290a42009-06-18 20:10:37 -0700123
Joe Onoratod2110db2009-05-19 13:41:21 -0700124 private native static int ctor(FileDescriptor fd);
125 private native static void dtor(int mBackupWriter);
Joe Onorato1cf58742009-06-12 11:06:24 -0700126
127 private native static int writeEntityHeader_native(int mBackupWriter, String key, int dataSize);
128 private native static int writeEntityData_native(int mBackupWriter, byte[] data, int size);
Joe Onorato06290a42009-06-18 20:10:37 -0700129 private native static void setKeyPrefix_native(int mBackupWriter, String keyPrefix);
Joe Onoratob1a7ffe2009-05-06 18:06:21 -0700130}
131