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; 2139194c0582463be17513b9ba82802a703b10c934Robert Berry 22b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.FileDescriptor; 231cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport java.io.IOException; 24b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 25e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate/** 26d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Provides the structured interface through which a {@link BackupAgent} commits 27d17da43c82c4edb97514d6138bc208eeba321636Scott Main * information to the backup data set, via its {@link 28d17da43c82c4edb97514d6138bc208eeba321636Scott Main * BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) 29d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method. Data written for backup is presented 304e14a829129feee14ebe453f61a124784c870610Christopher Tate * as a set of "entities," key/value pairs in which each binary data record "value" is 314e14a829129feee14ebe453f61a124784c870610Christopher Tate * named with a string "key." 324e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 334e14a829129feee14ebe453f61a124784c870610Christopher Tate * To commit a data record to the backup transport, the agent's 34d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) 35d17da43c82c4edb97514d6138bc208eeba321636Scott Main * onBackup()} method first writes an "entity header" that supplies the key string for the record 364e14a829129feee14ebe453f61a124784c870610Christopher Tate * and the total size of the binary value for the record. After the header has been 37d17da43c82c4edb97514d6138bc208eeba321636Scott Main * written, the agent then writes the binary entity value itself. The entity value can 384e14a829129feee14ebe453f61a124784c870610Christopher Tate * be written in multiple chunks if desired, as long as the total count of bytes written 39d17da43c82c4edb97514d6138bc208eeba321636Scott Main * matches what was supplied to {@link #writeEntityHeader(String, int) writeEntityHeader()}. 404e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 414e14a829129feee14ebe453f61a124784c870610Christopher Tate * Entity key strings are considered to be unique within a given application's backup 42d17da43c82c4edb97514d6138bc208eeba321636Scott Main * data set. If a backup agent writes a new entity under an existing key string, its value will 43d17da43c82c4edb97514d6138bc208eeba321636Scott Main * replace any previous value in the transport's remote data store. You can remove a record 44d17da43c82c4edb97514d6138bc208eeba321636Scott Main * entirely from the remote data set by writing a new entity header using the 454e14a829129feee14ebe453f61a124784c870610Christopher Tate * existing record's key, but supplying a negative <code>dataSize</code> parameter. 46d17da43c82c4edb97514d6138bc208eeba321636Scott Main * When you do so, the agent does not need to call {@link #writeEntityData(byte[], int)}. 47d17da43c82c4edb97514d6138bc208eeba321636Scott Main * <h3>Example</h3> 484e14a829129feee14ebe453f61a124784c870610Christopher Tate * <p> 494e14a829129feee14ebe453f61a124784c870610Christopher Tate * Here is an example illustrating a way to back up the value of a String variable 504e14a829129feee14ebe453f61a124784c870610Christopher Tate * called <code>mStringToBackUp</code>: 514e14a829129feee14ebe453f61a124784c870610Christopher Tate * <pre> 524e14a829129feee14ebe453f61a124784c870610Christopher Tate * static final String MY_STRING_KEY = "storedstring"; 534e14a829129feee14ebe453f61a124784c870610Christopher Tate * 544e14a829129feee14ebe453f61a124784c870610Christopher Tate * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)} 554e14a829129feee14ebe453f61a124784c870610Christopher Tate * throws IOException { 564e14a829129feee14ebe453f61a124784c870610Christopher Tate * ... 574e14a829129feee14ebe453f61a124784c870610Christopher Tate * byte[] stringBytes = mStringToBackUp.getBytes(); 584e14a829129feee14ebe453f61a124784c870610Christopher Tate * data.writeEntityHeader(MY_STRING_KEY, stringBytes.length); 594e14a829129feee14ebe453f61a124784c870610Christopher Tate * data.writeEntityData(stringBytes, stringBytes.length); 604e14a829129feee14ebe453f61a124784c870610Christopher Tate * ... 614e14a829129feee14ebe453f61a124784c870610Christopher Tate * }</pre> 624e14a829129feee14ebe453f61a124784c870610Christopher Tate * 634e14a829129feee14ebe453f61a124784c870610Christopher Tate * @see BackupAgent 64e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 65b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratopublic class BackupDataOutput { 6639194c0582463be17513b9ba82802a703b10c934Robert Berry 6739194c0582463be17513b9ba82802a703b10c934Robert Berry private final long mQuota; 6839194c0582463be17513b9ba82802a703b10c934Robert Berry private final int mTransportFlags; 6939194c0582463be17513b9ba82802a703b10c934Robert Berry 7058b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat long mBackupWriter; 71b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 72ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** 73ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * Construct a BackupDataOutput purely for data-stream manipulation. This instance will 74ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * not report usable quota information. 75ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * @hide */ 76ff31addb9b767496ba5c907513be172779eadfc5arete @SystemApi 7783248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato public BackupDataOutput(FileDescriptor fd) { 7839194c0582463be17513b9ba82802a703b10c934Robert Berry this(fd, /*quota=*/ -1, /*transportFlags=*/ 0); 79ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate } 80ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate 81ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** @hide */ 82ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate @SystemApi 83ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate public BackupDataOutput(FileDescriptor fd, long quota) { 8439194c0582463be17513b9ba82802a703b10c934Robert Berry this(fd, quota, /*transportFlags=*/ 0); 8539194c0582463be17513b9ba82802a703b10c934Robert Berry } 8639194c0582463be17513b9ba82802a703b10c934Robert Berry 8739194c0582463be17513b9ba82802a703b10c934Robert Berry /** @hide */ 8839194c0582463be17513b9ba82802a703b10c934Robert Berry public BackupDataOutput(FileDescriptor fd, long quota, int transportFlags) { 89d2110dbce071a236b6176de344ca797b737542ebJoe Onorato if (fd == null) throw new NullPointerException(); 90ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate mQuota = quota; 9139194c0582463be17513b9ba82802a703b10c934Robert Berry mTransportFlags = transportFlags; 92d2110dbce071a236b6176de344ca797b737542ebJoe Onorato mBackupWriter = ctor(fd); 93d2110dbce071a236b6176de344ca797b737542ebJoe Onorato if (mBackupWriter == 0) { 94d2110dbce071a236b6176de344ca797b737542ebJoe Onorato throw new RuntimeException("Native initialization failed with fd=" + fd); 95d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } 96b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato } 97b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 98e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** 99ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * Returns the quota in bytes for the application's current backup operation. The 100ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * value can vary for each operation. 101ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * 102ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate * @see FullBackupDataOutput#getQuota() 103ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate */ 104ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate public long getQuota() { 105ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate return mQuota; 106ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate } 107ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate 108ee87b96ee572e7245cf7b791e30c51505a8ba2a2Christopher Tate /** 10939194c0582463be17513b9ba82802a703b10c934Robert Berry * Returns flags with additional information about the backup transport. For supported flags see 11039194c0582463be17513b9ba82802a703b10c934Robert Berry * {@link android.app.backup.BackupAgent} 11139194c0582463be17513b9ba82802a703b10c934Robert Berry * 11239194c0582463be17513b9ba82802a703b10c934Robert Berry * @see FullBackupDataOutput#getTransportFlags() 11339194c0582463be17513b9ba82802a703b10c934Robert Berry */ 11439194c0582463be17513b9ba82802a703b10c934Robert Berry public int getTransportFlags() { 11539194c0582463be17513b9ba82802a703b10c934Robert Berry return mTransportFlags; 11639194c0582463be17513b9ba82802a703b10c934Robert Berry } 11739194c0582463be17513b9ba82802a703b10c934Robert Berry 11839194c0582463be17513b9ba82802a703b10c934Robert Berry /** 119d17da43c82c4edb97514d6138bc208eeba321636Scott Main * Mark the beginning of one record in the backup data stream. This must be called before 120d17da43c82c4edb97514d6138bc208eeba321636Scott Main * {@link #writeEntityData}. 121adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate * @param key A string key that uniquely identifies the data record within the application. 122adfe8b86e9178a553b6db9722340fa4ff5201cf1Christopher Tate * Keys whose first character is \uFF00 or higher are not valid. 123e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param dataSize The size in bytes of this record's data. Passing a dataSize 124e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * of -1 indicates that the record under this key should be deleted. 125e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @return The number of bytes written to the backup stream 126e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @throws IOException if the write failed 127e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 1281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato public int writeEntityHeader(String key, int dataSize) throws IOException { 1291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato int result = writeEntityHeader_native(mBackupWriter, key, dataSize); 1301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato if (result >= 0) { 1311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato return result; 1321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } else { 1331cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato throw new IOException("result=0x" + Integer.toHexString(result)); 1341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1351cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1361cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 137e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** 138e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * Write a chunk of data under the current entity to the backup transport. 139e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param data A raw data buffer to send 140e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @param size The number of bytes to be sent in this chunk 141e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @return the number of bytes written 142e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * @throws IOException if the write failed 143e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */ 1441cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato public int writeEntityData(byte[] data, int size) throws IOException { 1451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato int result = writeEntityData_native(mBackupWriter, data, size); 1461cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato if (result >= 0) { 1471cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato return result; 1481cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } else { 1491cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato throw new IOException("result=0x" + Integer.toHexString(result)); 1501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1511cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato } 1521cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 153fc922f115325371aaadd4e423472476303039a72Christopher Tate /** @hide */ 15406290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato public void setKeyPrefix(String keyPrefix) { 15506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato setKeyPrefix_native(mBackupWriter, keyPrefix); 15606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato } 15706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 158e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate /** @hide */ 159ff31addb9b767496ba5c907513be172779eadfc5arete @Override 160d2110dbce071a236b6176de344ca797b737542ebJoe Onorato protected void finalize() throws Throwable { 161d2110dbce071a236b6176de344ca797b737542ebJoe Onorato try { 162d2110dbce071a236b6176de344ca797b737542ebJoe Onorato dtor(mBackupWriter); 163d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } finally { 164d2110dbce071a236b6176de344ca797b737542ebJoe Onorato super.finalize(); 165d2110dbce071a236b6176de344ca797b737542ebJoe Onorato } 166b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato } 16706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato 16858b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static long ctor(FileDescriptor fd); 16958b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static void dtor(long mBackupWriter); 1701cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato 17158b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static int writeEntityHeader_native(long mBackupWriter, String key, int dataSize); 17258b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static int writeEntityData_native(long mBackupWriter, byte[] data, int size); 17358b8b24256bdc2b613b7fda9151845ed9898a4c7Ashok Bhat private native static void setKeyPrefix_native(long mBackupWriter, String keyPrefix); 174b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato} 175b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato 176