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 specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <functional> 20 #include <string> 21 #include <unordered_map> 22 #include <vector> 23 #include "apex_constants.h" 24 #include "apex_file.h" 25 26 #include <android-base/result.h> 27 28 namespace android { 29 namespace apex { 30 31 using ApexFileRef = std::reference_wrapper<const android::apex::ApexFile>; 32 33 // This class serves as a ApexFile repository for all apexes on device. It also 34 // provides information about the ApexFiles it hosts, such as which are 35 // pre-installed and which are data. Such information can be used, for example, 36 // to verify validity of an apex before trying to mount it. 37 // 38 // It's expected to have a single instance of this class in a process that 39 // mounts apexes (e.g. apexd, otapreopt_chroot). 40 class ApexFileRepository final { 41 public: 42 // c-tor and d-tor are exposed for testing. 43 explicit ApexFileRepository( 44 const std::string& decompression_dir = kApexDecompressedDir) 45 : decompression_dir_(decompression_dir){}; 46 47 ~ApexFileRepository() { 48 pre_installed_store_.clear(); 49 data_store_.clear(); 50 }; 51 52 // Returns a singletone instance of this class. 53 static ApexFileRepository& GetInstance(); 54 55 // Populate instance by collecting pre-installed apex files from the given 56 // |prebuilt_dirs|. 57 // Note: this call is **not thread safe** and is expected to be performed in a 58 // single thread during initialization of apexd. After initialization is 59 // finished, all queries to the instance are thread safe. 60 android::base::Result<void> AddPreInstalledApex( 61 const std::vector<std::string>& prebuilt_dirs); 62 63 // Populate instance by collecting data apex files from the given |data_dir|. 64 // Note: this call is **not thread safe** and is expected to be performed in a 65 // single thread during initialization of apexd. After initialization is 66 // finished, all queries to the instance are thread safe. 67 android::base::Result<void> AddDataApex(const std::string& data_dir); 68 69 // Returns trusted public key for an apex with the given |name|. 70 android::base::Result<const std::string> GetPublicKey( 71 const std::string& name) const; 72 73 // Returns path to the pre-installed version of an apex with the given |name|. 74 android::base::Result<const std::string> GetPreinstalledPath( 75 const std::string& name) const; 76 77 // Returns path to the data version of an apex with the given |name|. 78 android::base::Result<const std::string> GetDataPath( 79 const std::string& name) const; 80 81 // Checks whether there is a pre-installed version of an apex with the given 82 // |name|. 83 bool HasPreInstalledVersion(const std::string& name) const; 84 85 // Checks whether there is a data version of an apex with the given |name|. 86 bool HasDataVersion(const std::string& name) const; 87 88 // Checks if given |apex| is pre-installed. 89 bool IsPreInstalledApex(const ApexFile& apex) const; 90 91 // Checks if given |apex| is decompressed from a pre-installed APEX 92 bool IsDecompressedApex(const ApexFile& apex) const; 93 94 // Returns reference to all pre-installed APEX on device 95 std::vector<ApexFileRef> GetPreInstalledApexFiles() const; 96 97 // Returns reference to all data APEX on device 98 std::vector<ApexFileRef> GetDataApexFiles() const; 99 100 // Group all ApexFiles on device by their package name 101 std::unordered_map<std::string, std::vector<ApexFileRef>> AllApexFilesByName() 102 const; 103 104 // Returns a pre-installed version of apex with the given name. Caller is 105 // expected to check if there is a pre-installed apex with the given name 106 // using |HasPreinstalledVersion| function. 107 ApexFileRef GetPreInstalledApex(const std::string& name) const; 108 // Returns a data version of apex with the given name. Caller is 109 // expected to check if there is a data apex with the given name 110 // using |HasDataVersion| function. 111 ApexFileRef GetDataApex(const std::string& name) const; 112 113 // Clears ApexFileRepostiry. 114 // Only use in tests. 115 void Reset(const std::string& decompression_dir = kApexDecompressedDir) { 116 pre_installed_store_.clear(); 117 data_store_.clear(); 118 decompression_dir_ = decompression_dir; 119 } 120 121 private: 122 // Non-copyable && non-moveable. 123 ApexFileRepository(const ApexFileRepository&) = delete; 124 ApexFileRepository& operator=(const ApexFileRepository&) = delete; 125 ApexFileRepository& operator=(ApexFileRepository&&) = delete; 126 ApexFileRepository(ApexFileRepository&&) = delete; 127 128 // Scans apexes in the given directory and adds collected data into 129 // |pre_installed_store_|. 130 android::base::Result<void> ScanBuiltInDir(const std::string& dir); 131 132 std::unordered_map<std::string, ApexFile> pre_installed_store_, data_store_; 133 // Decompression directory which will be used to determine if apex is 134 // decompressed or not 135 std::string decompression_dir_; 136 }; 137 138 } // namespace apex 139 } // namespace android 140