android_content_res_ObbScanner.cpp revision dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4
102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root/*
202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * Copyright 2010, The Android Open Source Project
302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root *
402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * you may not use this file except in compliance with the License.
602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * You may obtain a copy of the License at
702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root *
802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root *     http://www.apache.org/licenses/LICENSE-2.0
902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root *
1002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * Unless required by applicable law or agreed to in writing, software
1102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * See the License for the specific language governing permissions and
1402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * limitations under the License.
1502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */
1602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
1702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#define LOG_TAG "ObbScanner"
1802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
1902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include <utils/Log.h>
2002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include <utils/String8.h>
2102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include <utils/ObbFile.h>
2202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
2302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include "jni.h"
248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "JNIHelp.h"
2502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include "utils/misc.h"
2602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include "android_runtime/AndroidRuntime.h"
2702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
2802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootnamespace android {
2902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
3002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootstatic struct {
3102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jclass clazz;
3202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
3302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jfieldID packageName;
3402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jfieldID version;
3502ca31fbae9f35dd30f79de6927fae11b549391aKenny Root    jfieldID flags;
363b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    jfieldID salt;
3702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root} gObbInfoClassInfo;
3802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
3905105f7abe02b2dff91d6260b3628c8b97816babKenny Rootstatic void android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
4002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        jobject obbInfo)
4102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root{
42dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes    const char* filePath = env->GetStringUTFChars(file, NULL);
4302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
4402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    sp<ObbFile> obb = new ObbFile();
4502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    if (!obb->readFrom(filePath)) {
4602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        env->ReleaseStringUTFChars(file, filePath);
478451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        jniThrowException(env, "java/io/IOException", "Could not read OBB file");
4805105f7abe02b2dff91d6260b3628c8b97816babKenny Root        return;
4902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    }
5002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
5102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->ReleaseStringUTFChars(file, filePath);
5202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
5302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    const char* packageNameStr = obb->getPackageName().string();
5402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
5502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jstring packageName = env->NewStringUTF(packageNameStr);
5602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    if (packageName == NULL) {
578451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        jniThrowException(env, "java/io/IOException", "Could not read OBB file");
5805105f7abe02b2dff91d6260b3628c8b97816babKenny Root        return;
5902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    }
6002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
6102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->SetObjectField(obbInfo, gObbInfoClassInfo.packageName, packageName);
6202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->SetIntField(obbInfo, gObbInfoClassInfo.version, obb->getVersion());
6305105f7abe02b2dff91d6260b3628c8b97816babKenny Root    env->SetIntField(obbInfo, gObbInfoClassInfo.flags, obb->getFlags());
643b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
653b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    size_t saltLen;
663b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    const unsigned char* salt = obb->getSalt(&saltLen);
673b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (saltLen > 0) {
683b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        jbyteArray saltArray = env->NewByteArray(saltLen);
693b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        env->SetByteArrayRegion(saltArray, 0, saltLen, (jbyte*)salt);
703b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        env->SetObjectField(obbInfo, gObbInfoClassInfo.salt, saltArray);
713b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
7202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}
7302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
7402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root/*
7502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * JNI registration.
7602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */
7702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootstatic JNINativeMethod gMethods[] = {
7802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    /* name, signature, funcPtr */
7905105f7abe02b2dff91d6260b3628c8b97816babKenny Root    { "getObbInfo_native", "(Ljava/lang/String;Landroid/content/res/ObbInfo;)V",
8002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            (void*) android_content_res_ObbScanner_getObbInfo },
8102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root};
8202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
8302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#define FIND_CLASS(var, className) \
8402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        var = env->FindClass(className); \
8517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro        LOG_FATAL_IF(! var, "Unable to find class " className);
8602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
8702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
8802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
8902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
9002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
9102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootint register_android_content_res_ObbScanner(JNIEnv* env)
9202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root{
9317cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    jclass clazz;
9417cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    FIND_CLASS(clazz, "android/content/res/ObbInfo");
9502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
9617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gObbInfoClassInfo.packageName, clazz,
9702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            "packageName", "Ljava/lang/String;");
9817cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gObbInfoClassInfo.version, clazz,
9902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            "version", "I");
10017cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gObbInfoClassInfo.flags, clazz,
10102ca31fbae9f35dd30f79de6927fae11b549391aKenny Root            "flags", "I");
10217cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_FIELD_ID(gObbInfoClassInfo.salt, clazz,
1033b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root            "salt", "[B");
10402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
10502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
10602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            NELEM(gMethods));
10702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}
10802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
10902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}; // namespace android
110