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