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; 21b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.FileDescriptor; 221cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport java.io.IOException; 23b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 24e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate/** 25d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Provides the structured interface through which a {@link BackupAgent} commits 26d17da43c82c4edb97514d6138bc208eeba321636Scott Main * information to the backup data set, via its {@link 27d17da43c82c4edb97514d6138bc208eeba321636Scott Main * BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) 28d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method. Data written for backup is presented 294e14a829129feee14ebe453f61a124784c870610Christopher Tate * as a set of "entities," key/value pairs in which each binary data record "value" is 304e14a829129feee14ebe453f61a124784c870610Christopher Tate * named with a string "key." 314e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 324e14a829129feee14ebe453f61a124784c870610Christopher Tate * To commit a data record to the backup transport, the agent's 33d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) 34d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method first writes an "entity header" that supplies the key string for the record 354e14a829129feee14ebe453f61a124784c870610Christopher Tate * and the total size of the binary value for the record. After the header has been 36d17da43c82c4edb97514d6138bc208eeba321636Scott Main * written, the agent then writes the binary entity value itself. The entity value can 374e14a829129feee14ebe453f61a124784c870610Christopher Tate * be written in multiple chunks if desired, as long as the total count of bytes written 38d17da43c82c4edb97514d6138bc208eeba321636Scott Main * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}. 394e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 404e14a829129feee14ebe453f61a124784c870610Christopher Tate * Entity key strings are considered to be unique within a given application's backup 41d17da43c82c4edb97514d6138bc208eeba321636Scott Main * data set. If a backup agent writes a new entity under an existing key string, its value will 42d17da43c82c4edb97514d6138bc208eeba321636Scott Main * replace any previous value in the transport's remote data store. You can remove a record 43d17da43c82c4edb97514d6138bc208eeba321636Scott Main * entirely from the remote data set by writing a new entity header using the 444e14a829129feee14ebe453f61a124784c870610Christopher Tate * existing record's key, but supplying a negative <code>dataSize</code> parameter. 45d17da43c82c4edb97514d6138bc208eeba321636Scott Main * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}. 46d17da43c82c4edb97514d6138bc208eeba321636Scott Main * <h3>Example</h3> 474e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 484e14a829129feee14ebe453f61a124784c870610Christopher Tate * Here is an example illustrating a way to back up the value of a String variable 494e14a829129feee14ebe453f61a124784c870610Christopher Tate * called <code>mStringToBackUp</code>: 504e14a829129feee14ebe453f61a124784c870610Christopher Tate * <pre> 514e14a829129feee14ebe453f61a124784c870610Christopher Tate * static final String MY_STRING_KEY = "storedstring"; 524e14a829129feee14ebe453f61a124784c870610Christopher Tate * 534e14a829129feee14ebe453f61a124784c870610Christopher Tate * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)} 544e14a829129feee14ebe453f61a124784c870610Christopher Tate * throws IOException { 554e14a829129feee14ebe453f61a124784c870610Christopher Tate * ... 564e14a829129feee14ebe453f61a124784c870610Christopher Tate * byte[] stringBytes = mStringToBackUp.getBytes(); 574e14a829129feee14ebe453f61a124784c870610Christopher Tate * data.writeEntityHeader(MY_STRING_KEY, stringBytes.length); 584e14a829129feee14ebe453f61a124784c870610Christopher Tate * data.writeEntityData(stringBytes, stringBytes.length); 594e14a829129feee14ebe453f61a124784c870610Christopher Tate * ... 604e14a829129feee14ebe453f61a124784c870610Christopher Tate * }</pre> 614e14a829129feee14ebe453f61a124784c870610Christopher Tate * 624e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see BackupAgent 63e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 64b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratopublic class BackupDataOutput { 65ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate final long mQuota; 6658b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat long mBackupWriter; 67b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 68ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** 69ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * Construct a BackupDataOutput purely for data-stream manipulation. This instance will 70ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * not report usable quota information. 71ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * @hide */ 72ff31addb9b767496ba5c907513be172779eadfc5arete @SystemApi 7383248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato public BackupDataOutput(FileDescriptor fd) { 74ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate this(fd, -1); 75ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate } 76ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate 77ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** @hide */ 78ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate @SystemApi 79ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate public BackupDataOutput(FileDescriptor fd, long quota) { 80d2110dbce071a236b6176de344ca797b737542ebJoe Onorato if (fd == null) throw new NullPointerException(); 81ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate mQuota = quota; 82d2110dbce071a236b6176de344ca797b737542ebJoe Onorato mBackupWriter = ctor(fd); 83d2110dbce071a236b6176de344ca797b737542ebJoe Onorato if (mBackupWriter == 0) { 84d2110dbce071a236b6176de344ca797b737542ebJoe Onorato throw new RuntimeException("Native initialization failed with fd=" + fd); 85d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } 86b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato } 87b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 88e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** 89ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * Returns the quota in bytes for the application's current backup operation. The 90ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * value can vary for each operation. 91ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * 92ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * @see FullBackupDataOutput#getQuota() 93ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate */ 94ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate public long getQuota() { 95ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate return mQuota; 96ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate } 97ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate 98ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** 99d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Mark the beginning of one record in the backup data stream. This must be called before 100d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link #writeEntityData}. 101adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate * @param key A string key that uniquely identifies the data record within the application. 102adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate * Keys whose first character is \uFF00 or higher are not valid. 103e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param dataSize The size in bytes of this record's data. Passing a dataSize 104e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * of -1 indicates that the record under this key should be deleted. 105e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @return The number of bytes written to the backup stream 106e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @throws IOException if the write failed 107e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 1081cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato public int writeEntityHeader(String key, int dataSize) throws IOException { 1091cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato int result = writeEntityHeader_native(mBackupWriter, key, dataSize); 1101cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato if (result >= 0) { 1111cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato return result; 1121cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } else { 1131cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato throw new IOException("result=0x" + Integer.toHexString(result)); 1141cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1151cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1161cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 117e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** 118e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * Write a chunk of data under the current entity to the backup transport. 119e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param data A raw data buffer to send 120e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param size The number of bytes to be sent in this chunk 121e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @return the number of bytes written 122e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @throws IOException if the write failed 123e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 1241cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato public int writeEntityData(byte[] data, int size) throws IOException { 1251cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato int result = writeEntityData_native(mBackupWriter, data, size); 1261cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato if (result >= 0) { 1271cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato return result; 1281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } else { 1291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato throw new IOException("result=0x" + Integer.toHexString(result)); 1301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 133fc922f115325371aaadd4e423472476303039a72Christopher Tate /** @hide */ 13406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato public void setKeyPrefix(String keyPrefix) { 13506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato setKeyPrefix_native(mBackupWriter, keyPrefix); 13606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 13706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 138e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** @hide */ 139ff31addb9b767496ba5c907513be172779eadfc5arete @Override 140d2110dbce071a236b6176de344ca797b737542ebJoe Onorato protected void finalize() throws Throwable { 141d2110dbce071a236b6176de344ca797b737542ebJoe Onorato try { 142d2110dbce071a236b6176de344ca797b737542ebJoe Onorato dtor(mBackupWriter); 143d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } finally { 144d2110dbce071a236b6176de344ca797b737542ebJoe Onorato super.finalize(); 145d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } 146b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato } 14706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 14858b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static long ctor(FileDescriptor fd); 14958b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static void dtor(long mBackupWriter); 1501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 15158b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static int writeEntityHeader_native(long mBackupWriter, String key, int dataSize); 15258b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static int writeEntityData_native(long mBackupWriter, byte[] data, int size); 15358b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static void setKeyPrefix_native(long mBackupWriter, String keyPrefix); 154b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato} 155b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 156