1 // Copyright (C) 2020 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef IORAP_SRC_PACKAGE_VERSION_MAP_H_ 16 #define IORAP_SRC_PACKAGE_VERSION_MAP_H_ 17 18 #include <android/content/pm/IPackageManagerNative.h> 19 #include <binder/IServiceManager.h> 20 21 #include <optional> 22 #include <unordered_map> 23 24 #include "package_manager_remote.h" 25 26 namespace iorap::binder { 27 28 class PackageVersionMap { 29 public: 30 static std::shared_ptr<PackageVersionMap> Create(); 31 PackageVersionMap(std::shared_ptr<PackageManagerRemote> package_manager,std::optional<VersionMap> version_map)32 PackageVersionMap(std::shared_ptr<PackageManagerRemote> package_manager, 33 std::optional<VersionMap> version_map) 34 : package_manager_(package_manager), 35 version_map_(version_map) {} 36 PackageVersionMap()37 PackageVersionMap() 38 : package_manager_(nullptr), version_map_(std::nullopt) {} 39 40 // Updates the version specified by 'package_name' to 'version'. 41 // 42 // Post-condition: Find(package_name) == version. 43 // * if the package is newly installed, insert and return true. 44 // * if the package version is changed, update the version to the 45 // given one and return true. 46 // * otherwise, return false. 47 bool Update(std::string package_name, int64_t version); 48 49 void UpdateAll(); 50 51 // Finds the version of the package in the hash table. 52 // -1 means the app is installed by unversioned. 53 // Empty means the app is not inside the RAM version map, maybe due to 54 // the app is newly installed. Find(const std::string & package_name)55 std::optional<int64_t> Find(const std::string& package_name) { 56 VersionMap::iterator it = version_map_->find(package_name); 57 if (it == version_map_->end()) { 58 return std::nullopt; 59 } 60 return it->second; 61 } 62 63 size_t Size(); 64 65 // Gets or queries the version for the package. 66 // 67 // The method firstly access the hash map in the RAM, which is built when 68 // iorapd starts. If the version is not in the map, it tries the query 69 // the package manager via IPC, with a cost of ~0.6ms. 70 // 71 // If no version can be found for some reason, return -1, 72 // because when an app has no version the package manager returns -1. 73 std::optional<int64_t> GetOrQueryPackageVersion( 74 const std::string& package_name); 75 76 private: 77 std::shared_ptr<PackageManagerRemote> package_manager_; 78 std::optional<VersionMap> version_map_; 79 std::mutex mutex_; 80 }; 81 } // namespace iorap::binder 82 83 #endif // IORAP_SRC_PACKAGE_MANAGER_REMOTE_H_ 84