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 25namespace android 26{ 27 28// android.app.backup.BackupDataInput$EntityHeader 29static jfieldID s_keyField = 0; 30static jfieldID s_dataSizeField = 0; 31 32static int 33ctor_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 43static void 44dtor_native(JNIEnv* env, jobject clazz, int r) 45{ 46 delete (BackupDataReader*)r; 47} 48 49static jint 50readNextHeader_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 91static jint 92readEntityData_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 114static jint 115skipEntityData_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 125static 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 134int 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