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