Home | History | Annotate | Download | only in tuningfork
      1 /*
      2  * Copyright 2019 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 #include "tuningfork_utils.h"
     18 
     19 #include <sys/stat.h>
     20 #include <errno.h>
     21 
     22 #define LOG_TAG "TuningFork"
     23 #include "Log.h"
     24 
     25 #include <android/asset_manager.h>
     26 #include <android/asset_manager_jni.h>
     27 
     28 namespace tuningfork {
     29 
     30 namespace apk_utils {
     31 
     32     // Get an asset from this APK's asset directory.
     33     // Returns NULL if the asset could not be found.
     34     // Asset_close must be called once the asset is no longer needed.
     35     AAsset* GetAsset(JNIEnv* env, jobject activity, const char* name) {
     36         jclass cls = env->FindClass("android/content/Context");
     37         jmethodID get_assets = env->GetMethodID(cls, "getAssets",
     38                                                 "()Landroid/content/res/AssetManager;");
     39         if(get_assets==nullptr) {
     40             ALOGE("No Context.getAssets() method");
     41             return nullptr;
     42         }
     43         auto javaMgr = env->CallObjectMethod(activity, get_assets);
     44         if (javaMgr == nullptr) {
     45             ALOGE("No java asset manager");
     46             return nullptr;
     47         }
     48         AAssetManager* mgr = AAssetManager_fromJava(env, javaMgr);
     49         if (mgr == nullptr) {
     50             ALOGE("No asset manager");
     51             return nullptr;
     52         }
     53         AAsset* asset = AAssetManager_open(mgr, name,
     54                                            AASSET_MODE_BUFFER);
     55         if (asset == nullptr) {
     56             ALOGW("Can't find %s in APK", name);
     57             return nullptr;
     58         }
     59         return asset;
     60     }
     61 
     62 
     63     // Get the app's version code. Also fills packageNameStr with the package name
     64     //  if it is non-null.
     65     int GetVersionCode(JNIEnv *env, jobject context, std::string* packageNameStr) {
     66         jstring packageName;
     67         jobject packageManagerObj;
     68         jobject packageInfoObj;
     69         jclass contextClass =  env->GetObjectClass( context);
     70         jmethodID getPackageNameMid = env->GetMethodID( contextClass, "getPackageName",
     71             "()Ljava/lang/String;");
     72         jmethodID getPackageManager =  env->GetMethodID( contextClass, "getPackageManager",
     73             "()Landroid/content/pm/PackageManager;");
     74 
     75         jclass packageManagerClass = env->FindClass("android/content/pm/PackageManager");
     76         jmethodID getPackageInfo = env->GetMethodID( packageManagerClass, "getPackageInfo",
     77             "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
     78 
     79         jclass packageInfoClass = env->FindClass("android/content/pm/PackageInfo");
     80         jfieldID versionCodeFid = env->GetFieldID( packageInfoClass, "versionCode", "I");
     81 
     82         packageName =  (jstring)env->CallObjectMethod(context, getPackageNameMid);
     83 
     84         if (packageNameStr != nullptr) {
     85             // Fill packageNameStr with the package name
     86             const char* packageName_cstr = env->GetStringUTFChars(packageName, NULL);
     87             *packageNameStr = std::string(packageName_cstr);
     88             env->ReleaseStringUTFChars(packageName, packageName_cstr);
     89         }
     90         // Get version code from package info
     91         packageManagerObj = env->CallObjectMethod(context, getPackageManager);
     92         packageInfoObj = env->CallObjectMethod(packageManagerObj,getPackageInfo,
     93                                                packageName, 0x0);
     94         int versionCode = env->GetIntField( packageInfoObj, versionCodeFid);
     95         return versionCode;
     96     }
     97 
     98 } // namespace apk_utils
     99 
    100 namespace file_utils {
    101 
    102     // Creates the directory if it does not exist. Returns true if the directory
    103     //  already existed or could be created.
    104     bool CheckAndCreateDir(const std::string& path) {
    105         struct stat sb;
    106         int32_t res = stat(path.c_str(), &sb);
    107         if (0 == res && sb.st_mode & S_IFDIR) {
    108             ALOGV("Directory %s already exists", path.c_str());
    109             return true;
    110         } else if (ENOENT == errno) {
    111             ALOGI("Creating directory %s", path.c_str());
    112             res = mkdir(path.c_str(), 0770);
    113             if(res!=0)
    114                 ALOGW("Error creating directory %s: %d", path.c_str(), res);
    115             return res==0;
    116         }
    117         return false;
    118     }
    119     bool FileExists(const std::string& fname) {
    120         struct stat buffer;
    121         return (stat(fname.c_str(), &buffer)==0);
    122     }
    123     std::string GetAppCacheDir(JNIEnv* env, jobject activity) {
    124         jclass activityClass = env->FindClass( "android/app/NativeActivity" );
    125         jmethodID getCacheDir = env->GetMethodID( activityClass, "getCacheDir",
    126             "()Ljava/io/File;" );
    127         jobject cache_dir = env->CallObjectMethod( activity, getCacheDir );
    128 
    129         jclass fileClass = env->FindClass( "java/io/File" );
    130         jmethodID getPath = env->GetMethodID( fileClass, "getPath", "()Ljava/lang/String;" );
    131         jstring path_string = (jstring)env->CallObjectMethod( cache_dir, getPath );
    132 
    133         const char *path_chars = env->GetStringUTFChars( path_string, NULL );
    134         std::string temp_folder( path_chars );
    135         env->ReleaseStringUTFChars( path_string, path_chars );
    136 
    137         return temp_folder;
    138     }
    139 
    140 } // namespace file_utils
    141 
    142 std::string UniqueId(JNIEnv* env) {
    143     jclass uuid_class = env->FindClass("java/util/UUID");
    144     jmethodID randomUUID = env->GetStaticMethodID( uuid_class, "randomUUID",
    145             "()Ljava/util/UUID;");
    146     jobject uuid = env->CallStaticObjectMethod(uuid_class, randomUUID);
    147     jmethodID toString = env->GetMethodID( uuid_class, "toString", "()Ljava/lang/String;");
    148     jstring uuid_string = (jstring)env->CallObjectMethod(uuid, toString);
    149     const char *uuid_chars = env->GetStringUTFChars( uuid_string, NULL );
    150     std::string temp_uuid( uuid_chars );
    151     env->ReleaseStringUTFChars( uuid_string, uuid_chars );
    152     return temp_uuid;
    153 }
    154 
    155 } // namespace tuningfork
    156