Orion Hodson | 4c3ade6 | 2021-02-10 14:07:10 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2021 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 | #ifndef ART_ODREFRESH_ODR_CONFIG_H_ |
| 18 | #define ART_ODREFRESH_ODR_CONFIG_H_ |
| 19 | |
| 20 | #include <string> |
| 21 | #include <vector> |
| 22 | |
| 23 | #include "android-base/file.h" |
| 24 | #include "arch/instruction_set.h" |
| 25 | #include "base/globals.h" |
| 26 | #include "log/log.h" |
| 27 | |
| 28 | namespace art { |
| 29 | namespace odrefresh { |
| 30 | |
| 31 | // An enumeration of the possible zygote configurations on Android. |
| 32 | enum class ZygoteKind : uint8_t { |
| 33 | // 32-bit primary zygote, no secondary zygote. |
| 34 | kZygote32 = 0, |
| 35 | // 32-bit primary zygote, 64-bit secondary zygote. |
| 36 | kZygote32_64 = 1, |
| 37 | // 64-bit primary zygote, 32-bit secondary zygote. |
| 38 | kZygote64_32 = 2, |
Orion Hodson | f96c916 | 2021-04-07 10:43:01 +0100 | [diff] [blame] | 39 | // 64-bit primary zygote, no secondary zygote. |
Orion Hodson | 4c3ade6 | 2021-02-10 14:07:10 +0000 | [diff] [blame] | 40 | kZygote64 = 3 |
| 41 | }; |
| 42 | |
| 43 | // Configuration class for odrefresh. Exists to enable abstracting environment variables and |
| 44 | // system properties into a configuration class for development and testing purposes. |
| 45 | class OdrConfig final { |
| 46 | private: |
| 47 | std::string apex_info_list_file_; |
| 48 | std::string art_bin_dir_; |
| 49 | std::string dex2oat_; |
| 50 | std::string dex2oat_boot_classpath_; |
| 51 | bool dry_run_; |
| 52 | InstructionSet isa_; |
| 53 | std::string program_name_; |
| 54 | std::string system_server_classpath_; |
| 55 | std::string updatable_bcp_packages_file_; |
| 56 | ZygoteKind zygote_kind_; |
| 57 | |
| 58 | public: |
| 59 | explicit OdrConfig(const char* program_name) |
| 60 | : dry_run_(false), |
| 61 | isa_(InstructionSet::kNone), |
| 62 | program_name_(android::base::Basename(program_name)) { |
| 63 | } |
| 64 | |
| 65 | const std::string& GetApexInfoListFile() const { return apex_info_list_file_; } |
| 66 | |
| 67 | std::vector<InstructionSet> GetBootExtensionIsas() const { |
| 68 | const auto [isa32, isa64] = GetPotentialInstructionSets(); |
| 69 | switch (zygote_kind_) { |
| 70 | case ZygoteKind::kZygote32: |
| 71 | return {isa32}; |
| 72 | case ZygoteKind::kZygote32_64: |
| 73 | case ZygoteKind::kZygote64_32: |
| 74 | return {isa32, isa64}; |
| 75 | case ZygoteKind::kZygote64: |
| 76 | return {isa64}; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | InstructionSet GetSystemServerIsa() const { |
| 81 | const auto [isa32, isa64] = GetPotentialInstructionSets(); |
| 82 | switch (zygote_kind_) { |
| 83 | case ZygoteKind::kZygote32: |
| 84 | case ZygoteKind::kZygote32_64: |
| 85 | return isa32; |
| 86 | case ZygoteKind::kZygote64_32: |
| 87 | case ZygoteKind::kZygote64: |
| 88 | return isa64; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | const std::string& GetDex2oatBootClasspath() const { return dex2oat_boot_classpath_; } |
| 93 | |
| 94 | std::string GetDex2Oat() const { |
| 95 | const char* prefix = UseDebugBinaries() ? "dex2oatd" : "dex2oat"; |
| 96 | const char* suffix = ""; |
| 97 | if (kIsTargetBuild) { |
| 98 | switch (zygote_kind_) { |
| 99 | case ZygoteKind::kZygote32: |
| 100 | suffix = "32"; |
| 101 | break; |
| 102 | case ZygoteKind::kZygote32_64: |
| 103 | case ZygoteKind::kZygote64_32: |
| 104 | case ZygoteKind::kZygote64: |
| 105 | suffix = "64"; |
| 106 | break; |
| 107 | } |
| 108 | } |
| 109 | return art_bin_dir_ + '/' + prefix + suffix; |
| 110 | } |
| 111 | |
| 112 | std::string GetDexOptAnalyzer() const { |
| 113 | const char* dexoptanalyzer{UseDebugBinaries() ? "dexoptanalyzerd" : "dexoptanalyzer"}; |
| 114 | return art_bin_dir_ + '/' + dexoptanalyzer; |
| 115 | } |
| 116 | |
| 117 | bool GetDryRun() const { return dry_run_; } |
| 118 | const std::string& GetSystemServerClasspath() const { return system_server_classpath_; } |
| 119 | const std::string& GetUpdatableBcpPackagesFile() const { return updatable_bcp_packages_file_; } |
| 120 | |
| 121 | void SetApexInfoListFile(const std::string& file_path) { apex_info_list_file_ = file_path; } |
| 122 | void SetArtBinDir(const std::string& art_bin_dir) { art_bin_dir_ = art_bin_dir; } |
| 123 | |
| 124 | void SetDex2oatBootclasspath(const std::string& classpath) { |
| 125 | dex2oat_boot_classpath_ = classpath; |
| 126 | } |
| 127 | |
| 128 | void SetDryRun() { dry_run_ = true; } |
| 129 | void SetIsa(const InstructionSet isa) { isa_ = isa; } |
| 130 | |
| 131 | void SetSystemServerClasspath(const std::string& classpath) { |
| 132 | system_server_classpath_ = classpath; |
| 133 | } |
| 134 | |
| 135 | void SetUpdatableBcpPackagesFile(const std::string& file) { updatable_bcp_packages_file_ = file; } |
| 136 | void SetZygoteKind(ZygoteKind zygote_kind) { zygote_kind_ = zygote_kind; } |
| 137 | |
| 138 | private: |
| 139 | // Returns a pair for the possible instruction sets for the configured instruction set |
| 140 | // architecture. The first item is the 32-bit architecture and the second item is the 64-bit |
| 141 | // architecture. The current `isa` is based on `kRuntimeISA` on target, odrefresh is compiled |
| 142 | // 32-bit by default so this method returns all options which are finessed based on the |
| 143 | // `ro.zygote` property. |
| 144 | std::pair<InstructionSet, InstructionSet> GetPotentialInstructionSets() const { |
| 145 | switch (isa_) { |
| 146 | case art::InstructionSet::kArm: |
| 147 | case art::InstructionSet::kArm64: |
| 148 | return std::make_pair(art::InstructionSet::kArm, art::InstructionSet::kArm64); |
| 149 | case art::InstructionSet::kX86: |
| 150 | case art::InstructionSet::kX86_64: |
| 151 | return std::make_pair(art::InstructionSet::kX86, art::InstructionSet::kX86_64); |
| 152 | case art::InstructionSet::kThumb2: |
| 153 | case art::InstructionSet::kNone: |
| 154 | LOG(FATAL) << "Invalid instruction set " << isa_; |
| 155 | return std::make_pair(art::InstructionSet::kNone, art::InstructionSet::kNone); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | bool UseDebugBinaries() const { return program_name_ == "odrefreshd"; } |
| 160 | |
| 161 | OdrConfig() = delete; |
| 162 | OdrConfig(const OdrConfig&) = delete; |
| 163 | OdrConfig& operator=(const OdrConfig&) = delete; |
| 164 | }; |
| 165 | |
| 166 | } // namespace odrefresh |
| 167 | } // namespace art |
| 168 | |
| 169 | #endif // ART_ODREFRESH_ODR_CONFIG_H_ |