• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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