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 #define LOG_TAG "FileBackupHelper_native" 18 #include <utils/Log.h> 19 20 #include "JNIHelp.h" 21 #include <android_runtime/AndroidRuntime.h> 22 23 #include <androidfw/BackupHelpers.h> 24 25 namespace android 26 { 27 28 // android.app.backup.BackupDataInput$EntityHeader 29 static jfieldID s_keyField = 0; 30 static jfieldID s_dataSizeField = 0; 31 32 static int 33 ctor_native(JNIEnv* env, jobject clazz, jobject fileDescriptor) 34 { 35 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 36 if (fd == -1) { 37 return NULL; 38 } 39 40 return (int)new BackupDataReader(fd); 41 } 42 43 static void 44 dtor_native(JNIEnv* env, jobject clazz, int r) 45 { 46 delete (BackupDataReader*)r; 47 } 48 49 static jint 50 readNextHeader_native(JNIEnv* env, jobject clazz, int r, jobject entity) 51 { 52 int err; 53 bool done; 54 BackupDataReader* reader = (BackupDataReader*)r; 55 56 int type = 0; 57 58 err = reader->ReadNextHeader(&done, &type); 59 if (done) { 60 return 1; 61 } 62 63 if (err != 0) { 64 return err < 0 ? err : -1; 65 } 66 67 switch (type) { 68 case BACKUP_HEADER_ENTITY_V1: 69 { 70 String8 key; 71 size_t dataSize; 72 err = reader->ReadEntityHeader(&key, &dataSize); 73 if (err != 0) { 74 return err < 0 ? err : -1; 75 } 76 // TODO: Set the fields in the entity object 77 jstring keyStr = env->NewStringUTF(key.string()); 78 env->SetObjectField(entity, s_keyField, keyStr); 79 env->SetIntField(entity, s_dataSizeField, dataSize); 80 return 0; 81 } 82 default: 83 ALOGD("Unknown header type: 0x%08x\n", type); 84 return -1; 85 } 86 87 // done 88 return 1; 89 } 90 91 static jint 92 readEntityData_native(JNIEnv* env, jobject clazz, int r, jbyteArray data, int offset, int size) 93 { 94 int err; 95 BackupDataReader* reader = (BackupDataReader*)r; 96 97 if (env->GetArrayLength(data) < (size+offset)) { 98 // size mismatch 99 return -1; 100 } 101 102 jbyte* dataBytes = env->GetByteArrayElements(data, NULL); 103 if (dataBytes == NULL) { 104 return -2; 105 } 106 107 err = reader->ReadEntityData(dataBytes+offset, size); 108 109 env->ReleaseByteArrayElements(data, dataBytes, 0); 110 111 return err; 112 } 113 114 static jint 115 skipEntityData_native(JNIEnv* env, jobject clazz, int r) 116 { 117 int err; 118 BackupDataReader* reader = (BackupDataReader*)r; 119 120 err = reader->SkipEntityData(); 121 122 return err; 123 } 124 125 static const JNINativeMethod g_methods[] = { 126 { "ctor", "(Ljava/io/FileDescriptor;)I", (void*)ctor_native }, 127 { "dtor", "(I)V", (void*)dtor_native }, 128 { "readNextHeader_native", "(ILandroid/app/backup/BackupDataInput$EntityHeader;)I", 129 (void*)readNextHeader_native }, 130 { "readEntityData_native", "(I[BII)I", (void*)readEntityData_native }, 131 { "skipEntityData_native", "(I)I", (void*)skipEntityData_native }, 132 }; 133 134 int register_android_backup_BackupDataInput(JNIEnv* env) 135 { 136 //ALOGD("register_android_backup_BackupDataInput"); 137 138 jclass clazz = env->FindClass("android/app/backup/BackupDataInput$EntityHeader"); 139 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.app.backup.BackupDataInput.EntityHeader"); 140 s_keyField = env->GetFieldID(clazz, "key", "Ljava/lang/String;"); 141 LOG_FATAL_IF(s_keyField == NULL, 142 "Unable to find key field in android.app.backup.BackupDataInput.EntityHeader"); 143 s_dataSizeField = env->GetFieldID(clazz, "dataSize", "I"); 144 LOG_FATAL_IF(s_dataSizeField == NULL, 145 "Unable to find dataSize field in android.app.backup.BackupDataInput.EntityHeader"); 146 147 return AndroidRuntime::registerNativeMethods(env, "android/app/backup/BackupDataInput", 148 g_methods, NELEM(g_methods)); 149 } 150 151 } 152