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, 39 // 64-bit primary zygote, no secondary zygote. 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: OdrConfig(const char * program_name)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 GetApexInfoListFile()65 const std::string& GetApexInfoListFile() const { return apex_info_list_file_; } 66 GetBootExtensionIsas()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 GetSystemServerIsa()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 GetDex2oatBootClasspath()92 const std::string& GetDex2oatBootClasspath() const { return dex2oat_boot_classpath_; } 93 GetDex2Oat()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 GetDexOptAnalyzer()112 std::string GetDexOptAnalyzer() const { 113 const char* dexoptanalyzer{UseDebugBinaries() ? "dexoptanalyzerd" : "dexoptanalyzer"}; 114 return art_bin_dir_ + '/' + dexoptanalyzer; 115 } 116 GetDryRun()117 bool GetDryRun() const { return dry_run_; } GetSystemServerClasspath()118 const std::string& GetSystemServerClasspath() const { return system_server_classpath_; } GetUpdatableBcpPackagesFile()119 const std::string& GetUpdatableBcpPackagesFile() const { return updatable_bcp_packages_file_; } 120 SetApexInfoListFile(const std::string & file_path)121 void SetApexInfoListFile(const std::string& file_path) { apex_info_list_file_ = file_path; } SetArtBinDir(const std::string & art_bin_dir)122 void SetArtBinDir(const std::string& art_bin_dir) { art_bin_dir_ = art_bin_dir; } 123 SetDex2oatBootclasspath(const std::string & classpath)124 void SetDex2oatBootclasspath(const std::string& classpath) { 125 dex2oat_boot_classpath_ = classpath; 126 } 127 SetDryRun()128 void SetDryRun() { dry_run_ = true; } SetIsa(const InstructionSet isa)129 void SetIsa(const InstructionSet isa) { isa_ = isa; } 130 SetSystemServerClasspath(const std::string & classpath)131 void SetSystemServerClasspath(const std::string& classpath) { 132 system_server_classpath_ = classpath; 133 } 134 SetUpdatableBcpPackagesFile(const std::string & file)135 void SetUpdatableBcpPackagesFile(const std::string& file) { updatable_bcp_packages_file_ = file; } SetZygoteKind(ZygoteKind zygote_kind)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. GetPotentialInstructionSets()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 UseDebugBinaries()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_ 170