android_content_res_ObbScanner.cpp revision 3b1abba6bbc895d63da3e82e9b158c01bd12eddd
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"
2402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include "utils/misc.h"
2502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#include "android_runtime/AndroidRuntime.h"
2602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
2702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootnamespace android {
2802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
2902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootstatic struct {
3002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jclass clazz;
3102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
3202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jfieldID packageName;
3302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jfieldID version;
3402ca31fbae9f35dd30f79de6927fae11b549391aKenny Root    jfieldID flags;
353b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    jfieldID salt;
3602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root} gObbInfoClassInfo;
3702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
3805105f7abe02b2dff91d6260b3628c8b97816babKenny Rootstatic void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
3905105f7abe02b2dff91d6260b3628c8b97816babKenny Root{
4005105f7abe02b2dff91d6260b3628c8b97816babKenny Root    jclass npeClazz;
4105105f7abe02b2dff91d6260b3628c8b97816babKenny Root
4205105f7abe02b2dff91d6260b3628c8b97816babKenny Root    npeClazz = env->FindClass(exc);
4305105f7abe02b2dff91d6260b3628c8b97816babKenny Root    LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
4405105f7abe02b2dff91d6260b3628c8b97816babKenny Root
4505105f7abe02b2dff91d6260b3628c8b97816babKenny Root    env->ThrowNew(npeClazz, msg);
4605105f7abe02b2dff91d6260b3628c8b97816babKenny Root}
4705105f7abe02b2dff91d6260b3628c8b97816babKenny Root
4805105f7abe02b2dff91d6260b3628c8b97816babKenny Rootstatic void android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
4902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        jobject obbInfo)
5002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root{
5102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    const char* filePath = env->GetStringUTFChars(file, JNI_FALSE);
5202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
5302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    sp<ObbFile> obb = new ObbFile();
5402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    if (!obb->readFrom(filePath)) {
5502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        env->ReleaseStringUTFChars(file, filePath);
5605105f7abe02b2dff91d6260b3628c8b97816babKenny Root        doThrow(env, "java/io/IOException", "Could not read OBB file");
5705105f7abe02b2dff91d6260b3628c8b97816babKenny Root        return;
5802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    }
5902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
6002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->ReleaseStringUTFChars(file, filePath);
6102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
6202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    const char* packageNameStr = obb->getPackageName().string();
6302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
6402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    jstring packageName = env->NewStringUTF(packageNameStr);
6502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    if (packageName == NULL) {
6605105f7abe02b2dff91d6260b3628c8b97816babKenny Root        doThrow(env, "java/io/IOException", "Could not read OBB file");
6705105f7abe02b2dff91d6260b3628c8b97816babKenny Root        return;
6802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    }
6902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
7002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->SetObjectField(obbInfo, gObbInfoClassInfo.packageName, packageName);
7102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    env->SetIntField(obbInfo, gObbInfoClassInfo.version, obb->getVersion());
7205105f7abe02b2dff91d6260b3628c8b97816babKenny Root    env->SetIntField(obbInfo, gObbInfoClassInfo.flags, obb->getFlags());
733b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
743b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    size_t saltLen;
753b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    const unsigned char* salt = obb->getSalt(&saltLen);
763b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (saltLen > 0) {
773b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        jbyteArray saltArray = env->NewByteArray(saltLen);
783b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        env->SetByteArrayRegion(saltArray, 0, saltLen, (jbyte*)salt);
793b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        env->SetObjectField(obbInfo, gObbInfoClassInfo.salt, saltArray);
803b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
8102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}
8202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
8302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root/*
8402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * JNI registration.
8502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */
8602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootstatic JNINativeMethod gMethods[] = {
8702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    /* name, signature, funcPtr */
8805105f7abe02b2dff91d6260b3628c8b97816babKenny Root    { "getObbInfo_native", "(Ljava/lang/String;Landroid/content/res/ObbInfo;)V",
8902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            (void*) android_content_res_ObbScanner_getObbInfo },
9002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root};
9102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
9202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#define FIND_CLASS(var, className) \
9302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        var = env->FindClass(className); \
9402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        LOG_FATAL_IF(! var, "Unable to find class " className); \
9502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        var = jclass(env->NewGlobalRef(var));
9602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
9702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
9802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
9902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
10002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
10102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Rootint register_android_content_res_ObbScanner(JNIEnv* env)
10202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root{
10302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    FIND_CLASS(gObbInfoClassInfo.clazz, "android/content/res/ObbInfo");
10402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
10502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    GET_FIELD_ID(gObbInfoClassInfo.packageName, gObbInfoClassInfo.clazz,
10602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            "packageName", "Ljava/lang/String;");
10702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
10802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            "version", "I");
10902ca31fbae9f35dd30f79de6927fae11b549391aKenny Root    GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
11002ca31fbae9f35dd30f79de6927fae11b549391aKenny Root            "flags", "I");
1113b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    GET_FIELD_ID(gObbInfoClassInfo.salt, gObbInfoClassInfo.clazz,
1123b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root            "salt", "[B");
11302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
11402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root    return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
11502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root            NELEM(gMethods));
11602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}
11702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
11802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root}; // namespace android
11902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root
120