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