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 <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