• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ctor_native(JNIEnv * env,jobject clazz,jobject fileDescriptor)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
dtor_native(JNIEnv * env,jobject clazz,int r)44 dtor_native(JNIEnv* env, jobject clazz, int r)
45 {
46     delete (BackupDataReader*)r;
47 }
48 
49 static jint
readNextHeader_native(JNIEnv * env,jobject clazz,int r,jobject entity)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
readEntityData_native(JNIEnv * env,jobject clazz,int r,jbyteArray data,int offset,int size)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
skipEntityData_native(JNIEnv * env,jobject clazz,int r)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 
register_android_backup_BackupDataInput(JNIEnv * env)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