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.annotation.SystemApi;
     20 import android.os.ParcelFileDescriptor;
     21 import android.os.Process;
     22 
     23 import java.io.FileDescriptor;
     24 import java.io.IOException;
     25 
     26 /**
     27  * Provides the structured interface through which a {@link BackupAgent} commits
     28  * information to the backup data set, via its {@link
     29  * BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
     30  * onBackup()} method.  Data written for backup is presented
     31  * as a set of "entities," key/value pairs in which each binary data record "value" is
     32  * named with a string "key."
     33  * <p>
     34  * To commit a data record to the backup transport, the agent's
     35  * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
     36  * onBackup()} method first writes an "entity header" that supplies the key string for the record
     37  * and the total size of the binary value for the record.  After the header has been
     38  * written, the agent then writes the binary entity value itself.  The entity value can
     39  * be written in multiple chunks if desired, as long as the total count of bytes written
     40  * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}.
     41  * <p>
     42  * Entity key strings are considered to be unique within a given application's backup
     43  * data set. If a backup agent writes a new entity under an existing key string, its value will
     44  * replace any previous value in the transport's remote data store.  You can remove a record
     45  * entirely from the remote data set by writing a new entity header using the
     46  * existing record's key, but supplying a negative <code>dataSize</code> parameter.
     47  * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}.
     48  * <h3>Example</h3>
     49  * <p>
     50  * Here is an example illustrating a way to back up the value of a String variable
     51  * called <code>mStringToBackUp</code>:
     52  * <pre>
     53  * static final String MY_STRING_KEY = "storedstring";
     54  *
     55  * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)}
     56  *         throws IOException {
     57  *     ...
     58  *     byte[] stringBytes = mStringToBackUp.getBytes();
     59  *     data.writeEntityHeader(MY_STRING_KEY, stringBytes.length);
     60  *     data.writeEntityData(stringBytes, stringBytes.length);
     61  *     ...
     62  * }</pre>
     63  *
     64  * @see BackupAgent
     65  */
     66 public class BackupDataOutput {
     67     long mBackupWriter;
     68 
     69     /** @hide */
     70     @SystemApi
     71     public BackupDataOutput(FileDescriptor fd) {
     72         if (fd == null) throw new NullPointerException();
     73         mBackupWriter = ctor(fd);
     74         if (mBackupWriter == 0) {
     75             throw new RuntimeException("Native initialization failed with fd=" + fd);
     76         }
     77     }
     78 
     79     /**
     80      * Mark the beginning of one record in the backup data stream. This must be called before
     81      * {@link #writeEntityData}.
     82      * @param key A string key that uniquely identifies the data record within the application.
     83      *    Keys whose first character is \uFF00 or higher are not valid.
     84      * @param dataSize The size in bytes of this record's data.  Passing a dataSize
     85      *    of -1 indicates that the record under this key should be deleted.
     86      * @return The number of bytes written to the backup stream
     87      * @throws IOException if the write failed
     88      */
     89     public int writeEntityHeader(String key, int dataSize) throws IOException {
     90         int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
     91         if (result >= 0) {
     92             return result;
     93         } else {
     94             throw new IOException("result=0x" + Integer.toHexString(result));
     95         }
     96     }
     97 
     98     /**
     99      * Write a chunk of data under the current entity to the backup transport.
    100      * @param data A raw data buffer to send
    101      * @param size The number of bytes to be sent in this chunk
    102      * @return the number of bytes written
    103      * @throws IOException if the write failed
    104      */
    105     public int writeEntityData(byte[] data, int size) throws IOException {
    106         int result = writeEntityData_native(mBackupWriter, data, size);
    107         if (result >= 0) {
    108             return result;
    109         } else {
    110             throw new IOException("result=0x" + Integer.toHexString(result));
    111         }
    112     }
    113 
    114     /** @hide */
    115     public void setKeyPrefix(String keyPrefix) {
    116         setKeyPrefix_native(mBackupWriter, keyPrefix);
    117     }
    118 
    119     /** @hide */
    120     @Override
    121     protected void finalize() throws Throwable {
    122         try {
    123             dtor(mBackupWriter);
    124         } finally {
    125             super.finalize();
    126         }
    127     }
    128 
    129     private native static long ctor(FileDescriptor fd);
    130     private native static void dtor(long mBackupWriter);
    131 
    132     private native static int writeEntityHeader_native(long mBackupWriter, String key, int dataSize);
    133     private native static int writeEntityData_native(long mBackupWriter, byte[] data, int size);
    134     private native static void setKeyPrefix_native(long mBackupWriter, String keyPrefix);
    135 }
    136 
    137