11cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato/*
21cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Copyright (C) 2009 The Android Open Source Project
31cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
41cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * you may not use this file except in compliance with the License.
61cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * You may obtain a copy of the License at
71cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
81cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
101cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Unless required by applicable law or agreed to in writing, software
111cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * See the License for the specific language governing permissions and
141cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * limitations under the License.
151cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato */
161cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
171cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato#define LOG_TAG "FileBackupHelper_native"
181cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato#include <utils/Log.h>
191cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
201cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato#include "JNIHelp.h"
211cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato#include <android_runtime/AndroidRuntime.h>
221cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
231cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato#include <utils/BackupHelpers.h>
241cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
251cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratonamespace android
261cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
271cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato// java.io.FileDescriptor
291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic jfieldID s_descriptorField = 0;
301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
314528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate// android.app.backup.BackupDataInput$EntityHeader
321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic jfieldID s_keyField = 0;
331cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic jfieldID s_dataSizeField = 0;
341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
351cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic int
361cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoctor_native(JNIEnv* env, jobject clazz, jobject fileDescriptor)
371cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
381cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    int err;
391cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
401cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    int fd = env->GetIntField(fileDescriptor, s_descriptorField);
411cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    if (fd == -1) {
421cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        return NULL;
431cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
441cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    return (int)new BackupDataReader(fd);
461cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
471cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
481cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic void
491cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratodtor_native(JNIEnv* env, jobject clazz, int r)
501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
511cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    delete (BackupDataReader*)r;
521cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
531cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
541cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic jint
551cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe OnoratoreadNextHeader_native(JNIEnv* env, jobject clazz, int r, jobject entity)
561cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
571cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    int err;
585f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
591cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    BackupDataReader* reader = (BackupDataReader*)r;
601cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
612fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    int type = 0;
621cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
635f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader->ReadNextHeader(&done, &type);
645f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
652fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        return 1;
662fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    }
672fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate
682fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    if (err != 0) {
692fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        return err < 0 ? err : -1;
702fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    }
712fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate
722fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    switch (type) {
732fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    case BACKUP_HEADER_ENTITY_V1:
742fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    {
752fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        String8 key;
762fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        size_t dataSize;
772fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        err = reader->ReadEntityHeader(&key, &dataSize);
782fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        if (err != 0) {
792fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate            return err < 0 ? err : -1;
801cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
812fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        // TODO: Set the fields in the entity object
822fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        jstring keyStr = env->NewStringUTF(key.string());
832fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        env->SetObjectField(entity, s_keyField, keyStr);
842fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        env->SetIntField(entity, s_dataSizeField, dataSize);
852fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        return 0;
862fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    }
872fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    default:
882fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        LOGD("Unknown header type: 0x%08x\n", type);
892fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        return -1;
902fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    }
912fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate
921cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    // done
931cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    return 1;
941cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
951cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
961cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic jint
975f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe OnoratoreadEntityData_native(JNIEnv* env, jobject clazz, int r, jbyteArray data, int offset, int size)
981cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
991cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    int err;
1001cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    BackupDataReader* reader = (BackupDataReader*)r;
1011cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1025f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (env->GetArrayLength(data) < (size+offset)) {
1031cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        // size mismatch
1041cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        return -1;
1051cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1061cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1071cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    jbyte* dataBytes = env->GetByteArrayElements(data, NULL);
1081cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    if (dataBytes == NULL) {
1092fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate        return -2;
1101cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1111cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1125f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader->ReadEntityData(dataBytes+offset, size);
1131cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1141cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    env->ReleaseByteArrayElements(data, dataBytes, 0);
1151cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1161cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    return err;
1171cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
1181cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1195f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratostatic jint
1205f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe OnoratoskipEntityData_native(JNIEnv* env, jobject clazz, int r)
1215f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato{
1225f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int err;
1235f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    BackupDataReader* reader = (BackupDataReader*)r;
1245f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
1255f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader->SkipEntityData();
1265f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
1275f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    return err;
1285f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato}
1295f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
1301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratostatic const JNINativeMethod g_methods[] = {
1311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    { "ctor", "(Ljava/io/FileDescriptor;)I", (void*)ctor_native },
1321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    { "dtor", "(I)V", (void*)dtor_native },
1334528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate    { "readNextHeader_native", "(ILandroid/app/backup/BackupDataInput$EntityHeader;)I",
1341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            (void*)readNextHeader_native },
1355f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    { "readEntityData_native", "(I[BII)I", (void*)readEntityData_native },
1365f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    { "skipEntityData_native", "(I)I", (void*)skipEntityData_native },
1371cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato};
1381cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1391cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoint register_android_backup_BackupDataInput(JNIEnv* env)
1401cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato{
1412fdd428e0f18384160f7c38ce3a2cd9ba7e7b2c2Christopher Tate    //LOGD("register_android_backup_BackupDataInput");
1421cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1431cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    jclass clazz;
1441cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    clazz = env->FindClass("java/io/FileDescriptor");
1461cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor");
1471cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    s_descriptorField = env->GetFieldID(clazz, "descriptor", "I");
1481cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    LOG_FATAL_IF(s_descriptorField == NULL,
1491cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            "Unable to find descriptor field in java.io.FileDescriptor");
1501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1514528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate    clazz = env->FindClass("android/app/backup/BackupDataInput$EntityHeader");
1524528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.app.backup.BackupDataInput.EntityHeader");
1531cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    s_keyField = env->GetFieldID(clazz, "key", "Ljava/lang/String;");
1541cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    LOG_FATAL_IF(s_keyField == NULL,
1554528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate            "Unable to find key field in android.app.backup.BackupDataInput.EntityHeader");
15603f4df4b3bf8b8828e795a0bf1f913e6e08f12f1Joe Onorato    s_dataSizeField = env->GetFieldID(clazz, "dataSize", "I");
1571cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    LOG_FATAL_IF(s_dataSizeField == NULL,
1584528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate            "Unable to find dataSize field in android.app.backup.BackupDataInput.EntityHeader");
1591cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1604528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate    return AndroidRuntime::registerNativeMethods(env, "android/app/backup/BackupDataInput",
1611cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            g_methods, NELEM(g_methods));
1621cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
1631cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1641cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
165