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_ODREFRESH_H_ 18 #define ART_ODREFRESH_ODREFRESH_H_ 19 20 #include <ctime> 21 #include <functional> 22 #include <memory> 23 #include <optional> 24 #include <set> 25 #include <string> 26 #include <unordered_set> 27 #include <vector> 28 29 #include "android-base/result.h" 30 #include "base/os.h" 31 #include "com_android_apex.h" 32 #include "com_android_art.h" 33 #include "exec_utils.h" 34 #include "odr_artifacts.h" 35 #include "odr_config.h" 36 #include "odr_metrics.h" 37 #include "odrefresh/odrefresh.h" 38 39 namespace art { 40 namespace odrefresh { 41 42 class OnDeviceRefresh; 43 44 struct BootImages { 45 static constexpr int kMaxCount = 2; 46 47 bool primary_boot_image : 1; 48 bool boot_image_mainline_extension : 1; 49 50 int Count() const; 51 52 OdrMetrics::BcpCompilationType GetTypeForMetrics() const; 53 }; 54 55 struct CompilationOptions { 56 // If not empty, generate the boot images for ISAs in the list. 57 std::vector<std::pair<InstructionSet, BootImages>> boot_images_to_generate_for_isas; 58 59 // If not empty, compile the system server jars in the list. 60 std::set<std::string> system_server_jars_to_compile; 61 62 static CompilationOptions CompileAll(const OnDeviceRefresh& odr); 63 64 int CompilationUnitCount() const; 65 }; 66 67 struct CompilationResult { 68 OdrMetrics::Status status = OdrMetrics::Status::kOK; 69 std::string error_msg; 70 int64_t elapsed_time_ms = 0; 71 std::optional<ExecResult> dex2oat_result; 72 OkCompilationResult73 static CompilationResult Ok() { return {}; } 74 Dex2oatOkCompilationResult75 static CompilationResult Dex2oatOk(int64_t elapsed_time_ms, const ExecResult& dex2oat_result) { 76 return {.elapsed_time_ms = elapsed_time_ms, .dex2oat_result = dex2oat_result}; 77 } 78 ErrorCompilationResult79 static CompilationResult Error(OdrMetrics::Status status, const std::string& error_msg) { 80 return {.status = status, .error_msg = error_msg}; 81 } 82 Dex2oatErrorCompilationResult83 static CompilationResult Dex2oatError(const std::string& error_msg, 84 int64_t elapsed_time_ms, 85 const ExecResult& dex2oat_result) { 86 return {.status = OdrMetrics::Status::kDex2OatError, 87 .error_msg = error_msg, 88 .elapsed_time_ms = elapsed_time_ms, 89 .dex2oat_result = dex2oat_result}; 90 } 91 IsOkCompilationResult92 bool IsOk() { return status == OdrMetrics::Status::kOK; } 93 MergeCompilationResult94 void Merge(const CompilationResult& other) { 95 // Accumulate the compilation time. 96 elapsed_time_ms += other.elapsed_time_ms; 97 98 // Only keep the first failure. 99 if (status == OdrMetrics::Status::kOK) { 100 status = other.status; 101 error_msg = other.error_msg; 102 dex2oat_result = other.dex2oat_result; 103 } 104 } 105 106 private: 107 CompilationResult() = default; 108 }; 109 110 class PreconditionCheckResult { 111 public: NoneOk(OdrMetrics::Trigger trigger)112 static PreconditionCheckResult NoneOk(OdrMetrics::Trigger trigger) { 113 return PreconditionCheckResult(trigger, 114 /*primary_boot_image_ok=*/false, 115 /*boot_image_mainline_extension_ok=*/false, 116 /*system_server_ok=*/false); 117 } BootImageMainlineExtensionNotOk(OdrMetrics::Trigger trigger)118 static PreconditionCheckResult BootImageMainlineExtensionNotOk(OdrMetrics::Trigger trigger) { 119 return PreconditionCheckResult(trigger, 120 /*primary_boot_image_ok=*/true, 121 /*boot_image_mainline_extension_ok=*/false, 122 /*system_server_ok=*/false); 123 } SystemServerNotOk(OdrMetrics::Trigger trigger)124 static PreconditionCheckResult SystemServerNotOk(OdrMetrics::Trigger trigger) { 125 return PreconditionCheckResult(trigger, 126 /*primary_boot_image_ok=*/true, 127 /*boot_image_mainline_extension_ok=*/true, 128 /*system_server_ok=*/false); 129 } AllOk()130 static PreconditionCheckResult AllOk() { 131 return PreconditionCheckResult(/*trigger=*/std::nullopt, 132 /*primary_boot_image_ok=*/true, 133 /*boot_image_mainline_extension_ok=*/true, 134 /*system_server_ok=*/true); 135 } IsAllOk()136 bool IsAllOk() const { return !trigger_.has_value(); } GetTrigger()137 OdrMetrics::Trigger GetTrigger() const { return trigger_.value(); } IsPrimaryBootImageOk()138 bool IsPrimaryBootImageOk() const { return primary_boot_image_ok_; } IsBootImageMainlineExtensionOk()139 bool IsBootImageMainlineExtensionOk() const { return boot_image_mainline_extension_ok_; } IsSystemServerOk()140 bool IsSystemServerOk() const { return system_server_ok_; } 141 142 private: 143 // Use static factory methods instead. PreconditionCheckResult(std::optional<OdrMetrics::Trigger> trigger,bool primary_boot_image_ok,bool boot_image_mainline_extension_ok,bool system_server_ok)144 PreconditionCheckResult(std::optional<OdrMetrics::Trigger> trigger, 145 bool primary_boot_image_ok, 146 bool boot_image_mainline_extension_ok, 147 bool system_server_ok) 148 : trigger_(trigger), 149 primary_boot_image_ok_(primary_boot_image_ok), 150 boot_image_mainline_extension_ok_(boot_image_mainline_extension_ok), 151 system_server_ok_(system_server_ok) {} 152 153 // Indicates why the precondition is not okay, or `std::nullopt` if it's okay. 154 std::optional<OdrMetrics::Trigger> trigger_; 155 bool primary_boot_image_ok_; 156 bool boot_image_mainline_extension_ok_; 157 bool system_server_ok_; 158 }; 159 160 class OnDeviceRefresh final { 161 public: 162 explicit OnDeviceRefresh(const OdrConfig& config); 163 164 // Constructor with injections. For testing and internal use only. 165 OnDeviceRefresh(const OdrConfig& config, 166 const std::string& cache_info_filename, 167 std::unique_ptr<ExecUtils> exec_utils); 168 169 // Returns the exit code and specifies what should be compiled in `compilation_options`. 170 WARN_UNUSED ExitCode 171 CheckArtifactsAreUpToDate(OdrMetrics& metrics, 172 /*out*/ CompilationOptions* compilation_options) const; 173 174 WARN_UNUSED ExitCode Compile(OdrMetrics& metrics, 175 const CompilationOptions& compilation_options) const; 176 177 WARN_UNUSED bool RemoveArtifactsDirectory() const; 178 179 // Returns a set of all system server jars. AllSystemServerJars()180 std::set<std::string> AllSystemServerJars() const { 181 return {all_systemserver_jars_.begin(), all_systemserver_jars_.end()}; 182 } 183 Config()184 const OdrConfig& Config() const { return config_; } 185 186 private: 187 time_t GetExecutionTimeUsed() const; 188 189 time_t GetExecutionTimeRemaining() const; 190 191 time_t GetSubprocessTimeout() const; 192 193 // Gets the `ApexInfo` for active APEXes. 194 std::optional<std::vector<com::android::apex::ApexInfo>> GetApexInfoList() const; 195 196 // Reads the ART APEX cache information (if any) found in the output artifact directory. 197 android::base::Result<com::android::art::CacheInfo> ReadCacheInfo() const; 198 199 // Writes ART APEX cache information to `kOnDeviceRefreshOdrefreshArtifactDirectory`. 200 android::base::Result<void> WriteCacheInfo() const; 201 202 std::vector<com::android::art::Component> GenerateBootClasspathComponents() const; 203 204 std::vector<com::android::art::Component> GenerateDex2oatBootClasspathComponents() const; 205 206 std::vector<com::android::art::SystemServerComponent> GenerateSystemServerComponents() const; 207 208 // Returns the list of BCP jars in the ART module. 209 std::vector<std::string> GetArtBcpJars() const; 210 211 // Returns the list of BCP jars for the boot image framework extension. 212 std::vector<std::string> GetFrameworkBcpJars() const; 213 214 // Returns the list of BCP jars for the boot image mainline extension. 215 std::vector<std::string> GetMainlineBcpJars() const; 216 217 // Returns the symbolic primary boot image location (without ISA). If `minimal` is true, returns 218 // the symbolic location of the minimal boot image. 219 std::string GetPrimaryBootImage(bool on_system, bool minimal) const; 220 221 // Returns the real primary boot image location (with ISA). If `minimal` is true, returns the 222 // real location of the minimal boot image. 223 std::string GetPrimaryBootImagePath(bool on_system, bool minimal, InstructionSet isa) const; 224 225 // Returns the symbolic boot image framework extension location (without ISA). Note that this only 226 // applies to boot images on /system. 227 std::string GetSystemBootImageFrameworkExtension() const; 228 229 // Returns the real boot image framework extension location (with ISA). Note that this only 230 // applies to boot images on /system. 231 std::string GetSystemBootImageFrameworkExtensionPath(InstructionSet isa) const; 232 233 // Returns the symbolic boot image mainline extension location (without ISA). 234 std::string GetBootImageMainlineExtension(bool on_system) const; 235 236 // Returns the real boot image mainline extension location (with ISA). 237 std::string GetBootImageMainlineExtensionPath(bool on_system, InstructionSet isa) const; 238 239 // Returns the best combination of symbolic boot image locations (without ISA) based on file 240 // existence. 241 std::vector<std::string> GetBestBootImages(InstructionSet isa, 242 bool include_mainline_extension) const; 243 244 std::string GetSystemServerImagePath(bool on_system, const std::string& jar_path) const; 245 246 // Removes files that are not in the list. 247 android::base::Result<void> CleanupArtifactDirectory( 248 OdrMetrics& metrics, const std::vector<std::string>& artifacts_to_keep) const; 249 250 // Loads artifacts to memory and writes them back. This is a workaround for old versions of 251 // odsign, which encounters "file exists" error when it adds existing artifacts to fs-verity. This 252 // function essentially removes existing artifacts from fs-verity to avoid the error. 253 android::base::Result<void> RefreshExistingArtifacts() const; 254 255 // Returns whether the primary boot image is present. 256 // If `on_system` is true, checks both the primary boot image and the framework extension on 257 // /system. 258 // If `minimal` is true, checks the minimal boot image. 259 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 260 WARN_UNUSED bool PrimaryBootImageExist( 261 bool on_system, 262 bool minimal, 263 InstructionSet isa, 264 /*out*/ std::string* error_msg, 265 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 266 267 // Returns whether the boot image mainline extension exists. 268 WARN_UNUSED bool BootImageMainlineExtensionExist( 269 bool on_system, 270 InstructionSet isa, 271 /*out*/ std::string* error_msg, 272 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 273 274 // Checks whether all system_server artifacts are present. The artifacts are checked in their 275 // order of compilation. Returns true if all are present, false otherwise. 276 // Adds the paths to the jars that are missing artifacts in `jars_with_missing_artifacts`. 277 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 278 bool SystemServerArtifactsExist( 279 bool on_system, 280 /*out*/ std::string* error_msg, 281 /*out*/ std::set<std::string>* jars_missing_artifacts, 282 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 283 284 // Returns true if all of the system properties listed in `kSystemProperties` are set to the 285 // default values. This function is usually called when cache-info.xml does not exist (i.e., 286 // compilation has not been done before). 287 WARN_UNUSED bool CheckSystemPropertiesAreDefault() const; 288 289 // Returns true if none of the system properties listed in `kSystemProperties` has changed since 290 // the last compilation. This function is usually called when cache-info.xml exists. 291 WARN_UNUSED bool CheckSystemPropertiesHaveNotChanged( 292 const com::android::art::CacheInfo& cache_info) const; 293 294 // Returns true if the system image is built with the right userfaultfd GC flag. 295 WARN_UNUSED bool CheckBuildUserfaultFdGc() const; 296 297 // Returns whether the precondition for using artifacts on /system is met. Note that this function 298 // does not check the artifacts. 299 WARN_UNUSED PreconditionCheckResult 300 CheckPreconditionForSystem(const std::vector<com::android::apex::ApexInfo>& apex_info_list) const; 301 302 // Returns whether the precondition for using artifacts on /data is met. Note that this function 303 // does not check the artifacts. 304 WARN_UNUSED PreconditionCheckResult 305 CheckPreconditionForData(const std::vector<com::android::apex::ApexInfo>& apex_info_list) const; 306 307 // Checks whether all boot classpath artifacts are up to date. Returns the boot images that need 308 // to be (re-)generated. If `checked_artifacts` is present, adds checked artifacts to 309 // `checked_artifacts`. 310 WARN_UNUSED BootImages 311 CheckBootClasspathArtifactsAreUpToDate(OdrMetrics& metrics, 312 InstructionSet isa, 313 const PreconditionCheckResult& system_result, 314 const PreconditionCheckResult& data_result, 315 /*out*/ std::vector<std::string>* checked_artifacts) const; 316 317 // Checks whether all system_server artifacts are up to date. The artifacts are checked in their 318 // order of compilation. Returns the paths to the jars that need to be compiled. 319 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 320 WARN_UNUSED std::set<std::string> CheckSystemServerArtifactsAreUpToDate( 321 OdrMetrics& metrics, 322 const PreconditionCheckResult& system_result, 323 const PreconditionCheckResult& data_result, 324 /*out*/ std::vector<std::string>* checked_artifacts) const; 325 326 WARN_UNUSED CompilationResult 327 RunDex2oat(const std::string& staging_dir, 328 const std::string& debug_message, 329 InstructionSet isa, 330 const std::vector<std::string>& dex_files, 331 const std::vector<std::string>& boot_classpath, 332 const std::vector<std::string>& input_boot_images, 333 const OdrArtifacts& artifacts, 334 const std::vector<std::string>& extra_args, 335 /*inout*/ std::vector<std::unique_ptr<File>>& readonly_files_raii) const; 336 337 WARN_UNUSED CompilationResult 338 RunDex2oatForBootClasspath(const std::string& staging_dir, 339 const std::string& debug_name, 340 InstructionSet isa, 341 const std::vector<std::string>& dex_files, 342 const std::vector<std::string>& boot_classpath, 343 const std::vector<std::string>& input_boot_images, 344 const std::string& output_path) const; 345 346 WARN_UNUSED CompilationResult 347 CompileBootClasspath(const std::string& staging_dir, 348 InstructionSet isa, 349 BootImages boot_images, 350 const std::function<void()>& on_dex2oat_success) const; 351 352 WARN_UNUSED CompilationResult 353 RunDex2oatForSystemServer(const std::string& staging_dir, 354 const std::string& dex_file, 355 const std::vector<std::string>& classloader_context) const; 356 357 WARN_UNUSED CompilationResult 358 CompileSystemServer(const std::string& staging_dir, 359 const std::set<std::string>& system_server_jars_to_compile, 360 const std::function<void()>& on_dex2oat_success) const; 361 362 // Configuration to use. 363 const OdrConfig& config_; 364 365 // Path to cache information file that is used to speed up artifact checking. 366 const std::string cache_info_filename_; 367 368 // The raw list from DEX2OATBOOTCLASSPATH. This is the list of jars that should be compiled into 369 // the primary boot image. 370 std::vector<std::string> dex2oat_boot_classpath_jars_; 371 372 // The raw list from BOOTCLASSPATH. This is the list of all BCP jars. 373 std::vector<std::string> boot_classpath_jars_; 374 375 // Set of system_server components in SYSTEMSERVERCLASSPATH that should be compiled. 376 std::unordered_set<std::string> systemserver_classpath_jars_; 377 378 // List of all system_server components, including those in SYSTEMSERVERCLASSPATH and those in 379 // STANDALONE_SYSTEMSERVER_JARS (jars that system_server loads dynamically using separate 380 // classloaders). 381 std::vector<std::string> all_systemserver_jars_; 382 383 const time_t start_time_; 384 385 std::unique_ptr<ExecUtils> exec_utils_; 386 387 DISALLOW_COPY_AND_ASSIGN(OnDeviceRefresh); 388 }; 389 390 } // namespace odrefresh 391 } // namespace art 392 393 #endif // ART_ODREFRESH_ODREFRESH_H_ 394