Home | History | Annotate | Download | only in backup
      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.os.ParcelFileDescriptor;
     20 
     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     int mBackupWriter;
     66 
     67     /** @hide */
     68     public BackupDataOutput(FileDescriptor fd) {
     69         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         }
     74     }
     75 
     76     /**
     77      * 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
     80      * @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      */
     85     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 
     94     /**
     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      */
    101     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 
    110     /** @hide */
    111     public void setKeyPrefix(String keyPrefix) {
    112         setKeyPrefix_native(mBackupWriter, keyPrefix);
    113     }
    114 
    115     /** @hide */
    116     protected void finalize() throws Throwable {
    117         try {
    118             dtor(mBackupWriter);
    119         } finally {
    120             super.finalize();
    121         }
    122     }
    123 
    124     private native static int ctor(FileDescriptor fd);
    125     private native static void dtor(int mBackupWriter);
    126 
    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);
    129     private native static void setKeyPrefix_native(int mBackupWriter, String keyPrefix);
    130 }
    131 
    132