Advertisement
splash5

A way to get ApplicationInfo when app start

Jan 8th, 2014
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.81 KB | None | 0 0
  1. /*
  2.  * content manager for Android
  3.  */
  4.  
  5. #include <android/log.h>
  6. #include <stdio.h>
  7.  
  8. #include "murmurhash3.h"
  9. #include "unzip.h"
  10.  
  11. #include "content_manager.h"
  12.  
  13. #define ACTIVITYTHREAD_CLASSNAME        "android/app/ActivityThread"
  14. #define APPBINDDATA_CLASSNAME           ACTIVITYTHREAD_CLASSNAME"$AppBindData"
  15. #define APPLICATIONINFO_CLASSNAME       "android/content/pm/ApplicationInfo"
  16. #define ENVIRONMENT_CLASSNAME           "android/os/Environment"
  17. #define FILE_CLASSNAME                  "java/io/File"
  18. #define STRING_CLASSNAME                "java/lang/String"
  19.  
  20. #define ACTIVITYTHREAD_CLASS_SIGNATURE  "L"ACTIVITYTHREAD_CLASSNAME";"
  21. #define APPBINDDATA_CLASS_SIGNATURE     "L"APPBINDDATA_CLASSNAME";"
  22. #define APPLICATIONINFO_CLASS_SIGNATURE "L"APPLICATIONINFO_CLASSNAME";"
  23. #define STRING_CLASS_SIGNATURE          "L"STRING_CLASSNAME";"
  24. #define FILE_CLASS_SIGNATURE            "L"FILE_CLASSNAME";"
  25.  
  26. #define DATA_DIRECTORY                  "/Android/data"
  27. #define MEDIA_DIRECTORY                 "/Android/media"
  28. #define OBB_DIRECTORY                   "/Android/obb"
  29.  
  30. #define LOG_TAG                         "ContentManager"
  31.  
  32. #ifndef NDEBUG
  33.     #define LOGD(...)   __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  34.     #define LOGE(...)   __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
  35.     #define LOGW(...)   __android_log_print(ANDROID_LOG_WARN,  LOG_TAG, __VA_ARGS__)
  36.     #define LOGI(...)   __android_log_print(ANDROID_LOG_INFO,  LOG_TAG, __VA_ARGS__)
  37. #else
  38.     #define LOGD(...)   do {} while (0)
  39.     #define LOGE(...)   do {} while (0)
  40.     #define LOGW(...)   do {} while (0)
  41.     #define LOGI(...)   do {} while (0)
  42. #endif
  43.  
  44. #define STRING_BUFFERSIZE               512
  45.  
  46. static char PackageName[STRING_BUFFERSIZE]              = {0};
  47. static char DataDir[STRING_BUFFERSIZE]                  = {0};
  48. static char SourceDir[STRING_BUFFERSIZE]                = {0};
  49. static char ExternalDirectory[STRING_BUFFERSIZE]        = {0};
  50. static char ExternalDataDirectory[STRING_BUFFERSIZE]    = {0};
  51. static char ExternalMediaDirectory[STRING_BUFFERSIZE]   = {0};
  52. static char ExternalOBBDirectory[STRING_BUFFERSIZE]     = {0};
  53.  
  54. static unzFile APKFile = 0;
  55.  
  56. typedef struct
  57. {
  58.     unz64_file_pos file_pos;
  59.     uLong uncompressed_size;
  60. } Content;
  61.  
  62. static jclass cm_get_jclass(const char *class_name, JNIEnv *env)
  63. {
  64.     jclass clazz = 0;
  65.  
  66.     if (env)
  67.     {
  68.         clazz = (*env)->FindClass(env, class_name);
  69.  
  70.         if ((*env)->ExceptionCheck(env))
  71.             (*env)->ExceptionClear(env);
  72.     }
  73.  
  74.     return clazz;
  75. }
  76.  
  77. static jmethodID cm_get_jmethod(jclass clazz, const char *method_name, const char *signature, JNIEnv *env)
  78. {
  79.     jmethodID methodId = 0;
  80.  
  81.     if (env)
  82.     {
  83.         methodId = (*env)->GetMethodID(env, clazz, method_name, signature);
  84.  
  85.         if ((*env)->ExceptionCheck(env))
  86.             (*env)->ExceptionClear(env);
  87.     }
  88.  
  89.     return methodId;
  90. }
  91.  
  92. static jmethodID cm_get_static_jmethod(jclass clazz, const char *method_name, const char *signature, JNIEnv *env)
  93. {
  94.     jmethodID methodId = 0;
  95.  
  96.     if (env)
  97.     {
  98.         methodId = (*env)->GetStaticMethodID(env, clazz, method_name, signature);
  99.  
  100.         if ((*env)->ExceptionCheck(env))
  101.             (*env)->ExceptionClear(env);
  102.     }
  103.  
  104.     return methodId;
  105. }
  106.  
  107. static jfieldID cm_get_jfield(jclass clazz, const char *field_name, const char *signature, JNIEnv *env)
  108. {
  109.     jfieldID fieldId = 0;
  110.  
  111.     if (env)
  112.     {
  113.         fieldId = (*env)->GetFieldID(env, clazz, field_name, signature);
  114.  
  115.         if ((*env)->ExceptionCheck(env))
  116.             (*env)->ExceptionClear(env);
  117.     }
  118.  
  119.     return fieldId;
  120. }
  121.  
  122. int cm_initialize(JNIEnv *env)
  123. {
  124.     int ret = 0;
  125.  
  126.     jclass jcActivityThread = 0, jcAppBindData = 0, jcApplicationInfo = 0, jcEnvironment = 0, jcFile = 0;
  127.     jstring jsString = 0;
  128.     jobject joActivityThread = 0, joAppBindData = 0, joAppInfo = 0, joFile = 0;
  129.  
  130.     jmethodID jmCurrentActivityThread, jmGetExtStorageDir, jmGetAbsolutePath;
  131.     jfieldID jfAppInfo, jfBoundApplication, jfSourceDir, jfDataDir, jfPackageName;
  132.  
  133.     const char *package_name, *source_dir, *data_dir, *ext_storage_dir;
  134.  
  135.     if (!env)
  136.         goto cm_initialize_error_;
  137.  
  138.     if ((*env)->PushLocalFrame(env, 10))
  139.         goto cm_initialize_error_;
  140.  
  141.     if (!(jcActivityThread = cm_get_jclass(ACTIVITYTHREAD_CLASSNAME, env)))
  142.         goto cm_initialize_error;
  143.  
  144.     if (!(jcAppBindData = cm_get_jclass(APPBINDDATA_CLASSNAME, env)))
  145.         goto cm_initialize_error;
  146.  
  147.     if (!(jcApplicationInfo = cm_get_jclass(APPLICATIONINFO_CLASSNAME, env)))
  148.         goto cm_initialize_error;
  149.  
  150.     if (!(jcEnvironment = cm_get_jclass(ENVIRONMENT_CLASSNAME, env)))
  151.         goto cm_initialize_error;
  152.  
  153.     if (!(jcFile = cm_get_jclass(FILE_CLASSNAME, env)))
  154.         goto cm_initialize_error;
  155.  
  156.     if (!(jmCurrentActivityThread = cm_get_static_jmethod(jcActivityThread, "currentActivityThread", "()"ACTIVITYTHREAD_CLASS_SIGNATURE, env)))
  157.         goto cm_initialize_error;
  158.  
  159.     if (!(jmGetExtStorageDir = cm_get_static_jmethod(jcEnvironment, "getExternalStorageDirectory", "()"FILE_CLASS_SIGNATURE, env)))
  160.         goto cm_initialize_error;
  161.  
  162.     if (!(jmGetAbsolutePath = cm_get_jmethod(jcFile, "getAbsolutePath", "()"STRING_CLASS_SIGNATURE, env)))
  163.         goto cm_initialize_error;
  164.  
  165.     if (!(jfBoundApplication = cm_get_jfield(jcActivityThread, "mBoundApplication", APPBINDDATA_CLASS_SIGNATURE, env)))
  166.         goto cm_initialize_error;
  167.  
  168.     if (!(jfAppInfo = cm_get_jfield(jcAppBindData, "appInfo", APPLICATIONINFO_CLASS_SIGNATURE, env)))
  169.         goto cm_initialize_error;
  170.  
  171.     if (!(jfPackageName = cm_get_jfield(jcApplicationInfo, "packageName", STRING_CLASS_SIGNATURE, env)))
  172.         goto cm_initialize_error;
  173.  
  174.     if (!(jfSourceDir = cm_get_jfield(jcApplicationInfo, "sourceDir", STRING_CLASS_SIGNATURE, env)))
  175.         goto cm_initialize_error;
  176.  
  177.     if (!(jfDataDir = cm_get_jfield(jcApplicationInfo, "dataDir", STRING_CLASS_SIGNATURE, env)))
  178.             goto cm_initialize_error;
  179.  
  180.     if (!(joActivityThread = (*env)->CallStaticObjectMethod(env, jcActivityThread, jmCurrentActivityThread)))
  181.         goto cm_initialize_error;
  182.  
  183.     if (!(joAppBindData = (*env)->GetObjectField(env, joActivityThread, jfBoundApplication)))
  184.         goto cm_initialize_error;
  185.  
  186.     if (!(joAppInfo = (*env)->GetObjectField(env, joAppBindData, jfAppInfo)))
  187.         goto cm_initialize_error;
  188.  
  189.     if (!(joFile = (*env)->CallStaticObjectMethod(env, jcEnvironment, jmGetExtStorageDir)))
  190.         goto cm_initialize_error;
  191.  
  192.     // get packagename
  193.     if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfPackageName)))
  194.         goto cm_initialize_error;
  195.  
  196.     if (!(package_name = (*env)->GetStringUTFChars(env, jsString, 0)))
  197.         goto cm_initialize_error;
  198.  
  199.     snprintf(PackageName, STRING_BUFFERSIZE, "%s", package_name);
  200.     (*env)->ReleaseStringUTFChars(env, jsString, package_name);
  201.     (*env)->DeleteLocalRef(env, jsString);
  202.  
  203.     // get sourceDir
  204.     if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfSourceDir)))
  205.         goto cm_initialize_error;
  206.  
  207.     if (!(source_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
  208.         goto cm_initialize_error;
  209.  
  210.     snprintf(SourceDir, STRING_BUFFERSIZE, "%s", source_dir);
  211.     (*env)->ReleaseStringUTFChars(env, jsString, source_dir);
  212.     (*env)->DeleteLocalRef(env, jsString);
  213.  
  214.     // get dataDir
  215.     if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfDataDir)))
  216.         goto cm_initialize_error;
  217.  
  218.     if (!(data_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
  219.         goto cm_initialize_error;
  220.  
  221.     snprintf(DataDir, STRING_BUFFERSIZE, "%s", data_dir);
  222.     (*env)->ReleaseStringUTFChars(env, jsString, data_dir);
  223.     (*env)->DeleteLocalRef(env, jsString);
  224.  
  225.     // get external storage directory
  226.     if (!(jsString = (*env)->CallObjectMethod(env, joFile, jmGetAbsolutePath)))
  227.         goto cm_initialize_error;
  228.  
  229.     if (!(ext_storage_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
  230.         goto cm_initialize_error;
  231.  
  232.     snprintf(ExternalDirectory, STRING_BUFFERSIZE, "%s", ext_storage_dir);
  233.     (*env)->ReleaseStringUTFChars(env, jsString, ext_storage_dir);
  234.     // delete local ref in cm_initialize_error
  235.  
  236.     snprintf(ExternalDataDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, DATA_DIRECTORY);
  237.     snprintf(ExternalMediaDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, MEDIA_DIRECTORY);
  238.     snprintf(ExternalOBBDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, OBB_DIRECTORY);
  239.  
  240.     LOGD("package = %s", PackageName);
  241.     LOGD("source dir = %s", SourceDir);
  242.     LOGD("data dir = %s", DataDir);
  243.     LOGD("ext dir = %s", ExternalDirectory);
  244.     LOGD("ext data = %s", ExternalDataDirectory);
  245.     LOGD("ext media = %s", ExternalMediaDirectory);
  246.     LOGD("ext obb = %s", ExternalOBBDirectory);
  247.  
  248.     if (!(APKFile = unzOpen(SourceDir)))
  249.         goto cm_initialize_error;
  250.  
  251.     char file_name[STRING_BUFFERSIZE];
  252.     unz_file_info64 file_info;
  253.     unz64_file_pos file_pos;
  254.     unz_global_info64 global_info;
  255.  
  256.     ZPOS64_T start_pos;
  257.     uLong handle;
  258.    
  259.     if (unzGetGlobalInfo64(APKFile, &global_info) == UNZ_OK)
  260.     {
  261.         LOGD("entry: %llu", global_info.number_entry);
  262.        
  263.         do
  264.         {
  265.             if (unzGetCurrentFileInfo64(APKFile, &file_info, file_name, STRING_BUFFERSIZE - 1, 0, 0, 0, 0) == UNZ_OK)
  266.             {
  267.                 if (unzGetFilePos64(APKFile, &file_pos) == UNZ_OK)
  268.                 {
  269.                     if (unzOpenCurrentFile(APKFile) == UNZ_OK)
  270.                     {
  271.                         start_pos = unzGetCurrentFileZStreamPos64(APKFile);
  272.                        
  273.                         handle = crc32(0, file_name, file_info.size_filename);
  274.                         // MurmurHash3_x86_32(file_name, file_info.size_filename, 0, &handle);
  275.                    
  276.                         LOGD("%s : start 0x%08llx length 0x%08llx 0x%08lx handle = %lu", file_name,
  277.                                                                                          start_pos,
  278.                                                                                          file_info.compressed_size,
  279.                                                                                          handle,
  280.                                                                                          (handle % 32));
  281.                     }
  282.                 }
  283.             }
  284.         } while (unzGoToNextFile(APKFile) == UNZ_OK);
  285.     }
  286.  
  287.     LOGD("end of list file");
  288.    
  289.     unzGoToFirstFile(APKFile);
  290.  
  291.     ret = 1;
  292.  
  293. cm_initialize_error:
  294.     (*env)->DeleteLocalRef(env, jcActivityThread);
  295.     (*env)->DeleteLocalRef(env, jcAppBindData);
  296.     (*env)->DeleteLocalRef(env, jcApplicationInfo);
  297.     (*env)->DeleteLocalRef(env, jcEnvironment);
  298.     (*env)->DeleteLocalRef(env, jcFile);
  299.  
  300.     (*env)->DeleteLocalRef(env, joActivityThread);
  301.     (*env)->DeleteLocalRef(env, joAppBindData);
  302.     (*env)->DeleteLocalRef(env, joAppInfo);
  303.     (*env)->DeleteLocalRef(env, joFile);
  304.  
  305.     (*env)->DeleteLocalRef(env, jsString);
  306.  
  307.     (*env)->PopLocalFrame(env, 0);
  308.  
  309. cm_initialize_error_:
  310.     return ret;
  311. }
  312.  
  313. int cm_deinitialize(void)
  314. {
  315.     unzClose(APKFile);
  316. }
  317.  
  318.  
  319. // for test
  320. #include <pthread.h>
  321. #define USE_JNI_VERSION JNI_VERSION_1_4
  322.  
  323. static JavaVM *jvm = 0;
  324.  
  325. static void jvm_detach_thread(void *arg)
  326. {
  327.     pthread_key_t *jvm_detach_key = (pthread_key_t *)arg;
  328.  
  329.     if (jvm)
  330.         (*jvm)->DetachCurrentThread(jvm);
  331.  
  332.     pthread_setspecific(*jvm_detach_key, 0);
  333.     free(jvm_detach_key);
  334. }
  335.  
  336. int getEnv(JNIEnv **env)
  337. {
  338.     switch ((*jvm)->GetEnv(jvm, (void **)env, USE_JNI_VERSION))
  339.     {
  340.         default:
  341.         {
  342.             return 0;
  343.         }
  344.         case JNI_EDETACHED:
  345.         {
  346.             if ((*jvm)->AttachCurrentThread(jvm, env, 0))
  347.             {
  348.                 return 0;
  349.             }
  350.  
  351.             pthread_key_t *jvm_detach_key = (pthread_key_t *)calloc(1, sizeof(pthread_key_t));
  352.  
  353.             // attach successfully
  354.             pthread_key_create(jvm_detach_key, jvm_detach_thread);
  355.             pthread_setspecific(*jvm_detach_key, jvm_detach_key);
  356.         }
  357.         case JNI_OK:
  358.         {
  359.             break;
  360.         }
  361.     }
  362.  
  363.     return 1;
  364. }
  365.  
  366. jint JNI_OnLoad(JavaVM *vm, void *reserved)
  367. {
  368.     JNIEnv *env;
  369.     jvm = vm;
  370.  
  371.     if (getEnv(&env) && cm_initialize(env))
  372.         return USE_JNI_VERSION;
  373.  
  374.     return -1;
  375. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement