1 /* 2 * Copyright (C) 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 specic language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MEDIAPROVIDER_FUSE_MEDIAPROVIDERWRAPPER_H_ 18 #define MEDIAPROVIDER_FUSE_MEDIAPROVIDERWRAPPER_H_ 19 20 #include <jni.h> 21 #include <sys/types.h> 22 23 #include <dirent.h> 24 #include <atomic> 25 #include <condition_variable> 26 #include <functional> 27 #include <mutex> 28 #include <queue> 29 #include <string> 30 #include <thread> 31 32 #include "libfuse_jni/ReaddirHelper.h" 33 #include "libfuse_jni/RedactionInfo.h" 34 35 namespace mediaprovider { 36 namespace fuse { 37 38 /** 39 * Class that wraps MediaProvider.java and all of the needed JNI calls to make 40 * interaction with MediaProvider easier. 41 */ 42 class MediaProviderWrapper final { 43 public: 44 MediaProviderWrapper(JNIEnv* env, jobject media_provider); 45 ~MediaProviderWrapper(); 46 47 /** 48 * Computes and returns the RedactionInfo for a given file and UID. 49 * 50 * @param uid UID of the app requesting the read 51 * @param path path of the requested file 52 * @return RedactionInfo on success, nullptr on failure to calculate 53 * redaction ranges (e.g. exception was thrown in Java world) 54 */ 55 std::unique_ptr<RedactionInfo> GetRedactionInfo(const std::string& path, uid_t uid, pid_t tid); 56 57 /** 58 * Inserts a new entry for the given path and UID. 59 * 60 * @param path the path of the file to be created 61 * @param uid UID of the calling app 62 * @return 0 if the operation succeeded, 63 * or errno error code if operation fails. 64 */ 65 int InsertFile(const std::string& path, uid_t uid); 66 67 /** 68 * Delete the file denoted by the given path on behalf of the given UID. 69 * 70 * @param path the path of the file to be deleted 71 * @param uid UID of the calling app 72 * @return 0 upon success, or errno error code if operation fails. 73 */ 74 int DeleteFile(const std::string& path, uid_t uid); 75 76 /** 77 * Gets directory entries for given path from MediaProvider database and lower file system 78 * 79 * @param uid UID of the calling app. 80 * @param path Relative path of the directory. 81 * @param dirp Pointer to directory stream, used to query lower file system. 82 * @return DirectoryEntries with list of directory entries on success. 83 * File names in a directory are obtained from MediaProvider. If a path is unknown to 84 * MediaProvider, file names are obtained from lower file system. All directory names in the 85 * given directory are obtained from lower file system. 86 * An empty string in first directory entry name indicates the error occurred while obtaining 87 * directory entries, directory entry type will hold the corresponding errno information. 88 */ 89 std::vector<std::shared_ptr<DirectoryEntry>> GetDirectoryEntries(uid_t uid, 90 const std::string& path, 91 DIR* dirp); 92 93 /** 94 * Determines if the given UID is allowed to open the file denoted by the given path. 95 * 96 * @param path the path of the file to be opened 97 * @param uid UID of the calling app 98 * @param for_write specifies if the file is to be opened for write 99 * @return 0 upon success or errno value upon failure. 100 */ 101 int IsOpenAllowed(const std::string& path, uid_t uid, bool for_write); 102 103 /** 104 * Potentially triggers a scan of the file before closing it and reconciles it with the 105 * MediaProvider database. 106 * 107 * @param path the path of the file to be scanned 108 */ 109 void ScanFile(const std::string& path); 110 111 /** 112 * Determines if the given UID is allowed to create a directory with the given path. 113 * 114 * @param path the path of the directory to be created 115 * @param uid UID of the calling app 116 * @return 0 if it's allowed, or errno error code if operation isn't allowed. 117 */ 118 int IsCreatingDirAllowed(const std::string& path, uid_t uid); 119 120 /** 121 * Determines if the given UID is allowed to delete the directory with the given path. 122 * 123 * @param path the path of the directory to be deleted 124 * @param uid UID of the calling app 125 * @return 0 if it's allowed, or errno error code if operation isn't allowed. 126 */ 127 int IsDeletingDirAllowed(const std::string& path, uid_t uid); 128 129 /** 130 * Determines if the given UID is allowed to open the directory with the given path. 131 * 132 * @param path the path of the directory to be opened 133 * @param uid UID of the calling app 134 * @param forWrite if it's a write access 135 * @return 0 if it's allowed, or errno error code if operation isn't allowed. 136 */ 137 int IsOpendirAllowed(const std::string& path, uid_t uid, bool forWrite); 138 139 /** 140 * Determines if the given package name matches its uid. 141 * 142 * @param pkg the package name of the app 143 * @param uid UID of the app 144 * @return true if it matches, otherwise return false. 145 */ 146 bool IsUidForPackage(const std::string& pkg, uid_t uid); 147 148 /** 149 * Renames a file or directory to new path. 150 * 151 * @param old_path path of the file or directory to be renamed. 152 * @param new_path new path of the file or directory to be renamed. 153 * @param uid UID of the calling app. 154 * @return 0 if rename is successful, errno if one of the rename fails. If return 155 * value is 0, it's guaranteed that file/directory is moved to new_path. For any other errno 156 * except EFAULT/EIO, it's guaranteed that file/directory is not renamed. 157 */ 158 int Rename(const std::string& old_path, const std::string& new_path, uid_t uid); 159 160 /** 161 * Called whenever a file has been created through FUSE. 162 * 163 * @param path path of the file that has been created. 164 */ 165 void OnFileCreated(const std::string& path); 166 167 /** 168 * Initializes per-process static variables associated with the lifetime of 169 * a managed runtime. 170 */ 171 static void OneTimeInit(JavaVM* vm); 172 173 /** TLS Key to map a given thread to its JNIEnv. */ 174 static pthread_key_t gJniEnvKey; 175 176 private: 177 jclass media_provider_class_; 178 jobject media_provider_object_; 179 /** Cached MediaProvider method IDs **/ 180 jmethodID mid_get_redaction_ranges_; 181 jmethodID mid_insert_file_; 182 jmethodID mid_delete_file_; 183 jmethodID mid_is_open_allowed_; 184 jmethodID mid_scan_file_; 185 jmethodID mid_is_mkdir_or_rmdir_allowed_; 186 jmethodID mid_is_opendir_allowed_; 187 jmethodID mid_get_files_in_dir_; 188 jmethodID mid_rename_; 189 jmethodID mid_is_uid_for_package_; 190 jmethodID mid_on_file_created_; 191 192 /** 193 * Auxiliary for caching MediaProvider methods. 194 */ 195 jmethodID CacheMethod(JNIEnv* env, const char method_name[], const char signature[], 196 bool is_static); 197 198 // Attaches the current thread (if necessary) and returns the JNIEnv 199 // associated with it. 200 static JNIEnv* MaybeAttachCurrentThread(); 201 // Destructor function for a given native thread. Called precisely once 202 // by the pthreads library. 203 static void DetachThreadFunction(void* unused); 204 205 static JavaVM* gJavaVm; 206 }; 207 208 } // namespace fuse 209 } // namespace mediaprovider 210 211 #endif // MEDIAPROVIDER_FUSE_MEDIAPROVIDERWRAPPER_H_ 212