Mark ab/6881855 as merged
Bug: 172690556
Change-Id: I5a2f345d46f744263cfd29385e63f03aaf737ebf
diff --git a/Android.bp b/Android.bp
index 8e9ec17..ed704ff 100644
--- a/Android.bp
+++ b/Android.bp
@@ -82,6 +82,28 @@
},
}
+// libcow_operation_convert (type: library)
+// ========================================================
+cc_library {
+ name: "libcow_operation_convert",
+ host_supported: true,
+ recovery_available: true,
+ defaults: [
+ "ue_defaults",
+ "update_metadata-protos_exports",
+ ],
+ srcs: [
+ "common/cow_operation_convert.cc",
+ ],
+ static_libs: [
+ "libsnapshot_cow",
+ "update_metadata-protos",
+ "libpayload_extent_ranges",
+ "libbrotli",
+ "libz",
+ ],
+}
+
// update_metadata-protos (type: static_library)
// ========================================================
// Protobufs.
@@ -124,6 +146,11 @@
"libfec_rs",
"libpuffpatch",
"libverity_tree",
+ "libsnapshot_cow",
+ "libbrotli",
+ "libz",
+ "libpayload_extent_ranges",
+ "libcow_operation_convert",
],
shared_libs: [
"libbase",
@@ -143,6 +170,7 @@
recovery_available: true,
srcs: [
+ "aosp/platform_constants_android.cc",
"common/action_processor.cc",
"common/boot_control_stub.cc",
"common/clock.cc",
@@ -156,17 +184,16 @@
"common/http_fetcher.cc",
"common/hwid_override.cc",
"common/multi_range_http_fetcher.cc",
- "common/platform_constants_android.cc",
"common/prefs.cc",
"common/proxy_resolver.cc",
"common/subprocess.cc",
"common/terminator.cc",
"common/utils.cc",
+ "download_action.cc",
"payload_consumer/bzip_extent_writer.cc",
"payload_consumer/cached_file_descriptor.cc",
"payload_consumer/certificate_parser_android.cc",
"payload_consumer/delta_performer.cc",
- "payload_consumer/download_action.cc",
"payload_consumer/extent_reader.cc",
"payload_consumer/extent_writer.cc",
"payload_consumer/file_descriptor.cc",
@@ -179,6 +206,9 @@
"payload_consumer/payload_metadata.cc",
"payload_consumer/payload_verifier.cc",
"payload_consumer/partition_writer.cc",
+ "payload_consumer/partition_writer_factory_android.cc",
+ "payload_consumer/vabc_partition_writer.cc",
+ "payload_consumer/snapshot_extent_writer.cc",
"payload_consumer/postinstall_runner_action.cc",
"payload_consumer/verity_writer_android.cc",
"payload_consumer/xz_extent_writer.cc",
@@ -201,6 +231,7 @@
"libpayload_consumer",
"libsnapshot",
"libsnapshot_cow",
+ "libz",
"update_metadata-protos",
],
shared_libs: [
@@ -242,10 +273,10 @@
recovery_available: true,
srcs: [
- "boot_control_android.cc",
- "cleanup_previous_update_action.cc",
- "dynamic_partition_control_android.cc",
- "dynamic_partition_utils.cc",
+ "aosp/boot_control_android.cc",
+ "aosp/cleanup_previous_update_action.cc",
+ "aosp/dynamic_partition_control_android.cc",
+ "aosp/dynamic_partition_utils.cc",
],
}
@@ -301,17 +332,17 @@
srcs: [
":libupdate_engine_aidl",
- "binder_service_android.cc",
- "binder_service_stable_android.cc",
+ "aosp/binder_service_android.cc",
+ "aosp/binder_service_stable_android.cc",
+ "aosp/daemon_android.cc",
+ "aosp/daemon_state_android.cc",
+ "aosp/hardware_android.cc",
+ "aosp/logging_android.cc",
+ "aosp/network_selector_android.cc",
+ "aosp/update_attempter_android.cc",
"certificate_checker.cc",
- "daemon_android.cc",
- "daemon_state_android.cc",
- "hardware_android.cc",
"libcurl_http_fetcher.cc",
- "logging_android.cc",
"metrics_utils.cc",
- "network_selector_android.cc",
- "update_attempter_android.cc",
"update_boot_flags_action.cc",
"update_status_utils.cc",
],
@@ -333,7 +364,7 @@
"otacerts",
],
- srcs: ["main.cc", "metrics_reporter_android.cc"],
+ srcs: ["main.cc", "aosp/metrics_reporter_android.cc"],
init_rc: ["update_engine.rc"],
}
@@ -358,13 +389,13 @@
include_dirs: ["external/cros/system_api/dbus"],
srcs: [
- "hardware_android.cc",
- "logging_android.cc",
- "metrics_reporter_stub.cc",
+ "aosp/hardware_android.cc",
+ "aosp/logging_android.cc",
+ "aosp/sideload_main.cc",
+ "aosp/update_attempter_android.cc",
+ "common/metrics_reporter_stub.cc",
+ "common/network_selector_stub.cc",
"metrics_utils.cc",
- "network_selector_stub.cc",
- "sideload_main.cc",
- "update_attempter_android.cc",
"update_boot_flags_action.cc",
"update_status_utils.cc",
],
@@ -434,8 +465,8 @@
srcs: [
":libupdate_engine_aidl",
+ "aosp/update_engine_client_android.cc",
"common/error_code_utils.cc",
- "update_engine_client_android.cc",
"update_status_utils.cc",
],
}
@@ -478,6 +509,7 @@
"ue_defaults",
],
host_supported: true,
+ recovery_available: true,
srcs: [
"payload_generator/extent_ranges.cc",
],
@@ -501,6 +533,7 @@
"payload_generator/block_mapping.cc",
"payload_generator/boot_img_filesystem.cc",
"payload_generator/bzip.cc",
+ "payload_generator/cow_size_estimator.cc",
"payload_generator/deflate_utils.cc",
"payload_generator/delta_diff_generator.cc",
"payload_generator/delta_diff_utils.cc",
@@ -667,16 +700,20 @@
test_suites: ["device-tests"],
srcs: [
+ "aosp/dynamic_partition_control_android_unittest.cc",
+ "aosp/update_attempter_android_unittest.cc",
"certificate_checker_unittest.cc",
"common/action_pipe_unittest.cc",
"common/action_processor_unittest.cc",
"common/action_unittest.cc",
+ "common/cow_operation_convert_unittest.cc",
"common/cpu_limiter_unittest.cc",
"common/fake_prefs.cc",
"common/file_fetcher_unittest.cc",
"common/hash_calculator_unittest.cc",
"common/http_fetcher_unittest.cc",
"common/hwid_override_unittest.cc",
+ "common/metrics_reporter_stub.cc",
"common/mock_http_fetcher.cc",
"common/prefs_unittest.cc",
"common/proxy_resolver_unittest.cc",
@@ -684,7 +721,7 @@
"common/terminator_unittest.cc",
"common/test_utils.cc",
"common/utils_unittest.cc",
- "dynamic_partition_control_android_unittest.cc",
+ "download_action_android_unittest.cc",
"libcurl_http_fetcher_unittest.cc",
"payload_consumer/bzip_extent_writer_unittest.cc",
"payload_consumer/cached_file_descriptor_unittest.cc",
@@ -692,9 +729,9 @@
"payload_consumer/delta_performer_integration_test.cc",
"payload_consumer/delta_performer_unittest.cc",
"payload_consumer/partition_writer_unittest.cc",
- "payload_consumer/download_action_android_unittest.cc",
"payload_consumer/extent_reader_unittest.cc",
"payload_consumer/extent_writer_unittest.cc",
+ "payload_consumer/snapshot_extent_writer_unittest.cc",
"payload_consumer/fake_file_descriptor.cc",
"payload_consumer/file_descriptor_utils_unittest.cc",
"payload_consumer/file_writer_unittest.cc",
@@ -724,9 +761,7 @@
"payload_generator/squashfs_filesystem_unittest.cc",
"payload_generator/zip_unittest.cc",
"testrunner.cc",
- "update_attempter_android_unittest.cc",
"update_status_utils_unittest.cc",
- "metrics_reporter_stub.cc",
],
}
@@ -754,6 +789,13 @@
// update_engine header library
cc_library_headers {
name: "libupdate_engine_headers",
+
+ // This header library is available to core and product modules.
+ // Right now, vendor_available is the only way to specify this.
+ // vendor modules should NOT use this library.
+ // TODO(b/150902910): change this to product_available.
+ vendor_available: true,
+
export_include_dirs: ["."],
apex_available: [
"com.android.gki.*",
diff --git a/BUILD.gn b/BUILD.gn
index b7de9fc..6e282f5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -44,6 +44,7 @@
":test_subprocess",
":update_engine-test_images",
":update_engine-testkeys",
+ ":update_engine-testkeys-ec",
":update_engine_test_libs",
":update_engine_unittests",
]
@@ -60,6 +61,7 @@
pkg_config("target_defaults") {
cflags_cc = [
"-fno-strict-aliasing",
+ "-std=gnu++17",
"-Wnon-virtual-dtor",
]
cflags = [
@@ -75,6 +77,7 @@
"__CHROMEOS__",
"_FILE_OFFSET_BITS=64",
"_POSIX_C_SOURCE=199309L",
+ "USE_CFM=${use.cfm}",
"USE_DBUS=${use.dbus}",
"USE_FEC=0",
"USE_HWID_OVERRIDE=${use.hwid_override}",
@@ -92,7 +95,7 @@
# NOSORT
pkg_deps = [
"libbrillo",
- "libchrome-${libbase_ver}",
+ "libchrome",
# system_api depends on protobuf (or protobuf-lite). It must appear
# before protobuf here or the linker flags won't be in the right
@@ -140,17 +143,17 @@
"common/http_fetcher.cc",
"common/hwid_override.cc",
"common/multi_range_http_fetcher.cc",
- "common/platform_constants_chromeos.cc",
"common/prefs.cc",
"common/proxy_resolver.cc",
"common/subprocess.cc",
"common/terminator.cc",
"common/utils.cc",
+ "cros/platform_constants_chromeos.cc",
+ "download_action.cc",
"payload_consumer/bzip_extent_writer.cc",
"payload_consumer/cached_file_descriptor.cc",
"payload_consumer/certificate_parser_stub.cc",
"payload_consumer/delta_performer.cc",
- "payload_consumer/download_action.cc",
"payload_consumer/extent_reader.cc",
"payload_consumer/extent_writer.cc",
"payload_consumer/file_descriptor.cc",
@@ -160,6 +163,8 @@
"payload_consumer/install_plan.cc",
"payload_consumer/mount_history.cc",
"payload_consumer/partition_update_generator_stub.cc",
+ "payload_consumer/partition_writer_factory_chromeos.cc",
+ "payload_consumer/partition_writer.cc",
"payload_consumer/payload_constants.cc",
"payload_consumer/payload_metadata.cc",
"payload_consumer/payload_verifier.cc",
@@ -192,31 +197,32 @@
# with Omaha and expose a DBus daemon.
static_library("libupdate_engine") {
sources = [
- "boot_control_chromeos.cc",
"certificate_checker.cc",
- "common_service.cc",
- "connection_manager.cc",
- "connection_utils.cc",
- "daemon_chromeos.cc",
- "dbus_connection.cc",
- "dbus_service.cc",
- "hardware_chromeos.cc",
- "image_properties_chromeos.cc",
+ "common/connection_utils.cc",
+ "cros/boot_control_chromeos.cc",
+ "cros/common_service.cc",
+ "cros/connection_manager.cc",
+ "cros/daemon_chromeos.cc",
+ "cros/dbus_connection.cc",
+ "cros/dbus_service.cc",
+ "cros/hardware_chromeos.cc",
+ "cros/image_properties_chromeos.cc",
+ "cros/logging.cc",
+ "cros/metrics_reporter_omaha.cc",
+ "cros/omaha_request_action.cc",
+ "cros/omaha_request_builder_xml.cc",
+ "cros/omaha_request_params.cc",
+ "cros/omaha_response_handler_action.cc",
+ "cros/omaha_utils.cc",
+ "cros/p2p_manager.cc",
+ "cros/payload_state.cc",
+ "cros/power_manager_chromeos.cc",
+ "cros/real_system_state.cc",
+ "cros/requisition_util.cc",
+ "cros/shill_proxy.cc",
+ "cros/update_attempter.cc",
"libcurl_http_fetcher.cc",
- "logging.cc",
- "metrics_reporter_omaha.cc",
"metrics_utils.cc",
- "omaha_request_action.cc",
- "omaha_request_builder_xml.cc",
- "omaha_request_params.cc",
- "omaha_response_handler_action.cc",
- "omaha_utils.cc",
- "p2p_manager.cc",
- "payload_state.cc",
- "power_manager_chromeos.cc",
- "real_system_state.cc",
- "shill_proxy.cc",
- "update_attempter.cc",
"update_boot_flags_action.cc",
"update_manager/boxed_value.cc",
"update_manager/chromeos_policy.cc",
@@ -256,7 +262,7 @@
"expat",
"libcurl",
"libdebugd-client",
- "libmetrics-${libbase_ver}",
+ "libmetrics",
"libpower_manager-client",
"libsession_manager-client",
"libshill-client",
@@ -275,7 +281,7 @@
}
if (use.chrome_network_proxy) {
- sources += [ "chrome_browser_proxy_resolver.cc" ]
+ sources += [ "cros/chrome_browser_proxy_resolver.cc" ]
}
if (use.chrome_kiosk_app) {
@@ -284,8 +290,8 @@
if (use.dlc) {
sources += [
- "dlcservice_chromeos.cc",
- "excluder_chromeos.cc",
+ "cros/dlcservice_chromeos.cc",
+ "cros/excluder_chromeos.cc",
]
} else {
sources += [
@@ -320,8 +326,8 @@
executable("update_engine_client") {
sources = [
"common/error_code_utils.cc",
- "omaha_utils.cc",
- "update_engine_client.cc",
+ "cros/omaha_utils.cc",
+ "cros/update_engine_client.cc",
]
configs += [ ":target_defaults" ]
deps = [ ":libupdate_engine_client" ]
@@ -338,6 +344,7 @@
"payload_generator/block_mapping.cc",
"payload_generator/boot_img_filesystem_stub.cc",
"payload_generator/bzip.cc",
+ "payload_generator/cow_size_estimator_stub.cc",
"payload_generator/deflate_utils.cc",
"payload_generator/delta_diff_generator.cc",
"payload_generator/delta_diff_utils.cc",
@@ -390,8 +397,8 @@
"common/fake_prefs.cc",
"common/mock_http_fetcher.cc",
"common/test_utils.cc",
- "fake_shill_proxy.cc",
- "fake_system_state.cc",
+ "cros/fake_shill_proxy.cc",
+ "cros/fake_system_state.cc",
"payload_consumer/fake_file_descriptor.cc",
"payload_generator/fake_filesystem.cc",
"update_manager/umtest_utils.cc",
@@ -417,9 +424,17 @@
sources = [
"unittest_key.pem",
"unittest_key2.pem",
+ "unittest_key_RSA4096.pem",
]
}
+ genopenssl_key("update_engine-testkeys-ec") {
+ openssl_pem_in_dir = "."
+ openssl_pem_out_dir = "include/update_engine"
+ openssl_pem_algorithm = "ec"
+ sources = [ "unittest_key_EC.pem" ]
+ }
+
# Unpacks sample images used for testing.
tar_bunzip2("update_engine-test_images") {
image_out_dir = "."
@@ -456,7 +471,6 @@
# Main unittest file.
executable("update_engine_unittests") {
sources = [
- "boot_control_chromeos_unittest.cc",
"certificate_checker_unittest.cc",
"common/action_pipe_unittest.cc",
"common/action_processor_unittest.cc",
@@ -470,24 +484,28 @@
"common/subprocess_unittest.cc",
"common/terminator_unittest.cc",
"common/utils_unittest.cc",
- "common_service_unittest.cc",
- "connection_manager_unittest.cc",
- "hardware_chromeos_unittest.cc",
- "image_properties_chromeos_unittest.cc",
+ "cros/boot_control_chromeos_unittest.cc",
+ "cros/common_service_unittest.cc",
+ "cros/connection_manager_unittest.cc",
+ "cros/hardware_chromeos_unittest.cc",
+ "cros/image_properties_chromeos_unittest.cc",
+ "cros/metrics_reporter_omaha_unittest.cc",
+ "cros/omaha_request_action_unittest.cc",
+ "cros/omaha_request_builder_xml_unittest.cc",
+ "cros/omaha_request_params_unittest.cc",
+ "cros/omaha_response_handler_action_unittest.cc",
+ "cros/omaha_utils_unittest.cc",
+ "cros/p2p_manager_unittest.cc",
+ "cros/payload_state_unittest.cc",
+ "cros/requisition_util_unittest.cc",
+ "cros/update_attempter_unittest.cc",
+ "download_action_unittest.cc",
"libcurl_http_fetcher_unittest.cc",
- "metrics_reporter_omaha_unittest.cc",
"metrics_utils_unittest.cc",
- "omaha_request_action_unittest.cc",
- "omaha_request_builder_xml_unittest.cc",
- "omaha_request_params_unittest.cc",
- "omaha_response_handler_action_unittest.cc",
- "omaha_utils_unittest.cc",
- "p2p_manager_unittest.cc",
"payload_consumer/bzip_extent_writer_unittest.cc",
"payload_consumer/cached_file_descriptor_unittest.cc",
"payload_consumer/delta_performer_integration_test.cc",
"payload_consumer/delta_performer_unittest.cc",
- "payload_consumer/download_action_unittest.cc",
"payload_consumer/extent_reader_unittest.cc",
"payload_consumer/extent_writer_unittest.cc",
"payload_consumer/file_descriptor_utils_unittest.cc",
@@ -512,12 +530,11 @@
"payload_generator/payload_signer_unittest.cc",
"payload_generator/squashfs_filesystem_unittest.cc",
"payload_generator/zip_unittest.cc",
- "payload_state_unittest.cc",
"testrunner.cc",
- "update_attempter_unittest.cc",
"update_boot_flags_action_unittest.cc",
"update_manager/boxed_value_unittest.cc",
"update_manager/chromeos_policy_unittest.cc",
+ "update_manager/enterprise_device_policy_impl_unittest.cc",
"update_manager/evaluation_context_unittest.cc",
"update_manager/generic_variables_unittest.cc",
"update_manager/prng_unittest.cc",
@@ -535,7 +552,7 @@
"update_status_utils_unittest.cc",
]
if (use.dlc) {
- sources += [ "excluder_chromeos_unittest.cc" ]
+ sources += [ "cros/excluder_chromeos_unittest.cc" ]
}
# //common-mk:test should be on the top.
@@ -546,7 +563,7 @@
]
pkg_deps = [
"libbrillo-test",
- "libchrome-test-${libbase_ver}",
+ "libchrome-test",
"libdebugd-client-test",
"libpower_manager-client-test",
"libsession_manager-client-test",
@@ -570,7 +587,7 @@
]
pkg_deps = [
"libbrillo-test",
- "libchrome-test-${libbase_ver}",
+ "libchrome-test",
]
deps = [
":libupdate_engine",
@@ -578,14 +595,14 @@
]
}
executable("update_engine_omaha_request_action_fuzzer") {
- sources = [ "omaha_request_action_fuzzer.cc" ]
+ sources = [ "cros/omaha_request_action_fuzzer.cc" ]
configs += [
"//common-mk/common_fuzzer",
":target_defaults",
]
pkg_deps = [
"libbrillo-test",
- "libchrome-test-${libbase_ver}",
+ "libchrome-test",
]
deps = [
":libupdate_engine",
diff --git a/binder_service_android.cc b/aosp/binder_service_android.cc
similarity index 98%
rename from binder_service_android.cc
rename to aosp/binder_service_android.cc
index 0c8bc2f..ed76c4a 100644
--- a/binder_service_android.cc
+++ b/aosp/binder_service_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/binder_service_android.h"
+#include "update_engine/aosp/binder_service_android.h"
#include <memory>
@@ -24,7 +24,7 @@
#include <brillo/errors/error.h>
#include <utils/String8.h>
-#include "update_engine/binder_service_android_common.h"
+#include "update_engine/aosp/binder_service_android_common.h"
using android::binder::Status;
using android::os::IUpdateEngineCallback;
diff --git a/binder_service_android.h b/aosp/binder_service_android.h
similarity index 92%
rename from binder_service_android.h
rename to aosp/binder_service_android.h
index 5f28225..f41fbdf 100644
--- a/binder_service_android.h
+++ b/aosp/binder_service_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
-#define UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
#include <stdint.h>
@@ -28,8 +28,8 @@
#include "android/os/BnUpdateEngine.h"
#include "android/os/IUpdateEngineCallback.h"
-#include "update_engine/service_delegate_android_interface.h"
-#include "update_engine/service_observer_interface.h"
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/common/service_observer_interface.h"
namespace chromeos_update_engine {
@@ -96,4 +96,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_H_
diff --git a/binder_service_android_common.h b/aosp/binder_service_android_common.h
similarity index 86%
rename from binder_service_android_common.h
rename to aosp/binder_service_android_common.h
index fc621d9..223b32e 100644
--- a/binder_service_android_common.h
+++ b/aosp/binder_service_android_common.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_BINDER_SERVICE_ANDROID_COMMON_H_
-#define UPDATE_ENGINE_BINDER_SERVICE_ANDROID_COMMON_H_
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
#include <string>
#include <vector>
@@ -42,4 +42,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_BINDER_SERVICE_ANDROID_COMMON_H_
+#endif // UPDATE_ENGINE_AOSP_BINDER_SERVICE_ANDROID_COMMON_H_
diff --git a/binder_service_stable_android.cc b/aosp/binder_service_stable_android.cc
similarity index 96%
rename from binder_service_stable_android.cc
rename to aosp/binder_service_stable_android.cc
index a12b349..17b35ee 100644
--- a/binder_service_stable_android.cc
+++ b/aosp/binder_service_stable_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/binder_service_stable_android.h"
+#include "update_engine/aosp/binder_service_stable_android.h"
#include <memory>
@@ -24,7 +24,7 @@
#include <brillo/errors/error.h>
#include <utils/String8.h>
-#include "update_engine/binder_service_android_common.h"
+#include "update_engine/aosp/binder_service_android_common.h"
using android::binder::Status;
using android::os::IUpdateEngineStableCallback;
diff --git a/binder_service_stable_android.h b/aosp/binder_service_stable_android.h
similarity index 89%
rename from binder_service_stable_android.h
rename to aosp/binder_service_stable_android.h
index 1667798..212afaa 100644
--- a/binder_service_stable_android.h
+++ b/aosp/binder_service_stable_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_BINDER_SERVICE_STABLE_ANDROID_H_
-#define UPDATE_ENGINE_BINDER_SERVICE_STABLE_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
#include <stdint.h>
@@ -28,8 +28,8 @@
#include "android/os/BnUpdateEngineStable.h"
#include "android/os/IUpdateEngineStableCallback.h"
-#include "update_engine/service_delegate_android_interface.h"
-#include "update_engine/service_observer_interface.h"
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/common/service_observer_interface.h"
namespace chromeos_update_engine {
@@ -82,4 +82,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_BINDER_SERVICE_STABLE_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_BINDER_SERVICE_STABLE_ANDROID_H_
diff --git a/boot_control_android.cc b/aosp/boot_control_android.cc
similarity index 97%
rename from boot_control_android.cc
rename to aosp/boot_control_android.cc
index dee5fa8..bda65be 100644
--- a/boot_control_android.cc
+++ b/aosp/boot_control_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/boot_control_android.h"
+#include "update_engine/aosp/boot_control_android.h"
#include <memory>
#include <utility>
@@ -25,8 +25,8 @@
#include <bootloader_message/bootloader_message.h>
#include <brillo/message_loops/message_loop.h>
+#include "update_engine/aosp/dynamic_partition_control_android.h"
#include "update_engine/common/utils.h"
-#include "update_engine/dynamic_partition_control_android.h"
using std::string;
diff --git a/boot_control_android.h b/aosp/boot_control_android.h
similarity index 91%
rename from boot_control_android.h
rename to aosp/boot_control_android.h
index 5009dbd..e288723 100644
--- a/boot_control_android.h
+++ b/aosp/boot_control_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_BOOT_CONTROL_ANDROID_H_
-#define UPDATE_ENGINE_BOOT_CONTROL_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
#include <map>
#include <memory>
@@ -24,9 +24,9 @@
#include <android/hardware/boot/1.0/IBootControl.h>
#include <liblp/builder.h>
+#include "update_engine/aosp/dynamic_partition_control_android.h"
#include "update_engine/common/boot_control.h"
#include "update_engine/common/dynamic_partition_control_interface.h"
-#include "update_engine/dynamic_partition_control_android.h"
namespace chromeos_update_engine {
@@ -70,4 +70,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_BOOT_CONTROL_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_BOOT_CONTROL_ANDROID_H_
diff --git a/cleanup_previous_update_action.cc b/aosp/cleanup_previous_update_action.cc
similarity index 99%
rename from cleanup_previous_update_action.cc
rename to aosp/cleanup_previous_update_action.cc
index 89ed6f8..16cb9fe 100644
--- a/cleanup_previous_update_action.cc
+++ b/aosp/cleanup_previous_update_action.cc
@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#include "update_engine/cleanup_previous_update_action.h"
+#include "update_engine/aosp/cleanup_previous_update_action.h"
#include <chrono> // NOLINT(build/c++11) -- for merge times
#include <functional>
diff --git a/cleanup_previous_update_action.h b/aosp/cleanup_previous_update_action.h
similarity index 94%
rename from cleanup_previous_update_action.h
rename to aosp/cleanup_previous_update_action.h
index fe65e60..b93c557 100644
--- a/cleanup_previous_update_action.h
+++ b/aosp/cleanup_previous_update_action.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
-#define UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
+#ifndef UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
+#define UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
#include <chrono> // NOLINT(build/c++11) -- for merge times
#include <memory>
@@ -100,4 +100,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
+#endif // UPDATE_ENGINE_AOSP_CLEANUP_PREVIOUS_UPDATE_ACTION_H_
diff --git a/daemon_android.cc b/aosp/daemon_android.cc
similarity index 95%
rename from daemon_android.cc
rename to aosp/daemon_android.cc
index 313d7dd..c102e3b 100644
--- a/daemon_android.cc
+++ b/aosp/daemon_android.cc
@@ -14,13 +14,13 @@
// limitations under the License.
//
-#include "update_engine/daemon_android.h"
+#include "update_engine/aosp/daemon_android.h"
#include <sysexits.h>
#include <binderwrapper/binder_wrapper.h>
-#include "update_engine/daemon_state_android.h"
+#include "update_engine/aosp/daemon_state_android.h"
using std::unique_ptr;
diff --git a/daemon_android.h b/aosp/daemon_android.h
similarity index 80%
rename from daemon_android.h
rename to aosp/daemon_android.h
index f0c028e..38a8689 100644
--- a/daemon_android.h
+++ b/aosp/daemon_android.h
@@ -14,18 +14,18 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DAEMON_ANDROID_H_
-#define UPDATE_ENGINE_DAEMON_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
#include <memory>
#include <brillo/binder_watcher.h>
-#include "update_engine/binder_service_android.h"
-#include "update_engine/binder_service_stable_android.h"
+#include "update_engine/aosp/binder_service_android.h"
+#include "update_engine/aosp/binder_service_stable_android.h"
+#include "update_engine/common/daemon_base.h"
+#include "update_engine/common/daemon_state_interface.h"
#include "update_engine/common/subprocess.h"
-#include "update_engine/daemon_base.h"
-#include "update_engine/daemon_state_interface.h"
namespace chromeos_update_engine {
@@ -55,4 +55,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DAEMON_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_DAEMON_ANDROID_H_
diff --git a/daemon_state_android.cc b/aosp/daemon_state_android.cc
similarity index 95%
rename from daemon_state_android.cc
rename to aosp/daemon_state_android.cc
index 3376e64..9bdd175 100644
--- a/daemon_state_android.cc
+++ b/aosp/daemon_state_android.cc
@@ -14,15 +14,15 @@
// limitations under the License.
//
-#include "update_engine/daemon_state_android.h"
+#include "update_engine/aosp/daemon_state_android.h"
#include <base/logging.h>
+#include "update_engine/aosp/update_attempter_android.h"
#include "update_engine/common/boot_control.h"
#include "update_engine/common/boot_control_stub.h"
#include "update_engine/common/hardware.h"
#include "update_engine/common/prefs.h"
-#include "update_engine/update_attempter_android.h"
namespace chromeos_update_engine {
diff --git a/daemon_state_android.h b/aosp/daemon_state_android.h
similarity index 84%
rename from daemon_state_android.h
rename to aosp/daemon_state_android.h
index 928a14e..dea3a23 100644
--- a/daemon_state_android.h
+++ b/aosp/daemon_state_android.h
@@ -14,20 +14,20 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DAEMON_STATE_ANDROID_H_
-#define UPDATE_ENGINE_DAEMON_STATE_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
#include <memory>
#include <set>
+#include "update_engine/aosp/service_delegate_android_interface.h"
+#include "update_engine/aosp/update_attempter_android.h"
#include "update_engine/certificate_checker.h"
#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/daemon_state_interface.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/daemon_state_interface.h"
-#include "update_engine/service_delegate_android_interface.h"
-#include "update_engine/service_observer_interface.h"
-#include "update_engine/update_attempter_android.h"
+#include "update_engine/common/service_observer_interface.h"
namespace chromeos_update_engine {
@@ -73,4 +73,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DAEMON_STATE_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_DAEMON_STATE_ANDROID_H_
diff --git a/dynamic_partition_control_android.cc b/aosp/dynamic_partition_control_android.cc
similarity index 94%
rename from dynamic_partition_control_android.cc
rename to aosp/dynamic_partition_control_android.cc
index c9888ab..3ced3e0 100644
--- a/dynamic_partition_control_android.cc
+++ b/aosp/dynamic_partition_control_android.cc
@@ -14,9 +14,10 @@
// limitations under the License.
//
-#include "update_engine/dynamic_partition_control_android.h"
+#include "update_engine/aosp/dynamic_partition_control_android.h"
#include <chrono> // NOLINT(build/c++11) - using libsnapshot / liblp API
+#include <cstdint>
#include <map>
#include <memory>
#include <set>
@@ -36,13 +37,15 @@
#include <fs_mgr_overlayfs.h>
#include <libavb/libavb.h>
#include <libdm/dm.h>
+#include <liblp/liblp.h>
+#include <libsnapshot/cow_writer.h>
#include <libsnapshot/snapshot.h>
#include <libsnapshot/snapshot_stub.h>
-#include "update_engine/cleanup_previous_update_action.h"
+#include "update_engine/aosp/cleanup_previous_update_action.h"
+#include "update_engine/aosp/dynamic_partition_utils.h"
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/utils.h"
-#include "update_engine/dynamic_partition_utils.h"
#include "update_engine/payload_consumer/delta_performer.h"
using android::base::GetBoolProperty;
@@ -86,12 +89,6 @@
// needs to be mapped, this timeout is longer than |kMapTimeout|.
constexpr std::chrono::milliseconds kMapSnapshotTimeout{5000};
-#ifdef __ANDROID_RECOVERY__
-constexpr bool kIsRecovery = true;
-#else
-constexpr bool kIsRecovery = false;
-#endif
-
DynamicPartitionControlAndroid::~DynamicPartitionControlAndroid() {
Cleanup();
}
@@ -276,9 +273,9 @@
return true;
}
-void DynamicPartitionControlAndroid::UnmapAllPartitions() {
+bool DynamicPartitionControlAndroid::UnmapAllPartitions() {
if (mapped_devices_.empty()) {
- return;
+ return false;
}
// UnmapPartitionOnDeviceMapper removes objects from mapped_devices_, hence
// a copy is needed for the loop.
@@ -287,6 +284,7 @@
for (const auto& partition_name : mapped) {
ignore_result(UnmapPartitionOnDeviceMapper(partition_name));
}
+ return true;
}
void DynamicPartitionControlAndroid::Cleanup() {
@@ -1085,7 +1083,7 @@
}
bool DynamicPartitionControlAndroid::IsRecovery() {
- return kIsRecovery;
+ return constants::kIsRecovery;
}
static bool IsIncrementalUpdate(const DeltaArchiveManifest& manifest) {
@@ -1236,4 +1234,64 @@
return metadata_device_ != nullptr;
}
+std::unique_ptr<android::snapshot::ISnapshotWriter>
+DynamicPartitionControlAndroid::OpenCowWriter(
+ const std::string& partition_name,
+ const std::optional<std::string>& source_path,
+ bool is_append) {
+ auto suffix = SlotSuffixForSlotNumber(target_slot_);
+
+ auto super_device = GetSuperDevice();
+ if (!super_device.has_value()) {
+ return nullptr;
+ }
+ CreateLogicalPartitionParams params = {
+ .block_device = super_device->value(),
+ .metadata_slot = target_slot_,
+ .partition_name = partition_name + suffix,
+ .force_writable = true,
+ .timeout_ms = kMapSnapshotTimeout};
+ // TODO(zhangkelvin) Open an APPEND mode CowWriter once there's an API to do
+ // it.
+ return snapshot_->OpenSnapshotWriter(params, std::move(source_path));
+} // namespace chromeos_update_engine
+
+FileDescriptorPtr DynamicPartitionControlAndroid::OpenCowReader(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>& source_path,
+ bool is_append) {
+ auto cow_writer =
+ OpenCowWriter(unsuffixed_partition_name, source_path, is_append);
+ if (cow_writer == nullptr) {
+ return nullptr;
+ }
+ cow_writer->InitializeAppend(kEndOfInstallLabel);
+ return cow_writer->OpenReader();
+}
+
+std::optional<base::FilePath> DynamicPartitionControlAndroid::GetSuperDevice() {
+ std::string device_dir_str;
+ if (!GetDeviceDir(&device_dir_str)) {
+ LOG(ERROR) << "Failed to get device dir!";
+ return {};
+ }
+ base::FilePath device_dir(device_dir_str);
+ auto super_device = device_dir.Append(GetSuperPartitionName(target_slot_));
+ return super_device;
+}
+
+bool DynamicPartitionControlAndroid::MapAllPartitions() {
+ return snapshot_->MapAllSnapshots(kMapSnapshotTimeout);
+}
+
+bool DynamicPartitionControlAndroid::IsDynamicPartition(
+ const std::string& partition_name) {
+ if (dynamic_partition_list_.empty() &&
+ GetDynamicPartitionsFeatureFlag().IsEnabled()) {
+ CHECK(ListDynamicPartitionsForSlot(source_slot_, &dynamic_partition_list_));
+ }
+ return std::find(dynamic_partition_list_.begin(),
+ dynamic_partition_list_.end(),
+ partition_name) != dynamic_partition_list_.end();
+}
} // namespace chromeos_update_engine
diff --git a/dynamic_partition_control_android.h b/aosp/dynamic_partition_control_android.h
similarity index 91%
rename from dynamic_partition_control_android.h
rename to aosp/dynamic_partition_control_android.h
index f3805f0..4a2b114 100644
--- a/dynamic_partition_control_android.h
+++ b/aosp/dynamic_partition_control_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
-#define UPDATE_ENGINE_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
#include <memory>
#include <set>
@@ -25,6 +25,7 @@
#include <base/files/file_util.h>
#include <libsnapshot/auto_device.h>
#include <libsnapshot/snapshot.h>
+#include <libsnapshot/snapshot_writer.h>
#include "update_engine/common/dynamic_partition_control_interface.h"
@@ -82,6 +83,20 @@
uint32_t current_slot,
std::string* device);
+ // Partition name is expected to be unsuffixed. e.g. system, vendor
+ // Return an interface to write to a snapshoted partition.
+ std::unique_ptr<android::snapshot::ISnapshotWriter> OpenCowWriter(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>& source_path,
+ bool is_append) override;
+ FileDescriptorPtr OpenCowReader(const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool is_append = false) override;
+
+ bool UnmapAllPartitions() override;
+
+ bool IsDynamicPartition(const std::string& part_name) override;
+
protected:
// These functions are exposed for testing.
@@ -193,11 +208,14 @@
const DeltaArchiveManifest& manifest,
bool delete_source);
+ bool MapAllPartitions() override;
+
private:
friend class DynamicPartitionControlAndroidTest;
friend class SnapshotPartitionTestP;
- void UnmapAllPartitions();
+ std::optional<base::FilePath> GetSuperDevice();
+
bool MapPartitionInternal(const std::string& super_device,
const std::string& target_partition_name,
uint32_t slot,
@@ -287,10 +305,11 @@
bool is_target_dynamic_ = false;
uint32_t source_slot_ = UINT32_MAX;
uint32_t target_slot_ = UINT32_MAX;
+ std::vector<std::string> dynamic_partition_list_;
DISALLOW_COPY_AND_ASSIGN(DynamicPartitionControlAndroid);
};
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_CONTROL_ANDROID_H_
diff --git a/dynamic_partition_control_android_unittest.cc b/aosp/dynamic_partition_control_android_unittest.cc
similarity index 97%
rename from dynamic_partition_control_android_unittest.cc
rename to aosp/dynamic_partition_control_android_unittest.cc
index 223e177..7e751db 100644
--- a/dynamic_partition_control_android_unittest.cc
+++ b/aosp/dynamic_partition_control_android_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/dynamic_partition_control_android.h"
+#include "update_engine/aosp/dynamic_partition_control_android.h"
#include <set>
#include <vector>
@@ -26,15 +26,14 @@
#include <libavb/libavb.h>
#include <libsnapshot/mock_snapshot.h>
+#include "update_engine/aosp/dynamic_partition_test_utils.h"
+#include "update_engine/aosp/mock_dynamic_partition_control_android.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/dynamic_partition_test_utils.h"
-#include "update_engine/mock_dynamic_partition_control.h"
using android::dm::DmDeviceState;
using android::snapshot::MockSnapshotManager;
using chromeos_update_engine::test_utils::ScopedLoopbackDeviceBinder;
-using chromeos_update_engine::test_utils::ScopedTempFile;
using std::string;
using testing::_;
using testing::AnyNumber;
@@ -793,11 +792,11 @@
}
TEST_F(DynamicPartitionControlAndroidTest, IsAvbNotEnabledInFstab) {
- // clang-format off
std::string fstab_content =
- "system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other,logical\n" // NOLINT(whitespace/line_length)
- "/dev/block/by-name/system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other\n"; // NOLINT(whitespace/line_length)
- // clang-format on
+ "system /postinstall ext4 ro,nosuid,nodev,noexec "
+ "slotselect_other,logical\n"
+ "/dev/block/by-name/system /postinstall ext4 "
+ "ro,nosuid,nodev,noexec slotselect_other\n";
ScopedTempFile fstab;
ASSERT_TRUE(test_utils::WriteFileString(fstab.path(), fstab_content));
ASSERT_THAT(dynamicControl().RealIsAvbEnabledInFstab(fstab.path()),
@@ -805,10 +804,9 @@
}
TEST_F(DynamicPartitionControlAndroidTest, IsAvbEnabledInFstab) {
- // clang-format off
std::string fstab_content =
- "system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other,logical,avb_keys=/foo\n"; // NOLINT(whitespace/line_length)
- // clang-format on
+ "system /postinstall ext4 ro,nosuid,nodev,noexec "
+ "slotselect_other,logical,avb_keys=/foo\n";
ScopedTempFile fstab;
ASSERT_TRUE(test_utils::WriteFileString(fstab.path(), fstab_content));
ASSERT_THAT(dynamicControl().RealIsAvbEnabledInFstab(fstab.path()),
diff --git a/dynamic_partition_test_utils.h b/aosp/dynamic_partition_test_utils.h
similarity index 97%
rename from dynamic_partition_test_utils.h
rename to aosp/dynamic_partition_test_utils.h
index d701dce..c7be1cb 100644
--- a/dynamic_partition_test_utils.h
+++ b/aosp/dynamic_partition_test_utils.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DYNAMIC_PARTITION_TEST_UTILS_H_
-#define UPDATE_ENGINE_DYNAMIC_PARTITION_TEST_UTILS_H_
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
#include <stdint.h>
@@ -285,4 +285,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DYNAMIC_PARTITION_TEST_UTILS_H_
+#endif // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_TEST_UTILS_H_
diff --git a/dynamic_partition_utils.cc b/aosp/dynamic_partition_utils.cc
similarity index 95%
rename from dynamic_partition_utils.cc
rename to aosp/dynamic_partition_utils.cc
index f9bd886..6b77a45 100644
--- a/dynamic_partition_utils.cc
+++ b/aosp/dynamic_partition_utils.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/dynamic_partition_utils.h"
+#include "update_engine/aosp/dynamic_partition_utils.h"
#include <vector>
diff --git a/dynamic_partition_utils.h b/aosp/dynamic_partition_utils.h
similarity index 85%
rename from dynamic_partition_utils.h
rename to aosp/dynamic_partition_utils.h
index 09fce00..5a51d5e 100644
--- a/dynamic_partition_utils.h
+++ b/aosp/dynamic_partition_utils.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DYNAMIC_PARTITION_UTILS_H_
-#define UPDATE_ENGINE_DYNAMIC_PARTITION_UTILS_H_
+#ifndef UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
+#define UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
#include <string>
@@ -30,4 +30,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DYNAMIC_PARTITION_UTILS_H_
+#endif // UPDATE_ENGINE_AOSP_DYNAMIC_PARTITION_UTILS_H_
diff --git a/hardware_android.cc b/aosp/hardware_android.cc
similarity index 94%
rename from hardware_android.cc
rename to aosp/hardware_android.cc
index a659bf6..6f884d4 100644
--- a/hardware_android.cc
+++ b/aosp/hardware_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/hardware_android.h"
+#include "update_engine/aosp/hardware_android.h"
#include <sys/types.h>
@@ -45,8 +45,6 @@
// Android properties that identify the hardware and potentially non-updatable
// parts of the bootloader (such as the bootloader version and the baseband
// version).
-const char kPropBootBootloader[] = "ro.boot.bootloader";
-const char kPropBootBaseband[] = "ro.boot.baseband";
const char kPropProductManufacturer[] = "ro.product.manufacturer";
const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku";
const char kPropBootRevision[] = "ro.boot.revision";
@@ -137,14 +135,6 @@
return manufacturer + ":" + sku + ":" + revision;
}
-string HardwareAndroid::GetFirmwareVersion() const {
- return GetProperty(kPropBootBootloader, "");
-}
-
-string HardwareAndroid::GetECVersion() const {
- return GetProperty(kPropBootBaseband, "");
-}
-
string HardwareAndroid::GetDeviceRequisition() const {
LOG(WARNING) << "STUB: Getting requisition is not supported.";
return "";
@@ -241,9 +231,11 @@
}
void HardwareAndroid::SetWarmReset(bool warm_reset) {
- constexpr char warm_reset_prop[] = "ota.warm_reset";
- if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) {
- LOG(WARNING) << "Failed to set prop " << warm_reset_prop;
+ if constexpr (!constants::kIsRecovery) {
+ constexpr char warm_reset_prop[] = "ota.warm_reset";
+ if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) {
+ LOG(WARNING) << "Failed to set prop " << warm_reset_prop;
+ }
}
}
diff --git a/hardware_android.h b/aosp/hardware_android.h
similarity index 91%
rename from hardware_android.h
rename to aosp/hardware_android.h
index d8fbbbe..5ffd7c5 100644
--- a/hardware_android.h
+++ b/aosp/hardware_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_HARDWARE_ANDROID_H_
-#define UPDATE_ENGINE_HARDWARE_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
#include <string>
#include <string_view>
@@ -42,8 +42,6 @@
bool IsOOBEEnabled() const override;
bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
std::string GetHardwareClass() const override;
- std::string GetFirmwareVersion() const override;
- std::string GetECVersion() const override;
std::string GetDeviceRequisition() const override;
int GetMinKernelKeyVersion() const override;
int GetMinFirmwareKeyVersion() const override;
@@ -72,4 +70,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_HARDWARE_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_HARDWARE_ANDROID_H_
diff --git a/logging_android.cc b/aosp/logging_android.cc
similarity index 100%
rename from logging_android.cc
rename to aosp/logging_android.cc
diff --git a/metrics_reporter_android.cc b/aosp/metrics_reporter_android.cc
similarity index 98%
rename from metrics_reporter_android.cc
rename to aosp/metrics_reporter_android.cc
index d8fa6e5..ea3bb6d 100644
--- a/metrics_reporter_android.cc
+++ b/aosp/metrics_reporter_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/metrics_reporter_android.h"
+#include "update_engine/aosp/metrics_reporter_android.h"
#include <stdint.h>
diff --git a/metrics_reporter_android.h b/aosp/metrics_reporter_android.h
similarity index 92%
rename from metrics_reporter_android.h
rename to aosp/metrics_reporter_android.h
index 7770619..4a173bf 100644
--- a/metrics_reporter_android.h
+++ b/aosp/metrics_reporter_android.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_METRICS_REPORTER_ANDROID_H_
-#define UPDATE_ENGINE_METRICS_REPORTER_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
#include <string>
#include "update_engine/common/error_code.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/metrics_reporter_interface.h"
namespace chromeos_update_engine {
@@ -98,4 +98,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_METRICS_REPORTER_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_METRICS_REPORTER_ANDROID_H_
diff --git a/mock_dynamic_partition_control.h b/aosp/mock_dynamic_partition_control_android.h
similarity index 82%
rename from mock_dynamic_partition_control.h
rename to aosp/mock_dynamic_partition_control_android.h
index e85df32..8d8ddb3 100644
--- a/mock_dynamic_partition_control.h
+++ b/aosp/mock_dynamic_partition_control_android.h
@@ -22,9 +22,13 @@
#include <gmock/gmock.h>
+#include <libsnapshot/cow_writer.h>
+#include <libsnapshot/snapshot_writer.h>
+
+#include "payload_consumer/file_descriptor.h"
+#include "update_engine/aosp/dynamic_partition_control_android.h"
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/dynamic_partition_control_interface.h"
-#include "update_engine/dynamic_partition_control_android.h"
namespace chromeos_update_engine {
@@ -81,6 +85,21 @@
PrepareDynamicPartitionsForUpdate,
(uint32_t, uint32_t, const DeltaArchiveManifest&, bool),
(override));
+ MOCK_METHOD(std::unique_ptr<android::snapshot::ISnapshotWriter>,
+ OpenCowWriter,
+ (const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>& source_path,
+ bool is_append),
+ (override));
+ MOCK_METHOD(FileDescriptorPtr,
+ OpenCowReader,
+ (const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>& source_path,
+ bool is_append),
+ (override));
+ MOCK_METHOD(bool, MapAllPartitions, (), (override));
+ MOCK_METHOD(bool, UnmapAllPartitions, (), (override));
+ MOCK_METHOD(bool, IsDynamicPartition, (const std::string&), (override));
void set_fake_mapped_devices(const std::set<std::string>& fake) override {
DynamicPartitionControlAndroid::set_fake_mapped_devices(fake);
diff --git a/network_selector_android.cc b/aosp/network_selector_android.cc
similarity index 88%
rename from network_selector_android.cc
rename to aosp/network_selector_android.cc
index 55ba799..a7db415 100644
--- a/network_selector_android.cc
+++ b/aosp/network_selector_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/network_selector_android.h"
+#include "update_engine/aosp/network_selector_android.h"
#include <memory>
@@ -25,14 +25,14 @@
namespace network {
-// Factory defined in network_selector.h.
+// Factory defined in common/network_selector.h.
std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector() {
return std::make_unique<NetworkSelectorAndroid>();
}
} // namespace network
-// Defined in network_selector_interface.h.
+// Defined in common/network_selector_interface.h.
const NetworkId kDefaultNetworkId = NETWORK_UNSPECIFIED;
bool NetworkSelectorAndroid::SetProcessNetwork(NetworkId network_id) {
diff --git a/network_selector_android.h b/aosp/network_selector_android.h
similarity index 81%
rename from network_selector_android.h
rename to aosp/network_selector_android.h
index 135536c..b79d1b3 100644
--- a/network_selector_android.h
+++ b/aosp/network_selector_android.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
-#define UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
#include <base/macros.h>
-#include "update_engine/network_selector_interface.h"
+#include "update_engine/common/network_selector_interface.h"
namespace chromeos_update_engine {
@@ -37,4 +37,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_NETWORK_SELECTOR_ANDROID_H_
diff --git a/common/platform_constants_android.cc b/aosp/platform_constants_android.cc
similarity index 100%
rename from common/platform_constants_android.cc
rename to aosp/platform_constants_android.cc
diff --git a/service_delegate_android_interface.h b/aosp/service_delegate_android_interface.h
similarity index 95%
rename from service_delegate_android_interface.h
rename to aosp/service_delegate_android_interface.h
index 34a9712..3c28794 100644
--- a/service_delegate_android_interface.h
+++ b/aosp/service_delegate_android_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
-#define UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+#ifndef UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+#define UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
#include <inttypes.h>
@@ -124,4 +124,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+#endif // UPDATE_ENGINE_AOSP_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
diff --git a/sideload_main.cc b/aosp/sideload_main.cc
similarity index 98%
rename from sideload_main.cc
rename to aosp/sideload_main.cc
index 27967cd..3cbc0c7 100644
--- a/sideload_main.cc
+++ b/aosp/sideload_main.cc
@@ -28,15 +28,15 @@
#include <brillo/streams/file_stream.h>
#include <brillo/streams/stream.h>
+#include "update_engine/aosp/update_attempter_android.h"
#include "update_engine/common/boot_control.h"
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/hardware.h"
+#include "update_engine/common/logging.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/common/terminator.h"
#include "update_engine/common/utils.h"
-#include "update_engine/logging.h"
-#include "update_engine/update_attempter_android.h"
using std::string;
using std::vector;
diff --git a/update_attempter_android.cc b/aosp/update_attempter_android.cc
similarity index 98%
rename from update_attempter_android.cc
rename to aosp/update_attempter_android.cc
index 3578d95..7ed3249 100644
--- a/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/update_attempter_android.h"
+#include "update_engine/aosp/update_attempter_android.h"
#include <algorithm>
#include <map>
@@ -31,18 +31,18 @@
#include <brillo/strings/string_utils.h>
#include <log/log_safetynet.h>
-#include "update_engine/cleanup_previous_update_action.h"
+#include "update_engine/aosp/cleanup_previous_update_action.h"
#include "update_engine/common/constants.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/file_fetcher.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+#include "update_engine/common/network_selector.h"
#include "update_engine/common/utils.h"
-#include "update_engine/daemon_state_interface.h"
-#include "update_engine/metrics_reporter_interface.h"
#include "update_engine/metrics_utils.h"
-#include "update_engine/network_selector.h"
#include "update_engine/payload_consumer/certificate_parser_interface.h"
#include "update_engine/payload_consumer/delta_performer.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/file_descriptor_utils.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
diff --git a/update_attempter_android.h b/aosp/update_attempter_android.h
similarity index 94%
rename from update_attempter_android.h
rename to aosp/update_attempter_android.h
index 55003a0..499f8f6 100644
--- a/update_attempter_android.h
+++ b/aosp/update_attempter_android.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_UPDATE_ATTEMPTER_ANDROID_H_
-#define UPDATE_ENGINE_UPDATE_ATTEMPTER_ANDROID_H_
+#ifndef UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
+#define UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
#include <stdint.h>
@@ -26,21 +26,21 @@
#include <android-base/unique_fd.h>
#include <base/time/time.h>
+#include "update_engine/aosp/service_delegate_android_interface.h"
#include "update_engine/client_library/include/update_engine/update_status.h"
#include "update_engine/common/action_processor.h"
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/clock.h"
+#include "update_engine/common/daemon_state_interface.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+#include "update_engine/common/network_selector_interface.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/daemon_state_interface.h"
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/common/service_observer_interface.h"
#include "update_engine/metrics_utils.h"
-#include "update_engine/network_selector_interface.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
#include "update_engine/payload_consumer/postinstall_runner_action.h"
-#include "update_engine/service_delegate_android_interface.h"
-#include "update_engine/service_observer_interface.h"
namespace chromeos_update_engine {
@@ -246,4 +246,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_UPDATE_ATTEMPTER_ANDROID_H_
+#endif // UPDATE_ENGINE_AOSP_UPDATE_ATTEMPTER_ANDROID_H_
diff --git a/update_attempter_android_unittest.cc b/aosp/update_attempter_android_unittest.cc
similarity index 97%
rename from update_attempter_android_unittest.cc
rename to aosp/update_attempter_android_unittest.cc
index 721b735..bb44450 100644
--- a/update_attempter_android_unittest.cc
+++ b/aosp/update_attempter_android_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/update_attempter_android.h"
+#include "update_engine/aosp/update_attempter_android.h"
#include <memory>
#include <string>
@@ -24,15 +24,15 @@
#include <base/time/time.h>
#include <gtest/gtest.h>
+#include "update_engine/aosp/daemon_state_android.h"
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/mock_action_processor.h"
+#include "update_engine/common/mock_metrics_reporter.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/daemon_state_android.h"
-#include "update_engine/mock_metrics_reporter.h"
using base::Time;
using base::TimeDelta;
diff --git a/update_engine_client_android.cc b/aosp/update_engine_client_android.cc
similarity index 100%
rename from update_engine_client_android.cc
rename to aosp/update_engine_client_android.cc
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
index 8e9a7fd..30ad78c 100644
--- a/client_library/client_dbus.cc
+++ b/client_library/client_dbus.cc
@@ -16,7 +16,7 @@
#include "update_engine/client_library/client_dbus.h"
-#include <base/message_loop/message_loop.h>
+#include <base/message_loop/message_loop_current.h>
#include <memory>
diff --git a/common/cleanup_previous_update_action_delegate.h b/common/cleanup_previous_update_action_delegate.h
index 7dad9c5..8daf860 100644
--- a/common/cleanup_previous_update_action_delegate.h
+++ b/common/cleanup_previous_update_action_delegate.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
-#define UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
+#ifndef UPDATE_ENGINE_COMMON_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
+#define UPDATE_ENGINE_COMMON_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
namespace chromeos_update_engine {
@@ -29,4 +29,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
+#endif // UPDATE_ENGINE_COMMON_CLEANUP_PREVIOUS_UPDATE_ACTION_DELEGETE_H_
diff --git a/connection_utils.cc b/common/connection_utils.cc
similarity index 97%
rename from connection_utils.cc
rename to common/connection_utils.cc
index 5af7341..44e5128 100644
--- a/connection_utils.cc
+++ b/common/connection_utils.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/connection_utils.h"
+#include "update_engine/common/connection_utils.h"
#include <shill/dbus-constants.h>
diff --git a/connection_utils.h b/common/connection_utils.h
similarity index 89%
rename from connection_utils.h
rename to common/connection_utils.h
index 4e71fcf..5d63fb2 100644
--- a/connection_utils.h
+++ b/common/connection_utils.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CONNECTION_UTILS_H_
-#define UPDATE_ENGINE_CONNECTION_UTILS_H_
+#ifndef UPDATE_ENGINE_COMMON_CONNECTION_UTILS_H_
+#define UPDATE_ENGINE_COMMON_CONNECTION_UTILS_H_
#include <string>
@@ -47,4 +47,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CONNECTION_UTILS_H_
+#endif // UPDATE_ENGINE_COMMON_CONNECTION_UTILS_H_
diff --git a/common/constants.cc b/common/constants.cc
index c85ba54..8883668 100644
--- a/common/constants.cc
+++ b/common/constants.cc
@@ -64,6 +64,8 @@
const char kPrefsP2PFirstAttemptTimestamp[] = "p2p-first-attempt-timestamp";
const char kPrefsP2PNumAttempts[] = "p2p-num-attempts";
const char kPrefsPayloadAttemptNumber[] = "payload-attempt-number";
+const char kPrefsTestUpdateCheckIntervalTimeout[] =
+ "test-update-check-interval-timeout";
// Keep |kPrefsPingActive| in sync with |kDlcMetadataFilePingActive| in
// dlcservice.
const char kPrefsPingActive[] = "active";
diff --git a/common/constants.h b/common/constants.h
index 7170201..f468b55 100644
--- a/common/constants.h
+++ b/common/constants.h
@@ -17,6 +17,8 @@
#ifndef UPDATE_ENGINE_COMMON_CONSTANTS_H_
#define UPDATE_ENGINE_COMMON_CONSTANTS_H_
+#include <cstdint>
+
namespace chromeos_update_engine {
// The root path of all exclusion prefs.
@@ -67,6 +69,7 @@
extern const char kPrefsP2PFirstAttemptTimestamp[];
extern const char kPrefsP2PNumAttempts[];
extern const char kPrefsPayloadAttemptNumber[];
+extern const char kPrefsTestUpdateCheckIntervalTimeout[];
extern const char kPrefsPingActive[];
extern const char kPrefsPingLastActive[];
extern const char kPrefsPingLastRollcall[];
@@ -152,30 +155,30 @@
} PayloadType;
// Maximum number of times we'll allow using p2p for the same update payload.
-const int kMaxP2PAttempts = 10;
+constexpr int kMaxP2PAttempts = 10;
// Maximum wallclock time we allow attempting to update using p2p for
// the same update payload - five days.
-const int kMaxP2PAttemptTimeSeconds = 5 * 24 * 60 * 60;
+constexpr int kMaxP2PAttemptTimeSeconds = 5 * 24 * 60 * 60;
// The maximum amount of time to spend waiting for p2p-client(1) to
// return while waiting in line to use the LAN - six hours.
-const int kMaxP2PNetworkWaitTimeSeconds = 6 * 60 * 60;
+constexpr int kMaxP2PNetworkWaitTimeSeconds = 6 * 60 * 60;
// The maximum number of payload files to keep in /var/cache/p2p.
-const int kMaxP2PFilesToKeep = 3;
+constexpr int kMaxP2PFilesToKeep = 3;
// The maximum number of days to keep a p2p file;
-const int kMaxP2PFileAgeDays = 5;
+constexpr int kMaxP2PFileAgeDays = 5;
// The default number of UMA buckets for metrics.
-const int kNumDefaultUmaBuckets = 50;
+constexpr int kNumDefaultUmaBuckets = 50;
-// General constants
-const int kNumBytesInOneMiB = 1024 * 1024;
+// General constexprants
+constexpr int kNumBytesInOneMiB = 1024 * 1024;
// Number of redirects allowed when downloading.
-const int kDownloadMaxRedirects = 10;
+constexpr int kDownloadMaxRedirects = 10;
// The minimum average speed that downloads must sustain...
//
@@ -183,8 +186,8 @@
// connectivity and we want to make as much forward progress as
// possible. For p2p this is high (25 kB/second) since we can assume
// high bandwidth (same LAN) and we want to fail fast.
-const int kDownloadLowSpeedLimitBps = 1;
-const int kDownloadP2PLowSpeedLimitBps = 25 * 1000;
+constexpr int kDownloadLowSpeedLimitBps = 1;
+constexpr int kDownloadP2PLowSpeedLimitBps = 25 * 1000;
// ... measured over this period.
//
@@ -193,18 +196,18 @@
// for the workstation to generate the payload. For normal operation
// and p2p, make this relatively low since we want to fail fast in
// those cases.
-const int kDownloadLowSpeedTimeSeconds = 30;
-const int kDownloadDevModeLowSpeedTimeSeconds = 180;
-const int kDownloadP2PLowSpeedTimeSeconds = 60;
+constexpr int kDownloadLowSpeedTimeSeconds = 30;
+constexpr int kDownloadDevModeLowSpeedTimeSeconds = 180;
+constexpr int kDownloadP2PLowSpeedTimeSeconds = 60;
// The maximum amount of HTTP server reconnect attempts.
//
// This is set high in order to maximize the attempt's chance of
// succeeding. When using p2p, this is low in order to fail fast.
-const int kDownloadMaxRetryCount = 20;
-const int kDownloadMaxRetryCountOobeNotComplete = 3;
-const int kDownloadMaxRetryCountInteractive = 3;
-const int kDownloadP2PMaxRetryCount = 5;
+constexpr int kDownloadMaxRetryCount = 20;
+constexpr int kDownloadMaxRetryCountOobeNotComplete = 3;
+constexpr int kDownloadMaxRetryCountInteractive = 3;
+constexpr int kDownloadP2PMaxRetryCount = 5;
// The connect timeout, in seconds.
//
@@ -212,11 +215,19 @@
// connectivity and we may be using HTTPS which involves complicated
// multi-roundtrip setup. For p2p, this is set low because we can
// the server is on the same LAN and we want to fail fast.
-const int kDownloadConnectTimeoutSeconds = 30;
-const int kDownloadP2PConnectTimeoutSeconds = 5;
+constexpr int kDownloadConnectTimeoutSeconds = 30;
+constexpr int kDownloadP2PConnectTimeoutSeconds = 5;
// Size in bytes of SHA256 hash.
-const int kSHA256Size = 32;
+constexpr int kSHA256Size = 32;
+
+// A hardcoded label to mark end of all InstallOps
+// This number must be greater than number of install ops.
+// Number of install ops is bounded by number of blocks on any partition.
+// Currently, the block size is 4096. Using |kEndOfInstallLabel| of 2^48 will
+// allow partitions with 2^48 * 4096 = 2^60 bytes. That's 1024PB? Partitions on
+// android aren't getting that big any time soon.
+constexpr uint64_t kEndOfInstallLabel = (1ULL << 48);
} // namespace chromeos_update_engine
diff --git a/common/cow_operation_convert.cc b/common/cow_operation_convert.cc
new file mode 100644
index 0000000..6b64a9c
--- /dev/null
+++ b/common/cow_operation_convert.cc
@@ -0,0 +1,93 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/common/cow_operation_convert.h"
+
+#include <base/logging.h>
+
+#include "update_engine/payload_generator/extent_ranges.h"
+#include "update_engine/payload_generator/extent_utils.h"
+
+namespace chromeos_update_engine {
+
+std::vector<CowOperation> ConvertToCowOperations(
+ const ::google::protobuf::RepeatedPtrField<
+ ::chromeos_update_engine::InstallOperation>& operations,
+ const ::google::protobuf::RepeatedPtrField<CowMergeOperation>&
+ merge_operations) {
+ ExtentRanges merge_extents;
+ std::vector<CowOperation> converted;
+ ExtentRanges modified_extents;
+
+ // We want all CowCopy ops to be done first, before any COW_REPLACE happen.
+ // Therefore we add these ops in 2 separate loops. This is because during
+ // merge, a CowReplace might modify a block needed by CowCopy, so we always
+ // perform CowCopy first.
+
+ // This loop handles CowCopy blocks within SOURCE_COPY, and the next loop
+ // converts the leftover blocks to CowReplace?
+ for (const auto& merge_op : merge_operations) {
+ merge_extents.AddExtent(merge_op.dst_extent());
+ const auto& src_extent = merge_op.src_extent();
+ const auto& dst_extent = merge_op.dst_extent();
+ // Add blocks in reverse order to avoid merge conflicts on self-overlapping
+ // Ops.
+ // For example: SOURCE_COPY [20 - 30] -> [25 - 35] If blocks are added in
+ // forward order, then 20->25 is performed first, destroying block 25, which
+ // is neede by a later operation.
+ if (src_extent.start_block() < dst_extent.start_block()) {
+ for (uint64_t i = src_extent.num_blocks(); i > 0; i--) {
+ auto src_block = src_extent.start_block() + i - 1;
+ auto dst_block = dst_extent.start_block() + i - 1;
+ CHECK(!modified_extents.ContainsBlock(src_block))
+ << "block " << src_block << " is modified by previous CowCopy";
+ converted.push_back({CowOperation::CowCopy, src_block, dst_block});
+ modified_extents.AddBlock(dst_block);
+ }
+ } else {
+ for (uint64_t i = 0; i < src_extent.num_blocks(); i++) {
+ auto src_block = src_extent.start_block() + i;
+ auto dst_block = dst_extent.start_block() + i;
+ CHECK(!modified_extents.ContainsBlock(src_block))
+ << "block " << src_block << " is modified by previous CowCopy";
+ converted.push_back({CowOperation::CowCopy, src_block, dst_block});
+ modified_extents.AddBlock(dst_block);
+ }
+ }
+ }
+ // COW_REPLACE are added after COW_COPY, because replace might modify blocks
+ // needed by COW_COPY. Please don't merge this loop with the previous one.
+ for (const auto& operation : operations) {
+ if (operation.type() != InstallOperation::SOURCE_COPY) {
+ continue;
+ }
+ const auto& src_extents = operation.src_extents();
+ const auto& dst_extents = operation.dst_extents();
+ BlockIterator it1{src_extents};
+ BlockIterator it2{dst_extents};
+ while (!it1.is_end() && !it2.is_end()) {
+ auto src_block = *it1;
+ auto dst_block = *it2;
+ if (!merge_extents.ContainsBlock(dst_block)) {
+ converted.push_back({CowOperation::CowReplace, src_block, dst_block});
+ }
+ ++it1;
+ ++it2;
+ }
+ }
+ return converted;
+}
+} // namespace chromeos_update_engine
diff --git a/common/cow_operation_convert.h b/common/cow_operation_convert.h
new file mode 100644
index 0000000..c0543f7
--- /dev/null
+++ b/common/cow_operation_convert.h
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef __COW_OPERATION_CONVERT_H
+#define __COW_OPERATION_CONVERT_H
+
+#include <vector>
+
+#include <libsnapshot/cow_format.h>
+
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+struct CowOperation {
+ enum Type {
+ CowCopy = android::snapshot::kCowCopyOp,
+ CowReplace = android::snapshot::kCowReplaceOp,
+ };
+ Type op;
+ uint64_t src_block;
+ uint64_t dst_block;
+};
+
+// Convert SOURCE_COPY operations in `operations` list to a list of
+// CowOperations according to the merge sequence. This function only converts
+// SOURCE_COPY, other operations are ignored. If there's a merge conflict in
+// SOURCE_COPY operations, some blocks may be converted to COW_REPLACE instead
+// of COW_COPY.
+
+// The list returned does not necessarily preserve the order of
+// SOURCE_COPY in `operations`. The only guarantee about ordering in the
+// returned list is that if operations are applied in such order, there would be
+// no merge conflicts.
+
+// This funnction is intended to be used by delta_performer to perform
+// SOURCE_COPY operations on Virtual AB Compression devices.
+std::vector<CowOperation> ConvertToCowOperations(
+ const ::google::protobuf::RepeatedPtrField<
+ ::chromeos_update_engine::InstallOperation>& operations,
+ const ::google::protobuf::RepeatedPtrField<CowMergeOperation>&
+ merge_operations);
+} // namespace chromeos_update_engine
+#endif
diff --git a/common/cow_operation_convert_unittest.cc b/common/cow_operation_convert_unittest.cc
new file mode 100644
index 0000000..93173fe
--- /dev/null
+++ b/common/cow_operation_convert_unittest.cc
@@ -0,0 +1,236 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+
+#include <gtest/gtest.h>
+
+#include "update_engine/common/cow_operation_convert.h"
+#include "update_engine/payload_generator/extent_ranges.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+using OperationList = ::google::protobuf::RepeatedPtrField<
+ ::chromeos_update_engine::InstallOperation>;
+using MergeOplist = ::google::protobuf::RepeatedPtrField<
+ ::chromeos_update_engine::CowMergeOperation>;
+
+std::ostream& operator<<(std::ostream& out, CowOperation::Type op) {
+ switch (op) {
+ case CowOperation::Type::CowCopy:
+ out << "CowCopy";
+ break;
+ case CowOperation::Type::CowReplace:
+ out << "CowReplace";
+ break;
+ default:
+ out << op;
+ break;
+ }
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const CowOperation& c) {
+ out << "{" << c.op << ", " << c.src_block << ", " << c.dst_block << "}";
+ return out;
+}
+
+class CowOperationConvertTest : public testing::Test {
+ public:
+ void VerifyCowMergeOp(const std::vector<CowOperation>& cow_ops) {
+ // Build a set of all extents covered by InstallOps.
+ ExtentRanges src_extent_set;
+ ExtentRanges dst_extent_set;
+ for (auto&& op : operations_) {
+ src_extent_set.AddRepeatedExtents(op.src_extents());
+ dst_extent_set.AddRepeatedExtents(op.dst_extents());
+ }
+ ExtentRanges modified_extents;
+ for (auto&& cow_op : cow_ops) {
+ if (cow_op.op == CowOperation::CowCopy) {
+ EXPECT_TRUE(src_extent_set.ContainsBlock(cow_op.src_block));
+ // converted operations should be conflict free.
+ EXPECT_FALSE(modified_extents.ContainsBlock(cow_op.src_block))
+ << "SOURCE_COPY operation " << cow_op
+ << " read from a modified block";
+ }
+ EXPECT_TRUE(dst_extent_set.ContainsBlock(cow_op.dst_block));
+ dst_extent_set.SubtractExtent(ExtentForRange(cow_op.dst_block, 1));
+ modified_extents.AddBlock(cow_op.dst_block);
+ }
+ // The generated CowOps should cover all extents in InstallOps.
+ EXPECT_EQ(dst_extent_set.blocks(), 0UL);
+ // It's possible that src_extent_set is non-empty, because some operations
+ // will be converted to CowReplace, and we don't count the source extent for
+ // those.
+ }
+ OperationList operations_;
+ MergeOplist merge_operations_;
+};
+
+void AddOperation(OperationList* operations,
+ ::chromeos_update_engine::InstallOperation_Type op_type,
+ std::initializer_list<std::array<int, 2>> src_extents,
+ std::initializer_list<std::array<int, 2>> dst_extents) {
+ auto&& op = operations->Add();
+ op->set_type(op_type);
+ for (const auto& extent : src_extents) {
+ *op->add_src_extents() = ExtentForRange(extent[0], extent[1]);
+ }
+ for (const auto& extent : dst_extents) {
+ *op->add_dst_extents() = ExtentForRange(extent[0], extent[1]);
+ }
+}
+
+void AddMergeOperation(MergeOplist* operations,
+ ::chromeos_update_engine::CowMergeOperation_Type op_type,
+ std::array<int, 2> src_extent,
+ std::array<int, 2> dst_extent) {
+ auto&& op = operations->Add();
+ op->set_type(op_type);
+ *op->mutable_src_extent() = ExtentForRange(src_extent[0], src_extent[1]);
+ *op->mutable_dst_extent() = ExtentForRange(dst_extent[0], dst_extent[1]);
+}
+
+TEST_F(CowOperationConvertTest, NoConflict) {
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{20, 1}}, {{30, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{10, 1}}, {{20, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{0, 1}}, {{10, 1}});
+
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {20, 1}, {30, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {10, 1}, {20, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {0, 1}, {10, 1});
+
+ auto cow_ops = ConvertToCowOperations(operations_, merge_operations_);
+ ASSERT_EQ(cow_ops.size(), 3UL);
+ ASSERT_TRUE(std::all_of(cow_ops.begin(), cow_ops.end(), [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowCopy;
+ }));
+ VerifyCowMergeOp(cow_ops);
+}
+
+TEST_F(CowOperationConvertTest, CowReplace) {
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{30, 1}}, {{0, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{20, 1}}, {{30, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{10, 1}}, {{20, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{0, 1}}, {{10, 1}});
+
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {20, 1}, {30, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {10, 1}, {20, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {0, 1}, {10, 1});
+
+ auto cow_ops = ConvertToCowOperations(operations_, merge_operations_);
+ ASSERT_EQ(cow_ops.size(), 4UL);
+ // Expect 3 COW_COPY and 1 COW_REPLACE
+ ASSERT_EQ(std::count_if(cow_ops.begin(),
+ cow_ops.end(),
+ [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowCopy;
+ }),
+ 3);
+ ASSERT_EQ(std::count_if(cow_ops.begin(),
+ cow_ops.end(),
+ [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowReplace;
+ }),
+ 1);
+ VerifyCowMergeOp(cow_ops);
+}
+
+TEST_F(CowOperationConvertTest, ReOrderSourceCopy) {
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{30, 1}}, {{20, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{20, 1}}, {{10, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{10, 1}}, {{0, 1}});
+
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {10, 1}, {0, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {20, 1}, {10, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {30, 1}, {20, 1});
+
+ auto cow_ops = ConvertToCowOperations(operations_, merge_operations_);
+ ASSERT_EQ(cow_ops.size(), 3UL);
+ // Expect 3 COW_COPY
+ ASSERT_TRUE(std::all_of(cow_ops.begin(), cow_ops.end(), [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowCopy;
+ }));
+ VerifyCowMergeOp(cow_ops);
+}
+
+TEST_F(CowOperationConvertTest, InterleavingSrcExtent) {
+ AddOperation(&operations_,
+ InstallOperation::SOURCE_COPY,
+ {{30, 5}, {35, 5}},
+ {{20, 10}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{20, 1}}, {{10, 1}});
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{10, 1}}, {{0, 1}});
+
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {10, 1}, {0, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {20, 1}, {10, 1});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {30, 5}, {20, 5});
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {35, 5}, {25, 5});
+
+ auto cow_ops = ConvertToCowOperations(operations_, merge_operations_);
+ // Expect 4 COW_COPY
+ ASSERT_EQ(cow_ops.size(), 12UL);
+ ASSERT_TRUE(std::all_of(cow_ops.begin(), cow_ops.end(), [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowCopy;
+ }));
+ VerifyCowMergeOp(cow_ops);
+}
+
+TEST_F(CowOperationConvertTest, SelfOverlappingOperation) {
+ AddOperation(
+ &operations_, InstallOperation::SOURCE_COPY, {{20, 10}}, {{25, 10}});
+
+ AddMergeOperation(
+ &merge_operations_, CowMergeOperation::COW_COPY, {20, 10}, {25, 10});
+
+ auto cow_ops = ConvertToCowOperations(operations_, merge_operations_);
+ // Expect 10 COW_COPY
+ ASSERT_EQ(cow_ops.size(), 10UL);
+ ASSERT_TRUE(std::all_of(cow_ops.begin(), cow_ops.end(), [](auto&& cow_op) {
+ return cow_op.op == CowOperation::CowCopy;
+ }));
+ VerifyCowMergeOp(cow_ops);
+}
+
+} // namespace chromeos_update_engine
diff --git a/daemon_base.h b/common/daemon_base.h
similarity index 87%
rename from daemon_base.h
rename to common/daemon_base.h
index 742a0ba..4bc5ef7 100644
--- a/daemon_base.h
+++ b/common/daemon_base.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DAEMON_BASE_H_
-#define UPDATE_ENGINE_DAEMON_BASE_H_
+#ifndef UPDATE_ENGINE_COMMON_DAEMON_BASE_H_
+#define UPDATE_ENGINE_COMMON_DAEMON_BASE_H_
#include <memory>
@@ -37,4 +37,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DAEMON_BASE_H_
+#endif // UPDATE_ENGINE_COMMON_DAEMON_BASE_H_
diff --git a/daemon_state_interface.h b/common/daemon_state_interface.h
similarity index 85%
rename from daemon_state_interface.h
rename to common/daemon_state_interface.h
index 2356816..9509fa2 100644
--- a/daemon_state_interface.h
+++ b/common/daemon_state_interface.h
@@ -14,10 +14,10 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DAEMON_STATE_INTERFACE_H_
-#define UPDATE_ENGINE_DAEMON_STATE_INTERFACE_H_
+#ifndef UPDATE_ENGINE_COMMON_DAEMON_STATE_INTERFACE_H_
+#define UPDATE_ENGINE_COMMON_DAEMON_STATE_INTERFACE_H_
-#include "update_engine/service_observer_interface.h"
+#include "update_engine/common/service_observer_interface.h"
#include <memory>
#include <set>
@@ -46,4 +46,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DAEMON_STATE_INTERFACE_H_
+#endif // UPDATE_ENGINE_COMMON_DAEMON_STATE_INTERFACE_H_
diff --git a/payload_consumer/download_action.h b/common/download_action.h
similarity index 96%
rename from payload_consumer/download_action.h
rename to common/download_action.h
index 6928443..c167c2d 100644
--- a/payload_consumer/download_action.h
+++ b/common/download_action.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
-#define UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
+#ifndef UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
+#define UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
#include <fcntl.h>
#include <sys/stat.h>
@@ -28,9 +28,9 @@
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/http_fetcher.h"
#include "update_engine/common/multi_range_http_fetcher.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/payload_consumer/delta_performer.h"
#include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/system_state.h"
// The Download Action downloads a specified url to disk. The url should point
// to an update in a delta payload format. The payload will be piped into a
@@ -200,4 +200,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
+#endif // UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h
index 22f6db8..1362c19 100644
--- a/common/dynamic_partition_control_interface.h
+++ b/common/dynamic_partition_control_interface.h
@@ -26,8 +26,14 @@
#include "update_engine/common/action.h"
#include "update_engine/common/cleanup_previous_update_action_delegate.h"
#include "update_engine/common/error_code.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/update_metadata.pb.h"
+// Forware declare for libsnapshot/snapshot_writer.h
+namespace android::snapshot {
+class ISnapshotWriter;
+}
+
namespace chromeos_update_engine {
struct FeatureFlag {
@@ -139,6 +145,26 @@
uint32_t source_slot,
uint32_t target_slot,
const std::vector<std::string>& partitions) = 0;
+ // Partition name is expected to be unsuffixed. e.g. system, vendor
+ // Return an interface to write to a snapshoted partition.
+ // If `is_append` is false, then existing COW data will be overwritten.
+ // Otherwise the cow writer will be opened on APPEND mode, existing COW data
+ // is preserved.
+ virtual std::unique_ptr<android::snapshot::ISnapshotWriter> OpenCowWriter(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool is_append = false) = 0;
+ virtual FileDescriptorPtr OpenCowReader(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool is_append = false) = 0;
+
+ virtual bool IsDynamicPartition(const std::string& part_name) = 0;
+
+ // Create virtual block devices for all partitions.
+ virtual bool MapAllPartitions() = 0;
+ // Unmap virtual block devices for all partitions.
+ virtual bool UnmapAllPartitions() = 0;
};
} // namespace chromeos_update_engine
diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc
index c63a8ff..2c6bb1b 100644
--- a/common/dynamic_partition_control_stub.cc
+++ b/common/dynamic_partition_control_stub.cc
@@ -20,6 +20,7 @@
#include <string>
#include <base/logging.h>
+#include <libsnapshot/cow_writer.h>
#include "update_engine/common/dynamic_partition_control_stub.h"
@@ -87,4 +88,32 @@
return true;
}
+std::unique_ptr<android::snapshot::ISnapshotWriter>
+DynamicPartitionControlStub::OpenCowWriter(
+ const std::string& /*unsuffixed_partition_name*/,
+ const std::optional<std::string>& /*source_path*/,
+ bool /*is_append*/) {
+ return nullptr;
+}
+
+FileDescriptorPtr DynamicPartitionControlStub::OpenCowReader(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool /*is_append */) {
+ return nullptr;
+}
+
+bool DynamicPartitionControlStub::MapAllPartitions() {
+ return false;
+}
+
+bool DynamicPartitionControlStub::UnmapAllPartitions() {
+ return false;
+}
+
+bool DynamicPartitionControlStub::IsDynamicPartition(
+ const std::string& part_name) {
+ return false;
+}
+
} // namespace chromeos_update_engine
diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h
index 8bff474..0f428ab 100644
--- a/common/dynamic_partition_control_stub.h
+++ b/common/dynamic_partition_control_stub.h
@@ -57,8 +57,20 @@
uint32_t source_slot,
uint32_t target_slot,
const std::vector<std::string>& partitions) override;
-};
+ std::unique_ptr<android::snapshot::ISnapshotWriter> OpenCowWriter(
+ const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool is_append) override;
+ FileDescriptorPtr OpenCowReader(const std::string& unsuffixed_partition_name,
+ const std::optional<std::string>&,
+ bool is_append = false) override;
+
+ bool MapAllPartitions() override;
+ bool UnmapAllPartitions() override;
+
+ bool IsDynamicPartition(const std::string& part_name) override;
+};
} // namespace chromeos_update_engine
#endif // UPDATE_ENGINE_COMMON_DYNAMIC_PARTITION_CONTROL_STUB_H_
diff --git a/common/error_code.h b/common/error_code.h
index e473a05..a889888 100644
--- a/common/error_code.h
+++ b/common/error_code.h
@@ -85,6 +85,8 @@
kUnresolvedHostRecovered = 59,
kNotEnoughSpace = 60,
kDeviceCorrupted = 61,
+ kPackageExcludedFromUpdate = 62,
+ kPostInstallMountError = 63,
// VERY IMPORTANT! When adding new error codes:
//
diff --git a/common/error_code_utils.cc b/common/error_code_utils.cc
index 64df24a..421544a 100644
--- a/common/error_code_utils.cc
+++ b/common/error_code_utils.cc
@@ -171,6 +171,10 @@
return "ErrorCode::kNotEnoughSpace";
case ErrorCode::kDeviceCorrupted:
return "ErrorCode::kDeviceCorrupted";
+ case ErrorCode::kPackageExcludedFromUpdate:
+ return "ErrorCode::kPackageExcludedFromUpdate";
+ case ErrorCode::kPostInstallMountError:
+ return "ErrorCode::kPostInstallMountError";
// Don't add a default case to let the compiler warn about newly added
// error codes which should be added here.
}
diff --git a/common/fake_boot_control.h b/common/fake_boot_control.h
index 5d8823a..98b93e6 100644
--- a/common/fake_boot_control.h
+++ b/common/fake_boot_control.h
@@ -116,7 +116,7 @@
is_bootable_[slot] = bootable;
}
- DynamicPartitionControlInterface* GetDynamicPartitionControl() {
+ DynamicPartitionControlInterface* GetDynamicPartitionControl() override {
return dynamic_partition_control_.get();
}
diff --git a/common/fake_hardware.h b/common/fake_hardware.h
index 82382ff..00a212e 100644
--- a/common/fake_hardware.h
+++ b/common/fake_hardware.h
@@ -76,10 +76,6 @@
std::string GetHardwareClass() const override { return hardware_class_; }
- std::string GetFirmwareVersion() const override { return firmware_version_; }
-
- std::string GetECVersion() const override { return ec_version_; }
-
std::string GetDeviceRequisition() const override {
return device_requisition_;
}
@@ -176,12 +172,6 @@
hardware_class_ = hardware_class;
}
- void SetFirmwareVersion(const std::string& firmware_version) {
- firmware_version_ = firmware_version;
- }
-
- void SetECVersion(const std::string& ec_version) { ec_version_ = ec_version; }
-
void SetDeviceRequisition(const std::string& requisition) {
device_requisition_ = requisition;
}
@@ -233,8 +223,6 @@
// Jan 20, 2007
base::Time oobe_timestamp_{base::Time::FromTimeT(1169280000)};
std::string hardware_class_{"Fake HWID BLAH-1234"};
- std::string firmware_version_{"Fake Firmware v1.0.1"};
- std::string ec_version_{"Fake EC v1.0a"};
std::string device_requisition_{"fake_requisition"};
int min_kernel_key_version_{kMinKernelKeyVersion};
int min_firmware_key_version_{kMinFirmwareKeyVersion};
diff --git a/common/hardware_interface.h b/common/hardware_interface.h
index b37b007..cad32fc 100644
--- a/common/hardware_interface.h
+++ b/common/hardware_interface.h
@@ -64,14 +64,6 @@
// Returns the HWID or an empty string on error.
virtual std::string GetHardwareClass() const = 0;
- // Returns the firmware version or an empty string if the system is
- // not running chrome os firmware.
- virtual std::string GetFirmwareVersion() const = 0;
-
- // Returns the ec version or an empty string if the system is not
- // running a custom chrome os ec.
- virtual std::string GetECVersion() const = 0;
-
// Returns the OEM device requisition or an empty string if the system does
// not have a requisition, or if not running Chrome OS.
virtual std::string GetDeviceRequisition() const = 0;
diff --git a/common/hash_calculator_unittest.cc b/common/hash_calculator_unittest.cc
index e8f73d5..fe7d543 100644
--- a/common/hash_calculator_unittest.cc
+++ b/common/hash_calculator_unittest.cc
@@ -104,7 +104,7 @@
}
TEST_F(HashCalculatorTest, UpdateFileSimpleTest) {
- test_utils::ScopedTempFile data_file("data.XXXXXX");
+ ScopedTempFile data_file("data.XXXXXX");
ASSERT_TRUE(test_utils::WriteFileString(data_file.path(), "hi"));
for (const int length : {-1, 2, 10}) {
@@ -126,7 +126,7 @@
}
TEST_F(HashCalculatorTest, RawHashOfFileSimpleTest) {
- test_utils::ScopedTempFile data_file("data.XXXXXX");
+ ScopedTempFile data_file("data.XXXXXX");
ASSERT_TRUE(test_utils::WriteFileString(data_file.path(), "hi"));
for (const int length : {-1, 2, 10}) {
diff --git a/common/http_fetcher.h b/common/http_fetcher.h
index f74a0f0..7fa5f09 100644
--- a/common/http_fetcher.h
+++ b/common/http_fetcher.h
@@ -28,8 +28,8 @@
#include <brillo/message_loops/message_loop.h>
#include "update_engine/common/http_common.h"
+#include "update_engine/common/metrics_constants.h"
#include "update_engine/common/proxy_resolver.h"
-#include "update_engine/metrics_constants.h"
// This class is a simple wrapper around an HTTP library (libcurl). We can
// easily mock out this interface for testing.
diff --git a/common/http_fetcher_unittest.cc b/common/http_fetcher_unittest.cc
index 9338087..99ea99b 100644
--- a/common/http_fetcher_unittest.cc
+++ b/common/http_fetcher_unittest.cc
@@ -28,11 +28,16 @@
#include <base/bind.h>
#include <base/location.h>
#include <base/logging.h>
+#if BASE_VER < 780000 // Android
#include <base/message_loop/message_loop.h>
+#endif // BASE_VER < 780000
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
+#if BASE_VER >= 780000 // CrOS
+#include <base/task/single_thread_task_executor.h>
+#endif // BASE_VER >= 780000
#include <base/time/time.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
@@ -364,7 +369,7 @@
HttpServer* CreateServer() override { return new NullHttpServer; }
private:
- test_utils::ScopedTempFile temp_file_{"ue_file_fetcher.XXXXXX"};
+ ScopedTempFile temp_file_{"ue_file_fetcher.XXXXXX"};
};
class MultiRangeHttpFetcherOverFileFetcherTest : public FileFetcherTest {
@@ -403,8 +408,13 @@
template <typename T>
class HttpFetcherTest : public ::testing::Test {
public:
+#if BASE_VER < 780000 // Android
base::MessageLoopForIO base_loop_;
brillo::BaseMessageLoop loop_{&base_loop_};
+#else // Chrome OS
+ base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
+ brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
+#endif // BASE_VER < 780000
T test_;
diff --git a/logging.h b/common/logging.h
similarity index 100%
rename from logging.h
rename to common/logging.h
diff --git a/metrics_constants.h b/common/metrics_constants.h
similarity index 95%
rename from metrics_constants.h
rename to common/metrics_constants.h
index db21d90..b7633b9 100644
--- a/metrics_constants.h
+++ b/common/metrics_constants.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_METRICS_CONSTANTS_H_
-#define UPDATE_ENGINE_METRICS_CONSTANTS_H_
+#ifndef UPDATE_ENGINE_COMMON_METRICS_CONSTANTS_H_
+#define UPDATE_ENGINE_COMMON_METRICS_CONSTANTS_H_
namespace chromeos_update_engine {
@@ -106,7 +106,7 @@
kUpdateCanceled, // Update canceled by the user.
kUpdateSucceededNotActive, // Update succeeded but the new slot is not
// active.
-
+ kUpdateSkipped, // Current update skipped.
kNumConstants,
kUnset = -1
@@ -144,4 +144,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_METRICS_CONSTANTS_H_
+#endif // UPDATE_ENGINE_COMMON_METRICS_CONSTANTS_H_
diff --git a/metrics_reporter_interface.h b/common/metrics_reporter_interface.h
similarity index 96%
rename from metrics_reporter_interface.h
rename to common/metrics_reporter_interface.h
index 180a680..d7c5347 100644
--- a/metrics_reporter_interface.h
+++ b/common/metrics_reporter_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
-#define UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
+#ifndef UPDATE_ENGINE_COMMON_METRICS_REPORTER_INTERFACE_H_
+#define UPDATE_ENGINE_COMMON_METRICS_REPORTER_INTERFACE_H_
#include <memory>
#include <string>
@@ -24,8 +24,8 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/error_code.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/system_state.h"
namespace chromeos_update_engine {
@@ -244,4 +244,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
+#endif // UPDATE_ENGINE_COMMON_METRICS_REPORTER_INTERFACE_H_
diff --git a/metrics_reporter_stub.cc b/common/metrics_reporter_stub.cc
similarity index 93%
rename from metrics_reporter_stub.cc
rename to common/metrics_reporter_stub.cc
index 81664a5..dcb4e8c 100644
--- a/metrics_reporter_stub.cc
+++ b/common/metrics_reporter_stub.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/metrics_reporter_stub.h"
+#include "update_engine/common/metrics_reporter_stub.h"
#include <memory>
diff --git a/metrics_reporter_stub.h b/common/metrics_reporter_stub.h
similarity index 92%
rename from metrics_reporter_stub.h
rename to common/metrics_reporter_stub.h
index 0cfeea0..1470aaa 100644
--- a/metrics_reporter_stub.h
+++ b/common/metrics_reporter_stub.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_METRICS_REPORTER_STUB_H_
-#define UPDATE_ENGINE_METRICS_REPORTER_STUB_H_
+#ifndef UPDATE_ENGINE_COMMON_METRICS_REPORTER_STUB_H_
+#define UPDATE_ENGINE_COMMON_METRICS_REPORTER_STUB_H_
#include <string>
#include "update_engine/common/error_code.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/metrics_reporter_interface.h"
namespace chromeos_update_engine {
@@ -98,4 +98,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_METRICS_REPORTER_STUB_H_
+#endif // UPDATE_ENGINE_COMMON_METRICS_REPORTER_STUB_H_
diff --git a/payload_consumer/mock_download_action.h b/common/mock_download_action.h
similarity index 81%
rename from payload_consumer/mock_download_action.h
rename to common/mock_download_action.h
index 3abb809..ecda9a3 100644
--- a/payload_consumer/mock_download_action.h
+++ b/common/mock_download_action.h
@@ -14,15 +14,15 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_
-#define UPDATE_ENGINE_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_DOWNLOAD_ACTION_H_
+#define UPDATE_ENGINE_COMMON_MOCK_DOWNLOAD_ACTION_H_
#include <stdint.h>
#include <gmock/gmock.h>
+#include "update_engine/common/download_action.h"
#include "update_engine/common/error_code.h"
-#include "update_engine/payload_consumer/download_action.h"
namespace chromeos_update_engine {
@@ -38,4 +38,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_MOCK_DOWNLOAD_ACTION_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_DOWNLOAD_ACTION_H_
diff --git a/common/mock_excluder.h b/common/mock_excluder.h
index bc54772..560ba0d 100644
--- a/common/mock_excluder.h
+++ b/common/mock_excluder.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_APP_EXCLUDER_H_
-#define UPDATE_ENGINE_MOCK_APP_EXCLUDER_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_APP_EXCLUDER_H_
+#define UPDATE_ENGINE_COMMON_MOCK_APP_EXCLUDER_H_
#include "update_engine/common/excluder_interface.h"
@@ -34,4 +34,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_APP_EXCLUDER_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_APP_EXCLUDER_H_
diff --git a/common/mock_hardware.h b/common/mock_hardware.h
index 84c0c5b..071906b 100644
--- a/common/mock_hardware.h
+++ b/common/mock_hardware.h
@@ -45,11 +45,6 @@
ON_CALL(*this, GetHardwareClass())
.WillByDefault(
testing::Invoke(&fake_, &FakeHardware::GetHardwareClass));
- ON_CALL(*this, GetFirmwareVersion())
- .WillByDefault(
- testing::Invoke(&fake_, &FakeHardware::GetFirmwareVersion));
- ON_CALL(*this, GetECVersion())
- .WillByDefault(testing::Invoke(&fake_, &FakeHardware::GetECVersion));
ON_CALL(*this, GetMinKernelKeyVersion())
.WillByDefault(
testing::Invoke(&fake_, &FakeHardware::GetMinKernelKeyVersion));
@@ -90,8 +85,6 @@
MOCK_CONST_METHOD0(IsOOBEEnabled, bool());
MOCK_CONST_METHOD1(IsOOBEComplete, bool(base::Time* out_time_of_oobe));
MOCK_CONST_METHOD0(GetHardwareClass, std::string());
- MOCK_CONST_METHOD0(GetFirmwareVersion, std::string());
- MOCK_CONST_METHOD0(GetECVersion, std::string());
MOCK_CONST_METHOD0(GetMinKernelKeyVersion, int());
MOCK_CONST_METHOD0(GetMinFirmwareKeyVersion, int());
MOCK_CONST_METHOD0(GetMaxFirmwareKeyRollforward, int());
diff --git a/mock_metrics_reporter.h b/common/mock_metrics_reporter.h
similarity index 93%
rename from mock_metrics_reporter.h
rename to common/mock_metrics_reporter.h
index baf3a78..922d1ee 100644
--- a/mock_metrics_reporter.h
+++ b/common/mock_metrics_reporter.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_METRICS_REPORTER_H_
-#define UPDATE_ENGINE_MOCK_METRICS_REPORTER_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_METRICS_REPORTER_H_
+#define UPDATE_ENGINE_COMMON_MOCK_METRICS_REPORTER_H_
#include <string>
#include <gmock/gmock.h>
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
namespace chromeos_update_engine {
@@ -96,4 +96,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_METRICS_REPORTER_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_METRICS_REPORTER_H_
diff --git a/mock_service_observer.h b/common/mock_service_observer.h
similarity index 81%
rename from mock_service_observer.h
rename to common/mock_service_observer.h
index e434eab..2c895f9 100644
--- a/mock_service_observer.h
+++ b/common/mock_service_observer.h
@@ -14,11 +14,11 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_SERVICE_OBSERVER_H_
-#define UPDATE_ENGINE_MOCK_SERVICE_OBSERVER_H_
+#ifndef UPDATE_ENGINE_COMMON_MOCK_SERVICE_OBSERVER_H_
+#define UPDATE_ENGINE_COMMON_MOCK_SERVICE_OBSERVER_H_
#include <gmock/gmock.h>
-#include "update_engine/service_observer_interface.h"
+#include "update_engine/common/service_observer_interface.h"
namespace chromeos_update_engine {
@@ -32,4 +32,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_SERVICE_OBSERVER_H_
+#endif // UPDATE_ENGINE_COMMON_MOCK_SERVICE_OBSERVER_H_
diff --git a/network_selector.h b/common/network_selector.h
similarity index 80%
rename from network_selector.h
rename to common/network_selector.h
index 22aed8e..bfc09c5 100644
--- a/network_selector.h
+++ b/common/network_selector.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_H_
-#define UPDATE_ENGINE_NETWORK_SELECTOR_H_
+#ifndef UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_H_
+#define UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_H_
#include <memory>
-#include "update_engine/network_selector_interface.h"
+#include "update_engine/common/network_selector_interface.h"
namespace chromeos_update_engine {
namespace network {
@@ -30,4 +30,4 @@
} // namespace network
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_NETWORK_SELECTOR_H_
+#endif // UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_H_
diff --git a/network_selector_interface.h b/common/network_selector_interface.h
similarity index 88%
rename from network_selector_interface.h
rename to common/network_selector_interface.h
index bd0948f..42ce32e 100644
--- a/network_selector_interface.h
+++ b/common/network_selector_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
-#define UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
+#ifndef UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_INTERFACE_H_
+#define UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_INTERFACE_H_
#include <cstdint>
@@ -45,4 +45,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
+#endif // UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_INTERFACE_H_
diff --git a/network_selector_stub.cc b/common/network_selector_stub.cc
similarity index 87%
rename from network_selector_stub.cc
rename to common/network_selector_stub.cc
index 67925f4..24c0e25 100644
--- a/network_selector_stub.cc
+++ b/common/network_selector_stub.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/network_selector_stub.h"
+#include "update_engine/common/network_selector_stub.h"
#include <memory>
@@ -24,14 +24,14 @@
namespace network {
-// Factory defined in network_selector.h.
+// Factory defined in common/network_selector.h.
std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector() {
return std::make_unique<NetworkSelectorStub>();
}
} // namespace network
-// Defined in network_selector_interface.h.
+// Defined in common/network_selector_interface.h.
const NetworkId kDefaultNetworkId = 0;
bool NetworkSelectorStub::SetProcessNetwork(NetworkId network_id) {
diff --git a/network_selector_stub.h b/common/network_selector_stub.h
similarity index 81%
rename from network_selector_stub.h
rename to common/network_selector_stub.h
index b3f7b48..b32df91 100644
--- a/network_selector_stub.h
+++ b/common/network_selector_stub.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
-#define UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
+#ifndef UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_STUB_H_
+#define UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_STUB_H_
#include <base/macros.h>
-#include "update_engine/network_selector_interface.h"
+#include "update_engine/common/network_selector_interface.h"
namespace chromeos_update_engine {
@@ -37,4 +37,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
+#endif // UPDATE_ENGINE_COMMON_NETWORK_SELECTOR_STUB_H_
diff --git a/common/platform_constants.h b/common/platform_constants.h
index 243af69..c060133 100644
--- a/common/platform_constants.h
+++ b/common/platform_constants.h
@@ -58,6 +58,12 @@
// postinstall.
extern const char kPostinstallMountOptions[];
+#ifdef __ANDROID_RECOVERY__
+constexpr bool kIsRecovery = true;
+#else
+constexpr bool kIsRecovery = false;
+#endif
+
} // namespace constants
} // namespace chromeos_update_engine
diff --git a/service_observer_interface.h b/common/service_observer_interface.h
similarity index 88%
rename from service_observer_interface.h
rename to common/service_observer_interface.h
index 4edb0ac..c471231 100644
--- a/service_observer_interface.h
+++ b/common/service_observer_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_SERVICE_OBSERVER_INTERFACE_H_
-#define UPDATE_ENGINE_SERVICE_OBSERVER_INTERFACE_H_
+#ifndef UPDATE_ENGINE_COMMON_SERVICE_OBSERVER_INTERFACE_H_
+#define UPDATE_ENGINE_COMMON_SERVICE_OBSERVER_INTERFACE_H_
#include <memory>
#include <string>
@@ -43,4 +43,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_SERVICE_OBSERVER_INTERFACE_H_
+#endif // UPDATE_ENGINE_COMMON_SERVICE_OBSERVER_INTERFACE_H_
diff --git a/common/subprocess.h b/common/subprocess.h
index 179a5c5..2ed8b81 100644
--- a/common/subprocess.h
+++ b/common/subprocess.h
@@ -37,7 +37,7 @@
#include <brillo/process.h>
#include <brillo/process_reaper.h>
#endif // __CHROMEOS__
-#include <gtest/gtest_prod.h> // for FRIEND_TEST
+#include <gtest/gtest_prod.h>
// The Subprocess class is a singleton. It's used to spawn off a subprocess
// and get notified when the subprocess exits. The result of Exec() can
diff --git a/common/subprocess_unittest.cc b/common/subprocess_unittest.cc
index b4d068f..ff4158e 100644
--- a/common/subprocess_unittest.cc
+++ b/common/subprocess_unittest.cc
@@ -28,9 +28,14 @@
#include <base/bind.h>
#include <base/files/scoped_temp_dir.h>
#include <base/location.h>
+#if BASE_VER < 780000 // Android
#include <base/message_loop/message_loop.h>
+#endif // BASE_VER < 780000
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
+#if BASE_VER >= 780000 // Chrome OS
+#include <base/task/single_thread_task_executor.h>
+#endif // BASE_VER >= 780000
#include <base/time/time.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
@@ -70,8 +75,13 @@
subprocess_.Init(&async_signal_handler_);
}
+#if BASE_VER < 780000 // Android
base::MessageLoopForIO base_loop_;
brillo::BaseMessageLoop loop_{&base_loop_};
+#else // Chrome OS
+ base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
+ brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
+#endif // BASE_VER < 780000
brillo::AsynchronousSignalHandler async_signal_handler_;
Subprocess subprocess_;
unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;
diff --git a/system_state.h b/common/system_state.h
similarity index 96%
rename from system_state.h
rename to common/system_state.h
index f46cbcf..7a67046 100644
--- a/system_state.h
+++ b/common/system_state.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_SYSTEM_STATE_H_
-#define UPDATE_ENGINE_SYSTEM_STATE_H_
+#ifndef UPDATE_ENGINE_COMMON_SYSTEM_STATE_H_
+#define UPDATE_ENGINE_COMMON_SYSTEM_STATE_H_
namespace chromeos_update_manager {
@@ -117,4 +117,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_SYSTEM_STATE_H_
+#endif // UPDATE_ENGINE_COMMON_SYSTEM_STATE_H_
diff --git a/common/test_utils.h b/common/test_utils.h
index 63ea749..bb5a678 100644
--- a/common/test_utils.h
+++ b/common/test_utils.h
@@ -138,22 +138,6 @@
DISALLOW_COPY_AND_ASSIGN(ScopedLoopbackDeviceBinder);
};
-class ScopedTempFile {
- public:
- ScopedTempFile() : ScopedTempFile("update_engine_test_temp_file.XXXXXX") {}
-
- explicit ScopedTempFile(const std::string& pattern) {
- EXPECT_TRUE(utils::MakeTempFile(pattern, &path_, nullptr));
- unlinker_.reset(new ScopedPathUnlinker(path_));
- }
-
- const std::string& path() const { return path_; }
-
- private:
- std::string path_;
- std::unique_ptr<ScopedPathUnlinker> unlinker_;
-};
-
class ScopedLoopMounter {
public:
explicit ScopedLoopMounter(const std::string& file_path,
diff --git a/common/utils.cc b/common/utils.cc
index 5d76f3f..1ac42dc 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -112,27 +112,6 @@
namespace utils {
-string ParseECVersion(string input_line) {
- base::TrimWhitespaceASCII(input_line, base::TRIM_ALL, &input_line);
-
- // At this point we want to convert the format key=value pair from mosys to
- // a vector of key value pairs.
- vector<pair<string, string>> kv_pairs;
- if (base::SplitStringIntoKeyValuePairs(input_line, '=', ' ', &kv_pairs)) {
- for (const pair<string, string>& kv_pair : kv_pairs) {
- // Finally match against the fw_verion which may have quotes.
- if (kv_pair.first == "fw_version") {
- string output;
- // Trim any quotes.
- base::TrimString(kv_pair.second, "\"", &output);
- return output;
- }
- }
- }
- LOG(ERROR) << "Unable to parse fwid from ec info.";
- return "";
-}
-
bool WriteFile(const char* path, const void* data, size_t data_len) {
int fd = HANDLE_EINTR(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600));
TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
@@ -213,10 +192,10 @@
return true;
}
-bool PWriteAll(const FileDescriptorPtr& fd,
- const void* buf,
- size_t count,
- off_t offset) {
+bool WriteAll(const FileDescriptorPtr& fd,
+ const void* buf,
+ size_t count,
+ off_t offset) {
TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(offset, SEEK_SET) !=
static_cast<off_t>(-1));
return WriteAll(fd, buf, count);
@@ -239,11 +218,11 @@
return true;
}
-bool PReadAll(const FileDescriptorPtr& fd,
- void* buf,
- size_t count,
- off_t offset,
- ssize_t* out_bytes_read) {
+bool ReadAll(const FileDescriptorPtr& fd,
+ void* buf,
+ size_t count,
+ off_t offset,
+ ssize_t* out_bytes_read) {
TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(offset, SEEK_SET) !=
static_cast<off_t>(-1));
char* c_buf = static_cast<char*>(buf);
@@ -260,6 +239,31 @@
return true;
}
+bool PReadAll(const FileDescriptorPtr& fd,
+ void* buf,
+ size_t count,
+ off_t offset,
+ ssize_t* out_bytes_read) {
+ auto old_off = fd->Seek(0, SEEK_CUR);
+ TEST_AND_RETURN_FALSE_ERRNO(old_off >= 0);
+
+ auto success = ReadAll(fd, buf, count, offset, out_bytes_read);
+ TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(old_off, SEEK_SET) == old_off);
+ return success;
+}
+
+bool PWriteAll(const FileDescriptorPtr& fd,
+ const void* buf,
+ size_t count,
+ off_t offset) {
+ auto old_off = fd->Seek(0, SEEK_CUR);
+ TEST_AND_RETURN_FALSE_ERRNO(old_off >= 0);
+
+ auto success = WriteAll(fd, buf, count, offset);
+ TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(old_off, SEEK_SET) == old_off);
+ return success;
+}
+
// Append |nbytes| of content from |buf| to the vector pointed to by either
// |vec_p| or |str_p|.
static void AppendBytes(const uint8_t* buf,
@@ -911,6 +915,25 @@
return true;
}
+bool GetVpdValue(string key, string* result) {
+ int exit_code = 0;
+ string value, error;
+ vector<string> cmd = {"vpd_get_value", key};
+ if (!chromeos_update_engine::Subprocess::SynchronousExec(
+ cmd, &exit_code, &value, &error) ||
+ exit_code) {
+ LOG(ERROR) << "Failed to get vpd key for " << value
+ << " with exit code: " << exit_code << " and error: " << error;
+ return false;
+ } else if (!error.empty()) {
+ LOG(INFO) << "vpd_get_value succeeded but with following errors: " << error;
+ }
+
+ base::TrimWhitespaceASCII(value, base::TRIM_ALL, &value);
+ *result = value;
+ return true;
+}
+
bool GetBootId(string* boot_id) {
TEST_AND_RETURN_FALSE(
base::ReadFileToString(base::FilePath(kBootIdPath), boot_id));
diff --git a/common/utils.h b/common/utils.h
index 0a1dc0c..616de06 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -18,6 +18,7 @@
#define UPDATE_ENGINE_COMMON_UTILS_H_
#include <errno.h>
+#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@@ -53,10 +54,6 @@
std::string CalculateP2PFileId(const brillo::Blob& payload_hash,
size_t payload_size);
-// Parse the firmware version from one line of output from the
-// "mosys" command.
-std::string ParseECVersion(std::string input_line);
-
// Writes the data passed to path. The file at path will be overwritten if it
// exists. Returns true on success, false otherwise.
bool WriteFile(const char* path, const void* data, size_t data_len);
@@ -67,6 +64,15 @@
bool PWriteAll(int fd, const void* buf, size_t count, off_t offset);
bool WriteAll(const FileDescriptorPtr& fd, const void* buf, size_t count);
+// WriteAll writes data at specified offset, but it modifies file position.
+bool WriteAll(const FileDescriptorPtr& fd,
+ const void* buf,
+ size_t count,
+ off_t off);
+
+// https://man7.org/linux/man-pages/man2/pread.2.html
+// PWriteAll writes data at specified offset, but it DOES NOT modify file
+// position. Behaves similar to linux' pwrite syscall.
bool PWriteAll(const FileDescriptorPtr& fd,
const void* buf,
size_t count,
@@ -85,6 +91,16 @@
bool PReadAll(
int fd, void* buf, size_t count, off_t offset, ssize_t* out_bytes_read);
+// Reads data at specified offset, this function does change file position.
+bool ReadAll(const FileDescriptorPtr& fd,
+ void* buf,
+ size_t count,
+ off_t offset,
+ ssize_t* out_bytes_read);
+
+// https://man7.org/linux/man-pages/man2/pread.2.html
+// Reads data at specified offset, this function DOES NOT change file position.
+// Behavior is similar to linux's pread syscall.
bool PReadAll(const FileDescriptorPtr& fd,
void* buf,
size_t count,
@@ -292,6 +308,10 @@
// reboot. Returns whether it succeeded getting the boot_id.
bool GetBootId(std::string* boot_id);
+// Gets a string value from the vpd for a given key using the `vpd_get_value`
+// shell command. Returns true on success.
+bool GetVpdValue(std::string key, std::string* result);
+
// This function gets the file path of the file pointed to by FileDiscriptor.
std::string GetFilePath(int fd);
@@ -370,6 +390,42 @@
DISALLOW_COPY_AND_ASSIGN(ScopedPathUnlinker);
};
+class ScopedTempFile {
+ public:
+ ScopedTempFile() : ScopedTempFile("update_engine_temp.XXXXXX") {}
+
+ // If |open_fd| is true, a writable file descriptor will be opened for this
+ // file.
+ explicit ScopedTempFile(const std::string& pattern, bool open_fd = false) {
+ CHECK(utils::MakeTempFile(pattern, &path_, open_fd ? &fd_ : nullptr));
+ unlinker_.reset(new ScopedPathUnlinker(path_));
+ if (open_fd) {
+ CHECK_GE(fd_, 0);
+ fd_closer_.reset(new ScopedFdCloser(&fd_));
+ }
+ }
+ virtual ~ScopedTempFile() = default;
+
+ const std::string& path() const { return path_; }
+ int fd() const {
+ CHECK(fd_closer_);
+ return fd_;
+ }
+ void CloseFd() {
+ CHECK(fd_closer_);
+ fd_closer_.reset();
+ }
+
+ private:
+ std::string path_;
+ std::unique_ptr<ScopedPathUnlinker> unlinker_;
+
+ int fd_{-1};
+ std::unique_ptr<ScopedFdCloser> fd_closer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedTempFile);
+};
+
// A little object to call ActionComplete on the ActionProcessor when
// it's destructed.
class ScopedActionCompleter {
diff --git a/common/utils_unittest.cc b/common/utils_unittest.cc
index d73b3da..20c6b84 100644
--- a/common/utils_unittest.cc
+++ b/common/utils_unittest.cc
@@ -41,25 +41,12 @@
class UtilsTest : public ::testing::Test {};
-TEST(UtilsTest, CanParseECVersion) {
- // Should be able to parse and valid key value line.
- EXPECT_EQ("12345", utils::ParseECVersion("fw_version=12345"));
- EXPECT_EQ("123456",
- utils::ParseECVersion("b=1231a fw_version=123456 a=fasd2"));
- EXPECT_EQ("12345", utils::ParseECVersion("fw_version=12345"));
- EXPECT_EQ("00VFA616",
- utils::ParseECVersion("vendor=\"sam\" fw_version=\"00VFA616\""));
-
- // For invalid entries, should return the empty string.
- EXPECT_EQ("", utils::ParseECVersion("b=1231a fw_version a=fasd2"));
-}
-
TEST(UtilsTest, WriteFileOpenFailure) {
EXPECT_FALSE(utils::WriteFile("/this/doesn't/exist", "hello", 5));
}
TEST(UtilsTest, WriteFileReadFile) {
- test_utils::ScopedTempFile file;
+ ScopedTempFile file;
EXPECT_TRUE(utils::WriteFile(file.path().c_str(), "hello", 5));
brillo::Blob readback;
@@ -73,7 +60,7 @@
}
TEST(UtilsTest, ReadFileChunk) {
- test_utils::ScopedTempFile file;
+ ScopedTempFile file;
brillo::Blob data;
const size_t kSize = 1024 * 1024;
for (size_t i = 0; i < kSize; i++) {
@@ -162,7 +149,7 @@
namespace {
void GetFileFormatTester(const string& expected,
const vector<uint8_t>& contents) {
- test_utils::ScopedTempFile file;
+ ScopedTempFile file;
ASSERT_TRUE(utils::WriteFile(file.path().c_str(),
reinterpret_cast<const char*>(contents.data()),
contents.size()));
@@ -391,7 +378,7 @@
}
TEST(UtilsTest, RunAsRootUnmountFilesystemBusyFailureTest) {
- test_utils::ScopedTempFile tmp_image("img.XXXXXX");
+ ScopedTempFile tmp_image("img.XXXXXX");
EXPECT_TRUE(base::CopyFile(
test_utils::GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
@@ -431,7 +418,7 @@
EXPECT_TRUE(mnt_dir.CreateUniqueTempDir());
EXPECT_FALSE(utils::IsMountpoint(mnt_dir.GetPath().value()));
- test_utils::ScopedTempFile file;
+ ScopedTempFile file;
EXPECT_FALSE(utils::IsMountpoint(file.path()));
}
@@ -473,7 +460,7 @@
}
TEST(UtilsTest, GetFilePathTest) {
- test_utils::ScopedTempFile file;
+ ScopedTempFile file;
int fd = HANDLE_EINTR(open(file.path().c_str(), O_RDONLY));
EXPECT_GE(fd, 0);
EXPECT_EQ(file.path(), utils::GetFilePath(fd));
diff --git a/connection_manager_android.cc b/connection_manager_android.cc
deleted file mode 100644
index 9d0c57b..0000000
--- a/connection_manager_android.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/connection_manager_android.h"
-
-#include <memory>
-
-namespace chromeos_update_engine {
-
-namespace connection_manager {
-std::unique_ptr<ConnectionManagerInterface> CreateConnectionManager(
- SystemState* system_state) {
- return std::unique_ptr<ConnectionManagerInterface>(
- new ConnectionManagerAndroid());
-}
-} // namespace connection_manager
-
-bool ConnectionManagerAndroid::GetConnectionProperties(
- ConnectionType* out_type, ConnectionTethering* out_tethering) {
- return false;
-}
-bool ConnectionManagerAndroid::IsUpdateAllowedOver(
- ConnectionType type, ConnectionTethering tethering) const {
- return true;
-}
-bool ConnectionManagerAndroid::IsAllowedConnectionTypesForUpdateSet() const {
- return false;
-}
-
-} // namespace chromeos_update_engine
diff --git a/connection_manager_android.h b/connection_manager_android.h
deleted file mode 100644
index 006f4ea..0000000
--- a/connection_manager_android.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_CONNECTION_MANAGER_ANDROID_H_
-#define UPDATE_ENGINE_CONNECTION_MANAGER_ANDROID_H_
-
-#include <base/macros.h>
-
-#include "update_engine/connection_manager_interface.h"
-
-namespace chromeos_update_engine {
-
-// TODO(senj): Remove this class and use ShillProvider from the UpdateManager.
-class ConnectionManagerAndroid : public ConnectionManagerInterface {
- public:
- ConnectionManagerAndroid() = default;
- ~ConnectionManagerAndroid() override = default;
-
- // ConnectionManagerInterface overrides.
- bool GetConnectionProperties(ConnectionType* out_type,
- ConnectionTethering* out_tethering) override;
- bool IsUpdateAllowedOver(ConnectionType type,
- ConnectionTethering tethering) const override;
- bool IsAllowedConnectionTypesForUpdateSet() const override;
-
- DISALLOW_COPY_AND_ASSIGN(ConnectionManagerAndroid);
-};
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_CONNECTION_MANAGER_ANDROID_H_
diff --git a/boot_control_chromeos.cc b/cros/boot_control_chromeos.cc
similarity index 97%
rename from boot_control_chromeos.cc
rename to cros/boot_control_chromeos.cc
index 95456f0..17659ae 100644
--- a/boot_control_chromeos.cc
+++ b/cros/boot_control_chromeos.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/boot_control_chromeos.h"
+#include "update_engine/cros/boot_control_chromeos.h"
#include <memory>
#include <string>
@@ -128,8 +128,9 @@
}
if (current_slot_ >= num_slots_) {
LOG(ERROR) << "Couldn't find the slot number corresponding to the "
- << "partition " << boot_device << ", number of slots: "
- << num_slots_ << ". This device is not updateable.";
+ << "partition " << boot_device
+ << ", number of slots: " << num_slots_
+ << ". This device is not updateable.";
num_slots_ = 1;
current_slot_ = BootControlInterface::kInvalidSlot;
return false;
diff --git a/boot_control_chromeos.h b/cros/boot_control_chromeos.h
similarity index 96%
rename from boot_control_chromeos.h
rename to cros/boot_control_chromeos.h
index 4271672..0dff2c0 100644
--- a/boot_control_chromeos.h
+++ b/cros/boot_control_chromeos.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_BOOT_CONTROL_CHROMEOS_H_
-#define UPDATE_ENGINE_BOOT_CONTROL_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_BOOT_CONTROL_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_BOOT_CONTROL_CHROMEOS_H_
#include <memory>
#include <string>
@@ -101,4 +101,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_BOOT_CONTROL_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_BOOT_CONTROL_CHROMEOS_H_
diff --git a/boot_control_chromeos_unittest.cc b/cros/boot_control_chromeos_unittest.cc
similarity index 97%
rename from boot_control_chromeos_unittest.cc
rename to cros/boot_control_chromeos_unittest.cc
index 1c40dce..fc1dd1e 100644
--- a/boot_control_chromeos_unittest.cc
+++ b/cros/boot_control_chromeos_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/boot_control_chromeos.h"
+#include "update_engine/cros/boot_control_chromeos.h"
#include <gtest/gtest.h>
diff --git a/chrome_browser_proxy_resolver.cc b/cros/chrome_browser_proxy_resolver.cc
similarity index 94%
rename from chrome_browser_proxy_resolver.cc
rename to cros/chrome_browser_proxy_resolver.cc
index bfb58f7..3ea8a9b 100644
--- a/chrome_browser_proxy_resolver.cc
+++ b/cros/chrome_browser_proxy_resolver.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/chrome_browser_proxy_resolver.h"
+#include "update_engine/cros/chrome_browser_proxy_resolver.h"
#include <utility>
@@ -23,7 +23,7 @@
#include <base/strings/string_util.h>
#include <brillo/http/http_proxy.h>
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
namespace chromeos_update_engine {
diff --git a/chrome_browser_proxy_resolver.h b/cros/chrome_browser_proxy_resolver.h
similarity index 91%
rename from chrome_browser_proxy_resolver.h
rename to cros/chrome_browser_proxy_resolver.h
index 10a55fb..76848ef 100644
--- a/chrome_browser_proxy_resolver.h
+++ b/cros/chrome_browser_proxy_resolver.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CHROME_BROWSER_PROXY_RESOLVER_H_
-#define UPDATE_ENGINE_CHROME_BROWSER_PROXY_RESOLVER_H_
+#ifndef UPDATE_ENGINE_CROS_CHROME_BROWSER_PROXY_RESOLVER_H_
+#define UPDATE_ENGINE_CROS_CHROME_BROWSER_PROXY_RESOLVER_H_
#include <deque>
#include <map>
@@ -63,4 +63,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CHROME_BROWSER_PROXY_RESOLVER_H_
+#endif // UPDATE_ENGINE_CROS_CHROME_BROWSER_PROXY_RESOLVER_H_
diff --git a/common_service.cc b/cros/common_service.cc
similarity index 97%
rename from common_service.cc
rename to cros/common_service.cc
index 85fb9e4..aecad8b 100644
--- a/common_service.cc
+++ b/cros/common_service.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/common_service.h"
+#include "update_engine/cros/common_service.h"
#include <string>
@@ -30,12 +30,12 @@
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/omaha_utils.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/payload_state_interface.h"
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/omaha_utils.h"
+#include "update_engine/cros/p2p_manager.h"
+#include "update_engine/cros/payload_state_interface.h"
+#include "update_engine/cros/update_attempter.h"
using base::StringPrintf;
using brillo::ErrorPtr;
diff --git a/common_service.h b/cros/common_service.h
similarity index 97%
rename from common_service.h
rename to cros/common_service.h
index cfcece5..6169d9c 100644
--- a/common_service.h
+++ b/cros/common_service.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_COMMON_SERVICE_H_
-#define UPDATE_ENGINE_COMMON_SERVICE_H_
+#ifndef UPDATE_ENGINE_CROS_SERVICE_H_
+#define UPDATE_ENGINE_CROS_SERVICE_H_
#include <inttypes.h>
@@ -26,7 +26,7 @@
#include <brillo/errors/error.h>
#include "update_engine/client_library/include/update_engine/update_status.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
namespace chromeos_update_engine {
@@ -167,4 +167,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_COMMON_SERVICE_H_
+#endif // UPDATE_ENGINE_CROS_SERVICE_H_
diff --git a/common_service_unittest.cc b/cros/common_service_unittest.cc
similarity index 97%
rename from common_service_unittest.cc
rename to cros/common_service_unittest.cc
index 3dc8a22..733ec0a 100644
--- a/common_service_unittest.cc
+++ b/cros/common_service_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/common_service.h"
+#include "update_engine/cros/common_service.h"
#include <gtest/gtest.h>
#include <string>
@@ -25,8 +25,8 @@
#include <policy/mock_device_policy.h>
#include "update_engine/common/fake_prefs.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/omaha_utils.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/omaha_utils.h"
using std::string;
using std::vector;
diff --git a/connection_manager.cc b/cros/connection_manager.cc
similarity index 96%
rename from connection_manager.cc
rename to cros/connection_manager.cc
index fe43f37..331f76b 100644
--- a/connection_manager.cc
+++ b/cros/connection_manager.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/connection_manager.h"
+#include "update_engine/cros/connection_manager.h"
#include <memory>
#include <set>
@@ -26,12 +26,12 @@
#include <shill/dbus-constants.h>
#include <shill/dbus-proxies.h>
+#include "update_engine/common/connection_utils.h"
#include "update_engine/common/prefs.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_utils.h"
-#include "update_engine/shill_proxy.h"
-#include "update_engine/system_state.h"
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/shill_proxy.h"
+#include "update_engine/cros/update_attempter.h"
using org::chromium::flimflam::ManagerProxyInterface;
using org::chromium::flimflam::ServiceProxyInterface;
diff --git a/connection_manager.h b/cros/connection_manager.h
similarity index 89%
rename from connection_manager.h
rename to cros/connection_manager.h
index d8527a3..b1fb961 100644
--- a/connection_manager.h
+++ b/cros/connection_manager.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CONNECTION_MANAGER_H_
-#define UPDATE_ENGINE_CONNECTION_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_CONNECTION_MANAGER_H_
+#define UPDATE_ENGINE_CROS_CONNECTION_MANAGER_H_
#include <memory>
#include <string>
@@ -23,8 +23,8 @@
#include <base/macros.h>
#include <dbus/object_path.h>
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/shill_proxy_interface.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/shill_proxy_interface.h"
namespace chromeos_update_engine {
@@ -66,4 +66,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CONNECTION_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_CONNECTION_MANAGER_H_
diff --git a/connection_manager_interface.h b/cros/connection_manager_interface.h
similarity index 90%
rename from connection_manager_interface.h
rename to cros/connection_manager_interface.h
index 9f77989..6dd9fbd 100644
--- a/connection_manager_interface.h
+++ b/cros/connection_manager_interface.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CONNECTION_MANAGER_INTERFACE_H_
-#define UPDATE_ENGINE_CONNECTION_MANAGER_INTERFACE_H_
+#ifndef UPDATE_ENGINE_CROS_CONNECTION_MANAGER_INTERFACE_H_
+#define UPDATE_ENGINE_CROS_CONNECTION_MANAGER_INTERFACE_H_
#include <memory>
#include <base/macros.h>
-#include "update_engine/connection_utils.h"
+#include "update_engine/common/connection_utils.h"
namespace chromeos_update_engine {
@@ -65,4 +65,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_CONNECTION_MANAGER_INTERFACE_H_
+#endif // UPDATE_ENGINE_CROS_CONNECTION_MANAGER_INTERFACE_H_
diff --git a/connection_manager_unittest.cc b/cros/connection_manager_unittest.cc
similarity index 98%
rename from connection_manager_unittest.cc
rename to cros/connection_manager_unittest.cc
index 97436c9..3f1ee5a 100644
--- a/connection_manager_unittest.cc
+++ b/cros/connection_manager_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/connection_manager.h"
+#include "update_engine/cros/connection_manager.h"
#include <memory>
#include <set>
@@ -32,8 +32,8 @@
#include <shill/dbus-proxy-mocks.h>
#include "update_engine/common/test_utils.h"
-#include "update_engine/fake_shill_proxy.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_shill_proxy.h"
+#include "update_engine/cros/fake_system_state.h"
using chromeos_update_engine::connection_utils::StringForConnectionType;
using org::chromium::flimflam::ManagerProxyMock;
diff --git a/daemon_chromeos.cc b/cros/daemon_chromeos.cc
similarity index 95%
rename from daemon_chromeos.cc
rename to cros/daemon_chromeos.cc
index 21740d8..a7cad8c 100644
--- a/daemon_chromeos.cc
+++ b/cros/daemon_chromeos.cc
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#include "update_engine/daemon_chromeos.h"
+#include "update_engine/cros/daemon_chromeos.h"
#include <sysexits.h>
#include <base/bind.h>
#include <base/location.h>
-#include "update_engine/real_system_state.h"
+#include "update_engine/cros/real_system_state.h"
using brillo::Daemon;
using std::unique_ptr;
diff --git a/daemon_chromeos.h b/cros/daemon_chromeos.h
similarity index 84%
rename from daemon_chromeos.h
rename to cros/daemon_chromeos.h
index 657e797..5d568c7 100644
--- a/daemon_chromeos.h
+++ b/cros/daemon_chromeos.h
@@ -14,15 +14,15 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DAEMON_CHROMEOS_H_
-#define UPDATE_ENGINE_DAEMON_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_DAEMON_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_DAEMON_CHROMEOS_H_
#include <memory>
+#include "update_engine/common/daemon_base.h"
+#include "update_engine/common/daemon_state_interface.h"
#include "update_engine/common/subprocess.h"
-#include "update_engine/daemon_base.h"
-#include "update_engine/daemon_state_interface.h"
-#include "update_engine/dbus_service.h"
+#include "update_engine/cros/dbus_service.h"
namespace chromeos_update_engine {
@@ -56,4 +56,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DAEMON_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_DAEMON_CHROMEOS_H_
diff --git a/dbus_connection.cc b/cros/dbus_connection.cc
similarity index 96%
rename from dbus_connection.cc
rename to cros/dbus_connection.cc
index cf17ec9..6808bae 100644
--- a/dbus_connection.cc
+++ b/cros/dbus_connection.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
#include <base/time/time.h>
diff --git a/dbus_connection.h b/cros/dbus_connection.h
similarity index 87%
rename from dbus_connection.h
rename to cros/dbus_connection.h
index c3205ba..8f0d6f1 100644
--- a/dbus_connection.h
+++ b/cros/dbus_connection.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DBUS_CONNECTION_H_
-#define UPDATE_ENGINE_DBUS_CONNECTION_H_
+#ifndef UPDATE_ENGINE_CROS_DBUS_CONNECTION_H_
+#define UPDATE_ENGINE_CROS_DBUS_CONNECTION_H_
#include <base/memory/ref_counted.h>
#include <brillo/dbus/dbus_connection.h>
@@ -41,4 +41,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DBUS_CONNECTION_H_
+#endif // UPDATE_ENGINE_CROS_DBUS_CONNECTION_H_
diff --git a/dbus_service.cc b/cros/dbus_service.cc
similarity index 98%
rename from dbus_service.cc
rename to cros/dbus_service.cc
index a282d1e..d115195 100644
--- a/dbus_service.cc
+++ b/cros/dbus_service.cc
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#include "update_engine/dbus_service.h"
+#include "update_engine/cros/dbus_service.h"
#include <string>
#include <vector>
#include <update_engine/dbus-constants.h>
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
#include "update_engine/proto_bindings/update_engine.pb.h"
#include "update_engine/update_status_utils.h"
diff --git a/dbus_service.h b/cros/dbus_service.h
similarity index 96%
rename from dbus_service.h
rename to cros/dbus_service.h
index 873909e..9e4457f 100644
--- a/dbus_service.h
+++ b/cros/dbus_service.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DBUS_SERVICE_H_
-#define UPDATE_ENGINE_DBUS_SERVICE_H_
+#ifndef UPDATE_ENGINE_CROS_DBUS_SERVICE_H_
+#define UPDATE_ENGINE_CROS_DBUS_SERVICE_H_
#include <inttypes.h>
@@ -27,9 +27,9 @@
#include <brillo/errors/error.h>
#include <update_engine/proto_bindings/update_engine.pb.h>
-#include "update_engine/common_service.h"
-#include "update_engine/service_observer_interface.h"
-#include "update_engine/update_attempter.h"
+#include "update_engine/common/service_observer_interface.h"
+#include "update_engine/cros/common_service.h"
+#include "update_engine/cros/update_attempter.h"
#include "dbus_bindings/org.chromium.UpdateEngineInterface.h"
@@ -191,4 +191,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DBUS_SERVICE_H_
+#endif // UPDATE_ENGINE_CROS_DBUS_SERVICE_H_
diff --git a/dbus_test_utils.h b/cros/dbus_test_utils.h
similarity index 95%
rename from dbus_test_utils.h
rename to cros/dbus_test_utils.h
index 72fd4e0..1116c52 100644
--- a/dbus_test_utils.h
+++ b/cros/dbus_test_utils.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DBUS_TEST_UTILS_H_
-#define UPDATE_ENGINE_DBUS_TEST_UTILS_H_
+#ifndef UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_
+#define UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_
#include <memory>
#include <set>
@@ -88,4 +88,4 @@
} // namespace dbus_test_utils
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DBUS_TEST_UTILS_H_
+#endif // UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_
diff --git a/dlcservice_chromeos.cc b/cros/dlcservice_chromeos.cc
similarity index 95%
rename from dlcservice_chromeos.cc
rename to cros/dlcservice_chromeos.cc
index 08482ee..e510c1d 100644
--- a/dlcservice_chromeos.cc
+++ b/cros/dlcservice_chromeos.cc
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#include "update_engine/dlcservice_chromeos.h"
+#include "update_engine/cros/dlcservice_chromeos.h"
#include <brillo/errors/error.h>
#include <dlcservice/proto_bindings/dlcservice.pb.h>
// NOLINTNEXTLINE(build/include_alpha) "dbus-proxies.h" needs "dlcservice.pb.h"
#include <dlcservice/dbus-proxies.h>
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
using std::string;
using std::vector;
diff --git a/dlcservice_chromeos.h b/cros/dlcservice_chromeos.h
similarity index 91%
rename from dlcservice_chromeos.h
rename to cros/dlcservice_chromeos.h
index 8828e1a..3f11b12 100644
--- a/dlcservice_chromeos.h
+++ b/cros/dlcservice_chromeos.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_DLCSERVICE_CHROMEOS_H_
-#define UPDATE_ENGINE_DLCSERVICE_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_DLCSERVICE_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_DLCSERVICE_CHROMEOS_H_
#include <memory>
#include <string>
@@ -52,4 +52,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_DLCSERVICE_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_DLCSERVICE_CHROMEOS_H_
diff --git a/excluder_chromeos.cc b/cros/excluder_chromeos.cc
similarity index 94%
rename from excluder_chromeos.cc
rename to cros/excluder_chromeos.cc
index bfd6f04..4796525 100644
--- a/excluder_chromeos.cc
+++ b/cros/excluder_chromeos.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/excluder_chromeos.h"
+#include "update_engine/cros/excluder_chromeos.h"
#include <memory>
#include <vector>
@@ -26,7 +26,7 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/prefs.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
using std::string;
using std::vector;
diff --git a/excluder_chromeos.h b/cros/excluder_chromeos.h
similarity index 90%
rename from excluder_chromeos.h
rename to cros/excluder_chromeos.h
index e4c1a52..2480066 100644
--- a/excluder_chromeos.h
+++ b/cros/excluder_chromeos.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_EXCLUDER_CHROMEOS_H_
-#define UPDATE_ENGINE_EXCLUDER_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_EXCLUDER_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_EXCLUDER_CHROMEOS_H_
#include <string>
@@ -49,4 +49,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_EXCLUDER_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_EXCLUDER_CHROMEOS_H_
diff --git a/excluder_chromeos_unittest.cc b/cros/excluder_chromeos_unittest.cc
similarity index 97%
rename from excluder_chromeos_unittest.cc
rename to cros/excluder_chromeos_unittest.cc
index dba77e4..3602e56 100644
--- a/excluder_chromeos_unittest.cc
+++ b/cros/excluder_chromeos_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/excluder_chromeos.h"
+#include "update_engine/cros/excluder_chromeos.h"
#include <memory>
diff --git a/fake_p2p_manager.h b/cros/fake_p2p_manager.h
similarity index 94%
rename from fake_p2p_manager.h
rename to cros/fake_p2p_manager.h
index 1f8ae95..1011b7e 100644
--- a/fake_p2p_manager.h
+++ b/cros/fake_p2p_manager.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_FAKE_P2P_MANAGER_H_
-#define UPDATE_ENGINE_FAKE_P2P_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_H_
+#define UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_H_
#include <string>
-#include "update_engine/p2p_manager.h"
+#include "update_engine/cros/p2p_manager.h"
namespace chromeos_update_engine {
@@ -109,4 +109,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_FAKE_P2P_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_H_
diff --git a/fake_p2p_manager_configuration.h b/cros/fake_p2p_manager_configuration.h
similarity index 93%
rename from fake_p2p_manager_configuration.h
rename to cros/fake_p2p_manager_configuration.h
index f5b0e80..8d50ac8 100644
--- a/fake_p2p_manager_configuration.h
+++ b/cros/fake_p2p_manager_configuration.h
@@ -14,10 +14,10 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_FAKE_P2P_MANAGER_CONFIGURATION_H_
-#define UPDATE_ENGINE_FAKE_P2P_MANAGER_CONFIGURATION_H_
+#ifndef UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_CONFIGURATION_H_
+#define UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_CONFIGURATION_H_
-#include "update_engine/p2p_manager.h"
+#include "update_engine/cros/p2p_manager.h"
#include <string>
#include <vector>
@@ -99,4 +99,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_FAKE_P2P_MANAGER_CONFIGURATION_H_
+#endif // UPDATE_ENGINE_CROS_FAKE_P2P_MANAGER_CONFIGURATION_H_
diff --git a/fake_shill_proxy.cc b/cros/fake_shill_proxy.cc
similarity index 96%
rename from fake_shill_proxy.cc
rename to cros/fake_shill_proxy.cc
index de96511..2d05a6b 100644
--- a/fake_shill_proxy.cc
+++ b/cros/fake_shill_proxy.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/fake_shill_proxy.h"
+#include "update_engine/cros/fake_shill_proxy.h"
#include <utility>
diff --git a/fake_shill_proxy.h b/cros/fake_shill_proxy.h
similarity index 90%
rename from fake_shill_proxy.h
rename to cros/fake_shill_proxy.h
index ae17eaa..8c15a9d 100644
--- a/fake_shill_proxy.h
+++ b/cros/fake_shill_proxy.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_FAKE_SHILL_PROXY_H_
-#define UPDATE_ENGINE_FAKE_SHILL_PROXY_H_
+#ifndef UPDATE_ENGINE_CROS_FAKE_SHILL_PROXY_H_
+#define UPDATE_ENGINE_CROS_FAKE_SHILL_PROXY_H_
#include <map>
#include <memory>
@@ -25,7 +25,7 @@
#include <shill/dbus-proxies.h>
#include <shill/dbus-proxy-mocks.h>
-#include "update_engine/shill_proxy_interface.h"
+#include "update_engine/cros/shill_proxy_interface.h"
namespace chromeos_update_engine {
@@ -63,4 +63,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_FAKE_SHILL_PROXY_H_
+#endif // UPDATE_ENGINE_CROS_FAKE_SHILL_PROXY_H_
diff --git a/fake_system_state.cc b/cros/fake_system_state.cc
similarity index 96%
rename from fake_system_state.cc
rename to cros/fake_system_state.cc
index 1bfcafa..9dfdc5b 100644
--- a/fake_system_state.cc
+++ b/cros/fake_system_state.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
namespace chromeos_update_engine {
diff --git a/fake_system_state.h b/cros/fake_system_state.h
similarity index 93%
rename from fake_system_state.h
rename to cros/fake_system_state.h
index 24b1eec..2f92b7c 100644
--- a/fake_system_state.h
+++ b/cros/fake_system_state.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_FAKE_SYSTEM_STATE_H_
-#define UPDATE_ENGINE_FAKE_SYSTEM_STATE_H_
+#ifndef UPDATE_ENGINE_CROS_FAKE_SYSTEM_STATE_H_
+#define UPDATE_ENGINE_CROS_FAKE_SYSTEM_STATE_H_
#include <base/logging.h>
#include <gmock/gmock.h>
@@ -25,15 +25,15 @@
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/mock_metrics_reporter.h"
#include "update_engine/common/mock_prefs.h"
-#include "update_engine/mock_connection_manager.h"
-#include "update_engine/mock_metrics_reporter.h"
-#include "update_engine/mock_omaha_request_params.h"
-#include "update_engine/mock_p2p_manager.h"
-#include "update_engine/mock_payload_state.h"
-#include "update_engine/mock_power_manager.h"
-#include "update_engine/mock_update_attempter.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/mock_connection_manager.h"
+#include "update_engine/cros/mock_omaha_request_params.h"
+#include "update_engine/cros/mock_p2p_manager.h"
+#include "update_engine/cros/mock_payload_state.h"
+#include "update_engine/cros/mock_power_manager.h"
+#include "update_engine/cros/mock_update_attempter.h"
#include "update_engine/update_manager/fake_update_manager.h"
namespace chromeos_update_engine {
@@ -278,4 +278,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_FAKE_SYSTEM_STATE_H_
+#endif // UPDATE_ENGINE_CROS_FAKE_SYSTEM_STATE_H_
diff --git a/hardware_chromeos.cc b/cros/hardware_chromeos.cc
similarity index 87%
rename from hardware_chromeos.cc
rename to cros/hardware_chromeos.cc
index 807e086..b9018ff 100644
--- a/hardware_chromeos.cc
+++ b/cros/hardware_chromeos.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/hardware_chromeos.h"
+#include "update_engine/cros/hardware_chromeos.h"
#include <utility>
@@ -37,7 +37,10 @@
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/common/utils.h"
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
+#if USE_CFM
+#include "update_engine/cros/requisition_util.h"
+#endif
using std::string;
using std::vector;
@@ -81,29 +84,6 @@
const char* kActivePingKey = "first_active_omaha_ping_sent";
-const char* kOemRequisitionKey = "oem_device_requisition";
-
-// Gets a string value from the vpd for a given key using the `vpd_get_value`
-// shell command. Returns true on success.
-int GetVpdValue(string key, string* result) {
- int exit_code = 0;
- string value, error;
- vector<string> cmd = {"vpd_get_value", key};
- if (!chromeos_update_engine::Subprocess::SynchronousExec(
- cmd, &exit_code, &value, &error) ||
- exit_code) {
- LOG(ERROR) << "Failed to get vpd key for " << value
- << " with exit code: " << exit_code << " and error: " << error;
- return false;
- } else if (!error.empty()) {
- LOG(INFO) << "vpd_get_value succeeded but with following errors: " << error;
- }
-
- base::TrimWhitespaceASCII(value, base::TRIM_ALL, &value);
- *result = value;
- return true;
-}
-
} // namespace
namespace chromeos_update_engine {
@@ -195,28 +175,13 @@
return ReadValueFromCrosSystem("hwid");
}
-string HardwareChromeOS::GetFirmwareVersion() const {
- return ReadValueFromCrosSystem("fwid");
-}
-
-string HardwareChromeOS::GetECVersion() const {
- string input_line, error;
- int exit_code = 0;
- vector<string> cmd = {"/usr/sbin/mosys", "-k", "ec", "info"};
-
- if (!Subprocess::SynchronousExec(cmd, &exit_code, &input_line, &error) ||
- exit_code != 0) {
- LOG(ERROR) << "Unable to read EC info from mosys with exit code: "
- << exit_code << " and error: " << error;
- return "";
- }
-
- return utils::ParseECVersion(input_line);
-}
-
string HardwareChromeOS::GetDeviceRequisition() const {
- string requisition;
- return GetVpdValue(kOemRequisitionKey, &requisition) ? requisition : "";
+#if USE_CFM
+ const char* kLocalStatePath = "/home/chronos/Local State";
+ return ReadDeviceRequisition(base::FilePath(kLocalStatePath));
+#else
+ return "";
+#endif
}
int HardwareChromeOS::GetMinKernelKeyVersion() const {
@@ -341,7 +306,7 @@
bool HardwareChromeOS::GetFirstActiveOmahaPingSent() const {
string active_ping_str;
- if (!GetVpdValue(kActivePingKey, &active_ping_str)) {
+ if (!utils::GetVpdValue(kActivePingKey, &active_ping_str)) {
return false;
}
diff --git a/hardware_chromeos.h b/cros/hardware_chromeos.h
similarity index 92%
rename from hardware_chromeos.h
rename to cros/hardware_chromeos.h
index bbfe273..de84d78 100644
--- a/hardware_chromeos.h
+++ b/cros/hardware_chromeos.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
-#define UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_HARDWARE_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_HARDWARE_CHROMEOS_H_
#include <memory>
#include <string>
@@ -46,8 +46,6 @@
bool IsOOBEEnabled() const override;
bool IsOOBEComplete(base::Time* out_time_of_oobe) const override;
std::string GetHardwareClass() const override;
- std::string GetFirmwareVersion() const override;
- std::string GetECVersion() const override;
std::string GetDeviceRequisition() const override;
int GetMinKernelKeyVersion() const override;
int GetMinFirmwareKeyVersion() const override;
@@ -87,4 +85,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_HARDWARE_CHROMEOS_H_
diff --git a/hardware_chromeos_unittest.cc b/cros/hardware_chromeos_unittest.cc
similarity index 97%
rename from hardware_chromeos_unittest.cc
rename to cros/hardware_chromeos_unittest.cc
index 162dec4..50bced6 100644
--- a/hardware_chromeos_unittest.cc
+++ b/cros/hardware_chromeos_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/hardware_chromeos.h"
+#include "update_engine/cros/hardware_chromeos.h"
#include <memory>
diff --git a/image_properties.h b/cros/image_properties.h
similarity index 91%
rename from image_properties.h
rename to cros/image_properties.h
index 49fe82f..4957d12 100644
--- a/image_properties.h
+++ b/cros/image_properties.h
@@ -18,8 +18,8 @@
// properties are meant to be constant during the life of this daemon, but can
// be modified in dev-move or non-official builds.
-#ifndef UPDATE_ENGINE_IMAGE_PROPERTIES_H_
-#define UPDATE_ENGINE_IMAGE_PROPERTIES_H_
+#ifndef UPDATE_ENGINE_CROS_IMAGE_PROPERTIES_H_
+#define UPDATE_ENGINE_CROS_IMAGE_PROPERTIES_H_
#include <string>
@@ -33,13 +33,9 @@
std::string product_id;
// The canary-channel product id.
std::string canary_product_id;
- // The system id for the Android Things SoM, empty for Chrome OS.
- std::string system_id;
// The product version of this image.
std::string version;
- // The system version of this image.
- std::string system_version;
// The version of all product components in key values pairs.
std::string product_components;
@@ -103,4 +99,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_IMAGE_PROPERTIES_H_
+#endif // UPDATE_ENGINE_CROS_IMAGE_PROPERTIES_H_
diff --git a/image_properties_chromeos.cc b/cros/image_properties_chromeos.cc
similarity index 98%
rename from image_properties_chromeos.cc
rename to cros/image_properties_chromeos.cc
index 5ab8f05..c22da7c 100644
--- a/image_properties_chromeos.cc
+++ b/cros/image_properties_chromeos.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/image_properties.h"
+#include "update_engine/cros/image_properties.h"
#include <string>
#include <vector>
@@ -26,8 +26,8 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/platform_constants.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
-#include "update_engine/system_state.h"
namespace {
diff --git a/image_properties_chromeos_unittest.cc b/cros/image_properties_chromeos_unittest.cc
similarity index 98%
rename from image_properties_chromeos_unittest.cc
rename to cros/image_properties_chromeos_unittest.cc
index d9ed688..4822995 100644
--- a/image_properties_chromeos_unittest.cc
+++ b/cros/image_properties_chromeos_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/image_properties.h"
+#include "update_engine/cros/image_properties.h"
#include <string>
@@ -24,7 +24,7 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
using chromeos_update_engine::test_utils::WriteFileString;
using std::string;
diff --git a/logging.cc b/cros/logging.cc
similarity index 95%
rename from logging.cc
rename to cros/logging.cc
index 6320e36..e09166c 100644
--- a/logging.cc
+++ b/cros/logging.cc
@@ -25,8 +25,8 @@
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
+#include "update_engine/common/logging.h"
#include "update_engine/common/utils.h"
-#include "update_engine/logging.h"
using std::string;
@@ -79,7 +79,11 @@
if (log_to_file) {
log_file = SetupLogFile(kSystemLogsRoot);
log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
+#if BASE_VER < 780000
log_settings.log_file = log_file.c_str();
+#else
+ log_settings.log_file_path = log_file.c_str();
+#endif
}
logging::InitLogging(log_settings);
}
diff --git a/metrics_reporter_omaha.cc b/cros/metrics_reporter_omaha.cc
similarity index 82%
rename from metrics_reporter_omaha.cc
rename to cros/metrics_reporter_omaha.cc
index fb4e4ce..2cc0de5 100644
--- a/metrics_reporter_omaha.cc
+++ b/cros/metrics_reporter_omaha.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/metrics_reporter_omaha.h"
+#include "update_engine/cros/metrics_reporter_omaha.h"
#include <memory>
@@ -25,15 +25,16 @@
#include "update_engine/common/clock_interface.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
+#include "update_engine/cros/omaha_request_params.h"
#include "update_engine/metrics_utils.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/system_state.h"
+using base::Time;
+using base::TimeDelta;
using std::string;
namespace chromeos_update_engine {
-
namespace metrics {
// UpdateEngine.Daily.* metrics.
@@ -146,8 +147,6 @@
void MetricsReporterOmaha::ReportDailyMetrics(base::TimeDelta os_age) {
string metric = metrics::kMetricDailyOSAgeDays;
- LOG(INFO) << "Uploading " << utils::FormatTimeDelta(os_age) << " for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
static_cast<int>(os_age.InDays()),
0, // min: 0 days
@@ -168,31 +167,25 @@
metric = metrics::kMetricCheckResult;
value = static_cast<int>(result);
max_value = static_cast<int>(metrics::CheckResult::kNumConstants) - 1;
- LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
metrics_lib_->SendEnumToUMA(metric, value, max_value);
}
if (reaction != metrics::CheckReaction::kUnset) {
metric = metrics::kMetricCheckReaction;
value = static_cast<int>(reaction);
max_value = static_cast<int>(metrics::CheckReaction::kNumConstants) - 1;
- LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
metrics_lib_->SendEnumToUMA(metric, value, max_value);
}
if (download_error_code != metrics::DownloadErrorCode::kUnset) {
metric = metrics::kMetricCheckDownloadErrorCode;
value = static_cast<int>(download_error_code);
- LOG(INFO) << "Sending " << value << " for metric " << metric << " (sparse)";
metrics_lib_->SendSparseToUMA(metric, value);
}
base::TimeDelta time_since_last;
- if (metrics_utils::WallclockDurationHelper(
- system_state,
- kPrefsMetricsCheckLastReportingTime,
- &time_since_last)) {
+ if (WallclockDurationHelper(system_state,
+ kPrefsMetricsCheckLastReportingTime,
+ &time_since_last)) {
metric = metrics::kMetricCheckTimeSinceLastCheckMinutes;
- LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
time_since_last.InMinutes(),
0, // min: 0 min
@@ -202,11 +195,9 @@
base::TimeDelta uptime_since_last;
static int64_t uptime_since_last_storage = 0;
- if (metrics_utils::MonotonicDurationHelper(
+ if (MonotonicDurationHelper(
system_state, &uptime_since_last_storage, &uptime_since_last)) {
metric = metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes;
- LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
uptime_since_last.InMinutes(),
0, // min: 0 min
@@ -221,13 +212,9 @@
value = utils::VersionPrefix(target_version);
if (value != 0) {
metric = metrics::kMetricCheckTargetVersion;
- LOG(INFO) << "Sending " << value << " for metric " << metric
- << " (sparse)";
metrics_lib_->SendSparseToUMA(metric, value);
if (system_state->request_params()->rollback_allowed()) {
metric = metrics::kMetricCheckRollbackTargetVersion;
- LOG(INFO) << "Sending " << value << " for metric " << metric
- << " (sparse)";
metrics_lib_->SendSparseToUMA(metric, value);
}
}
@@ -239,8 +226,6 @@
metrics::AttemptResult attempt_result =
metrics::AttemptResult::kAbnormalTermination;
- LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
- << " for metric " << metric;
metrics_lib_->SendEnumToUMA(
metric,
static_cast<int>(attempt_result),
@@ -257,7 +242,6 @@
metrics::AttemptResult attempt_result,
ErrorCode internal_error_code) {
string metric = metrics::kMetricAttemptNumber;
- LOG(INFO) << "Uploading " << attempt_number << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
attempt_number,
0, // min: 0 attempts
@@ -265,13 +249,9 @@
50); // num_buckets
metric = metrics::kMetricAttemptPayloadType;
- LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
- << metric;
metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
metric = metrics::kMetricAttemptDurationMinutes;
- LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
duration.InMinutes(),
0, // min: 0 min
@@ -279,8 +259,6 @@
50); // num_buckets
metric = metrics::kMetricAttemptDurationUptimeMinutes;
- LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration_uptime)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
duration_uptime.InMinutes(),
0, // min: 0 min
@@ -289,7 +267,6 @@
metric = metrics::kMetricAttemptPayloadSizeMiB;
int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
- LOG(INFO) << "Uploading " << payload_size_mib << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
payload_size_mib,
0, // min: 0 MiB
@@ -297,8 +274,6 @@
50); // num_buckets
metric = metrics::kMetricAttemptResult;
- LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
- << " for metric " << metric;
metrics_lib_->SendEnumToUMA(
metric,
static_cast<int>(attempt_result),
@@ -309,13 +284,10 @@
}
base::TimeDelta time_since_last;
- if (metrics_utils::WallclockDurationHelper(
- system_state,
- kPrefsMetricsAttemptLastReportingTime,
- &time_since_last)) {
+ if (WallclockDurationHelper(system_state,
+ kPrefsMetricsAttemptLastReportingTime,
+ &time_since_last)) {
metric = metrics::kMetricAttemptTimeSinceLastAttemptMinutes;
- LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
time_since_last.InMinutes(),
0, // min: 0 min
@@ -325,11 +297,9 @@
static int64_t uptime_since_last_storage = 0;
base::TimeDelta uptime_since_last;
- if (metrics_utils::MonotonicDurationHelper(
+ if (MonotonicDurationHelper(
system_state, &uptime_since_last_storage, &uptime_since_last)) {
metric = metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
- LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
uptime_since_last.InMinutes(),
0, // min: 0 min
@@ -347,8 +317,6 @@
string metric = metrics::kMetricAttemptPayloadBytesDownloadedMiB;
int64_t payload_bytes_downloaded_mib =
payload_bytes_downloaded / kNumBytesInOneMiB;
- LOG(INFO) << "Uploading " << payload_bytes_downloaded_mib << " for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
payload_bytes_downloaded_mib,
0, // min: 0 MiB
@@ -357,8 +325,6 @@
metric = metrics::kMetricAttemptPayloadDownloadSpeedKBps;
int64_t payload_download_speed_kbps = payload_download_speed_bps / 1000;
- LOG(INFO) << "Uploading " << payload_download_speed_kbps << " for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
payload_download_speed_kbps,
0, // min: 0 kB/s
@@ -366,20 +332,15 @@
50); // num_buckets
metric = metrics::kMetricAttemptDownloadSource;
- LOG(INFO) << "Uploading " << download_source << " for metric " << metric;
metrics_lib_->SendEnumToUMA(metric, download_source, kNumDownloadSources);
if (payload_download_error_code != metrics::DownloadErrorCode::kUnset) {
metric = metrics::kMetricAttemptDownloadErrorCode;
- LOG(INFO) << "Uploading " << static_cast<int>(payload_download_error_code)
- << " for metric " << metric << " (sparse)";
metrics_lib_->SendSparseToUMA(
metric, static_cast<int>(payload_download_error_code));
}
metric = metrics::kMetricAttemptConnectionType;
- LOG(INFO) << "Uploading " << static_cast<int>(connection_type)
- << " for metric " << metric;
metrics_lib_->SendEnumToUMA(
metric,
static_cast<int>(connection_type),
@@ -399,7 +360,6 @@
int url_switch_count) {
string metric = metrics::kMetricSuccessfulUpdatePayloadSizeMiB;
int64_t mbs = payload_size / kNumBytesInOneMiB;
- LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
metrics_lib_->SendToUMA(metric,
mbs,
0, // min: 0 MiB
@@ -429,7 +389,6 @@
}
if (mbs > 0) {
- LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
metrics_lib_->SendToUMA(metric,
mbs,
0, // min: 0 MiB
@@ -439,8 +398,6 @@
}
metric = metrics::kMetricSuccessfulUpdateDownloadSourcesUsed;
- LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
- << " (bit flags) for metric " << metric;
metrics_lib_->SendToUMA(metric,
download_sources_used,
0, // min
@@ -448,8 +405,6 @@
1 << kNumDownloadSources); // num_buckets
metric = metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage;
- LOG(INFO) << "Uploading " << download_overhead_percentage << "% for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
download_overhead_percentage,
0, // min: 0% overhead
@@ -457,8 +412,6 @@
50); // num_buckets
metric = metrics::kMetricSuccessfulUpdateUrlSwitchCount;
- LOG(INFO) << "Uploading " << url_switch_count << " (count) for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
url_switch_count,
0, // min: 0 URL switches
@@ -466,8 +419,6 @@
50); // num_buckets
metric = metrics::kMetricSuccessfulUpdateTotalDurationMinutes;
- LOG(INFO) << "Uploading " << utils::FormatTimeDelta(total_duration)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
static_cast<int>(total_duration.InMinutes()),
0, // min: 0 min
@@ -475,8 +426,6 @@
50); // num_buckets
metric = metrics::kMetricSuccessfulUpdateTotalDurationUptimeMinutes;
- LOG(INFO) << "Uploading " << utils::FormatTimeDelta(total_duration_uptime)
- << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
static_cast<int>(total_duration_uptime.InMinutes()),
0, // min: 0 min
@@ -484,8 +433,6 @@
50); // num_buckets
metric = metrics::kMetricSuccessfulUpdateRebootCount;
- LOG(INFO) << "Uploading reboot count of " << reboot_count << " for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
reboot_count,
0, // min: 0 reboots
@@ -494,8 +441,6 @@
metric = metrics::kMetricSuccessfulUpdatePayloadType;
metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
- LOG(INFO) << "Uploading " << utils::ToString(payload_type) << " for metric "
- << metric;
metric = metrics::kMetricSuccessfulUpdateAttemptCount;
metrics_lib_->SendToUMA(metric,
@@ -503,11 +448,8 @@
1, // min: 1 attempt
50, // max: 50 attempts
50); // num_buckets
- LOG(INFO) << "Uploading " << attempt_count << " for metric " << metric;
metric = metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount;
- LOG(INFO) << "Uploading " << updates_abandoned_count << " (count) for metric "
- << metric;
metrics_lib_->SendToUMA(metric,
updates_abandoned_count,
0, // min: 0 counts
@@ -519,7 +461,6 @@
metrics::RollbackResult result) {
string metric = metrics::kMetricRollbackResult;
int value = static_cast<int>(result);
- LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
metrics_lib_->SendEnumToUMA(
metric, value, static_cast<int>(metrics::RollbackResult::kNumConstants));
}
@@ -530,7 +471,6 @@
string metric = metrics::kMetricEnterpriseRollbackSuccess;
if (!success)
metric = metrics::kMetricEnterpriseRollbackFailure;
- LOG(INFO) << "Sending " << value << " for metric " << metric;
metrics_lib_->SendSparseToUMA(metric, value);
}
@@ -547,8 +487,6 @@
case ServerToCheck::kNone:
return;
}
- LOG(INFO) << "Uploading " << static_cast<int>(result) << " for metric "
- << metric;
metrics_lib_->SendEnumToUMA(
metric,
static_cast<int>(result),
@@ -562,9 +500,6 @@
1, // min value
50, // max value
kNumDefaultUmaBuckets);
-
- LOG(INFO) << "Uploading " << target_attempt << " (count) for metric "
- << metric;
}
void MetricsReporterOmaha::ReportTimeToReboot(int time_to_reboot_minutes) {
@@ -574,9 +509,6 @@
0, // min: 0 minute
30 * 24 * 60, // max: 1 month (approx)
kNumDefaultUmaBuckets);
-
- LOG(INFO) << "Uploading " << time_to_reboot_minutes << " for metric "
- << metric;
}
void MetricsReporterOmaha::ReportInstallDateProvisioningSource(int source,
@@ -588,7 +520,6 @@
void MetricsReporterOmaha::ReportInternalErrorCode(ErrorCode error_code) {
auto metric = metrics::kMetricAttemptInternalErrorCode;
- LOG(INFO) << "Uploading " << error_code << " for metric " << metric;
metrics_lib_->SendEnumToUMA(metric,
static_cast<int>(error_code),
static_cast<int>(ErrorCode::kUmaReportedMax));
@@ -600,18 +531,14 @@
bool kernel_max_rollforward_success) {
int value = kernel_min_version;
string metric = metrics::kMetricKernelMinVersion;
- LOG(INFO) << "Sending " << value << " for metric " << metric;
metrics_lib_->SendSparseToUMA(metric, value);
value = kernel_max_rollforward_version;
metric = metrics::kMetricKernelMaxRollforwardVersion;
- LOG(INFO) << "Sending " << value << " for metric " << metric;
metrics_lib_->SendSparseToUMA(metric, value);
bool bool_value = kernel_max_rollforward_success;
metric = metrics::kMetricKernelMaxRollforwardSetSuccess;
- LOG(INFO) << "Sending " << bool_value << " for metric " << metric
- << " (bool)";
metrics_lib_->SendBoolToUMA(metric, bool_value);
}
@@ -621,7 +548,6 @@
has_time_restriction_policy
? metrics::kMetricSuccessfulUpdateDurationFromSeenTimeRestrictedDays
: metrics::kMetricSuccessfulUpdateDurationFromSeenDays;
- LOG(INFO) << "Sending " << time_to_update_days << " for metric " << metric;
metrics_lib_->SendToUMA(metric,
time_to_update_days,
@@ -630,4 +556,45 @@
50); // num_buckets
}
+bool MetricsReporterOmaha::WallclockDurationHelper(
+ SystemState* system_state,
+ const std::string& state_variable_key,
+ TimeDelta* out_duration) {
+ bool ret = false;
+ Time now = system_state->clock()->GetWallclockTime();
+ int64_t stored_value;
+ if (system_state->prefs()->GetInt64(state_variable_key, &stored_value)) {
+ Time stored_time = Time::FromInternalValue(stored_value);
+ if (stored_time > now) {
+ LOG(ERROR) << "Stored time-stamp used for " << state_variable_key
+ << " is in the future.";
+ } else {
+ *out_duration = now - stored_time;
+ ret = true;
+ }
+ }
+
+ if (!system_state->prefs()->SetInt64(state_variable_key,
+ now.ToInternalValue())) {
+ LOG(ERROR) << "Error storing time-stamp in " << state_variable_key;
+ }
+
+ return ret;
+}
+
+bool MetricsReporterOmaha::MonotonicDurationHelper(SystemState* system_state,
+ int64_t* storage,
+ TimeDelta* out_duration) {
+ bool ret = false;
+ Time now = system_state->clock()->GetMonotonicTime();
+ if (*storage != 0) {
+ Time stored_time = Time::FromInternalValue(*storage);
+ *out_duration = now - stored_time;
+ ret = true;
+ }
+ *storage = now.ToInternalValue();
+
+ return ret;
+}
+
} // namespace chromeos_update_engine
diff --git a/metrics_reporter_omaha.h b/cros/metrics_reporter_omaha.h
similarity index 79%
rename from metrics_reporter_omaha.h
rename to cros/metrics_reporter_omaha.h
index c84ac1e..5b3fdb1 100644
--- a/metrics_reporter_omaha.h
+++ b/cros/metrics_reporter_omaha.h
@@ -14,21 +14,22 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
-#define UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
+#ifndef UPDATE_ENGINE_CROS_METRICS_REPORTER_OMAHA_H_
+#define UPDATE_ENGINE_CROS_METRICS_REPORTER_OMAHA_H_
#include <memory>
#include <string>
#include <base/time/time.h>
+#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include <metrics/metrics_library.h>
#include "update_engine/certificate_checker.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/error_code.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/metrics_reporter_interface.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/metrics_reporter_interface.h"
+#include "update_engine/common/system_state.h"
namespace chromeos_update_engine {
@@ -171,6 +172,31 @@
private:
friend class MetricsReporterOmahaTest;
+ FRIEND_TEST(MetricsReporterOmahaTest, WallclockDurationHelper);
+ FRIEND_TEST(MetricsReporterOmahaTest, MonotonicDurationHelper);
+
+ // This function returns the duration on the wallclock since the last
+ // time it was called for the same |state_variable_key| value.
+ //
+ // If the function returns |true|, the duration (always non-negative)
+ // is returned in |out_duration|. If the function returns |false|
+ // something went wrong or there was no previous measurement.
+ bool WallclockDurationHelper(SystemState* system_state,
+ const std::string& state_variable_key,
+ base::TimeDelta* out_duration);
+
+ // This function returns the duration on the monotonic clock since the
+ // last time it was called for the same |storage| pointer.
+ //
+ // You should pass a pointer to a 64-bit integer in |storage| which
+ // should be initialized to 0.
+ //
+ // If the function returns |true|, the duration (always non-negative)
+ // is returned in |out_duration|. If the function returns |false|
+ // something went wrong or there was no previous measurement.
+ bool MonotonicDurationHelper(SystemState* system_state,
+ int64_t* storage,
+ base::TimeDelta* out_duration);
std::unique_ptr<MetricsLibraryInterface> metrics_lib_;
@@ -179,4 +205,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
+#endif // UPDATE_ENGINE_CROS_METRICS_REPORTER_OMAHA_H_
diff --git a/metrics_reporter_omaha_unittest.cc b/cros/metrics_reporter_omaha_unittest.cc
similarity index 80%
rename from metrics_reporter_omaha_unittest.cc
rename to cros/metrics_reporter_omaha_unittest.cc
index 545d02f..a25472a 100644
--- a/metrics_reporter_omaha_unittest.cc
+++ b/cros/metrics_reporter_omaha_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/metrics_reporter_omaha.h"
+#include "update_engine/cros/metrics_reporter_omaha.h"
#include <memory>
#include <string>
@@ -26,7 +26,7 @@
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_prefs.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
using base::TimeDelta;
using testing::_;
@@ -538,4 +538,115 @@
true /* has_time_restriction_policy */, kDaysToUpdate);
}
+TEST_F(MetricsReporterOmahaTest, WallclockDurationHelper) {
+ FakeSystemState fake_system_state;
+ FakeClock fake_clock;
+ base::TimeDelta duration;
+ const std::string state_variable_key = "test-prefs";
+ FakePrefs fake_prefs;
+
+ fake_system_state.set_clock(&fake_clock);
+ fake_system_state.set_prefs(&fake_prefs);
+
+ // Initialize wallclock to 1 sec.
+ fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
+
+ // First time called so no previous measurement available.
+ EXPECT_FALSE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+
+ // Next time, we should get zero since the clock didn't advance.
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // We can also call it as many times as we want with it being
+ // considered a failure.
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // Advance the clock one second, then we should get 1 sec on the
+ // next call and 0 sec on the subsequent call.
+ fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000));
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 1);
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // Advance clock two seconds and we should get 2 sec and then 0 sec.
+ fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 2);
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // There's a possibility that the wallclock can go backwards (NTP
+ // adjustments, for example) so check that we properly handle this
+ // case.
+ fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000));
+ EXPECT_FALSE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
+ EXPECT_TRUE(reporter_.WallclockDurationHelper(
+ &fake_system_state, state_variable_key, &duration));
+ EXPECT_EQ(duration.InSeconds(), 1);
+}
+
+TEST_F(MetricsReporterOmahaTest, MonotonicDurationHelper) {
+ int64_t storage = 0;
+ FakeSystemState fake_system_state;
+ FakeClock fake_clock;
+ base::TimeDelta duration;
+
+ fake_system_state.set_clock(&fake_clock);
+
+ // Initialize monotonic clock to 1 sec.
+ fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
+
+ // First time called so no previous measurement available.
+ EXPECT_FALSE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+
+ // Next time, we should get zero since the clock didn't advance.
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // We can also call it as many times as we want with it being
+ // considered a failure.
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // Advance the clock one second, then we should get 1 sec on the
+ // next call and 0 sec on the subsequent call.
+ fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000));
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 1);
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+
+ // Advance clock two seconds and we should get 2 sec and then 0 sec.
+ fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000));
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 2);
+ EXPECT_TRUE(reporter_.MonotonicDurationHelper(
+ &fake_system_state, &storage, &duration));
+ EXPECT_EQ(duration.InSeconds(), 0);
+}
+
} // namespace chromeos_update_engine
diff --git a/mock_connection_manager.h b/cros/mock_connection_manager.h
similarity index 85%
rename from mock_connection_manager.h
rename to cros/mock_connection_manager.h
index 2fff68c..899a49b 100644
--- a/mock_connection_manager.h
+++ b/cros/mock_connection_manager.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_CONNECTION_MANAGER_H_
-#define UPDATE_ENGINE_MOCK_CONNECTION_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_CONNECTION_MANAGER_H_
+#define UPDATE_ENGINE_CROS_MOCK_CONNECTION_MANAGER_H_
#include <gmock/gmock.h>
-#include "update_engine/connection_manager_interface.h"
+#include "update_engine/cros/connection_manager_interface.h"
namespace chromeos_update_engine {
@@ -41,4 +41,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_CONNECTION_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_CONNECTION_MANAGER_H_
diff --git a/mock_omaha_request_params.h b/cros/mock_omaha_request_params.h
similarity index 92%
rename from mock_omaha_request_params.h
rename to cros/mock_omaha_request_params.h
index 41bdc19..6072d22 100644
--- a/mock_omaha_request_params.h
+++ b/cros/mock_omaha_request_params.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_OMAHA_REQUEST_PARAMS_H_
-#define UPDATE_ENGINE_MOCK_OMAHA_REQUEST_PARAMS_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_OMAHA_REQUEST_PARAMS_H_
+#define UPDATE_ENGINE_CROS_MOCK_OMAHA_REQUEST_PARAMS_H_
#include <string>
#include <gmock/gmock.h>
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/omaha_request_params.h"
namespace chromeos_update_engine {
@@ -79,4 +79,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_OMAHA_REQUEST_PARAMS_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_OMAHA_REQUEST_PARAMS_H_
diff --git a/mock_p2p_manager.h b/cros/mock_p2p_manager.h
similarity index 94%
rename from mock_p2p_manager.h
rename to cros/mock_p2p_manager.h
index fd67034..273f7f9 100644
--- a/mock_p2p_manager.h
+++ b/cros/mock_p2p_manager.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_P2P_MANAGER_H_
-#define UPDATE_ENGINE_MOCK_P2P_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_P2P_MANAGER_H_
+#define UPDATE_ENGINE_CROS_MOCK_P2P_MANAGER_H_
#include <string>
-#include "update_engine/fake_p2p_manager.h"
+#include "update_engine/cros/fake_p2p_manager.h"
#include <gmock/gmock.h>
@@ -99,4 +99,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_P2P_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_P2P_MANAGER_H_
diff --git a/mock_payload_state.h b/cros/mock_payload_state.h
similarity index 92%
rename from mock_payload_state.h
rename to cros/mock_payload_state.h
index ad22de5..56094e6 100644
--- a/mock_payload_state.h
+++ b/cros/mock_payload_state.h
@@ -14,15 +14,15 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_PAYLOAD_STATE_H_
-#define UPDATE_ENGINE_MOCK_PAYLOAD_STATE_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_PAYLOAD_STATE_H_
+#define UPDATE_ENGINE_CROS_MOCK_PAYLOAD_STATE_H_
#include <string>
#include <gmock/gmock.h>
-#include "update_engine/omaha_request_action.h"
-#include "update_engine/payload_state_interface.h"
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/payload_state_interface.h"
namespace chromeos_update_engine {
@@ -81,4 +81,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_PAYLOAD_STATE_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_PAYLOAD_STATE_H_
diff --git a/mock_power_manager.h b/cros/mock_power_manager.h
similarity index 80%
rename from mock_power_manager.h
rename to cros/mock_power_manager.h
index 8363171..d4a8682 100644
--- a/mock_power_manager.h
+++ b/cros/mock_power_manager.h
@@ -14,12 +14,12 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_POWER_MANAGER_H_
-#define UPDATE_ENGINE_MOCK_POWER_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_POWER_MANAGER_H_
+#define UPDATE_ENGINE_CROS_MOCK_POWER_MANAGER_H_
#include <gmock/gmock.h>
-#include "update_engine/power_manager_interface.h"
+#include "update_engine/cros/power_manager_interface.h"
namespace chromeos_update_engine {
@@ -32,4 +32,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_POWER_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_POWER_MANAGER_H_
diff --git a/mock_update_attempter.h b/cros/mock_update_attempter.h
similarity index 72%
rename from mock_update_attempter.h
rename to cros/mock_update_attempter.h
index ad34802..be8cfcc 100644
--- a/mock_update_attempter.h
+++ b/cros/mock_update_attempter.h
@@ -14,13 +14,13 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_MOCK_UPDATE_ATTEMPTER_H_
-#define UPDATE_ENGINE_MOCK_UPDATE_ATTEMPTER_H_
+#ifndef UPDATE_ENGINE_CROS_MOCK_UPDATE_ATTEMPTER_H_
+#define UPDATE_ENGINE_CROS_MOCK_UPDATE_ATTEMPTER_H_
#include <string>
#include <vector>
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/update_attempter.h"
#include <gmock/gmock.h>
@@ -30,16 +30,10 @@
public:
using UpdateAttempter::UpdateAttempter;
- MOCK_METHOD9(Update,
- void(const std::string& app_version,
- const std::string& omaha_url,
- const std::string& target_channel,
- const std::string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive));
+ MOCK_METHOD(void,
+ Update,
+ (const chromeos_update_manager::UpdateCheckParams& params),
+ (override));
MOCK_METHOD1(GetStatus, bool(update_engine::UpdateEngineStatus* out_status));
@@ -71,4 +65,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_MOCK_UPDATE_ATTEMPTER_H_
+#endif // UPDATE_ENGINE_CROS_MOCK_UPDATE_ATTEMPTER_H_
diff --git a/omaha_request_action.cc b/cros/omaha_request_action.cc
similarity index 98%
rename from omaha_request_action.cc
rename to cros/omaha_request_action.cc
index 95e1250..0916f9d 100644
--- a/omaha_request_action.cc
+++ b/cros/omaha_request_action.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_action.h"
+#include "update_engine/cros/omaha_request_action.h"
#include <inttypes.h>
@@ -44,18 +44,18 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/p2p_manager.h"
+#include "update_engine/cros/payload_state_interface.h"
+#include "update_engine/cros/update_attempter.h"
#include "update_engine/metrics_utils.h"
-#include "update_engine/omaha_request_builder_xml.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/payload_state_interface.h"
-#include "update_engine/update_attempter.h"
using base::Optional;
using base::Time;
@@ -582,6 +582,7 @@
LOG(INFO) << "Found package " << package.name;
OmahaResponse::Package out_package;
+ out_package.app_id = app->id;
out_package.can_exclude = can_exclude;
for (const string& codebase : app->url_codebase) {
if (codebase.empty()) {
@@ -631,6 +632,7 @@
// Removes the candidate URLs which are excluded within packages, if all the
// candidate URLs are excluded within a package, the package will be excluded.
void ProcessExclusions(OmahaResponse* output_object,
+ OmahaRequestParams* params,
ExcluderInterface* excluder) {
for (auto package_it = output_object->packages.begin();
package_it != output_object->packages.end();
@@ -657,6 +659,9 @@
// If there are no candidate payload URLs, remove the package.
if (package_it->payload_urls.empty()) {
LOG(INFO) << "Excluding payload hash=" << package_it->hash;
+ // Need to set DLC as not updated so correct metrics can be sent when an
+ // update is completed.
+ params->SetDlcNoUpdate(package_it->app_id);
package_it = output_object->packages.erase(package_it);
continue;
}
@@ -860,11 +865,6 @@
if (app.id == params_->GetAppId()) {
// this is the app (potentially the only app)
output_object->version = app.manifest_version;
- } else if (!params_->system_app_id().empty() &&
- app.id == params_->system_app_id()) {
- // this is the system app (this check is intentionally skipped if there is
- // no system_app_id set)
- output_object->system_version = app.manifest_version;
} else if (params_->is_install() &&
app.manifest_version != params_->app_version()) {
LOG(WARNING) << "An app has a different version (" << app.manifest_version
@@ -1023,6 +1023,7 @@
if (!ParseResponse(&parser_data, &output_object, &completer))
return;
ProcessExclusions(&output_object,
+ system_state_->request_params(),
system_state_->update_attempter()->GetExcluder());
output_object.update_exists = true;
SetOutputObject(output_object);
diff --git a/omaha_request_action.h b/cros/omaha_request_action.h
similarity index 97%
rename from omaha_request_action.h
rename to cros/omaha_request_action.h
index 30b3d22..1a3a912 100644
--- a/omaha_request_action.h
+++ b/cros/omaha_request_action.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_
-#define UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_REQUEST_ACTION_H_
+#define UPDATE_ENGINE_CROS_OMAHA_REQUEST_ACTION_H_
#include <fcntl.h>
#include <sys/stat.h>
@@ -33,9 +33,9 @@
#include "update_engine/common/action.h"
#include "update_engine/common/http_fetcher.h"
-#include "update_engine/omaha_request_builder_xml.h"
-#include "update_engine/omaha_response.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_response.h"
// The Omaha Request action makes a request to Omaha and can output
// the response on the output ActionPipe.
@@ -317,4 +317,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_REQUEST_ACTION_H_
diff --git a/omaha_request_action_fuzzer.cc b/cros/omaha_request_action_fuzzer.cc
similarity index 94%
rename from omaha_request_action_fuzzer.cc
rename to cros/omaha_request_action_fuzzer.cc
index 6c41b12..dd02467 100644
--- a/omaha_request_action_fuzzer.cc
+++ b/cros/omaha_request_action_fuzzer.cc
@@ -18,8 +18,8 @@
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/omaha_request_action.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/omaha_request_action.h"
class Environment {
public:
diff --git a/omaha_request_action_unittest.cc b/cros/omaha_request_action_unittest.cc
similarity index 97%
rename from omaha_request_action_unittest.cc
rename to cros/omaha_request_action_unittest.cc
index 6a0c213..c3842b8 100644
--- a/omaha_request_action_unittest.cc
+++ b/cros/omaha_request_action_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_action.h"
+#include "update_engine/cros/omaha_request_action.h"
#include <stdint.h>
@@ -44,18 +44,18 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/mock_excluder.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/metrics_reporter_interface.h"
-#include "update_engine/mock_connection_manager.h"
-#include "update_engine/mock_payload_state.h"
-#include "update_engine/omaha_request_builder_xml.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/omaha_utils.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/mock_connection_manager.h"
+#include "update_engine/cros/mock_payload_state.h"
+#include "update_engine/cros/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/omaha_utils.h"
#include "update_engine/update_manager/rollback_prefs.h"
using base::Time;
@@ -365,8 +365,6 @@
request_params_.set_current_channel("unittest");
request_params_.set_target_channel("unittest");
request_params_.set_hwid("OEM MODEL 09235 7471");
- request_params_.set_fw_version("ChromeOSFirmware.1.0");
- request_params_.set_ec_version("0X0A1");
request_params_.set_delta_okay(true);
request_params_.set_interactive(false);
request_params_.set_update_url("http://url");
@@ -650,7 +648,6 @@
EXPECT_TRUE(response.update_exists);
EXPECT_EQ(fake_update_response_.version, response.version);
- EXPECT_EQ("", response.system_version);
EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
response.packages[0].payload_urls[0]);
EXPECT_EQ(fake_update_response_.more_info_url, response.more_info_url);
@@ -713,32 +710,6 @@
EXPECT_EQ(false, response.packages[1].is_delta);
}
-TEST_F(OmahaRequestActionTest, MultiAppAndSystemUpdateTest) {
- fake_update_response_.multi_app = true;
- // Trigger the lining up of the app and system versions.
- request_params_.set_system_app_id(fake_update_response_.app_id2);
- tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
-
- ASSERT_TRUE(TestUpdateCheck());
-
- EXPECT_TRUE(response.update_exists);
- EXPECT_EQ(fake_update_response_.version, response.version);
- EXPECT_EQ(fake_update_response_.version2, response.system_version);
- EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
- response.packages[0].payload_urls[0]);
- EXPECT_EQ(fake_update_response_.codebase2 + "package3",
- response.packages[1].payload_urls[0]);
- EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
- EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
- EXPECT_EQ(11u, response.packages[0].metadata_size);
- EXPECT_EQ(true, response.packages[0].is_delta);
- ASSERT_EQ(2u, response.packages.size());
- EXPECT_EQ(string("hash3"), response.packages[1].hash);
- EXPECT_EQ(333u, response.packages[1].size);
- EXPECT_EQ(33u, response.packages[1].metadata_size);
- EXPECT_EQ(false, response.packages[1].is_delta);
-}
-
TEST_F(OmahaRequestActionTest, MultiAppPartialUpdateTest) {
fake_update_response_.multi_app = true;
fake_update_response_.multi_app_self_update = true;
@@ -748,7 +719,6 @@
EXPECT_TRUE(response.update_exists);
EXPECT_EQ(fake_update_response_.version, response.version);
- EXPECT_EQ("", response.system_version);
EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
response.packages[0].payload_urls[0]);
EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
@@ -770,7 +740,6 @@
EXPECT_TRUE(response.update_exists);
EXPECT_EQ(fake_update_response_.version, response.version);
- EXPECT_EQ("", response.system_version);
EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
response.packages[0].payload_urls[0]);
EXPECT_EQ(fake_update_response_.codebase + "package2",
@@ -1528,6 +1497,7 @@
request_params_.set_os_board("x86 generic<id");
request_params_.set_current_channel("unittest_track<");
request_params_.set_target_channel("unittest_track<");
+ request_params_.set_lts_tag("unittest_hint<");
request_params_.set_hwid("<OEM MODEL>");
fake_prefs_.SetString(kPrefsOmahaCohort, "evil\nstring");
fake_prefs_.SetString(kPrefsOmahaCohortHint, "evil&string\\");
@@ -1547,6 +1517,8 @@
EXPECT_EQ(string::npos, post_str.find("x86 generic<id"));
EXPECT_NE(string::npos, post_str.find("unittest_track&lt;"));
EXPECT_EQ(string::npos, post_str.find("unittest_track<"));
+ EXPECT_NE(string::npos, post_str.find("unittest_hint&lt;"));
+ EXPECT_EQ(string::npos, post_str.find("unittest_hint<"));
EXPECT_NE(string::npos, post_str.find("<OEM MODEL>"));
EXPECT_EQ(string::npos, post_str.find("<OEM MODEL>"));
EXPECT_NE(string::npos, post_str.find("cohort=\"evil\nstring\""));
@@ -1601,8 +1573,6 @@
string::npos);
EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
string::npos);
- EXPECT_NE(post_str.find("fw_version=\"ChromeOSFirmware.1.0\""), string::npos);
- EXPECT_NE(post_str.find("ec_version=\"0X0A1\""), string::npos);
// No <event> tag should be sent if we didn't reboot to an update.
EXPECT_EQ(post_str.find("<event"), string::npos);
}
@@ -1801,6 +1771,17 @@
EXPECT_EQ(string::npos, post_str.find(omaha_cohort_hint));
}
+TEST_F(OmahaRequestActionTest, TargetChannelHintTest) {
+ tuc_params_.http_response = fake_update_response_.GetNoUpdateResponse();
+ tuc_params_.expected_check_result = metrics::CheckResult::kNoUpdateAvailable;
+ tuc_params_.expected_check_reaction = metrics::CheckReaction::kUnset;
+ request_params_.set_lts_tag("hint>");
+
+ ASSERT_TRUE(TestUpdateCheck());
+
+ EXPECT_NE(string::npos, post_str.find("ltstag=\"hint>\""));
+}
+
void OmahaRequestActionTest::PingTest(bool ping_only) {
NiceMock<MockPrefs> prefs;
fake_system_state_.set_prefs(&prefs);
@@ -2776,8 +2757,8 @@
}
TEST_F(OmahaRequestActionTest, UpdateWithPartiallyExcludedDlcTest) {
- request_params_.set_dlc_apps_params(
- {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}}});
+ const string kDlcAppId = request_params_.GetDlcAppId(kDlcId1);
+ request_params_.set_dlc_apps_params({{kDlcAppId, {.name = kDlcId1}}});
fake_update_response_.dlc_app_update = true;
tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
// The first DLC candidate URL is excluded.
@@ -2790,11 +2771,12 @@
// One candidate URL.
EXPECT_EQ(response.packages[1].payload_urls.size(), 1u);
EXPECT_TRUE(response.update_exists);
+ EXPECT_TRUE(request_params_.dlc_apps_params().at(kDlcAppId).updated);
}
TEST_F(OmahaRequestActionTest, UpdateWithExcludedDlcTest) {
- request_params_.set_dlc_apps_params(
- {{request_params_.GetDlcAppId(kDlcId1), {.name = kDlcId1}}});
+ const string kDlcAppId = request_params_.GetDlcAppId(kDlcId1);
+ request_params_.set_dlc_apps_params({{kDlcAppId, {.name = kDlcId1}}});
fake_update_response_.dlc_app_update = true;
tuc_params_.http_response = fake_update_response_.GetUpdateResponse();
// Both DLC candidate URLs are excluded.
@@ -2805,6 +2787,7 @@
EXPECT_EQ(response.packages.size(), 1u);
EXPECT_TRUE(response.update_exists);
+ EXPECT_FALSE(request_params_.dlc_apps_params().at(kDlcAppId).updated);
}
TEST_F(OmahaRequestActionTest, UpdateWithDeprecatedDlcTest) {
diff --git a/omaha_request_builder_xml.cc b/cros/omaha_request_builder_xml.cc
similarity index 94%
rename from omaha_request_builder_xml.cc
rename to cros/omaha_request_builder_xml.cc
index e2857f1..43ee548 100644
--- a/omaha_request_builder_xml.cc
+++ b/cros/omaha_request_builder_xml.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_request_builder_xml.h"
#include <inttypes.h>
@@ -30,7 +30,7 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/utils.h"
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/omaha_request_params.h"
using std::string;
@@ -154,6 +154,11 @@
app_body += " rollback_allowed=\"true\"";
}
}
+ if (!params_->lts_tag().empty()) {
+ app_body += base::StringPrintf(
+ " ltstag=\"%s\"",
+ XmlEncodeWithDefault(params_->lts_tag()).c_str());
+ }
app_body += "></updatecheck>\n";
}
@@ -184,17 +189,26 @@
}
}
} else {
+ int event_result = event_->result;
// The error code is an optional attribute so append it only if the result
// is not success.
string error_code;
- if (event_->result != OmahaEvent::kResultSuccess) {
+ if (event_result != OmahaEvent::kResultSuccess) {
error_code = base::StringPrintf(" errorcode=\"%d\"",
static_cast<int>(event_->error_code));
+ } else if (app_data.is_dlc && !app_data.app_params.updated) {
+ // On a |OmahaEvent::kResultSuccess|, if the event is for an update
+ // completion and the App is a DLC, send error for excluded DLCs as they
+ // did not update.
+ event_result = OmahaEvent::Result::kResultError;
+ error_code = base::StringPrintf(
+ " errorcode=\"%d\"",
+ static_cast<int>(ErrorCode::kPackageExcludedFromUpdate));
}
app_body = base::StringPrintf(
" <event eventtype=\"%d\" eventresult=\"%d\"%s></event>\n",
event_->type,
- event_->result,
+ event_result,
error_code.c_str());
}
@@ -354,8 +368,6 @@
// DLC excluded for installs and updates.
(app_data.is_dlc ? "" :
"lang=\"" + XmlEncodeWithDefault(params_->app_lang(), "en-US") + "\" " +
- "fw_version=\"" + XmlEncodeWithDefault(params_->fw_version()) + "\" " +
- "ec_version=\"" + XmlEncodeWithDefault(params_->ec_version()) + "\" " +
requisition_arg) +
">\n" +
@@ -410,16 +422,6 @@
.app_params = {.active_counting_type = OmahaRequestParams::kDayBased,
.send_ping = include_ping_}};
app_xml += GetApp(product_app);
- if (!params_->system_app_id().empty()) {
- OmahaAppData system_app = {
- .id = params_->system_app_id(),
- .version = params_->system_version(),
- .skip_update = false,
- .is_dlc = false,
- .app_params = {.active_counting_type = OmahaRequestParams::kDayBased,
- .send_ping = include_ping_}};
- app_xml += GetApp(system_app);
- }
for (const auto& it : params_->dlc_apps_params()) {
OmahaAppData dlc_app_data = {
.id = it.first,
diff --git a/omaha_request_builder_xml.h b/cros/omaha_request_builder_xml.h
similarity index 94%
rename from omaha_request_builder_xml.h
rename to cros/omaha_request_builder_xml.h
index 50c708d..4f860dd 100644
--- a/omaha_request_builder_xml.h
+++ b/cros/omaha_request_builder_xml.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_
-#define UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_REQUEST_BUILDER_XML_H_
+#define UPDATE_ENGINE_CROS_OMAHA_REQUEST_BUILDER_XML_H_
#include <fcntl.h>
#include <sys/stat.h>
@@ -33,9 +33,9 @@
#include "update_engine/common/action.h"
#include "update_engine/common/http_fetcher.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/omaha_response.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/omaha_response.h"
namespace chromeos_update_engine {
@@ -196,4 +196,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_REQUEST_BUILDER_XML_H_
diff --git a/omaha_request_builder_xml_unittest.cc b/cros/omaha_request_builder_xml_unittest.cc
similarity index 71%
rename from omaha_request_builder_xml_unittest.cc
rename to cros/omaha_request_builder_xml_unittest.cc
index 017acec..11d808b 100644
--- a/omaha_request_builder_xml_unittest.cc
+++ b/cros/omaha_request_builder_xml_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_request_builder_xml.h"
#include <string>
#include <utility>
@@ -23,7 +23,7 @@
#include <base/guid.h>
#include <gtest/gtest.h>
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
using std::pair;
using std::string;
@@ -108,8 +108,6 @@
// in fact present in the <app ...></app>.
const string app = omaha_request.GetApp(dlc_app_data);
EXPECT_NE(string::npos, app.find("lang="));
- EXPECT_NE(string::npos, app.find("fw_version="));
- EXPECT_NE(string::npos, app.find("ec_version="));
EXPECT_NE(string::npos, app.find("requisition="));
}
@@ -132,8 +130,6 @@
// fact not present in the <app ...></app>.
const string app = omaha_request.GetApp(dlc_app_data);
EXPECT_EQ(string::npos, app.find("lang="));
- EXPECT_EQ(string::npos, app.find("fw_version="));
- EXPECT_EQ(string::npos, app.find("ec_version="));
EXPECT_EQ(string::npos, app.find("requisition="));
}
@@ -148,10 +144,10 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
+ const string kRequestXml = omaha_request.GetRequest();
const string key = "requestid";
const string request_id =
- FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
+ FindAttributeKeyValueInXml(kRequestXml, key, kGuidSize);
// A valid |request_id| is either a GUID version 4 or empty string.
if (!request_id.empty())
EXPECT_TRUE(base::IsValidGUID(request_id));
@@ -169,10 +165,10 @@
0,
fake_system_state_.prefs(),
gen_session_id};
- const string request_xml = omaha_request.GetRequest();
+ const string kRequestXml = omaha_request.GetRequest();
const string key = "sessionid";
const string session_id =
- FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
+ FindAttributeKeyValueInXml(kRequestXml, key, kGuidSize);
// A valid |session_id| is either a GUID version 4 or empty string.
if (!session_id.empty()) {
EXPECT_TRUE(base::IsValidGUID(session_id));
@@ -191,9 +187,9 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
- EXPECT_EQ(1, CountSubstringInString(request_xml, "<updatecheck"))
- << request_xml;
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(1, CountSubstringInString(kRequestXml, "<updatecheck"))
+ << kRequestXml;
}
TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlPlatformUpdateWithDlcsTest) {
@@ -210,9 +206,9 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
- EXPECT_EQ(3, CountSubstringInString(request_xml, "<updatecheck"))
- << request_xml;
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(3, CountSubstringInString(kRequestXml, "<updatecheck"))
+ << kRequestXml;
}
TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcInstallationTest) {
@@ -231,25 +227,25 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
- EXPECT_EQ(2, CountSubstringInString(request_xml, "<updatecheck"))
- << request_xml;
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(2, CountSubstringInString(kRequestXml, "<updatecheck"))
+ << kRequestXml;
- auto FindAppId = [request_xml](size_t pos) -> size_t {
- return request_xml.find("<app appid", pos);
+ auto FindAppId = [kRequestXml](size_t pos) -> size_t {
+ return kRequestXml.find("<app appid", pos);
};
// Skip over the Platform AppID, which is always first.
size_t pos = FindAppId(0);
for (auto&& _ : dlcs) {
(void)_;
- EXPECT_NE(string::npos, (pos = FindAppId(pos + 1))) << request_xml;
+ EXPECT_NE(string::npos, (pos = FindAppId(pos + 1))) << kRequestXml;
const string dlc_app_id_version = FindAttributeKeyValueInXml(
- request_xml.substr(pos), "version", string(kNoVersion).size());
+ kRequestXml.substr(pos), "version", string(kNoVersion).size());
EXPECT_EQ(kNoVersion, dlc_app_id_version);
const string false_str = "false";
const string dlc_app_id_delta_okay = FindAttributeKeyValueInXml(
- request_xml.substr(pos), "delta_okay", false_str.length());
+ kRequestXml.substr(pos), "delta_okay", false_str.length());
EXPECT_EQ(false_str, dlc_app_id_delta_okay);
}
}
@@ -267,8 +263,8 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
- EXPECT_EQ(0, CountSubstringInString(request_xml, "<ping")) << request_xml;
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(0, CountSubstringInString(kRequestXml, "<ping")) << kRequestXml;
}
TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcPingRollCallNoActive) {
@@ -289,9 +285,9 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
- EXPECT_EQ(1, CountSubstringInString(request_xml, "<ping rd=\"36\""))
- << request_xml;
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(1, CountSubstringInString(kRequestXml, "<ping rd=\"36\""))
+ << kRequestXml;
}
TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlDlcPingRollCallAndActive) {
@@ -313,10 +309,93 @@
0,
fake_system_state_.prefs(),
""};
- const string request_xml = omaha_request.GetRequest();
+ const string kRequestXml = omaha_request.GetRequest();
EXPECT_EQ(1,
- CountSubstringInString(request_xml,
+ CountSubstringInString(kRequestXml,
"<ping active=\"1\" ad=\"25\" rd=\"36\""))
- << request_xml;
+ << kRequestXml;
+}
+
+TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlUpdateCompleteEvent) {
+ OmahaRequestParams omaha_request_params{&fake_system_state_};
+ OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
+ OmahaRequestBuilderXml omaha_request{&event,
+ &omaha_request_params,
+ false,
+ false,
+ 0,
+ 0,
+ 0,
+ fake_system_state_.prefs(),
+ ""};
+ const string kRequestXml = omaha_request.GetRequest();
+ LOG(INFO) << kRequestXml;
+ EXPECT_EQ(
+ 1,
+ CountSubstringInString(
+ kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+ << kRequestXml;
+}
+
+TEST_F(OmahaRequestBuilderXmlTest,
+ GetRequestXmlUpdateCompleteEventSomeDlcsExcluded) {
+ OmahaRequestParams omaha_request_params{&fake_system_state_};
+ omaha_request_params.set_dlc_apps_params({
+ {omaha_request_params.GetDlcAppId("dlc_1"), {.updated = true}},
+ {omaha_request_params.GetDlcAppId("dlc_2"), {.updated = false}},
+ });
+ OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
+ OmahaRequestBuilderXml omaha_request{&event,
+ &omaha_request_params,
+ false,
+ false,
+ 0,
+ 0,
+ 0,
+ fake_system_state_.prefs(),
+ ""};
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(
+ 2,
+ CountSubstringInString(
+ kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+ << kRequestXml;
+ EXPECT_EQ(
+ 1,
+ CountSubstringInString(
+ kRequestXml,
+ "<event eventtype=\"3\" eventresult=\"0\" errorcode=\"62\"></event>"))
+ << kRequestXml;
+}
+
+TEST_F(OmahaRequestBuilderXmlTest,
+ GetRequestXmlUpdateCompleteEventAllDlcsExcluded) {
+ OmahaRequestParams omaha_request_params{&fake_system_state_};
+ omaha_request_params.set_dlc_apps_params({
+ {omaha_request_params.GetDlcAppId("dlc_1"), {.updated = false}},
+ {omaha_request_params.GetDlcAppId("dlc_2"), {.updated = false}},
+ });
+ OmahaEvent event(OmahaEvent::kTypeUpdateComplete);
+ OmahaRequestBuilderXml omaha_request{&event,
+ &omaha_request_params,
+ false,
+ false,
+ 0,
+ 0,
+ 0,
+ fake_system_state_.prefs(),
+ ""};
+ const string kRequestXml = omaha_request.GetRequest();
+ EXPECT_EQ(
+ 1,
+ CountSubstringInString(
+ kRequestXml, "<event eventtype=\"3\" eventresult=\"1\"></event>"))
+ << kRequestXml;
+ EXPECT_EQ(
+ 2,
+ CountSubstringInString(
+ kRequestXml,
+ "<event eventtype=\"3\" eventresult=\"0\" errorcode=\"62\"></event>"))
+ << kRequestXml;
}
} // namespace chromeos_update_engine
diff --git a/omaha_request_params.cc b/cros/omaha_request_params.cc
similarity index 81%
rename from omaha_request_params.cc
rename to cros/omaha_request_params.cc
index 8a2e3dc..c814e00 100644
--- a/omaha_request_params.cc
+++ b/cros/omaha_request_params.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/omaha_request_params.h"
#include <errno.h>
#include <fcntl.h>
@@ -35,11 +35,13 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/platform_constants.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
-#include "update_engine/system_state.h"
+#include "update_engine/update_manager/policy.h"
#define CALL_MEMBER_FN(object, member) ((object).*(member))
+using chromeos_update_manager::UpdateCheckParams;
using std::string;
namespace chromeos_update_engine {
@@ -59,9 +61,9 @@
test::SetImagePropertiesRootPrefix(nullptr);
}
-bool OmahaRequestParams::Init(const string& in_app_version,
- const string& in_update_url,
- bool in_interactive) {
+bool OmahaRequestParams::Init(const string& app_version,
+ const string& update_url,
+ const UpdateCheckParams& params) {
LOG(INFO) << "Initializing parameters for this update attempt";
image_props_ = LoadImageProperties(system_state_);
mutable_image_props_ = LoadMutableImageProperties(system_state_);
@@ -76,24 +78,13 @@
LOG(INFO) << "Running from channel " << image_props_.current_channel;
os_platform_ = constants::kOmahaPlatformName;
- if (!image_props_.system_version.empty()) {
- if (in_app_version == "ForcedUpdate") {
- image_props_.system_version = in_app_version;
- }
- os_version_ = image_props_.system_version;
- } else {
- os_version_ = OmahaRequestParams::kOsVersion;
- }
- if (!in_app_version.empty())
- image_props_.version = in_app_version;
+ os_version_ = OmahaRequestParams::kOsVersion;
+ if (!app_version.empty())
+ image_props_.version = app_version;
os_sp_ = image_props_.version + "_" + GetMachineType();
app_lang_ = "en-US";
hwid_ = system_state_->hardware()->GetHardwareClass();
- if (CollectECFWVersions()) {
- fw_version_ = system_state_->hardware()->GetFirmwareVersion();
- ec_version_ = system_state_->hardware()->GetECVersion();
- }
device_requisition_ = system_state_->hardware()->GetDeviceRequisition();
if (image_props_.current_channel == mutable_image_props_.target_channel) {
@@ -115,17 +106,51 @@
delta_okay_ = false;
}
- if (in_update_url.empty())
+ if (update_url.empty())
update_url_ = image_props_.omaha_url;
else
- update_url_ = in_update_url;
+ update_url_ = update_url;
// Set the interactive flag accordingly.
- interactive_ = in_interactive;
+ interactive_ = params.interactive;
dlc_apps_params_.clear();
// Set false so it will do update by default.
is_install_ = false;
+
+ target_version_prefix_ = params.target_version_prefix;
+
+ lts_tag_ = params.lts_tag;
+
+ rollback_allowed_ = params.rollback_allowed;
+
+ // Set whether saving data over rollback is requested.
+ rollback_data_save_requested_ = params.rollback_data_save_requested;
+
+ // Set how many milestones of rollback are allowed.
+ rollback_allowed_milestones_ = params.rollback_allowed_milestones;
+
+ // Set the target channel, if one was provided.
+ if (params.target_channel.empty()) {
+ LOG(INFO) << "No target channel mandated by policy.";
+ } else {
+ LOG(INFO) << "Setting target channel as mandated: "
+ << params.target_channel;
+ string error_message;
+ if (!SetTargetChannel(params.target_channel,
+ params.rollback_on_channel_downgrade,
+ &error_message)) {
+ LOG(ERROR) << "Setting the channel failed: " << error_message;
+ }
+
+ // Since this is the beginning of a new attempt, update the download
+ // channel. The download channel won't be updated until the next attempt,
+ // even if target channel changes meanwhile, so that how we'll know if we
+ // should cancel the current download attempt if there's such a change in
+ // target channel.
+ UpdateDownloadChannel();
+ }
+
return true;
}
@@ -134,14 +159,6 @@
update_url_ == image_props_.omaha_url);
}
-bool OmahaRequestParams::CollectECFWVersions() const {
- return base::StartsWith(
- hwid_, string("PARROT"), base::CompareCase::SENSITIVE) ||
- base::StartsWith(
- hwid_, string("SPRING"), base::CompareCase::SENSITIVE) ||
- base::StartsWith(hwid_, string("SNOW"), base::CompareCase::SENSITIVE);
-}
-
bool OmahaRequestParams::SetTargetChannel(const string& new_target_channel,
bool is_powerwash_allowed,
string* error_message) {
diff --git a/omaha_request_params.h b/cros/omaha_request_params.h
similarity index 91%
rename from omaha_request_params.h
rename to cros/omaha_request_params.h
index 76fc806..26ea1c9 100644
--- a/omaha_request_params.h
+++ b/cros/omaha_request_params.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
-#define UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_REQUEST_PARAMS_H_
+#define UPDATE_ENGINE_CROS_OMAHA_REQUEST_PARAMS_H_
#include <stdint.h>
@@ -29,7 +29,8 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/platform_constants.h"
-#include "update_engine/image_properties.h"
+#include "update_engine/cros/image_properties.h"
+#include "update_engine/update_manager/policy.h"
// This gathers local system information and prepares info used by the
// Omaha request action.
@@ -93,27 +94,18 @@
inline std::string canary_app_id() const {
return image_props_.canary_product_id;
}
- inline std::string system_app_id() const { return image_props_.system_id; }
- inline void set_system_app_id(const std::string& system_app_id) {
- image_props_.system_id = system_app_id;
- }
inline void set_app_id(const std::string& app_id) {
image_props_.product_id = app_id;
image_props_.canary_product_id = app_id;
}
inline std::string app_lang() const { return app_lang_; }
inline std::string hwid() const { return hwid_; }
- inline std::string fw_version() const { return fw_version_; }
- inline std::string ec_version() const { return ec_version_; }
inline std::string device_requisition() const { return device_requisition_; }
inline void set_app_version(const std::string& version) {
image_props_.version = version;
}
inline std::string app_version() const { return image_props_.version; }
- inline std::string system_version() const {
- return image_props_.system_version;
- }
inline std::string product_components() const {
return image_props_.product_components;
}
@@ -148,6 +140,10 @@
return target_version_prefix_;
}
+ inline std::string lts_tag() const { return lts_tag_; }
+
+ inline void set_lts_tag(const std::string& hint) { lts_tag_ = hint; }
+
inline void set_rollback_allowed(bool rollback_allowed) {
rollback_allowed_ = rollback_allowed;
}
@@ -245,7 +241,7 @@
// of the parameter. Returns true on success, false otherwise.
bool Init(const std::string& in_app_version,
const std::string& in_update_url,
- bool in_interactive);
+ const chromeos_update_manager::UpdateCheckParams& params);
// Permanently changes the release channel to |channel|. Performs a
// powerwash, if required and allowed.
@@ -289,22 +285,19 @@
}
void set_app_lang(const std::string& app_lang) { app_lang_ = app_lang; }
void set_hwid(const std::string& hwid) { hwid_ = hwid; }
- void set_fw_version(const std::string& fw_version) {
- fw_version_ = fw_version;
- }
- void set_ec_version(const std::string& ec_version) {
- ec_version_ = ec_version;
- }
void set_is_powerwash_allowed(bool powerwash_allowed) {
mutable_image_props_.is_powerwash_allowed = powerwash_allowed;
}
+ bool is_powerwash_allowed() {
+ return mutable_image_props_.is_powerwash_allowed;
+ }
+
void set_device_requisition(const std::string& requisition) {
device_requisition_ = requisition;
}
private:
FRIEND_TEST(OmahaRequestParamsTest, ChannelIndexTest);
- FRIEND_TEST(OmahaRequestParamsTest, CollectECFWVersionsTest);
FRIEND_TEST(OmahaRequestParamsTest, IsValidChannelTest);
FRIEND_TEST(OmahaRequestParamsTest, SetIsPowerwashAllowedTest);
FRIEND_TEST(OmahaRequestParamsTest, SetTargetChannelInvalidTest);
@@ -327,10 +320,6 @@
// i.e. index(target_channel) > index(current_channel).
bool ToMoreStableChannel() const;
- // Returns True if we should store the fw/ec versions based on our hwid_.
- // Compares hwid to a set of prefixes in the allowlist.
- bool CollectECFWVersions() const;
-
// Gets the machine type (e.g. "i686").
std::string GetMachineType() const;
@@ -367,14 +356,15 @@
// changed and cancel the current download attempt.
std::string download_channel_;
- std::string hwid_; // Hardware Qualification ID of the client
- std::string fw_version_; // Chrome OS Firmware Version.
- std::string ec_version_; // Chrome OS EC Version.
+ // The value defining the parameters of the LTS (Long Term Support).
+ std::string lts_tag_;
+
+ std::string hwid_; // Hardware Qualification ID of the client
// TODO(b:133324571) tracks removal of this field once it is no longer
// needed in AU requests. Remove by October 1st 2019.
std::string device_requisition_; // Chrome OS Requisition type.
- bool delta_okay_; // If this client can accept a delta
- bool interactive_; // Whether this is a user-initiated update check
+ bool delta_okay_; // If this client can accept a delta
+ bool interactive_; // Whether this is a user-initiated update check
// The URL to send the Omaha request to.
std::string update_url_;
@@ -427,4 +417,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_REQUEST_PARAMS_H_
diff --git a/omaha_request_params_unittest.cc b/cros/omaha_request_params_unittest.cc
similarity index 89%
rename from omaha_request_params_unittest.cc
rename to cros/omaha_request_params_unittest.cc
index bfcbc32..71f3d4c 100644
--- a/omaha_request_params_unittest.cc
+++ b/cros/omaha_request_params_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/omaha_request_params.h"
#include <stdio.h>
@@ -29,7 +29,7 @@
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
using chromeos_update_engine::test_utils::WriteFileString;
using std::string;
@@ -75,36 +75,36 @@
} // namespace
TEST_F(OmahaRequestParamsTest, MissingChannelTest) {
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
// By default, if no channel is set, we should track the stable-channel.
EXPECT_EQ("stable-channel", params_.target_channel());
}
TEST_F(OmahaRequestParamsTest, ForceVersionTest) {
- EXPECT_TRUE(params_.Init("ForcedVersion", "", false));
+ EXPECT_TRUE(params_.Init("ForcedVersion", "", {}));
EXPECT_EQ(string("ForcedVersion_") + GetMachineType(), params_.os_sp());
EXPECT_EQ("ForcedVersion", params_.app_version());
}
TEST_F(OmahaRequestParamsTest, ForcedURLTest) {
- EXPECT_TRUE(params_.Init("", "http://forced.google.com", false));
+ EXPECT_TRUE(params_.Init("", "http://forced.google.com", {}));
EXPECT_EQ("http://forced.google.com", params_.update_url());
}
TEST_F(OmahaRequestParamsTest, MissingURLTest) {
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_EQ(constants::kOmahaDefaultProductionURL, params_.update_url());
}
TEST_F(OmahaRequestParamsTest, DeltaOKTest) {
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_TRUE(params_.delta_okay());
}
TEST_F(OmahaRequestParamsTest, NoDeltasTest) {
ASSERT_TRUE(
WriteFileString(tempdir_.GetPath().Append(".nodelta").value(), ""));
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_FALSE(params_.delta_okay());
}
@@ -112,12 +112,12 @@
{
OmahaRequestParams params(&fake_system_state_);
params.set_root(tempdir_.GetPath().value());
- EXPECT_TRUE(params.Init("", "", false));
+ EXPECT_TRUE(params.Init("", "", {}));
EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
EXPECT_FALSE(params.mutable_image_props_.is_powerwash_allowed);
}
params_.set_root(tempdir_.GetPath().value());
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_EQ("canary-channel", params_.target_channel());
EXPECT_FALSE(params_.mutable_image_props_.is_powerwash_allowed);
}
@@ -126,12 +126,12 @@
{
OmahaRequestParams params(&fake_system_state_);
params.set_root(tempdir_.GetPath().value());
- EXPECT_TRUE(params.Init("", "", false));
+ EXPECT_TRUE(params.Init("", "", {}));
EXPECT_TRUE(params.SetTargetChannel("canary-channel", true, nullptr));
EXPECT_TRUE(params.mutable_image_props_.is_powerwash_allowed);
}
params_.set_root(tempdir_.GetPath().value());
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_EQ("canary-channel", params_.target_channel());
EXPECT_TRUE(params_.mutable_image_props_.is_powerwash_allowed);
}
@@ -141,7 +141,7 @@
OmahaRequestParams params(&fake_system_state_);
params.set_root(tempdir_.GetPath().value());
SetLockDown(true);
- EXPECT_TRUE(params.Init("", "", false));
+ EXPECT_TRUE(params.Init("", "", {}));
params.image_props_.allow_arbitrary_channels = false;
string error_message;
EXPECT_FALSE(
@@ -151,7 +151,7 @@
EXPECT_FALSE(params.mutable_image_props_.is_powerwash_allowed);
}
params_.set_root(tempdir_.GetPath().value());
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_EQ("stable-channel", params_.target_channel());
EXPECT_FALSE(params_.mutable_image_props_.is_powerwash_allowed);
}
@@ -197,7 +197,7 @@
// When set to a valid value while a change is already pending, it should
// succeed.
- params_.Init("", "", false);
+ params_.Init("", "", {});
EXPECT_TRUE(params_.SetTargetChannel("beta-channel", true, nullptr));
// The target channel should reflect the change, but the download channel
// should continue to retain the old value ...
@@ -236,6 +236,13 @@
EXPECT_FALSE(params_.ToMoreStableChannel());
}
+TEST_F(OmahaRequestParamsTest, TargetChannelHintTest) {
+ EXPECT_TRUE(params_.Init("", "", {}));
+ const string kHint("foo-hint");
+ params_.set_lts_tag(kHint);
+ EXPECT_EQ(kHint, params_.lts_tag());
+}
+
TEST_F(OmahaRequestParamsTest, ShouldPowerwashTest) {
params_.mutable_image_props_.is_powerwash_allowed = false;
EXPECT_FALSE(params_.ShouldPowerwash());
@@ -250,16 +257,8 @@
EXPECT_TRUE(params_.ShouldPowerwash());
}
-TEST_F(OmahaRequestParamsTest, CollectECFWVersionsTest) {
- params_.hwid_ = string("STUMPY ALEX 12345");
- EXPECT_FALSE(params_.CollectECFWVersions());
-
- params_.hwid_ = string("SNOW 12345");
- EXPECT_TRUE(params_.CollectECFWVersions());
-}
-
TEST_F(OmahaRequestParamsTest, RequisitionIsSetTest) {
- EXPECT_TRUE(params_.Init("", "", false));
+ EXPECT_TRUE(params_.Init("", "", {}));
EXPECT_EQ("fake_requisition", params_.device_requisition());
}
} // namespace chromeos_update_engine
diff --git a/omaha_response.h b/cros/omaha_response.h
similarity index 94%
rename from omaha_response.h
rename to cros/omaha_response.h
index 2b86fe7..43783d6 100644
--- a/omaha_response.h
+++ b/cros/omaha_response.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_RESPONSE_H_
-#define UPDATE_ENGINE_OMAHA_RESPONSE_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_RESPONSE_H_
+#define UPDATE_ENGINE_CROS_OMAHA_RESPONSE_H_
#include <fcntl.h>
#include <sys/stat.h>
@@ -38,7 +38,6 @@
// These are only valid if update_exists is true:
std::string version;
- std::string system_version;
struct Package {
// The ordered list of URLs in the Omaha response. Each item is a complete
@@ -54,6 +53,8 @@
// True if the payload can be excluded from updating if consistently faulty.
// False if the payload is critical to update.
bool can_exclude = false;
+ // The App ID associated with the package.
+ std::string app_id;
};
std::vector<Package> packages;
@@ -117,4 +118,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_RESPONSE_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_RESPONSE_H_
diff --git a/omaha_response_handler_action.cc b/cros/omaha_response_handler_action.cc
similarity index 94%
rename from omaha_response_handler_action.cc
rename to cros/omaha_response_handler_action.cc
index 040f8e7..b6c223f 100644
--- a/omaha_response_handler_action.cc
+++ b/cros/omaha_response_handler_action.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_response_handler_action.h"
+#include "update_engine/cros/omaha_response_handler_action.h"
#include <limits>
#include <string>
@@ -28,10 +28,10 @@
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/payload_state_interface.h"
#include "update_engine/payload_consumer/delta_performer.h"
-#include "update_engine/payload_state_interface.h"
#include "update_engine/update_manager/policy.h"
#include "update_engine/update_manager/update_manager.h"
@@ -75,7 +75,6 @@
// |OmahaRequestAction| and keep the enforcement of exclusions for updates.
install_plan_.download_url = current_url;
install_plan_.version = response.version;
- install_plan_.system_version = response.system_version;
OmahaRequestParams* const params = system_state_->request_params();
PayloadStateInterface* const payload_state = system_state_->payload_state();
@@ -188,10 +187,12 @@
}
// Powerwash if either the response requires it or the parameters indicated
- // powerwash and we are downgrading the version.
+ // powerwash (usually because there was a channel downgrade) and we are
+ // downgrading the version. Enterprise rollback, indicated by
+ // |response.is_rollback| is dealt with separately above.
if (response.powerwash_required) {
install_plan_.powerwash_required = true;
- } else if (params->ShouldPowerwash()) {
+ } else if (params->ShouldPowerwash() && !response.is_rollback) {
base::Version new_version(response.version);
base::Version current_version(params->app_version());
@@ -205,6 +206,10 @@
<< " Current version number: " << params->app_version();
} else if (new_version < current_version) {
install_plan_.powerwash_required = true;
+ // Always try to preserve enrollment and wifi data for enrolled devices.
+ install_plan_.rollback_data_save_requested =
+ system_state_ && system_state_->device_policy() &&
+ system_state_->device_policy()->IsEnterpriseEnrolled();
}
}
diff --git a/omaha_response_handler_action.h b/cros/omaha_response_handler_action.h
similarity index 91%
rename from omaha_response_handler_action.h
rename to cros/omaha_response_handler_action.h
index d2e6db8..f3b821e 100644
--- a/omaha_response_handler_action.h
+++ b/cros/omaha_response_handler_action.h
@@ -14,17 +14,17 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_RESPONSE_HANDLER_ACTION_H_
-#define UPDATE_ENGINE_OMAHA_RESPONSE_HANDLER_ACTION_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_RESPONSE_HANDLER_ACTION_H_
+#define UPDATE_ENGINE_CROS_OMAHA_RESPONSE_HANDLER_ACTION_H_
#include <string>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "update_engine/common/action.h"
-#include "update_engine/omaha_request_action.h"
+#include "update_engine/common/system_state.h"
+#include "update_engine/cros/omaha_request_action.h"
#include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/system_state.h"
// This class reads in an Omaha response and converts what it sees into
// an install plan which is passed out.
@@ -90,4 +90,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_RESPONSE_HANDLER_ACTION_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_RESPONSE_HANDLER_ACTION_H_
diff --git a/omaha_response_handler_action_unittest.cc b/cros/omaha_response_handler_action_unittest.cc
similarity index 86%
rename from omaha_response_handler_action_unittest.cc
rename to cros/omaha_response_handler_action_unittest.cc
index 04cfa73..8da3205 100644
--- a/omaha_response_handler_action_unittest.cc
+++ b/cros/omaha_response_handler_action_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_response_handler_action.h"
+#include "update_engine/cros/omaha_response_handler_action.h"
#include <memory>
#include <string>
@@ -29,8 +29,8 @@
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/mock_payload_state.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/mock_payload_state.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/update_manager/mock_policy.h"
@@ -176,7 +176,7 @@
}
TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
- test_utils::ScopedTempFile test_deadline_file(
+ ScopedTempFile test_deadline_file(
"omaha_response_handler_action_unittest-XXXXXX");
{
OmahaResponse in;
@@ -532,6 +532,132 @@
}
TEST_F(OmahaResponseHandlerActionTest,
+ ChangeToMoreStableChannelButSameVersionTest) {
+ OmahaResponse in;
+ in.update_exists = true;
+ in.version = "12345.0.0.0";
+ in.packages.push_back({.payload_urls = {"https://ChannelDownVersionUp"},
+ .size = 1,
+ .hash = kPayloadHashHex});
+ in.more_info_url = "http://more/info";
+
+ // Create a uniquely named test directory.
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+
+ OmahaRequestParams params(&fake_system_state_);
+ fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
+ params.set_root(tempdir.GetPath().value());
+ params.set_current_channel("beta-channel");
+ EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
+ params.UpdateDownloadChannel();
+ params.set_app_version("12345.0.0.0");
+
+ fake_system_state_.set_request_params(¶ms);
+ InstallPlan install_plan;
+ EXPECT_TRUE(DoTest(in, "", &install_plan));
+ EXPECT_FALSE(install_plan.powerwash_required);
+ EXPECT_FALSE(install_plan.rollback_data_save_requested);
+}
+
+// On an enrolled device, the rollback data restore should be attempted when
+// doing a powerwash and channel downgrade.
+TEST_F(OmahaResponseHandlerActionTest,
+ ChangeToMoreStableChannelEnrolledDataRestore) {
+ OmahaResponse in;
+ in.update_exists = true;
+ in.version = "12345.96.0.0";
+ in.packages.push_back({.payload_urls = {"https://ChannelDownEnrolled"},
+ .size = 1,
+ .hash = kPayloadHashHex});
+ in.more_info_url = "http://more/info";
+
+ // Create a uniquely named test directory.
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+
+ OmahaRequestParams params(&fake_system_state_);
+ fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+ params.set_root(tempdir.GetPath().value());
+ params.set_current_channel("beta-channel");
+ EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
+ params.UpdateDownloadChannel();
+ params.set_app_version("12347.48.0.0");
+
+ testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
+ EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
+ .WillOnce(Return(true));
+ fake_system_state_.set_device_policy(&mock_device_policy);
+
+ fake_system_state_.set_request_params(¶ms);
+ InstallPlan install_plan;
+ EXPECT_TRUE(DoTest(in, "", &install_plan));
+ EXPECT_TRUE(install_plan.rollback_data_save_requested);
+}
+
+// Never attempt rollback data restore if the device is not enrolled.
+TEST_F(OmahaResponseHandlerActionTest,
+ ChangeToMoreStableChannelUnenrolledNoDataRestore) {
+ OmahaResponse in;
+ in.update_exists = true;
+ in.version = "12345.96.0.0";
+ in.packages.push_back({.payload_urls = {"https://ChannelDownEnrolled"},
+ .size = 1,
+ .hash = kPayloadHashHex});
+ in.more_info_url = "http://more/info";
+
+ // Create a uniquely named test directory.
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+
+ OmahaRequestParams params(&fake_system_state_);
+ fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+ params.set_root(tempdir.GetPath().value());
+ params.set_current_channel("beta-channel");
+ EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
+ params.UpdateDownloadChannel();
+ params.set_app_version("12347.48.0.0");
+
+ testing::NiceMock<policy::MockDevicePolicy> mock_device_policy;
+ EXPECT_CALL(mock_device_policy, IsEnterpriseEnrolled())
+ .WillOnce(Return(false));
+ fake_system_state_.set_device_policy(&mock_device_policy);
+
+ fake_system_state_.set_request_params(¶ms);
+ InstallPlan install_plan;
+ EXPECT_TRUE(DoTest(in, "", &install_plan));
+ EXPECT_FALSE(install_plan.rollback_data_save_requested);
+}
+
+// Never attempt rollback data restore if powerwash is not allowed.
+TEST_F(OmahaResponseHandlerActionTest,
+ ChangeToMoreStableChannelNoPowerwashNoDataRestore) {
+ OmahaResponse in;
+ in.update_exists = true;
+ in.version = "12345.96.0.0";
+ in.packages.push_back(
+ {.payload_urls = {"https://URL"}, .size = 1, .hash = kPayloadHashHex});
+ in.more_info_url = "http://more/info";
+
+ // Create a uniquely named test directory.
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+
+ OmahaRequestParams params(&fake_system_state_);
+ fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
+ params.set_root(tempdir.GetPath().value());
+ params.set_current_channel("beta-channel");
+ EXPECT_TRUE(params.SetTargetChannel("stable-channel", false, nullptr));
+ params.UpdateDownloadChannel();
+ params.set_app_version("12347.48.0.0");
+
+ fake_system_state_.set_request_params(¶ms);
+ InstallPlan install_plan;
+ EXPECT_TRUE(DoTest(in, "", &install_plan));
+ EXPECT_FALSE(install_plan.rollback_data_save_requested);
+}
+
+TEST_F(OmahaResponseHandlerActionTest,
ChangeToLessStableVersionAndChannelTest) {
OmahaResponse in;
in.update_exists = true;
@@ -793,7 +919,6 @@
OmahaResponse in;
in.update_exists = true;
in.version = "a.b.c.d";
- in.system_version = "b.c.d.e";
in.packages.push_back({.payload_urls = {"http://package/1"},
.size = 1,
.hash = kPayloadHashHex});
@@ -810,7 +935,6 @@
EXPECT_EQ(expected_hash_, install_plan.payloads[0].hash);
EXPECT_EQ(expected_hash_, install_plan.payloads[1].hash);
EXPECT_EQ(in.version, install_plan.version);
- EXPECT_EQ(in.system_version, install_plan.system_version);
}
TEST_F(OmahaResponseHandlerActionTest, TestDeferredByPolicy) {
diff --git a/omaha_utils.cc b/cros/omaha_utils.cc
similarity index 95%
rename from omaha_utils.cc
rename to cros/omaha_utils.cc
index c7f9921..fc05cb9 100644
--- a/omaha_utils.cc
+++ b/cros/omaha_utils.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_utils.h"
+#include "update_engine/cros/omaha_utils.h"
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
diff --git a/omaha_utils.h b/cros/omaha_utils.h
similarity index 89%
rename from omaha_utils.h
rename to cros/omaha_utils.h
index 458bf9e..6741635 100644
--- a/omaha_utils.h
+++ b/cros/omaha_utils.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_OMAHA_UTILS_H_
-#define UPDATE_ENGINE_OMAHA_UTILS_H_
+#ifndef UPDATE_ENGINE_CROS_OMAHA_UTILS_H_
+#define UPDATE_ENGINE_CROS_OMAHA_UTILS_H_
#include <string>
@@ -36,4 +36,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_OMAHA_UTILS_H_
+#endif // UPDATE_ENGINE_CROS_OMAHA_UTILS_H_
diff --git a/omaha_utils_unittest.cc b/cros/omaha_utils_unittest.cc
similarity index 96%
rename from omaha_utils_unittest.cc
rename to cros/omaha_utils_unittest.cc
index 849905a..f89f690 100644
--- a/omaha_utils_unittest.cc
+++ b/cros/omaha_utils_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/omaha_utils.h"
+#include "update_engine/cros/omaha_utils.h"
#include <gtest/gtest.h>
#include <vector>
diff --git a/p2p_manager.cc b/cros/p2p_manager.cc
similarity index 99%
rename from p2p_manager.cc
rename to cros/p2p_manager.cc
index 00ff8ce..dc12b35 100644
--- a/p2p_manager.cc
+++ b/cros/p2p_manager.cc
@@ -23,7 +23,7 @@
#define _BSD_SOURCE
#endif
-#include "update_engine/p2p_manager.h"
+#include "update_engine/cros/p2p_manager.h"
#include <errno.h>
#include <fcntl.h>
diff --git a/p2p_manager.h b/cros/p2p_manager.h
similarity index 97%
rename from p2p_manager.h
rename to cros/p2p_manager.h
index ef62f0d..bd359fa 100644
--- a/p2p_manager.h
+++ b/cros/p2p_manager.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_P2P_MANAGER_H_
-#define UPDATE_ENGINE_P2P_MANAGER_H_
+#ifndef UPDATE_ENGINE_CROS_P2P_MANAGER_H_
+#define UPDATE_ENGINE_CROS_P2P_MANAGER_H_
#include <string>
#include <vector>
@@ -183,4 +183,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_P2P_MANAGER_H_
+#endif // UPDATE_ENGINE_CROS_P2P_MANAGER_H_
diff --git a/p2p_manager_unittest.cc b/cros/p2p_manager_unittest.cc
similarity index 97%
rename from p2p_manager_unittest.cc
rename to cros/p2p_manager_unittest.cc
index 5771ec1..8b6d741 100644
--- a/p2p_manager_unittest.cc
+++ b/cros/p2p_manager_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/p2p_manager.h"
+#include "update_engine/cros/p2p_manager.h"
#include <dirent.h>
#include <fcntl.h>
@@ -30,8 +30,13 @@
#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_util.h>
+#if BASE_VER < 780000 // Android
#include <base/message_loop/message_loop.h>
+#endif // BASE_VER < 780000
#include <base/strings/stringprintf.h>
+#if BASE_VER >= 780000 // CrOS
+#include <base/task/single_thread_task_executor.h>
+#endif // BASE_VER >= 780000
#include <brillo/asynchronous_signal_handler.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
@@ -46,7 +51,7 @@
#include "update_engine/common/subprocess.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_p2p_manager_configuration.h"
+#include "update_engine/cros/fake_p2p_manager_configuration.h"
#include "update_engine/update_manager/fake_update_manager.h"
#include "update_engine/update_manager/mock_policy.h"
@@ -92,8 +97,13 @@
TimeDelta::FromDays(5)));
}
+#if BASE_VER < 780000 // Android
base::MessageLoopForIO base_loop_;
brillo::BaseMessageLoop loop_{&base_loop_};
+#else // CrOS
+ base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
+ brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
+#endif // BASE_VER < 780000
brillo::AsynchronousSignalHandler async_signal_handler_;
Subprocess subprocess_;
diff --git a/payload_state.cc b/cros/payload_state.cc
similarity index 98%
rename from payload_state.cc
rename to cros/payload_state.cc
index 4945fe7..d2e6851 100644
--- a/payload_state.cc
+++ b/cros/payload_state.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/payload_state.h"
+#include "update_engine/cros/payload_state.h"
#include <algorithm>
#include <string>
@@ -29,15 +29,15 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/prefs.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/metrics_reporter_interface.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/update_attempter.h"
#include "update_engine/metrics_utils.h"
-#include "update_engine/omaha_request_params.h"
#include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/system_state.h"
-#include "update_engine/update_attempter.h"
using base::Time;
using base::TimeDelta;
@@ -375,6 +375,7 @@
case ErrorCode::kUnresolvedHostRecovered:
case ErrorCode::kNotEnoughSpace:
case ErrorCode::kDeviceCorrupted:
+ case ErrorCode::kPackageExcludedFromUpdate:
LOG(INFO) << "Not incrementing URL index or failure count for this error";
break;
@@ -463,6 +464,7 @@
}
void PayloadState::IncrementFullPayloadAttemptNumber() {
+ DCHECK(payload_index_ < response_.packages.size());
// Update the payload attempt number for full payloads and the backoff time.
if (response_.packages[payload_index_].is_delta) {
LOG(INFO) << "Not incrementing payload attempt number for delta payloads";
@@ -475,6 +477,7 @@
}
void PayloadState::IncrementUrlIndex() {
+ DCHECK(payload_index_ < candidate_urls_.size());
size_t next_url_index = url_index_ + 1;
size_t max_url_size = candidate_urls_[payload_index_].size();
if (next_url_index < max_url_size) {
@@ -511,6 +514,10 @@
}
void PayloadState::ExcludeCurrentPayload() {
+ if (payload_index_ >= response_.packages.size()) {
+ LOG(INFO) << "Skipping exclusion of the current payload.";
+ return;
+ }
const auto& package = response_.packages[payload_index_];
if (!package.can_exclude) {
LOG(INFO) << "Not excluding as marked non-excludable for package hash="
@@ -613,10 +620,6 @@
return kPayloadTypeForcedFull;
}
-// TODO(zeuthen): Currently we don't report the UpdateEngine.Attempt.*
-// metrics if the attempt ends abnormally, e.g. if the update_engine
-// process crashes or the device is rebooted. See
-// http://crbug.com/357676
void PayloadState::CollectAndReportAttemptMetrics(ErrorCode code) {
int attempt_number = GetPayloadAttemptNumber();
@@ -671,6 +674,7 @@
case metrics::AttemptResult::kAbnormalTermination:
case metrics::AttemptResult::kUpdateCanceled:
case metrics::AttemptResult::kUpdateSucceededNotActive:
+ case metrics::AttemptResult::kUpdateSkipped:
case metrics::AttemptResult::kNumConstants:
case metrics::AttemptResult::kUnset:
break;
@@ -924,10 +928,12 @@
}
bool PayloadState::NextPayload() {
- if (payload_index_ + 1 >= candidate_urls_.size())
+ if (payload_index_ >= candidate_urls_.size())
+ return false;
+ SetPayloadIndex(payload_index_ + 1);
+ if (payload_index_ >= candidate_urls_.size())
return false;
SetUrlIndex(0);
- SetPayloadIndex(payload_index_ + 1);
return true;
}
diff --git a/payload_state.h b/cros/payload_state.h
similarity index 97%
rename from payload_state.h
rename to cros/payload_state.h
index 427836b..0827273 100644
--- a/payload_state.h
+++ b/cros/payload_state.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_PAYLOAD_STATE_H_
-#define UPDATE_ENGINE_PAYLOAD_STATE_H_
+#ifndef UPDATE_ENGINE_CROS_PAYLOAD_STATE_H_
+#define UPDATE_ENGINE_CROS_PAYLOAD_STATE_H_
#include <algorithm>
#include <string>
@@ -25,9 +25,9 @@
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "update_engine/common/excluder_interface.h"
+#include "update_engine/common/metrics_constants.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/payload_state_interface.h"
+#include "update_engine/cros/payload_state_interface.h"
namespace chromeos_update_engine {
@@ -161,6 +161,8 @@
FRIEND_TEST(PayloadStateTest, ExcludeNoopForNonExcludables);
FRIEND_TEST(PayloadStateTest, ExcludeOnlyCanExcludables);
FRIEND_TEST(PayloadStateTest, IncrementFailureExclusionTest);
+ FRIEND_TEST(PayloadStateTest, HaltExclusionPostPayloadExhaustion);
+ FRIEND_TEST(PayloadStateTest, NonInfinitePayloadIndexIncrement);
// Helper called when an attempt has begun, is called by
// UpdateResumed(), UpdateRestarted() and Rollback().
@@ -597,4 +599,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_PAYLOAD_STATE_H_
+#endif // UPDATE_ENGINE_CROS_PAYLOAD_STATE_H_
diff --git a/payload_state_interface.h b/cros/payload_state_interface.h
similarity index 97%
rename from payload_state_interface.h
rename to cros/payload_state_interface.h
index d384a0e..9ead650 100644
--- a/payload_state_interface.h
+++ b/cros/payload_state_interface.h
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_PAYLOAD_STATE_INTERFACE_H_
-#define UPDATE_ENGINE_PAYLOAD_STATE_INTERFACE_H_
+#ifndef UPDATE_ENGINE_CROS_PAYLOAD_STATE_INTERFACE_H_
+#define UPDATE_ENGINE_CROS_PAYLOAD_STATE_INTERFACE_H_
#include <string>
#include "update_engine/common/action_processor.h"
#include "update_engine/common/constants.h"
-#include "update_engine/omaha_response.h"
+#include "update_engine/cros/omaha_response.h"
namespace chromeos_update_engine {
@@ -212,4 +212,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_PAYLOAD_STATE_INTERFACE_H_
+#endif // UPDATE_ENGINE_CROS_PAYLOAD_STATE_INTERFACE_H_
diff --git a/payload_state_unittest.cc b/cros/payload_state_unittest.cc
similarity index 97%
rename from payload_state_unittest.cc
rename to cros/payload_state_unittest.cc
index c33bda4..b48cff4 100644
--- a/payload_state_unittest.cc
+++ b/cros/payload_state_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/payload_state.h"
+#include "update_engine/cros/payload_state.h"
#include <base/files/file_path.h>
#include <base/files/file_util.h>
@@ -27,14 +27,14 @@
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/mock_excluder.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/metrics_reporter_interface.h"
-#include "update_engine/omaha_request_action.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/omaha_request_action.h"
using base::Time;
using base::TimeDelta;
@@ -630,7 +630,7 @@
PayloadState payload_state;
FakeSystemState fake_system_state;
OmahaRequestParams params(&fake_system_state);
- params.Init("", "", true); // interactive = True.
+ params.Init("", "", {.interactive = true});
fake_system_state.set_request_params(¶ms);
EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
@@ -653,7 +653,7 @@
PayloadState payload_state;
FakeSystemState fake_system_state;
OmahaRequestParams params(&fake_system_state);
- params.Init("", "", false); // interactive = False.
+ params.Init("", "", {});
fake_system_state.set_request_params(¶ms);
EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
@@ -1019,7 +1019,7 @@
// Mock out the os version and make sure it's excluded correctly.
string rollback_version = "2345.0.0";
OmahaRequestParams params(&fake_system_state);
- params.Init(rollback_version, "", false);
+ params.Init(rollback_version, "", {});
fake_system_state.set_request_params(¶ms);
EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
@@ -1778,4 +1778,49 @@
payload_state.IncrementFailureCount();
}
+TEST(PayloadStateTest, HaltExclusionPostPayloadExhaustion) {
+ PayloadState payload_state;
+ FakeSystemState fake_system_state;
+ StrictMock<MockExcluder> mock_excluder;
+ EXPECT_CALL(*fake_system_state.mock_update_attempter(), GetExcluder())
+ .WillOnce(Return(&mock_excluder));
+ EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+
+ OmahaResponse response;
+ // Non-critical package.
+ response.packages.push_back(
+ {.payload_urls = {"http://test1a", "http://test2a"},
+ .size = 123456789,
+ .metadata_size = 58123,
+ .metadata_signature = "msign",
+ .hash = "hash",
+ .can_exclude = true});
+ payload_state.SetResponse(response);
+
+ // Exclusion should be called when excluded.
+ EXPECT_CALL(mock_excluder, Exclude(utils::GetExclusionName("http://test1a")))
+ .WillOnce(Return(true));
+ payload_state.ExcludeCurrentPayload();
+
+ // No more paylods to go through.
+ EXPECT_FALSE(payload_state.NextPayload());
+
+ // Exclusion should not be called as all |Payload|s are exhausted.
+ payload_state.ExcludeCurrentPayload();
+}
+
+TEST(PayloadStateTest, NonInfinitePayloadIndexIncrement) {
+ PayloadState payload_state;
+ FakeSystemState fake_system_state;
+ EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
+
+ payload_state.SetResponse({});
+
+ EXPECT_FALSE(payload_state.NextPayload());
+ int payload_index = payload_state.payload_index_;
+
+ EXPECT_FALSE(payload_state.NextPayload());
+ EXPECT_EQ(payload_index, payload_state.payload_index_);
+}
+
} // namespace chromeos_update_engine
diff --git a/common/platform_constants_chromeos.cc b/cros/platform_constants_chromeos.cc
similarity index 100%
rename from common/platform_constants_chromeos.cc
rename to cros/platform_constants_chromeos.cc
diff --git a/power_manager_chromeos.cc b/cros/power_manager_chromeos.cc
similarity index 92%
rename from power_manager_chromeos.cc
rename to cros/power_manager_chromeos.cc
index 531d367..c1a2859 100644
--- a/power_manager_chromeos.cc
+++ b/cros/power_manager_chromeos.cc
@@ -14,14 +14,14 @@
// limitations under the License.
//
-#include "update_engine/power_manager_chromeos.h"
+#include "update_engine/cros/power_manager_chromeos.h"
#include <memory>
#include <power_manager/dbus-constants.h>
#include <power_manager/dbus-proxies.h>
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
namespace chromeos_update_engine {
diff --git a/power_manager_chromeos.h b/cros/power_manager_chromeos.h
similarity index 83%
rename from power_manager_chromeos.h
rename to cros/power_manager_chromeos.h
index eeb14d8..8930508 100644
--- a/power_manager_chromeos.h
+++ b/cros/power_manager_chromeos.h
@@ -14,13 +14,13 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_POWER_MANAGER_CHROMEOS_H_
-#define UPDATE_ENGINE_POWER_MANAGER_CHROMEOS_H_
+#ifndef UPDATE_ENGINE_CROS_POWER_MANAGER_CHROMEOS_H_
+#define UPDATE_ENGINE_CROS_POWER_MANAGER_CHROMEOS_H_
#include <base/macros.h>
#include <power_manager/dbus-proxies.h>
-#include "update_engine/power_manager_interface.h"
+#include "update_engine/cros/power_manager_interface.h"
namespace chromeos_update_engine {
@@ -41,4 +41,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_POWER_MANAGER_CHROMEOS_H_
+#endif // UPDATE_ENGINE_CROS_POWER_MANAGER_CHROMEOS_H_
diff --git a/power_manager_interface.h b/cros/power_manager_interface.h
similarity index 87%
rename from power_manager_interface.h
rename to cros/power_manager_interface.h
index 8f77650..1f712d2 100644
--- a/power_manager_interface.h
+++ b/cros/power_manager_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_POWER_MANAGER_INTERFACE_H_
-#define UPDATE_ENGINE_POWER_MANAGER_INTERFACE_H_
+#ifndef UPDATE_ENGINE_CROS_POWER_MANAGER_INTERFACE_H_
+#define UPDATE_ENGINE_CROS_POWER_MANAGER_INTERFACE_H_
#include <memory>
@@ -44,4 +44,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_POWER_MANAGER_INTERFACE_H_
+#endif // UPDATE_ENGINE_CROS_POWER_MANAGER_INTERFACE_H_
diff --git a/real_system_state.cc b/cros/real_system_state.cc
similarity index 97%
rename from real_system_state.cc
rename to cros/real_system_state.cc
index 74a37f3..4f57246 100644
--- a/real_system_state.cc
+++ b/cros/real_system_state.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/real_system_state.h"
+#include "update_engine/cros/real_system_state.h"
#include <memory>
#include <string>
@@ -35,11 +35,11 @@
#include "update_engine/common/dlcservice_interface.h"
#include "update_engine/common/hardware.h"
#include "update_engine/common/utils.h"
-#include "update_engine/metrics_reporter_omaha.h"
-#include "update_engine/update_boot_flags_action.h"
+#include "update_engine/cros/metrics_reporter_omaha.h"
#if USE_DBUS
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
#endif // USE_DBUS
+#include "update_engine/update_boot_flags_action.h"
#include "update_engine/update_manager/state_factory.h"
using brillo::MessageLoop;
@@ -138,7 +138,7 @@
// will be re-initialized before every request using the actual request
// options. This initialization here pre-loads current channel and version, so
// the DBus service can access it.
- if (!request_params_.Init("", "", false)) {
+ if (!request_params_.Init("", "", {})) {
LOG(WARNING) << "Ignoring OmahaRequestParams initialization error. Some "
"features might not work properly.";
}
diff --git a/real_system_state.h b/cros/real_system_state.h
similarity index 90%
rename from real_system_state.h
rename to cros/real_system_state.h
index 807a205..798fca0 100644
--- a/real_system_state.h
+++ b/cros/real_system_state.h
@@ -14,10 +14,10 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_REAL_SYSTEM_STATE_H_
-#define UPDATE_ENGINE_REAL_SYSTEM_STATE_H_
+#ifndef UPDATE_ENGINE_CROS_REAL_SYSTEM_STATE_H_
+#define UPDATE_ENGINE_CROS_REAL_SYSTEM_STATE_H_
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
#include <memory>
#include <set>
@@ -31,17 +31,17 @@
#include "update_engine/certificate_checker.h"
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/clock.h"
+#include "update_engine/common/daemon_state_interface.h"
#include "update_engine/common/dlcservice_interface.h"
#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/prefs.h"
-#include "update_engine/connection_manager_interface.h"
-#include "update_engine/daemon_state_interface.h"
-#include "update_engine/metrics_reporter_interface.h"
-#include "update_engine/metrics_reporter_omaha.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/payload_state.h"
-#include "update_engine/power_manager_interface.h"
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/connection_manager_interface.h"
+#include "update_engine/cros/metrics_reporter_omaha.h"
+#include "update_engine/cros/p2p_manager.h"
+#include "update_engine/cros/payload_state.h"
+#include "update_engine/cros/power_manager_interface.h"
+#include "update_engine/cros/update_attempter.h"
#include "update_engine/update_manager/update_manager.h"
namespace chromeos_update_engine {
@@ -199,4 +199,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_REAL_SYSTEM_STATE_H_
+#endif // UPDATE_ENGINE_CROS_REAL_SYSTEM_STATE_H_
diff --git a/cros/requisition_util.cc b/cros/requisition_util.cc
new file mode 100644
index 0000000..6296d0b
--- /dev/null
+++ b/cros/requisition_util.cc
@@ -0,0 +1,69 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/cros/requisition_util.h"
+
+#include <memory>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <base/json/json_file_value_serializer.h>
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+
+#include "update_engine/common/subprocess.h"
+#include "update_engine/common/utils.h"
+
+using std::string;
+using std::vector;
+
+namespace {
+
+constexpr char kOemRequisitionKey[] = "oem_device_requisition";
+
+} // namespace
+
+namespace chromeos_update_engine {
+
+string ReadDeviceRequisition(const base::FilePath& local_state) {
+ string requisition;
+ bool vpd_retval = utils::GetVpdValue(kOemRequisitionKey, &requisition);
+
+ // Some users manually convert non-CfM hardware at enrollment time, so VPD
+ // value may be missing. So check the Local State JSON as well.
+ if ((requisition.empty() || !vpd_retval) && base::PathExists(local_state)) {
+ int error_code;
+ std::string error_msg;
+ JSONFileValueDeserializer deserializer(local_state);
+ std::unique_ptr<base::Value> root =
+ deserializer.Deserialize(&error_code, &error_msg);
+ if (!root) {
+ if (error_code != 0) {
+ LOG(ERROR) << "Unable to deserialize Local State with exit code: "
+ << error_code << " and error: " << error_msg;
+ }
+ return "";
+ }
+ auto* path = root->FindPath({"enrollment", "device_requisition"});
+ if (!path || !path->is_string()) {
+ return "";
+ }
+ path->GetAsString(&requisition);
+ }
+ return requisition;
+}
+
+} // namespace chromeos_update_engine
diff --git a/cros/requisition_util.h b/cros/requisition_util.h
new file mode 100644
index 0000000..6ec4783
--- /dev/null
+++ b/cros/requisition_util.h
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_CROS_REQUISITION_UTIL_H_
+#define UPDATE_ENGINE_CROS_REQUISITION_UTIL_H_
+
+#include <string>
+
+#include <base/files/file_path.h>
+
+namespace chromeos_update_engine {
+
+// Checks the VPD and Local State for the device's requisition and returns it,
+// or an empty string if the device has no requisition.
+std::string ReadDeviceRequisition(const base::FilePath& local_state);
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_CROS_REQUISITION_UTIL_H_
diff --git a/cros/requisition_util_unittest.cc b/cros/requisition_util_unittest.cc
new file mode 100644
index 0000000..269585e
--- /dev/null
+++ b/cros/requisition_util_unittest.cc
@@ -0,0 +1,94 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/cros/requisition_util.h"
+
+#include <string>
+
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/test_utils.h"
+
+using chromeos_update_engine::test_utils::WriteFileString;
+using std::string;
+
+namespace {
+
+const char kRemoraJSON[] =
+ "{\n"
+ " \"the_list\": [ \"val1\", \"val2\" ],\n"
+ " \"enrollment\": {\n"
+ " \"autostart\": true,\n"
+ " \"can_exit\": false,\n"
+ " \"device_requisition\": \"remora\"\n"
+ " },\n"
+ " \"some_String\": \"1337\",\n"
+ " \"some_int\": 42\n"
+ "}\n";
+
+const char kNoEnrollmentJSON[] =
+ "{\n"
+ " \"the_list\": [ \"val1\", \"val2\" ],\n"
+ " \"enrollment\": {\n"
+ " \"autostart\": true,\n"
+ " \"can_exit\": false,\n"
+ " \"device_requisition\": \"\"\n"
+ " },\n"
+ " \"some_String\": \"1337\",\n"
+ " \"some_int\": 42\n"
+ "}\n";
+} // namespace
+
+namespace chromeos_update_engine {
+
+class RequisitionUtilTest : public ::testing::Test {
+ protected:
+ void SetUp() override { ASSERT_TRUE(root_dir_.CreateUniqueTempDir()); }
+
+ void WriteJsonToFile(const string& json) {
+ path_ =
+ base::FilePath(root_dir_.GetPath().value() + "/chronos/Local State");
+ ASSERT_TRUE(base::CreateDirectory(path_.DirName()));
+ ASSERT_TRUE(WriteFileString(path_.value(), json));
+ }
+
+ base::ScopedTempDir root_dir_;
+ base::FilePath path_;
+};
+
+TEST_F(RequisitionUtilTest, BadJsonReturnsEmpty) {
+ WriteJsonToFile("this isn't JSON");
+ EXPECT_EQ("", ReadDeviceRequisition(path_));
+}
+
+TEST_F(RequisitionUtilTest, NoFileReturnsEmpty) {
+ EXPECT_EQ("", ReadDeviceRequisition(path_));
+}
+
+TEST_F(RequisitionUtilTest, EnrollmentRequisition) {
+ WriteJsonToFile(kRemoraJSON);
+ EXPECT_EQ("remora", ReadDeviceRequisition(path_));
+}
+
+TEST_F(RequisitionUtilTest, BlankEnrollment) {
+ WriteJsonToFile(kNoEnrollmentJSON);
+ EXPECT_EQ("", ReadDeviceRequisition(path_));
+}
+
+} // namespace chromeos_update_engine
diff --git a/shill_proxy.cc b/cros/shill_proxy.cc
similarity index 93%
rename from shill_proxy.cc
rename to cros/shill_proxy.cc
index d398bba..a3c8543 100644
--- a/shill_proxy.cc
+++ b/cros/shill_proxy.cc
@@ -14,9 +14,9 @@
// limitations under the License.
//
-#include "update_engine/shill_proxy.h"
+#include "update_engine/cros/shill_proxy.h"
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
using org::chromium::flimflam::ManagerProxy;
using org::chromium::flimflam::ManagerProxyInterface;
diff --git a/shill_proxy.h b/cros/shill_proxy.h
similarity index 88%
rename from shill_proxy.h
rename to cros/shill_proxy.h
index 4b466c9..aff428a 100644
--- a/shill_proxy.h
+++ b/cros/shill_proxy.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_SHILL_PROXY_H_
-#define UPDATE_ENGINE_SHILL_PROXY_H_
+#ifndef UPDATE_ENGINE_CROS_SHILL_PROXY_H_
+#define UPDATE_ENGINE_CROS_SHILL_PROXY_H_
#include <memory>
#include <string>
@@ -25,7 +25,7 @@
#include <dbus/object_path.h>
#include <shill/dbus-proxies.h>
-#include "update_engine/shill_proxy_interface.h"
+#include "update_engine/cros/shill_proxy_interface.h"
namespace chromeos_update_engine {
@@ -51,4 +51,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_SHILL_PROXY_H_
+#endif // UPDATE_ENGINE_CROS_SHILL_PROXY_H_
diff --git a/shill_proxy_interface.h b/cros/shill_proxy_interface.h
similarity index 91%
rename from shill_proxy_interface.h
rename to cros/shill_proxy_interface.h
index 5f6b44e..19e81f3 100644
--- a/shill_proxy_interface.h
+++ b/cros/shill_proxy_interface.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_SHILL_PROXY_INTERFACE_H_
-#define UPDATE_ENGINE_SHILL_PROXY_INTERFACE_H_
+#ifndef UPDATE_ENGINE_CROS_SHILL_PROXY_INTERFACE_H_
+#define UPDATE_ENGINE_CROS_SHILL_PROXY_INTERFACE_H_
#include <memory>
#include <string>
@@ -53,4 +53,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_SHILL_PROXY_INTERFACE_H_
+#endif // UPDATE_ENGINE_CROS_SHILL_PROXY_INTERFACE_H_
diff --git a/update_attempter.cc b/cros/update_attempter.cc
similarity index 93%
rename from update_attempter.cc
rename to cros/update_attempter.cc
index c4fe348..e8cb291 100644
--- a/update_attempter.cc
+++ b/cros/update_attempter.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/update_attempter.h"
#include <stdint.h>
@@ -47,26 +47,26 @@
#include "update_engine/common/clock_interface.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/dlcservice_interface.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/excluder_interface.h"
#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/subprocess.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/common/utils.h"
+#include "update_engine/cros/omaha_request_action.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/omaha_response_handler_action.h"
+#include "update_engine/cros/omaha_utils.h"
+#include "update_engine/cros/p2p_manager.h"
+#include "update_engine/cros/payload_state_interface.h"
+#include "update_engine/cros/power_manager_interface.h"
#include "update_engine/libcurl_http_fetcher.h"
-#include "update_engine/metrics_reporter_interface.h"
-#include "update_engine/omaha_request_action.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/omaha_response_handler_action.h"
-#include "update_engine/omaha_utils.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
#include "update_engine/payload_consumer/postinstall_runner_action.h"
-#include "update_engine/payload_state_interface.h"
-#include "update_engine/power_manager_interface.h"
-#include "update_engine/system_state.h"
#include "update_engine/update_boot_flags_action.h"
#include "update_engine/update_manager/policy.h"
#include "update_engine/update_manager/policy_utils.h"
@@ -244,15 +244,7 @@
system_state_->metrics_reporter()->ReportDailyMetrics(age);
}
-void UpdateAttempter::Update(const string& app_version,
- const string& omaha_url,
- const string& target_channel,
- const string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive) {
+void UpdateAttempter::Update(const UpdateCheckParams& params) {
// This is normally called frequently enough so it's appropriate to use as a
// hook for reporting daily metrics.
// TODO(garnold) This should be hooked to a separate (reliable and consistent)
@@ -281,19 +273,11 @@
return;
}
- if (!CalculateUpdateParams(app_version,
- omaha_url,
- target_channel,
- target_version_prefix,
- rollback_allowed,
- rollback_data_save_requested,
- rollback_allowed_milestones,
- obey_proxies,
- interactive)) {
+ if (!CalculateUpdateParams(params)) {
return;
}
- BuildUpdateActions(interactive);
+ BuildUpdateActions(params.interactive);
SetStatusAndNotify(UpdateStatus::CHECKING_FOR_UPDATE);
@@ -356,15 +340,7 @@
payload_state->SetUsingP2PForSharing(use_p2p_for_sharing);
}
-bool UpdateAttempter::CalculateUpdateParams(const string& app_version,
- const string& omaha_url,
- const string& target_channel,
- const string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive) {
+bool UpdateAttempter::CalculateUpdateParams(const UpdateCheckParams& params) {
http_response_code_ = 0;
PayloadStateInterface* const payload_state = system_state_->payload_state();
@@ -375,27 +351,13 @@
// policy is available again.
UpdateRollbackHappened();
- // Update the target version prefix.
- omaha_request_params_->set_target_version_prefix(target_version_prefix);
-
- // Set whether rollback is allowed.
- omaha_request_params_->set_rollback_allowed(rollback_allowed);
-
- // Set whether saving data over rollback is requested.
- omaha_request_params_->set_rollback_data_save_requested(
- rollback_data_save_requested);
-
- CalculateStagingParams(interactive);
+ CalculateStagingParams(params.interactive);
// If staging_wait_time_ wasn't set, staging is off, use scattering instead.
if (staging_wait_time_.InSeconds() == 0) {
- CalculateScatteringParams(interactive);
+ CalculateScatteringParams(params.interactive);
}
- // Set how many milestones of rollback are allowed.
- omaha_request_params_->set_rollback_allowed_milestones(
- rollback_allowed_milestones);
-
- CalculateP2PParams(interactive);
+ CalculateP2PParams(params.interactive);
if (payload_state->GetUsingP2PForDownloading() ||
payload_state->GetUsingP2PForSharing()) {
// OK, p2p is to be used - start it and perform housekeeping.
@@ -408,32 +370,12 @@
}
}
- if (!omaha_request_params_->Init(app_version, omaha_url, interactive)) {
+ if (!omaha_request_params_->Init(
+ forced_app_version_, forced_omaha_url_, params)) {
LOG(ERROR) << "Unable to initialize Omaha request params.";
return false;
}
- // Set the target channel, if one was provided.
- if (target_channel.empty()) {
- LOG(INFO) << "No target channel mandated by policy.";
- } else {
- LOG(INFO) << "Setting target channel as mandated: " << target_channel;
- // Pass in false for powerwash_allowed until we add it to the policy
- // protobuf.
- string error_message;
- if (!omaha_request_params_->SetTargetChannel(
- target_channel, false, &error_message)) {
- LOG(ERROR) << "Setting the channel failed: " << error_message;
- }
-
- // Since this is the beginning of a new attempt, update the download
- // channel. The download channel won't be updated until the next attempt,
- // even if target channel changes meanwhile, so that how we'll know if we
- // should cancel the current download attempt if there's such a change in
- // target channel.
- omaha_request_params_->UpdateDownloadChannel();
- }
-
// The function |CalculateDlcParams| makes use of the function |GetAppId| from
// |OmahaRequestParams|, so to ensure that the return from |GetAppId|
// doesn't change, no changes to the values |download_channel_|,
@@ -441,8 +383,6 @@
// |omaha_request_params_| shall be made below this line.
CalculateDlcParams();
- omaha_request_params_->set_is_install(is_install_);
-
// Set Quick Fix Build token if policy is set and the device is enterprise
// enrolled.
string token;
@@ -473,7 +413,7 @@
<< payload_state->GetUsingP2PForSharing();
obeying_proxies_ = true;
- if (obey_proxies || proxy_manual_checks_ == 0) {
+ if (proxy_manual_checks_ == 0) {
LOG(INFO) << "forced to obey proxies";
// If forced to obey proxies, every 20th request will not use proxies
proxy_manual_checks_++;
@@ -760,6 +700,7 @@
dlc_apps_params[omaha_request_params_->GetDlcAppId(dlc_id)] = dlc_params;
}
omaha_request_params_->set_dlc_apps_params(dlc_apps_params);
+ omaha_request_params_->set_is_install(is_install_);
}
void UpdateAttempter::BuildUpdateActions(bool interactive) {
@@ -874,7 +815,7 @@
processor_->set_delegate(this);
// Initialize the default request params.
- if (!omaha_request_params_->Init("", "", true)) {
+ if (!omaha_request_params_->Init("", "", {.interactive = true})) {
LOG(ERROR) << "Unable to initialize Omaha request params.";
return false;
}
@@ -1100,15 +1041,7 @@
LOG(INFO) << "Update attempt flags in use = 0x" << std::hex
<< current_update_attempt_flags_;
- Update(forced_app_version_,
- forced_omaha_url_,
- params.target_channel,
- params.target_version_prefix,
- params.rollback_allowed,
- params.rollback_data_save_requested,
- params.rollback_allowed_milestones,
- /*obey_proxies=*/false,
- params.interactive);
+ Update(params);
// Always clear the forced app_version and omaha_url after an update attempt
// so the next update uses the defaults.
forced_app_version_.clear();
diff --git a/update_attempter.h b/cros/update_attempter.h
similarity index 91%
rename from update_attempter.h
rename to cros/update_attempter.h
index dd958f5..0f4c952 100644
--- a/update_attempter.h
+++ b/cros/update_attempter.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_UPDATE_ATTEMPTER_H_
-#define UPDATE_ENGINE_UPDATE_ATTEMPTER_H_
+#ifndef UPDATE_ENGINE_CROS_UPDATE_ATTEMPTER_H_
+#define UPDATE_ENGINE_CROS_UPDATE_ATTEMPTER_H_
#include <time.h>
@@ -30,22 +30,22 @@
#include <base/time/time.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
-#if USE_CHROME_NETWORK_PROXY
-#include "update_engine/chrome_browser_proxy_resolver.h"
-#endif // USE_CHROME_NETWORK_PROXY
#include "update_engine/certificate_checker.h"
#include "update_engine/client_library/include/update_engine/update_status.h"
#include "update_engine/common/action_processor.h"
#include "update_engine/common/cpu_limiter.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/excluder_interface.h"
#include "update_engine/common/proxy_resolver.h"
-#include "update_engine/omaha_request_builder_xml.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/omaha_response_handler_action.h"
-#include "update_engine/payload_consumer/download_action.h"
+#include "update_engine/common/service_observer_interface.h"
+#include "update_engine/common/system_state.h"
+#if USE_CHROME_NETWORK_PROXY
+#include "update_engine/cros/chrome_browser_proxy_resolver.h"
+#endif // USE_CHROME_NETWORK_PROXY
+#include "update_engine/cros/omaha_request_builder_xml.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/omaha_response_handler_action.h"
#include "update_engine/payload_consumer/postinstall_runner_action.h"
-#include "update_engine/service_observer_interface.h"
-#include "update_engine/system_state.h"
#include "update_engine/update_manager/policy.h"
#include "update_engine/update_manager/staging_utils.h"
#include "update_engine/update_manager/update_manager.h"
@@ -76,21 +76,8 @@
virtual bool ScheduleUpdates();
// Checks for update and, if a newer version is available, attempts to update
- // the system. Non-empty |in_app_version| or |in_update_url| prevents
- // automatic detection of the parameter. |target_channel| denotes a
- // policy-mandated channel we are updating to, if not empty. If |obey_proxies|
- // is true, the update will likely respect Chrome's proxy setting. For
- // security reasons, we may still not honor them. |interactive| should be true
- // if this was called from the user (ie dbus).
- virtual void Update(const std::string& app_version,
- const std::string& omaha_url,
- const std::string& target_channel,
- const std::string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive);
+ // the system.
+ virtual void Update(const chromeos_update_manager::UpdateCheckParams& params);
// ActionProcessorDelegate methods:
void ProcessingDone(const ActionProcessor* processor,
@@ -163,7 +150,7 @@
// UPDATED_NEED_REBOOT. Returns true on success, false otherwise.
bool RebootIfNeeded();
- // Sets the DLC as active or inactive. See common_service.h
+ // Sets the DLC as active or inactive. See chromeos/common_service.h
virtual bool SetDlcActiveValue(bool is_active, const std::string& dlc_id);
// DownloadActionDelegate methods:
@@ -283,6 +270,8 @@
FRIEND_TEST(UpdateAttempterTest, RollbackAfterInstall);
FRIEND_TEST(UpdateAttempterTest, RollbackAllowed);
FRIEND_TEST(UpdateAttempterTest, RollbackAllowedSetAndReset);
+ FRIEND_TEST(UpdateAttempterTest, ChannelDowngradeNoRollback);
+ FRIEND_TEST(UpdateAttempterTest, ChannelDowngradeRollback);
FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackFailure);
FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackSuccess);
FRIEND_TEST(UpdateAttempterTest, RollbackMetricsRollbackFailure);
@@ -293,6 +282,7 @@
FRIEND_TEST(UpdateAttempterTest, SessionIdTestOnOmahaRequestActions);
FRIEND_TEST(UpdateAttempterTest, SetRollbackHappenedNotRollback);
FRIEND_TEST(UpdateAttempterTest, SetRollbackHappenedRollback);
+ FRIEND_TEST(UpdateAttempterTest, TargetChannelHintSetAndReset);
FRIEND_TEST(UpdateAttempterTest, TargetVersionPrefixSetAndReset);
FRIEND_TEST(UpdateAttempterTest, UpdateAfterInstall);
FRIEND_TEST(UpdateAttempterTest, UpdateAttemptFlagsCachedAtUpdateStart);
@@ -366,15 +356,8 @@
// Helper method of Update() to calculate the update-related parameters
// from various sources and set the appropriate state. Please refer to
// Update() method for the meaning of the parameters.
- bool CalculateUpdateParams(const std::string& app_version,
- const std::string& omaha_url,
- const std::string& target_channel,
- const std::string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive);
+ bool CalculateUpdateParams(
+ const chromeos_update_manager::UpdateCheckParams& params);
// Calculates all the scattering related parameters (such as waiting period,
// which type of scattering is enabled, etc.) and also updates/deletes
@@ -590,4 +573,4 @@
} // namespace chromeos_update_engine
-#endif // UPDATE_ENGINE_UPDATE_ATTEMPTER_H_
+#endif // UPDATE_ENGINE_CROS_UPDATE_ATTEMPTER_H_
diff --git a/update_attempter_unittest.cc b/cros/update_attempter_unittest.cc
similarity index 95%
rename from update_attempter_unittest.cc
rename to cros/update_attempter_unittest.cc
index 305dbdb..f3211a0 100644
--- a/update_attempter_unittest.cc
+++ b/cros/update_attempter_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/update_attempter.h"
#include <stdint.h>
@@ -25,7 +25,8 @@
#include <unordered_set>
#include <base/files/file_util.h>
-#include <base/message_loop/message_loop.h>
+#include <base/files/scoped_temp_dir.h>
+#include <base/task/single_thread_task_executor.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
#include <brillo/message_loops/message_loop_utils.h>
@@ -42,16 +43,16 @@
#include "update_engine/common/mock_action_processor.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
+#include "update_engine/common/mock_service_observer.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_system_state.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/mock_p2p_manager.h"
+#include "update_engine/cros/mock_payload_state.h"
+#include "update_engine/cros/omaha_utils.h"
#include "update_engine/libcurl_http_fetcher.h"
-#include "update_engine/mock_p2p_manager.h"
-#include "update_engine/mock_payload_state.h"
-#include "update_engine/mock_service_observer.h"
-#include "update_engine/omaha_utils.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/payload_consumer/payload_constants.h"
@@ -171,26 +172,10 @@
explicit UpdateAttempterUnderTest(SystemState* system_state)
: UpdateAttempter(system_state, nullptr) {}
- void Update(const std::string& app_version,
- const std::string& omaha_url,
- const std::string& target_channel,
- const std::string& target_version_prefix,
- bool rollback_allowed,
- bool rollback_data_save_requested,
- int rollback_allowed_milestones,
- bool obey_proxies,
- bool interactive) override {
+ void Update(const UpdateCheckParams& params) override {
update_called_ = true;
if (do_update_) {
- UpdateAttempter::Update(app_version,
- omaha_url,
- target_channel,
- target_version_prefix,
- rollback_allowed,
- rollback_data_save_requested,
- rollback_allowed_milestones,
- obey_proxies,
- interactive);
+ UpdateAttempter::Update(params);
return;
}
LOG(INFO) << "[TEST] Update() disabled.";
@@ -332,8 +317,8 @@
// |ProcessingDone()| related member functions.
void TestProcessingDone();
- base::MessageLoopForIO base_loop_;
- brillo::BaseMessageLoop loop_{&base_loop_};
+ base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
+ brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
FakeSystemState fake_system_state_;
UpdateAttempterUnderTest attempter_{&fake_system_state_};
@@ -425,7 +410,7 @@
void UpdateAttempterTest::SessionIdTestChange() {
EXPECT_NE(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status());
const auto old_session_id = attempter_.session_id_;
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_NE(old_session_id, attempter_.session_id_);
ScheduleQuitMainLoop();
}
@@ -796,7 +781,7 @@
EXPECT_CALL(*processor_, StartProcessing());
}
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
loop_.PostTask(FROM_HERE,
base::Bind(&UpdateAttempterTest::UpdateTestVerify,
base::Unretained(this)));
@@ -996,7 +981,7 @@
fake_system_state_.set_p2p_manager(&mock_p2p_manager);
mock_p2p_manager.fake().SetP2PEnabled(false);
EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_FALSE(actual_using_p2p_for_downloading_);
EXPECT_FALSE(actual_using_p2p_for_sharing());
ScheduleQuitMainLoop();
@@ -1018,7 +1003,7 @@
mock_p2p_manager.fake().SetEnsureP2PRunningResult(false);
mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_FALSE(actual_using_p2p_for_downloading());
EXPECT_FALSE(actual_using_p2p_for_sharing());
ScheduleQuitMainLoop();
@@ -1041,7 +1026,7 @@
mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_FALSE(actual_using_p2p_for_downloading());
EXPECT_FALSE(actual_using_p2p_for_sharing());
ScheduleQuitMainLoop();
@@ -1063,7 +1048,7 @@
mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
mock_p2p_manager.fake().SetPerformHousekeepingResult(true);
EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_TRUE(actual_using_p2p_for_downloading());
EXPECT_TRUE(actual_using_p2p_for_sharing());
ScheduleQuitMainLoop();
@@ -1086,15 +1071,7 @@
mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
mock_p2p_manager.fake().SetPerformHousekeepingResult(true);
EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
- attempter_.Update("",
- "",
- "",
- "",
- false,
- false,
- /*rollback_allowed_milestones=*/0,
- false,
- /*interactive=*/true);
+ attempter_.Update({.interactive = true});
EXPECT_FALSE(actual_using_p2p_for_downloading());
EXPECT_TRUE(actual_using_p2p_for_sharing());
ScheduleQuitMainLoop();
@@ -1124,7 +1101,7 @@
attempter_.policy_provider_.reset(
new policy::PolicyProvider(std::move(device_policy)));
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());
ScheduleQuitMainLoop();
@@ -1162,7 +1139,7 @@
attempter_.policy_provider_.reset(
new policy::PolicyProvider(std::move(device_policy)));
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());
// Make sure the file still exists.
@@ -1178,7 +1155,7 @@
// However, if the count is already 0, it's not decremented. Test that.
initial_value = 0;
EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_TRUE(fake_prefs.Exists(kPrefsUpdateCheckCount));
EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
EXPECT_EQ(initial_value, new_value);
@@ -1225,15 +1202,7 @@
new policy::PolicyProvider(std::move(device_policy)));
// Trigger an interactive check so we can test that scattering is disabled.
- attempter_.Update("",
- "",
- "",
- "",
- false,
- false,
- /*rollback_allowed_milestones=*/0,
- false,
- /*interactive=*/true);
+ attempter_.Update({.interactive = true});
EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());
// Make sure scattering is disabled for manual (i.e. user initiated) update
@@ -1285,7 +1254,7 @@
FakePrefs fake_prefs;
SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
// Check that prefs have the correct values.
int64_t update_count;
EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &update_count));
@@ -1342,8 +1311,7 @@
FakePrefs fake_prefs;
SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
- attempter_.Update(
- "", "", "", "", false, false, 0, false, /* interactive = */ true);
+ attempter_.Update({.interactive = true});
CheckStagingOff();
ScheduleQuitMainLoop();
@@ -1363,8 +1331,7 @@
FakePrefs fake_prefs;
SetUpStagingTest(kValidStagingSchedule, &fake_prefs);
- attempter_.Update(
- "", "", "", "", false, false, 0, false, /* interactive = */ true);
+ attempter_.Update({.interactive = true});
CheckStagingOff();
ScheduleQuitMainLoop();
@@ -1692,51 +1659,69 @@
}
TEST_F(UpdateAttempterTest, TargetVersionPrefixSetAndReset) {
- attempter_.CalculateUpdateParams(
- "", "", "", "1234", false, false, 4, false, false);
+ UpdateCheckParams params;
+ attempter_.CalculateUpdateParams({.target_version_prefix = "1234"});
EXPECT_EQ("1234",
fake_system_state_.request_params()->target_version_prefix());
- attempter_.CalculateUpdateParams(
- "", "", "", "", false, 4, false, false, false);
+ attempter_.CalculateUpdateParams({});
EXPECT_TRUE(
fake_system_state_.request_params()->target_version_prefix().empty());
}
+TEST_F(UpdateAttempterTest, TargetChannelHintSetAndReset) {
+ attempter_.CalculateUpdateParams({.lts_tag = "hint"});
+ EXPECT_EQ("hint", fake_system_state_.request_params()->lts_tag());
+
+ attempter_.CalculateUpdateParams({});
+ EXPECT_TRUE(fake_system_state_.request_params()->lts_tag().empty());
+}
+
TEST_F(UpdateAttempterTest, RollbackAllowedSetAndReset) {
- attempter_.CalculateUpdateParams("",
- "",
- "",
- "1234",
- /*rollback_allowed=*/true,
- /*rollback_data_save_requested=*/false,
- /*rollback_allowed_milestones=*/4,
- false,
- false);
+ attempter_.CalculateUpdateParams({
+ .target_version_prefix = "1234",
+ .rollback_allowed = true,
+ .rollback_allowed_milestones = 4,
+ });
EXPECT_TRUE(fake_system_state_.request_params()->rollback_allowed());
EXPECT_EQ(4,
fake_system_state_.request_params()->rollback_allowed_milestones());
- attempter_.CalculateUpdateParams("",
- "",
- "",
- "1234",
- /*rollback_allowed=*/false,
- /*rollback_data_save_requested=*/false,
- /*rollback_allowed_milestones=*/4,
- false,
- false);
+ attempter_.CalculateUpdateParams({
+ .target_version_prefix = "1234",
+ .rollback_allowed_milestones = 4,
+ });
EXPECT_FALSE(fake_system_state_.request_params()->rollback_allowed());
EXPECT_EQ(4,
fake_system_state_.request_params()->rollback_allowed_milestones());
}
+TEST_F(UpdateAttempterTest, ChannelDowngradeNoRollback) {
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+ fake_system_state_.request_params()->set_root(tempdir.GetPath().value());
+ attempter_.CalculateUpdateParams({
+ .target_channel = "stable-channel",
+ });
+ EXPECT_FALSE(fake_system_state_.request_params()->is_powerwash_allowed());
+}
+
+TEST_F(UpdateAttempterTest, ChannelDowngradeRollback) {
+ base::ScopedTempDir tempdir;
+ ASSERT_TRUE(tempdir.CreateUniqueTempDir());
+ fake_system_state_.request_params()->set_root(tempdir.GetPath().value());
+ attempter_.CalculateUpdateParams({
+ .rollback_on_channel_downgrade = true,
+ .target_channel = "stable-channel",
+ });
+ EXPECT_TRUE(fake_system_state_.request_params()->is_powerwash_allowed());
+}
+
TEST_F(UpdateAttempterTest, UpdateDeferredByPolicyTest) {
// Construct an OmahaResponseHandlerAction that has processed an InstallPlan,
// but the update is being deferred by the Policy.
OmahaResponseHandlerAction response_action(&fake_system_state_);
response_action.install_plan_.version = "a.b.c.d";
- response_action.install_plan_.system_version = "b.c.d.e";
response_action.install_plan_.payloads.push_back(
{.size = 1234ULL, .type = InstallPayloadType::kFull});
// Inform the UpdateAttempter that the OmahaResponseHandlerAction has
@@ -1845,7 +1830,7 @@
SetRollbackHappened(false))
.Times(expected_reset ? 1 : 0);
attempter_.policy_provider_ = std::move(mock_policy_provider);
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
ScheduleQuitMainLoop();
}
@@ -2186,7 +2171,7 @@
.WillOnce(Return(false));
attempter_.policy_provider_.reset(
new policy::PolicyProvider(std::move(device_policy)));
- attempter_.Update("", "", "", "", false, false, 0, false, false);
+ attempter_.Update({});
EXPECT_EQ(token, attempter_.omaha_request_params_->autoupdate_token());
ScheduleQuitMainLoop();
diff --git a/update_engine_client.cc b/cros/update_engine_client.cc
similarity index 99%
rename from update_engine_client.cc
rename to cros/update_engine_client.cc
index 31448ea..6f20f11 100644
--- a/update_engine_client.cc
+++ b/cros/update_engine_client.cc
@@ -37,7 +37,7 @@
#include "update_engine/client.h"
#include "update_engine/common/error_code.h"
#include "update_engine/common/error_code_utils.h"
-#include "update_engine/omaha_utils.h"
+#include "update_engine/cros/omaha_utils.h"
#include "update_engine/status_update_handler.h"
#include "update_engine/update_status.h"
#include "update_engine/update_status_utils.h"
diff --git a/payload_consumer/download_action.cc b/download_action.cc
similarity index 98%
rename from payload_consumer/download_action.cc
rename to download_action.cc
index ea99892..10dffd2 100644
--- a/payload_consumer/download_action.cc
+++ b/download_action.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/payload_consumer/download_action.h"
+#include "update_engine/common/download_action.h"
#include <errno.h>
@@ -30,9 +30,9 @@
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/multi_range_http_fetcher.h"
#include "update_engine/common/utils.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/payload_state_interface.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/p2p_manager.h"
+#include "update_engine/cros/payload_state_interface.h"
using base::FilePath;
using std::string;
diff --git a/payload_consumer/download_action_android_unittest.cc b/download_action_android_unittest.cc
similarity index 97%
rename from payload_consumer/download_action_android_unittest.cc
rename to download_action_android_unittest.cc
index f78845f..f222977 100644
--- a/payload_consumer/download_action_android_unittest.cc
+++ b/download_action_android_unittest.cc
@@ -23,10 +23,10 @@
#include "update_engine/common/action_pipe.h"
#include "update_engine/common/boot_control_stub.h"
#include "update_engine/common/constants.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/payload_consumer/download_action.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
diff --git a/payload_consumer/download_action_unittest.cc b/download_action_unittest.cc
similarity index 98%
rename from payload_consumer/download_action_unittest.cc
rename to download_action_unittest.cc
index e6ca219..5264b0f 100644
--- a/payload_consumer/download_action_unittest.cc
+++ b/download_action_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/payload_consumer/download_action.h"
+#include "update_engine/common/download_action.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -34,14 +34,14 @@
#include "update_engine/common/action_pipe.h"
#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/mock_download_action.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/fake_p2p_manager_configuration.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/mock_file_writer.h"
-#include "update_engine/payload_consumer/mock_download_action.h"
+#include "update_engine/cros/fake_p2p_manager_configuration.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/payload_consumer/mock_file_writer.h"
#include "update_engine/update_manager/fake_update_manager.h"
namespace chromeos_update_engine {
@@ -51,7 +51,6 @@
using base::WriteFile;
using std::string;
using std::unique_ptr;
-using test_utils::ScopedTempFile;
using testing::_;
using testing::AtLeast;
using testing::InSequence;
@@ -133,7 +132,6 @@
loop.SetAsCurrent();
FakeSystemState fake_system_state;
- // TODO(adlr): see if we need a different file for build bots
ScopedTempFile output_temp_file;
TestDirectFileWriter writer;
EXPECT_EQ(
diff --git a/image_properties_android.cc b/image_properties_android.cc
deleted file mode 100644
index 2d418b3..0000000
--- a/image_properties_android.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/image_properties.h"
-
-#include <fcntl.h>
-
-#include <string>
-
-#include <android-base/properties.h>
-#include <base/logging.h>
-#include <base/strings/string_util.h>
-#include <bootloader_message/bootloader_message.h>
-#include <brillo/osrelease_reader.h>
-#include <brillo/strings/string_utils.h>
-
-#include "update_engine/common/boot_control_interface.h"
-#include "update_engine/common/constants.h"
-#include "update_engine/common/platform_constants.h"
-#include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/utils.h"
-#include "update_engine/system_state.h"
-
-using android::base::GetProperty;
-using std::string;
-
-namespace chromeos_update_engine {
-
-namespace {
-
-// Build time properties name used in Android Things.
-const char kProductId[] = "product_id";
-const char kProductVersion[] = "product_version";
-const char kSystemId[] = "system_id";
-const char kSystemVersion[] = "system_version";
-
-// The path to the product_components file which stores the version of each
-// components in OEM partition.
-const char kProductComponentsPath[] = "/oem/os-release.d/product_components";
-
-// Prefs used to store the powerwash settings.
-const char kPrefsImgPropPowerwashAllowed[] = "img-prop-powerwash-allowed";
-
-// System properties that identifies the "board".
-const char kPropProductName[] = "ro.product.name";
-const char kPropBuildFingerprint[] = "ro.build.fingerprint";
-const char kPropBuildType[] = "ro.build.type";
-
-// Default channel from factory.prop
-const char kPropDefaultChannel[] = "ro.update.default_channel";
-
-// A prefix added to the path, used for testing.
-const char* root_prefix = nullptr;
-
-string GetStringWithDefault(const brillo::OsReleaseReader& osrelease,
- const string& key,
- const string& default_value) {
- string result;
- if (osrelease.GetString(key, &result))
- return result;
- LOG(INFO) << "Cannot load ImageProperty " << key << ", using default value "
- << default_value;
- return default_value;
-}
-
-// Open misc partition for read or write and output the fd in |out_fd|.
-bool OpenMisc(bool write, int* out_fd) {
- string misc_device;
- int flags = write ? O_WRONLY | O_SYNC : O_RDONLY;
- if (root_prefix) {
- // Use a file for unittest and create one if doesn't exist.
- misc_device = base::FilePath(root_prefix).Append("misc").value();
- if (write)
- flags |= O_CREAT;
- } else {
- string err;
- misc_device = get_bootloader_message_blk_device(&err);
- if (misc_device.empty()) {
- LOG(ERROR) << "Unable to get misc block device: " << err;
- return false;
- }
- }
-
- int fd = HANDLE_EINTR(open(misc_device.c_str(), flags, 0600));
- if (fd < 0) {
- PLOG(ERROR) << "Opening misc failed";
- return false;
- }
- *out_fd = fd;
- return true;
-}
-
-// The offset and size of the channel field in misc partition.
-constexpr size_t kChannelOffset =
- BOOTLOADER_MESSAGE_OFFSET_IN_MISC +
- offsetof(bootloader_message_ab, update_channel);
-constexpr size_t kChannelSize = sizeof(bootloader_message_ab::update_channel);
-
-// Read channel from misc partition to |out_channel|, return false if unable to
-// read misc or no channel is set in misc.
-bool ReadChannelFromMisc(string* out_channel) {
- int fd;
- TEST_AND_RETURN_FALSE(OpenMisc(false, &fd));
- ScopedFdCloser fd_closer(&fd);
- char channel[kChannelSize] = {0};
- ssize_t bytes_read = 0;
- if (!utils::PReadAll(
- fd, channel, kChannelSize - 1, kChannelOffset, &bytes_read) ||
- bytes_read != kChannelSize - 1) {
- PLOG(ERROR) << "Reading update channel from misc failed";
- return false;
- }
- if (channel[0] == '\0') {
- LOG(INFO) << "No channel set in misc.";
- return false;
- }
- if (!base::EndsWith(channel, "-channel", base::CompareCase::SENSITIVE)) {
- LOG(ERROR) << "Channel " << channel << " doesn't end with -channel.";
- return false;
- }
- out_channel->assign(channel);
- return true;
-}
-
-// Write |in_channel| to misc partition, return false if failed to write.
-bool WriteChannelToMisc(const string& in_channel) {
- int fd;
- TEST_AND_RETURN_FALSE(OpenMisc(true, &fd));
- ScopedFdCloser fd_closer(&fd);
- if (in_channel.size() >= kChannelSize) {
- LOG(ERROR) << "Channel name is too long: " << in_channel
- << ", the maximum length is " << kChannelSize - 1;
- return false;
- }
- char channel[kChannelSize] = {0};
- memcpy(channel, in_channel.data(), in_channel.size());
- if (!utils::PWriteAll(fd, channel, kChannelSize, kChannelOffset)) {
- PLOG(ERROR) << "Writing update channel to misc failed";
- return false;
- }
- return true;
-}
-
-string GetTargetChannel() {
- string channel;
- if (!ReadChannelFromMisc(&channel))
- channel = GetProperty(kPropDefaultChannel, "stable-channel");
- return channel;
-}
-} // namespace
-
-namespace test {
-void SetImagePropertiesRootPrefix(const char* test_root_prefix) {
- root_prefix = test_root_prefix;
-}
-} // namespace test
-
-ImageProperties LoadImageProperties(SystemState* system_state) {
- ImageProperties result;
-
- brillo::OsReleaseReader osrelease;
- if (root_prefix)
- osrelease.LoadTestingOnly(base::FilePath(root_prefix));
- else
- osrelease.Load();
- result.product_id =
- GetStringWithDefault(osrelease, kProductId, "invalid-product");
- result.system_id = GetStringWithDefault(
- osrelease, kSystemId, "developer-boards:brillo-starter-board");
- // Update the system id to match the prefix of product id for testing.
- string prefix, not_used, system_id;
- if (brillo::string_utils::SplitAtFirst(
- result.product_id, ":", &prefix, ¬_used, false) &&
- brillo::string_utils::SplitAtFirst(
- result.system_id, ":", ¬_used, &system_id, false)) {
- result.system_id = prefix + ":" + system_id;
- }
- result.canary_product_id = result.product_id;
- result.version = GetStringWithDefault(osrelease, kProductVersion, "0.0.0.0");
- result.system_version =
- GetStringWithDefault(osrelease, kSystemVersion, "0.0.0.0");
- // Can't read it with OsReleaseReader because it has multiple lines.
- utils::ReadFile(kProductComponentsPath, &result.product_components);
-
- result.board = GetProperty(kPropProductName, "brillo");
- result.build_fingerprint = GetProperty(kPropBuildFingerprint, "none");
- result.build_type = GetProperty(kPropBuildType, "");
-
- // Android doesn't have channel information in system image, we try to read
- // the channel of current slot from prefs and then fallback to use the
- // persisted target channel as current channel.
- string current_channel_key =
- kPrefsChannelOnSlotPrefix +
- std::to_string(system_state->boot_control()->GetCurrentSlot());
- string current_channel;
- if (!system_state->prefs()->Exists(current_channel_key) ||
- !system_state->prefs()->GetString(current_channel_key, ¤t_channel))
- current_channel = GetTargetChannel();
- result.current_channel = current_channel;
- result.allow_arbitrary_channels = true;
-
- // Brillo only supports the official omaha URL.
- result.omaha_url = constants::kOmahaDefaultProductionURL;
-
- return result;
-}
-
-MutableImageProperties LoadMutableImageProperties(SystemState* system_state) {
- MutableImageProperties result;
- result.target_channel = GetTargetChannel();
- if (!system_state->prefs()->GetBoolean(kPrefsImgPropPowerwashAllowed,
- &result.is_powerwash_allowed)) {
- result.is_powerwash_allowed = false;
- }
- return result;
-}
-
-bool StoreMutableImageProperties(SystemState* system_state,
- const MutableImageProperties& properties) {
- bool ret = true;
- if (!WriteChannelToMisc(properties.target_channel))
- ret = false;
- if (!system_state->prefs()->SetBoolean(kPrefsImgPropPowerwashAllowed,
- properties.is_powerwash_allowed))
- ret = false;
- return ret;
-}
-
-void LogImageProperties() {
- // TODO(*): Implement this.
-}
-
-} // namespace chromeos_update_engine
diff --git a/image_properties_android_unittest.cc b/image_properties_android_unittest.cc
deleted file mode 100644
index 607284a..0000000
--- a/image_properties_android_unittest.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/image_properties.h"
-
-#include <string>
-
-#include <base/files/file_util.h>
-#include <base/files/scoped_temp_dir.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/common/constants.h"
-#include "update_engine/common/fake_prefs.h"
-#include "update_engine/common/test_utils.h"
-#include "update_engine/fake_system_state.h"
-
-using chromeos_update_engine::test_utils::WriteFileString;
-using std::string;
-
-namespace chromeos_update_engine {
-
-class ImagePropertiesTest : public ::testing::Test {
- protected:
- void SetUp() override {
- // Create a uniquely named test directory.
- ASSERT_TRUE(tempdir_.CreateUniqueTempDir());
- osrelease_dir_ = tempdir_.GetPath().Append("etc/os-release.d");
- EXPECT_TRUE(base::CreateDirectory(osrelease_dir_));
- test::SetImagePropertiesRootPrefix(tempdir_.GetPath().value().c_str());
- }
-
- void WriteOsRelease(const string& key, const string& value) {
- ASSERT_TRUE(WriteFileString(osrelease_dir_.Append(key).value(), value));
- }
-
- void WriteChannel(const string& channel) {
- string misc(2080, '\0');
- misc += channel;
- misc.resize(4096);
- ASSERT_TRUE(
- WriteFileString(tempdir_.GetPath().Append("misc").value(), misc));
- }
-
- FakeSystemState fake_system_state_;
-
- base::ScopedTempDir tempdir_;
- base::FilePath osrelease_dir_;
-};
-
-TEST_F(ImagePropertiesTest, SimpleTest) {
- WriteOsRelease("product_id", "abc");
- WriteOsRelease("system_id", "def");
- WriteOsRelease("product_version", "1.2.3.4");
- WriteOsRelease("system_version", "5.6.7.8");
- ImageProperties props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("abc", props.product_id);
- EXPECT_EQ("def", props.system_id);
- EXPECT_EQ("1.2.3.4", props.version);
- EXPECT_EQ("5.6.7.8", props.system_version);
- EXPECT_EQ("stable-channel", props.current_channel);
- EXPECT_EQ(constants::kOmahaDefaultProductionURL, props.omaha_url);
-}
-
-TEST_F(ImagePropertiesTest, IDPrefixTest) {
- WriteOsRelease("product_id", "abc:def");
- WriteOsRelease("system_id", "foo:bar");
- ImageProperties props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("abc:def", props.product_id);
- EXPECT_EQ("abc:bar", props.system_id);
-}
-
-TEST_F(ImagePropertiesTest, IDInvalidPrefixTest) {
- WriteOsRelease("product_id", "def");
- WriteOsRelease("system_id", "foo:bar");
- ImageProperties props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("def", props.product_id);
- EXPECT_EQ("foo:bar", props.system_id);
-
- WriteOsRelease("product_id", "abc:def");
- WriteOsRelease("system_id", "bar");
- props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("abc:def", props.product_id);
- EXPECT_EQ("bar", props.system_id);
-}
-
-TEST_F(ImagePropertiesTest, LoadChannelTest) {
- WriteChannel("unittest-channel");
- ImageProperties props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("unittest-channel", props.current_channel);
-}
-
-TEST_F(ImagePropertiesTest, DefaultStableChannelTest) {
- WriteChannel("");
- ImageProperties props = LoadImageProperties(&fake_system_state_);
- EXPECT_EQ("stable-channel", props.current_channel);
-}
-
-TEST_F(ImagePropertiesTest, StoreLoadMutableChannelTest) {
- FakePrefs prefs;
- fake_system_state_.set_prefs(&prefs);
- WriteChannel("previous-channel");
- MutableImageProperties props;
- props.target_channel = "new-channel";
- EXPECT_TRUE(StoreMutableImageProperties(&fake_system_state_, props));
- MutableImageProperties loaded_props =
- LoadMutableImageProperties(&fake_system_state_);
- EXPECT_EQ(props.target_channel, loaded_props.target_channel);
-}
-
-} // namespace chromeos_update_engine
diff --git a/init/update-engine.conf b/init/update-engine.conf
index ca54c4a..36c89d7 100644
--- a/init/update-engine.conf
+++ b/init/update-engine.conf
@@ -37,7 +37,17 @@
# Put update_engine process in its own cgroup.
# Default cpu.shares is 1024.
post-start script
- cgroup_dir="/sys/fs/cgroup/cpu/${UPSTART_JOB}"
- mkdir -p "${cgroup_dir}"
- echo $(status | cut -f 4 -d ' ') > "${cgroup_dir}/tasks"
+ pid=$(status | cut -f 4 -d ' ')
+
+ cgroup_cpu_dir="/sys/fs/cgroup/cpu/${UPSTART_JOB}"
+ mkdir -p "${cgroup_cpu_dir}"
+ echo ${pid} > "${cgroup_cpu_dir}/tasks"
+
+ # Assigns net_cls handle 1:1 to packets generated from update_engine. For
+ # routing and tagging purposes, that value will be redefined in
+ # patchpanel/routing_service.h .
+ cgroup_net_cls_dir="/sys/fs/cgroup/net_cls/${UPSTART_JOB}"
+ mkdir -p "${cgroup_net_cls_dir}"
+ echo ${pid} > "${cgroup_net_cls_dir}/tasks"
+ echo "0x10001" > "${cgroup_net_cls_dir}/net_cls.classid"
end script
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index bce0920..1599aac 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -458,10 +458,10 @@
// There's either more work to do or we are paused, so we just keep the
// file descriptors to watch up to date and exit, until we are done with the
// work and we are not paused.
-#ifdef __ANDROID__
- // When there's no base::SingleThreadTaskRunner on current thread, it's not
- // possible to watch file descriptors. Just poll it later. This usually
- // happens if brillo::FakeMessageLoop is used.
+ //
+ // When there's no |base::SingleThreadTaskRunner| on current thread, it's
+ // not possible to watch file descriptors. Just poll it later. This usually
+ // happens if |brillo::FakeMessageLoop| is used.
if (!base::ThreadTaskRunnerHandle::IsSet()) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
@@ -470,7 +470,6 @@
TimeDelta::FromSeconds(1));
return;
}
-#endif
SetupMessageLoopSources();
return;
}
diff --git a/libcurl_http_fetcher_unittest.cc b/libcurl_http_fetcher_unittest.cc
index 874ef2e..5d67570 100644
--- a/libcurl_http_fetcher_unittest.cc
+++ b/libcurl_http_fetcher_unittest.cc
@@ -100,7 +100,6 @@
libcurl_fetcher_.BeginTransfer("https://An-uNres0lvable-uRl.invalid");
-#ifdef __ANDROID__
// It's slower on Android that libcurl handle may not finish within 1 cycle.
// Will need to wait for more cycles until it finishes. Original test didn't
// correctly handle when we need to re-watch libcurl fds.
@@ -108,10 +107,7 @@
libcurl_fetcher_.GetAuxiliaryErrorCode() == ErrorCode::kSuccess) {
loop_.RunOnce(true);
}
-#else
- // The first time it can't resolve.
- loop_.RunOnce(true);
-#endif
+
EXPECT_EQ(libcurl_fetcher_.GetAuxiliaryErrorCode(),
ErrorCode::kUnresolvedHostError);
@@ -141,7 +137,6 @@
// easier to mock the part that depends on internet connectivity.
libcurl_fetcher_.BeginTransfer("https://An-uNres0lvable-uRl.invalid");
-#ifdef __ANDROID__
// It's slower on Android that libcurl handle may not finish within 1 cycle.
// Will need to wait for more cycles until it finishes. Original test didn't
// correctly handle when we need to re-watch libcurl fds.
@@ -149,10 +144,7 @@
libcurl_fetcher_.GetAuxiliaryErrorCode() == ErrorCode::kSuccess) {
loop_.RunOnce(true);
}
-#else
- // The first time it can't resolve.
- loop_.RunOnce(true);
-#endif
+
EXPECT_EQ(libcurl_fetcher_.GetAuxiliaryErrorCode(),
ErrorCode::kUnresolvedHostError);
@@ -165,7 +157,6 @@
[this]() { libcurl_fetcher_.http_response_code_ = 0; }));
libcurl_fetcher_.transfer_size_ = 10;
-#ifdef __ANDROID__
// It's slower on Android that libcurl handle may not finish within 1 cycle.
// Will need to wait for more cycles until it finishes. Original test didn't
// correctly handle when we need to re-watch libcurl fds.
@@ -173,11 +164,7 @@
ErrorCode::kUnresolvedHostError) {
loop_.RunOnce(true);
}
-#else
- // This time the host is resolved. But after that again we can't resolve
- // anymore (See above).
- loop_.RunOnce(true);
-#endif
+
EXPECT_EQ(libcurl_fetcher_.GetAuxiliaryErrorCode(),
ErrorCode::kUnresolvedHostRecovered);
diff --git a/main.cc b/main.cc
index ceb5b56..a23a08b 100644
--- a/main.cc
+++ b/main.cc
@@ -23,11 +23,11 @@
#include <base/logging.h>
#include <brillo/flag_helper.h>
+#include "update_engine/common/daemon_base.h"
+#include "update_engine/common/logging.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/common/terminator.h"
#include "update_engine/common/utils.h"
-#include "update_engine/daemon_base.h"
-#include "update_engine/logging.h"
using std::string;
diff --git a/metrics_utils.cc b/metrics_utils.cc
index da3a2c3..34da5a1 100644
--- a/metrics_utils.cc
+++ b/metrics_utils.cc
@@ -23,7 +23,6 @@
#include "update_engine/common/clock_interface.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/utils.h"
-#include "update_engine/system_state.h"
using base::Time;
using base::TimeDelta;
@@ -95,6 +94,7 @@
case ErrorCode::kPostinstallRunnerError:
case ErrorCode::kPostinstallBootedFromFirmwareB:
case ErrorCode::kPostinstallFirmwareRONotUpdatable:
+ case ErrorCode::kPostInstallMountError:
return metrics::AttemptResult::kPostInstallFailed;
case ErrorCode::kUserCanceled:
@@ -111,10 +111,6 @@
case ErrorCode::kDownloadInvalidMetadataSignature:
case ErrorCode::kOmahaResponseInvalid:
case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
- // TODO(deymo): The next two items belong in their own category; they
- // should not be counted as internal errors. b/27112092
- case ErrorCode::kOmahaUpdateDeferredPerPolicy:
- case ErrorCode::kNonCriticalUpdateInOOBE:
case ErrorCode::kOmahaErrorInHTTPResponse:
case ErrorCode::kDownloadMetadataSignatureMissingError:
case ErrorCode::kOmahaUpdateDeferredForBackoff:
@@ -124,8 +120,13 @@
case ErrorCode::kOmahaUpdateIgnoredOverCellular:
case ErrorCode::kNoUpdate:
case ErrorCode::kFirstActiveOmahaPingSentPersistenceError:
+ case ErrorCode::kPackageExcludedFromUpdate:
return metrics::AttemptResult::kInternalError;
+ case ErrorCode::kOmahaUpdateDeferredPerPolicy:
+ case ErrorCode::kNonCriticalUpdateInOOBE:
+ return metrics::AttemptResult::kUpdateSkipped;
+
// Special flags. These can't happen (we mask them out above) but
// the compiler doesn't know that. Just break out so we can warn and
// return |kInternalError|.
@@ -188,6 +189,7 @@
case ErrorCode::kOmahaResponseHandlerError:
case ErrorCode::kFilesystemCopierError:
case ErrorCode::kPostinstallRunnerError:
+ case ErrorCode::kPostInstallMountError:
case ErrorCode::kPayloadMismatchedType:
case ErrorCode::kInstallDeviceOpenError:
case ErrorCode::kKernelDeviceOpenError:
@@ -240,6 +242,7 @@
case ErrorCode::kVerityCalculationError:
case ErrorCode::kNotEnoughSpace:
case ErrorCode::kDeviceCorrupted:
+ case ErrorCode::kPackageExcludedFromUpdate:
break;
// Special flags. These can't happen (we mask them out above) but
@@ -291,48 +294,6 @@
return metrics::ConnectionType::kUnknown;
}
-bool WallclockDurationHelper(SystemState* system_state,
- const std::string& state_variable_key,
- TimeDelta* out_duration) {
- bool ret = false;
-
- Time now = system_state->clock()->GetWallclockTime();
- int64_t stored_value;
- if (system_state->prefs()->GetInt64(state_variable_key, &stored_value)) {
- Time stored_time = Time::FromInternalValue(stored_value);
- if (stored_time > now) {
- LOG(ERROR) << "Stored time-stamp used for " << state_variable_key
- << " is in the future.";
- } else {
- *out_duration = now - stored_time;
- ret = true;
- }
- }
-
- if (!system_state->prefs()->SetInt64(state_variable_key,
- now.ToInternalValue())) {
- LOG(ERROR) << "Error storing time-stamp in " << state_variable_key;
- }
-
- return ret;
-}
-
-bool MonotonicDurationHelper(SystemState* system_state,
- int64_t* storage,
- TimeDelta* out_duration) {
- bool ret = false;
-
- Time now = system_state->clock()->GetMonotonicTime();
- if (*storage != 0) {
- Time stored_time = Time::FromInternalValue(*storage);
- *out_duration = now - stored_time;
- ret = true;
- }
- *storage = now.ToInternalValue();
-
- return ret;
-}
-
int64_t GetPersistedValue(const std::string& key, PrefsInterface* prefs) {
CHECK(prefs);
if (!prefs->Exists(key))
@@ -402,8 +363,7 @@
return false;
Time system_updated_at = Time::FromInternalValue(stored_value);
- base::TimeDelta time_to_reboot =
- clock->GetMonotonicTime() - system_updated_at;
+ TimeDelta time_to_reboot = clock->GetMonotonicTime() - system_updated_at;
if (time_to_reboot.ToInternalValue() < 0) {
LOG(ERROR) << "time_to_reboot is negative - system_updated_at: "
<< utils::ToString(system_updated_at);
diff --git a/metrics_utils.h b/metrics_utils.h
index 8f1aad1..5952ec3 100644
--- a/metrics_utils.h
+++ b/metrics_utils.h
@@ -22,11 +22,11 @@
#include <base/time/time.h>
#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/connection_utils.h"
#include "update_engine/common/error_code.h"
+#include "update_engine/common/metrics_constants.h"
+#include "update_engine/common/metrics_reporter_interface.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/connection_utils.h"
-#include "update_engine/metrics_constants.h"
-#include "update_engine/metrics_reporter_interface.h"
namespace chromeos_update_engine {
@@ -50,29 +50,6 @@
metrics::ConnectionType GetConnectionType(ConnectionType type,
ConnectionTethering tethering);
-// This function returns the duration on the wallclock since the last
-// time it was called for the same |state_variable_key| value.
-//
-// If the function returns |true|, the duration (always non-negative)
-// is returned in |out_duration|. If the function returns |false|
-// something went wrong or there was no previous measurement.
-bool WallclockDurationHelper(SystemState* system_state,
- const std::string& state_variable_key,
- base::TimeDelta* out_duration);
-
-// This function returns the duration on the monotonic clock since the
-// last time it was called for the same |storage| pointer.
-//
-// You should pass a pointer to a 64-bit integer in |storage| which
-// should be initialized to 0.
-//
-// If the function returns |true|, the duration (always non-negative)
-// is returned in |out_duration|. If the function returns |false|
-// something went wrong or there was no previous measurement.
-bool MonotonicDurationHelper(SystemState* system_state,
- int64_t* storage,
- base::TimeDelta* out_duration);
-
// Returns the persisted value from prefs for the given key. It also
// validates that the value returned is non-negative.
int64_t GetPersistedValue(const std::string& key, PrefsInterface* prefs);
diff --git a/metrics_utils_unittest.cc b/metrics_utils_unittest.cc
index 6ea996f..cedd269 100644
--- a/metrics_utils_unittest.cc
+++ b/metrics_utils_unittest.cc
@@ -20,7 +20,6 @@
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_prefs.h"
-#include "update_engine/fake_system_state.h"
namespace chromeos_update_engine {
namespace metrics_utils {
@@ -74,116 +73,5 @@
GetConnectionType(ConnectionType::kWifi, ConnectionTethering::kUnknown));
}
-TEST(MetricsUtilsTest, WallclockDurationHelper) {
- FakeSystemState fake_system_state;
- FakeClock fake_clock;
- base::TimeDelta duration;
- const std::string state_variable_key = "test-prefs";
- FakePrefs fake_prefs;
-
- fake_system_state.set_clock(&fake_clock);
- fake_system_state.set_prefs(&fake_prefs);
-
- // Initialize wallclock to 1 sec.
- fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
-
- // First time called so no previous measurement available.
- EXPECT_FALSE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
-
- // Next time, we should get zero since the clock didn't advance.
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // We can also call it as many times as we want with it being
- // considered a failure.
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // Advance the clock one second, then we should get 1 sec on the
- // next call and 0 sec on the subsequent call.
- fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000));
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 1);
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // Advance clock two seconds and we should get 2 sec and then 0 sec.
- fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 2);
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // There's a possibility that the wallclock can go backwards (NTP
- // adjustments, for example) so check that we properly handle this
- // case.
- fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000));
- EXPECT_FALSE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
- EXPECT_TRUE(metrics_utils::WallclockDurationHelper(
- &fake_system_state, state_variable_key, &duration));
- EXPECT_EQ(duration.InSeconds(), 1);
-}
-
-TEST(MetricsUtilsTest, MonotonicDurationHelper) {
- int64_t storage = 0;
- FakeSystemState fake_system_state;
- FakeClock fake_clock;
- base::TimeDelta duration;
-
- fake_system_state.set_clock(&fake_clock);
-
- // Initialize monotonic clock to 1 sec.
- fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
-
- // First time called so no previous measurement available.
- EXPECT_FALSE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
-
- // Next time, we should get zero since the clock didn't advance.
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // We can also call it as many times as we want with it being
- // considered a failure.
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // Advance the clock one second, then we should get 1 sec on the
- // next call and 0 sec on the subsequent call.
- fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000));
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 1);
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-
- // Advance clock two seconds and we should get 2 sec and then 0 sec.
- fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000));
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 2);
- EXPECT_TRUE(metrics_utils::MonotonicDurationHelper(
- &fake_system_state, &storage, &duration));
- EXPECT_EQ(duration.InSeconds(), 0);
-}
-
} // namespace metrics_utils
} // namespace chromeos_update_engine
diff --git a/mock_boot_control_hal.h b/mock_boot_control_hal.h
deleted file mode 100644
index 4e9cb50..0000000
--- a/mock_boot_control_hal.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include <android/hardware/boot/1.0/IBootControl.h>
-#include <stdint.h>
-
-#include <gmock/gmock.h>
-
-namespace chromeos_update_engine {
-
-class MockBootControlHal
- : public ::android::hardware::boot::V1_0::IBootControl {
- public:
- MOCK_METHOD0(getNumberSlots, ::android::hardware::Return<uint32_t>());
- MOCK_METHOD0(getCurrentSlot, ::android::hardware::Return<uint32_t>());
- MOCK_METHOD1(markBootSuccessful,
- ::android::hardware::Return<void>(markBootSuccessful_cb));
- MOCK_METHOD2(setActiveBootSlot,
- ::android::hardware::Return<void>(uint32_t,
- setActiveBootSlot_cb));
- MOCK_METHOD2(setSlotAsUnbootable,
- ::android::hardware::Return<void>(uint32_t,
- setSlotAsUnbootable_cb));
- MOCK_METHOD1(
- isSlotBootable,
- ::android::hardware::Return<::android::hardware::boot::V1_0::BoolResult>(
- uint32_t));
- MOCK_METHOD1(
- isSlotMarkedSuccessful,
- ::android::hardware::Return<::android::hardware::boot::V1_0::BoolResult>(
- uint32_t));
- MOCK_METHOD2(getSuffix,
- ::android::hardware::Return<void>(uint32_t, getSuffix_cb));
-};
-
-} // namespace chromeos_update_engine
diff --git a/mock_libcurl_http_fetcher.h b/mock_libcurl_http_fetcher.h
index a8ef0f4..a14f953 100644
--- a/mock_libcurl_http_fetcher.h
+++ b/mock_libcurl_http_fetcher.h
@@ -19,7 +19,7 @@
#include <gmock/gmock.h>
-#include "update_engine/connection_manager_interface.h"
+#include "update_engine/libcurl_http_fetcher.h"
namespace chromeos_update_engine {
diff --git a/payload_consumer/bzip_extent_writer_unittest.cc b/payload_consumer/bzip_extent_writer_unittest.cc
index 125e1e5..b587040 100644
--- a/payload_consumer/bzip_extent_writer_unittest.cc
+++ b/payload_consumer/bzip_extent_writer_unittest.cc
@@ -49,7 +49,7 @@
void TearDown() override { fd_->Close(); }
FileDescriptorPtr fd_;
- test_utils::ScopedTempFile temp_file_{"BzipExtentWriterTest-file.XXXXXX"};
+ ScopedTempFile temp_file_{"BzipExtentWriterTest-file.XXXXXX"};
};
TEST_F(BzipExtentWriterTest, SimpleTest) {
diff --git a/payload_consumer/cached_file_descriptor_unittest.cc b/payload_consumer/cached_file_descriptor_unittest.cc
index d2965fc..b64420a 100644
--- a/payload_consumer/cached_file_descriptor_unittest.cc
+++ b/payload_consumer/cached_file_descriptor_unittest.cc
@@ -73,7 +73,7 @@
protected:
FileDescriptorPtr fd_{new EintrSafeFileDescriptor};
- test_utils::ScopedTempFile temp_file_{"CachedFileDescriptor-file.XXXXXX"};
+ ScopedTempFile temp_file_{"CachedFileDescriptor-file.XXXXXX"};
int value_{1};
FileDescriptorPtr cfd_;
};
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 87fc4cf..c3a321e 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -41,16 +41,17 @@
#include <puffin/puffpatch.h>
#include "update_engine/common/constants.h"
+#include "update_engine/common/download_action.h"
#include "update_engine/common/error_code.h"
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/common/terminator.h"
+#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/bzip_extent_writer.h"
#include "update_engine/payload_consumer/cached_file_descriptor.h"
#include "update_engine/payload_consumer/certificate_parser_interface.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/extent_reader.h"
#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/partition_update_generator_interface.h"
@@ -197,12 +198,9 @@
if (op_result)
return true;
- size_t partition_first_op_num =
- current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0;
LOG(ERROR) << "Failed to perform " << op_type_name << " operation "
<< next_operation_num_ << ", which is the operation "
- << next_operation_num_ - partition_first_op_num
- << " in partition \""
+ << GetPartitionOperationNum() << " in partition \""
<< partitions_[current_partition_].partition_name() << "\"";
if (*error == ErrorCode::kSuccess)
*error = ErrorCode::kDownloadOperationExecutionError;
@@ -241,18 +239,29 @@
install_plan_->partitions.size() - partitions_.size();
const InstallPlan::Partition& install_part =
install_plan_->partitions[num_previous_partitions + current_partition_];
- partition_writer_ = std::make_unique<PartitionWriter>(
+ auto dynamic_control = boot_control_->GetDynamicPartitionControl();
+ partition_writer_ = partition_writer::CreatePartitionWriter(
partition,
install_part,
- boot_control_->GetDynamicPartitionControl(),
+ dynamic_control,
block_size_,
- interactive_);
-
+ interactive_,
+ IsDynamicPartition(install_part.name));
// Open source fds if we have a delta payload, or for partitions in the
// partial update.
bool source_may_exist = manifest_.partial_update() ||
payload_->type == InstallPayloadType::kDelta;
- return partition_writer_->Init(install_plan_, source_may_exist);
+ const size_t partition_operation_num = GetPartitionOperationNum();
+
+ TEST_AND_RETURN_FALSE(partition_writer_->Init(
+ install_plan_, source_may_exist, partition_operation_num));
+ CheckpointUpdateProgress(true);
+ return true;
+}
+
+size_t DeltaPerformer::GetPartitionOperationNum() {
+ return next_operation_num_ -
+ (current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0);
}
namespace {
@@ -276,15 +285,6 @@
} // namespace
-uint32_t DeltaPerformer::GetMinorVersion() const {
- if (manifest_.has_minor_version()) {
- return manifest_.minor_version();
- }
- return payload_->type == InstallPayloadType::kDelta
- ? kMaxSupportedMinorPayloadVersion
- : kFullPayloadMinorVersion;
-}
-
bool DeltaPerformer::IsHeaderParsed() const {
return metadata_size_ != 0;
}
@@ -353,6 +353,7 @@
<< "Trusting metadata size in payload = " << metadata_size_;
}
+ // NOLINTNEXTLINE(whitespace/braces)
auto [payload_verifier, perform_verification] = CreatePayloadVerifier();
if (!payload_verifier) {
LOG(ERROR) << "Failed to create payload verifier.";
@@ -496,6 +497,9 @@
// We know there are more operations to perform because we didn't reach the
// |num_total_operations_| limit yet.
if (next_operation_num_ >= acc_num_operations_[current_partition_]) {
+ if (partition_writer_) {
+ TEST_AND_RETURN_FALSE(partition_writer_->FinishedInstallOps());
+ }
CloseCurrentPartition();
// Skip until there are operations for current_partition_.
while (next_operation_num_ >= acc_num_operations_[current_partition_]) {
@@ -506,12 +510,9 @@
return false;
}
}
- const size_t partition_operation_num =
- next_operation_num_ -
- (current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0);
const InstallOperation& op =
- partitions_[current_partition_].operations(partition_operation_num);
+ partitions_[current_partition_].operations(GetPartitionOperationNum());
CopyDataToBuffer(&c_bytes, &count, op.data_length());
@@ -642,6 +643,11 @@
}
}
+ auto dynamic_control = boot_control_->GetDynamicPartitionControl();
+ CHECK_NE(dynamic_control, nullptr);
+ TEST_AND_RETURN_FALSE(dynamic_control->ListDynamicPartitionsForSlot(
+ install_plan_->target_slot, &dynamic_partitions_));
+
// Partitions in manifest are no longer needed after preparing partitions.
manifest_.clear_partitions();
// TODO(xunchang) TBD: allow partial update only on devices with dynamic
@@ -1085,13 +1091,6 @@
}
}
- if (manifest_.has_old_rootfs_info() || manifest_.has_new_rootfs_info() ||
- manifest_.has_old_kernel_info() || manifest_.has_new_kernel_info() ||
- manifest_.install_operations_size() != 0 ||
- manifest_.kernel_install_operations_size() != 0) {
- LOG(ERROR) << "Manifest contains deprecated fields.";
- return ErrorCode::kPayloadMismatchedType;
- }
ErrorCode error_code = CheckTimestampError();
if (error_code != ErrorCode::kSuccess) {
if (error_code == ErrorCode::kPayloadTimestampError) {
@@ -1126,28 +1125,35 @@
auto&& timestamp_valid = [this](const PartitionUpdate& partition,
bool allow_empty_version,
bool* downgrade_detected) -> ErrorCode {
+ const auto& partition_name = partition.partition_name();
if (!partition.has_version()) {
+ if (hardware_->GetVersionForLogging(partition_name).empty()) {
+ LOG(INFO) << partition_name << " does't have version, skipping "
+ << "downgrade check.";
+ return ErrorCode::kSuccess;
+ }
+
if (allow_empty_version) {
return ErrorCode::kSuccess;
}
LOG(ERROR)
- << "PartitionUpdate " << partition.partition_name()
- << " does ot have a version field. Not allowed in partial updates.";
+ << "PartitionUpdate " << partition_name
+ << " doesn't have a version field. Not allowed in partial updates.";
return ErrorCode::kDownloadManifestParseError;
}
- auto error_code = hardware_->IsPartitionUpdateValid(
- partition.partition_name(), partition.version());
+ auto error_code =
+ hardware_->IsPartitionUpdateValid(partition_name, partition.version());
switch (error_code) {
case ErrorCode::kSuccess:
break;
case ErrorCode::kPayloadTimestampError:
*downgrade_detected = true;
- LOG(WARNING) << "PartitionUpdate " << partition.partition_name()
+ LOG(WARNING) << "PartitionUpdate " << partition_name
<< " has an older version than partition on device.";
break;
default:
- LOG(ERROR) << "IsPartitionUpdateValid(" << partition.partition_name()
+ LOG(ERROR) << "IsPartitionUpdateValid(" << partition_name
<< ") returned" << utils::ErrorCodeToString(error_code);
break;
}
@@ -1281,6 +1287,14 @@
return ErrorCode::kPayloadSizeMismatchError;
}
+ // Verifies the payload hash.
+ TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadVerificationError,
+ !payload_hash_calculator_.raw_hash().empty());
+ TEST_AND_RETURN_VAL(
+ ErrorCode::kPayloadHashMismatchError,
+ payload_hash_calculator_.raw_hash() == update_check_response_hash);
+
+ // NOLINTNEXTLINE(whitespace/braces)
auto [payload_verifier, perform_verification] = CreatePayloadVerifier();
if (!perform_verification) {
LOG(WARNING) << "Not verifying signed delta payload -- missing public key.";
@@ -1291,13 +1305,6 @@
return ErrorCode::kDownloadPayloadPubKeyVerificationError;
}
- // Verifies the payload hash.
- TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadVerificationError,
- !payload_hash_calculator_.raw_hash().empty());
- TEST_AND_RETURN_VAL(
- ErrorCode::kPayloadHashMismatchError,
- payload_hash_calculator_.raw_hash() == update_check_response_hash);
-
TEST_AND_RETURN_VAL(ErrorCode::kSignedDeltaPayloadExpectedError,
!signatures_message_data_.empty());
brillo::Blob hash_data = signed_hash_calculator_.raw_hash();
@@ -1436,6 +1443,7 @@
TEST_AND_RETURN_FALSE(
prefs_->SetInt64(kPrefsUpdateStateNextDataLength, 0));
}
+ partition_writer_->CheckpointUpdateProgress(GetPartitionOperationNum());
}
TEST_AND_RETURN_FALSE(
prefs_->SetInt64(kPrefsUpdateStateNextOperation, next_operation_num_));
@@ -1503,4 +1511,10 @@
return true;
}
+bool DeltaPerformer::IsDynamicPartition(const std::string& part_name) {
+ return std::find(dynamic_partitions_.begin(),
+ dynamic_partitions_.end(),
+ part_name) != dynamic_partitions_.end();
+}
+
} // namespace chromeos_update_engine
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index d44f6c2..7df2bd3 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -170,9 +170,13 @@
// Return true if header parsing is finished and no errors occurred.
bool IsHeaderParsed() const;
- // Returns the delta minor version. If this value is defined in the manifest,
- // it returns that value, otherwise it returns the default value.
- uint32_t GetMinorVersion() const;
+ // Compare |calculated_hash| with source hash in |operation|, return false and
+ // dump hash and set |error| if don't match.
+ // |source_fd| is the file descriptor of the source partition.
+ static bool ValidateSourceHash(const brillo::Blob& calculated_hash,
+ const InstallOperation& operation,
+ const FileDescriptorPtr source_fd,
+ ErrorCode* error);
// Initialize partitions and allocate required space for an update with the
// given |manifest|. |update_check_response_hash| is used to check if the
@@ -199,6 +203,12 @@
FRIEND_TEST(DeltaPerformerTest, BrilloParsePayloadMetadataTest);
FRIEND_TEST(DeltaPerformerTest, UsePublicKeyFromResponse);
+ // Obtain the operation index for current partition. If all operations for
+ // current partition is are finished, return # of operations. This is mostly
+ // intended to be used by CheckpointUpdateProgress, where partition writer
+ // needs to know the current operation number to properly checkpoint update.
+ size_t GetPartitionOperationNum();
+
// Parse and move the update instructions of all partitions into our local
// |partitions_| variable based on the version of the payload. Requires the
// manifest to be parsed and valid.
@@ -299,6 +309,8 @@
// a generic error on the device.
ErrorCode CheckTimestampError() const;
+ // Check if partition `part_name` is a dynamic partition.
+ bool IsDynamicPartition(const std::string& part_name);
// Update Engine preference store.
PrefsInterface* prefs_;
@@ -336,22 +348,22 @@
// otherwise 0.
size_t num_total_operations_{0};
- // The list of partitions to update as found in the manifest major version 2.
- // When parsing an older manifest format, the information is converted over to
- // this format instead.
+ // The list of partitions to update as found in the manifest major
+ // version 2. When parsing an older manifest format, the information is
+ // converted over to this format instead.
std::vector<PartitionUpdate> partitions_;
// Index in the list of partitions (|partitions_| member) of the current
// partition being processed.
size_t current_partition_{0};
- // Index of the next operation to perform in the manifest. The index is linear
- // on the total number of operation on the manifest.
+ // Index of the next operation to perform in the manifest. The index is
+ // linear on the total number of operation on the manifest.
size_t next_operation_num_{0};
// A buffer used for accumulating downloaded data. Initially, it stores the
- // payload metadata; once that's downloaded and parsed, it stores data for the
- // next update operation.
+ // payload metadata; once that's downloaded and parsed, it stores data for
+ // the next update operation.
brillo::Blob buffer_;
// Offset of buffer_ in the binary blobs section of the update.
uint64_t buffer_offset_{0};
@@ -393,8 +405,9 @@
// If |true|, the update is user initiated (vs. periodic update checks).
bool interactive_{false};
- // The timeout after which we should force emitting a progress log (constant),
- // and the actual point in time for the next forced log to be emitted.
+ // The timeout after which we should force emitting a progress log
+ // (constant), and the actual point in time for the next forced log to be
+ // emitted.
const base::TimeDelta forced_progress_log_wait_{
base::TimeDelta::FromSeconds(kProgressLogTimeoutSeconds)};
base::TimeTicks forced_progress_log_time_;
@@ -407,6 +420,8 @@
std::unique_ptr<PartitionWriter> partition_writer_;
+ // List of dynamic partitions on device.
+ std::vector<std::string> dynamic_partitions_;
DISALLOW_COPY_AND_ASSIGN(DeltaPerformer);
};
diff --git a/payload_consumer/delta_performer_fuzzer.cc b/payload_consumer/delta_performer_fuzzer.cc
index 73082c4..0ce5081 100644
--- a/payload_consumer/delta_performer_fuzzer.cc
+++ b/payload_consumer/delta_performer_fuzzer.cc
@@ -18,11 +18,11 @@
#include <base/logging.h>
#include <fuzzer/FuzzedDataProvider.h>
+#include "update_engine/common/download_action.h"
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/prefs.h"
#include "update_engine/payload_consumer/delta_performer.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/install_plan.h"
namespace chromeos_update_engine {
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index f2aeb03..374131e 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -37,12 +37,12 @@
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
+#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/mock_download_action.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/hardware_android.h"
#include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/payload_consumer/mock_download_action.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_consumer/payload_metadata.h"
#include "update_engine/payload_consumer/payload_verifier.h"
@@ -52,7 +52,9 @@
namespace chromeos_update_engine {
+using std::list;
using std::string;
+using std::unique_ptr;
using std::vector;
using test_utils::GetBuildArtifactsPath;
using test_utils::kRandomString;
@@ -76,22 +78,24 @@
namespace {
struct DeltaState {
- string a_img;
- string b_img;
- string result_img;
+ unique_ptr<ScopedTempFile> a_img;
+ unique_ptr<ScopedTempFile> b_img;
+ unique_ptr<ScopedTempFile> result_img;
size_t image_size;
- string delta_path;
+ unique_ptr<ScopedTempFile> delta_file;
+ // The in-memory copy of delta file.
+ brillo::Blob delta;
uint64_t metadata_size;
uint32_t metadata_signature_size;
- string old_kernel;
+ unique_ptr<ScopedTempFile> old_kernel;
brillo::Blob old_kernel_data;
- string new_kernel;
+ unique_ptr<ScopedTempFile> new_kernel;
brillo::Blob new_kernel_data;
- string result_kernel;
+ unique_ptr<ScopedTempFile> result_kernel;
brillo::Blob result_kernel_data;
size_t kernel_size;
@@ -99,9 +103,6 @@
// the DeltaPerformer.
InstallPlan install_plan;
- // The in-memory copy of delta file.
- brillo::Blob delta;
-
// Mock and fake instances used by the delta performer.
FakeBootControl fake_boot_control_;
FakeHardware fake_hardware_;
@@ -155,7 +156,7 @@
EXPECT_EQ(expected, performer.ValidateManifest());
}
void AddPartition(DeltaArchiveManifest* manifest,
- std::string name,
+ string name,
int timestamp) {
auto& partition = *manifest->add_partitions();
partition.set_version(std::to_string(timestamp));
@@ -259,8 +260,7 @@
}
string signature_size_string = base::JoinString(signature_size_strings, ":");
- test_utils::ScopedTempFile hash_file("hash.XXXXXX"),
- metadata_hash_file("hash.XXXXXX");
+ ScopedTempFile hash_file("hash.XXXXXX"), metadata_hash_file("hash.XXXXXX");
string delta_generator_path = GetBuildArtifactsPath("delta_generator");
ASSERT_EQ(0,
System(base::StringPrintf(
@@ -273,29 +273,27 @@
metadata_hash_file.path().c_str())));
// Sign the hash with all private keys.
- vector<test_utils::ScopedTempFile> sig_files, metadata_sig_files;
+ list<ScopedTempFile> sig_files, metadata_sig_files;
vector<string> sig_file_paths, metadata_sig_file_paths;
for (const auto& key_path : private_key_paths) {
brillo::Blob hash, signature;
ASSERT_TRUE(utils::ReadFile(hash_file.path(), &hash));
ASSERT_TRUE(PayloadSigner::SignHash(hash, key_path, &signature));
- test_utils::ScopedTempFile sig_file("signature.XXXXXX");
- ASSERT_TRUE(test_utils::WriteFileVector(sig_file.path(), signature));
- sig_file_paths.push_back(sig_file.path());
- sig_files.push_back(std::move(sig_file));
+ sig_files.emplace_back("signature.XXXXXX");
+ ASSERT_TRUE(
+ test_utils::WriteFileVector(sig_files.back().path(), signature));
+ sig_file_paths.push_back(sig_files.back().path());
brillo::Blob metadata_hash, metadata_signature;
ASSERT_TRUE(utils::ReadFile(metadata_hash_file.path(), &metadata_hash));
ASSERT_TRUE(
PayloadSigner::SignHash(metadata_hash, key_path, &metadata_signature));
- test_utils::ScopedTempFile metadata_sig_file("signature.XXXXXX");
- ASSERT_TRUE(test_utils::WriteFileVector(metadata_sig_file.path(),
+ metadata_sig_files.emplace_back("metadata_signature.XXXXXX");
+ ASSERT_TRUE(test_utils::WriteFileVector(metadata_sig_files.back().path(),
metadata_signature));
-
- metadata_sig_file_paths.push_back(metadata_sig_file.path());
- metadata_sig_files.push_back(std::move(metadata_sig_file));
+ metadata_sig_file_paths.push_back(metadata_sig_files.back().path());
}
string sig_files_string = base::JoinString(sig_file_paths, ":");
string metadata_sig_files_string =
@@ -377,7 +375,7 @@
GetBuildArtifactsPath(kUnittestPrivateKey2Path));
}
- std::string public_key;
+ string public_key;
if (signature_test == kSignatureGeneratedShellRotateCl2) {
public_key = GetBuildArtifactsPath(kUnittestPublicKey2Path);
} else if (signature_test == kSignatureGeneratedShellECKey) {
@@ -397,44 +395,23 @@
SignatureTest signature_test,
DeltaState* state,
uint32_t minor_version) {
- EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
- EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
+ state->a_img.reset(new ScopedTempFile("a_img.XXXXXX"));
+ state->b_img.reset(new ScopedTempFile("b_img.XXXXXX"));
// result_img is used in minor version 2. Instead of applying the update
// in-place on A, we apply it to a new image, result_img.
- EXPECT_TRUE(
- utils::MakeTempFile("result_img.XXXXXX", &state->result_img, nullptr));
+ state->result_img.reset(new ScopedTempFile("result_img.XXXXXX"));
EXPECT_TRUE(
base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
- base::FilePath(state->a_img)));
+ base::FilePath(state->a_img->path())));
- state->image_size = utils::FileSize(state->a_img);
-
- // Create ImageInfo A & B
- ImageInfo old_image_info;
- ImageInfo new_image_info;
-
- if (!full_rootfs) {
- old_image_info.set_channel("src-channel");
- old_image_info.set_board("src-board");
- old_image_info.set_version("src-version");
- old_image_info.set_key("src-key");
- old_image_info.set_build_channel("src-build-channel");
- old_image_info.set_build_version("src-build-version");
- }
-
- new_image_info.set_channel("test-channel");
- new_image_info.set_board("test-board");
- new_image_info.set_version("test-version");
- new_image_info.set_key("test-key");
- new_image_info.set_build_channel("test-build-channel");
- new_image_info.set_build_version("test-build-version");
+ state->image_size = utils::FileSize(state->a_img->path());
// Make some changes to the A image.
{
string a_mnt;
- ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
+ ScopedLoopMounter b_mounter(state->a_img->path(), &a_mnt, 0);
brillo::Blob hardtocompress;
while (hardtocompress.size() < 3 * kBlockSize) {
@@ -471,17 +448,18 @@
// Create a result image with image_size bytes of garbage.
brillo::Blob ones(state->image_size, 0xff);
- EXPECT_TRUE(
- utils::WriteFile(state->result_img.c_str(), ones.data(), ones.size()));
- EXPECT_EQ(utils::FileSize(state->a_img), utils::FileSize(state->result_img));
+ EXPECT_TRUE(utils::WriteFile(
+ state->result_img->path().c_str(), ones.data(), ones.size()));
+ EXPECT_EQ(utils::FileSize(state->a_img->path()),
+ utils::FileSize(state->result_img->path()));
EXPECT_TRUE(
base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
- base::FilePath(state->b_img)));
+ base::FilePath(state->b_img->path())));
{
// Make some changes to the B image.
string b_mnt;
- ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
+ ScopedLoopMounter b_mounter(state->b_img->path(), &b_mnt, 0);
base::FilePath mnt_path(b_mnt);
EXPECT_TRUE(base::CopyFile(mnt_path.Append("regular-small"),
@@ -529,18 +507,9 @@
hardtocompress.size()));
}
- string old_kernel;
- EXPECT_TRUE(
- utils::MakeTempFile("old_kernel.XXXXXX", &state->old_kernel, nullptr));
-
- string new_kernel;
- EXPECT_TRUE(
- utils::MakeTempFile("new_kernel.XXXXXX", &state->new_kernel, nullptr));
-
- string result_kernel;
- EXPECT_TRUE(utils::MakeTempFile(
- "result_kernel.XXXXXX", &state->result_kernel, nullptr));
-
+ state->old_kernel.reset(new ScopedTempFile("old_kernel.XXXXXX"));
+ state->new_kernel.reset(new ScopedTempFile("new_kernel.XXXXXX"));
+ state->result_kernel.reset(new ScopedTempFile("result_kernel.XXXXXX"));
state->kernel_size = kDefaultKernelSize;
state->old_kernel_data.resize(kDefaultKernelSize);
state->new_kernel_data.resize(state->old_kernel_data.size());
@@ -554,18 +523,17 @@
std::begin(kNewData), std::end(kNewData), state->new_kernel_data.begin());
// Write kernels to disk
- EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
+ EXPECT_TRUE(utils::WriteFile(state->old_kernel->path().c_str(),
state->old_kernel_data.data(),
state->old_kernel_data.size()));
- EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
+ EXPECT_TRUE(utils::WriteFile(state->new_kernel->path().c_str(),
state->new_kernel_data.data(),
state->new_kernel_data.size()));
- EXPECT_TRUE(utils::WriteFile(state->result_kernel.c_str(),
+ EXPECT_TRUE(utils::WriteFile(state->result_kernel->path().c_str(),
state->result_kernel_data.data(),
state->result_kernel_data.size()));
- EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX", &state->delta_path, nullptr));
- LOG(INFO) << "delta path: " << state->delta_path;
+ state->delta_file.reset(new ScopedTempFile("delta.XXXXXX"));
{
const string private_key =
signature_test == kSignatureGenerator
@@ -581,10 +549,10 @@
if (!full_rootfs) {
payload_config.source.partitions.emplace_back(kPartitionNameRoot);
payload_config.source.partitions.emplace_back(kPartitionNameKernel);
- payload_config.source.partitions.front().path = state->a_img;
+ payload_config.source.partitions.front().path = state->a_img->path();
if (!full_kernel)
- payload_config.source.partitions.back().path = state->old_kernel;
- payload_config.source.image_info = old_image_info;
+ payload_config.source.partitions.back().path =
+ state->old_kernel->path();
EXPECT_TRUE(payload_config.source.LoadImageSize());
for (PartitionConfig& part : payload_config.source.partitions)
EXPECT_TRUE(part.OpenFilesystem());
@@ -594,29 +562,30 @@
payload_config.hard_chunk_size = 1024 * 1024;
}
payload_config.target.partitions.emplace_back(kPartitionNameRoot);
- payload_config.target.partitions.back().path = state->b_img;
+ payload_config.target.partitions.back().path = state->b_img->path();
payload_config.target.partitions.emplace_back(kPartitionNameKernel);
- payload_config.target.partitions.back().path = state->new_kernel;
- payload_config.target.image_info = new_image_info;
+ payload_config.target.partitions.back().path = state->new_kernel->path();
EXPECT_TRUE(payload_config.target.LoadImageSize());
for (PartitionConfig& part : payload_config.target.partitions)
EXPECT_TRUE(part.OpenFilesystem());
EXPECT_TRUE(payload_config.Validate());
- EXPECT_TRUE(GenerateUpdatePayloadFile(
- payload_config, state->delta_path, private_key, &state->metadata_size));
+ EXPECT_TRUE(GenerateUpdatePayloadFile(payload_config,
+ state->delta_file->path(),
+ private_key,
+ &state->metadata_size));
}
// Extend the "partitions" holding the file system a bit.
EXPECT_EQ(0,
- HANDLE_EINTR(truncate(state->a_img.c_str(),
+ HANDLE_EINTR(truncate(state->a_img->path().c_str(),
state->image_size + 1024 * 1024)));
EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
- utils::FileSize(state->a_img));
+ utils::FileSize(state->a_img->path()));
EXPECT_EQ(0,
- HANDLE_EINTR(truncate(state->b_img.c_str(),
+ HANDLE_EINTR(truncate(state->b_img->path().c_str(),
state->image_size + 1024 * 1024)));
EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
- utils::FileSize(state->b_img));
+ utils::FileSize(state->b_img->path()));
if (signature_test == kSignatureGeneratedPlaceholder ||
signature_test == kSignatureGeneratedPlaceholderMismatch) {
@@ -625,13 +594,13 @@
GetBuildArtifactsPath(kUnittestPrivateKeyPath), &signature_size));
LOG(INFO) << "Inserting placeholder signature.";
ASSERT_TRUE(InsertSignaturePlaceholder(
- signature_size, state->delta_path, &state->metadata_size));
+ signature_size, state->delta_file->path(), &state->metadata_size));
if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
signature_size -= 1;
LOG(INFO) << "Inserting mismatched placeholder signature.";
ASSERT_FALSE(InsertSignaturePlaceholder(
- signature_size, state->delta_path, &state->metadata_size));
+ signature_size, state->delta_file->path(), &state->metadata_size));
return;
}
}
@@ -643,13 +612,13 @@
// reflect the new size after adding the signature operation to the
// manifest.
LOG(INFO) << "Signing payload.";
- SignGeneratedPayload(state->delta_path, &state->metadata_size);
+ SignGeneratedPayload(state->delta_file->path(), &state->metadata_size);
} else if (signature_test == kSignatureGeneratedShell ||
signature_test == kSignatureGeneratedShellECKey ||
signature_test == kSignatureGeneratedShellBadKey ||
signature_test == kSignatureGeneratedShellRotateCl1 ||
signature_test == kSignatureGeneratedShellRotateCl2) {
- SignGeneratedShellPayload(signature_test, state->delta_path);
+ SignGeneratedShellPayload(signature_test, state->delta_file->path());
}
}
@@ -663,7 +632,7 @@
uint32_t minor_version) {
// Check the metadata.
{
- EXPECT_TRUE(utils::ReadFile(state->delta_path, &state->delta));
+ EXPECT_TRUE(utils::ReadFile(state->delta_file->path(), &state->delta));
PayloadMetadata payload_metadata;
EXPECT_TRUE(payload_metadata.ParsePayloadHeader(state->delta));
state->metadata_size = payload_metadata.GetMetadataSize();
@@ -738,22 +707,6 @@
EXPECT_FALSE(rootfs_part.old_partition_info().hash().empty());
}
EXPECT_FALSE(rootfs_part.new_partition_info().hash().empty());
-
- EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
- EXPECT_EQ(manifest.new_image_info().board(), "test-board");
- EXPECT_EQ(manifest.new_image_info().version(), "test-version");
- EXPECT_EQ(manifest.new_image_info().key(), "test-key");
- EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
- EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
-
- if (!full_rootfs) {
- EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
- EXPECT_EQ(manifest.old_image_info().board(), "src-board");
- EXPECT_EQ(manifest.old_image_info().version(), "src-version");
- EXPECT_EQ(manifest.old_image_info().key(), "src-key");
- EXPECT_EQ(manifest.old_image_info().build_channel(), "src-build-channel");
- EXPECT_EQ(manifest.old_image_info().build_version(), "src-build-version");
- }
}
MockPrefs prefs;
@@ -832,9 +785,10 @@
(*performer)->set_public_key_path(public_key_path);
(*performer)->set_update_certificates_path("");
- EXPECT_EQ(static_cast<off_t>(state->image_size),
- HashCalculator::RawHashOfFile(
- state->a_img, state->image_size, &root_part.source_hash));
+ EXPECT_EQ(
+ static_cast<off_t>(state->image_size),
+ HashCalculator::RawHashOfFile(
+ state->a_img->path(), state->image_size, &root_part.source_hash));
EXPECT_TRUE(HashCalculator::RawHashOfData(state->old_kernel_data,
&kernel_part.source_hash));
@@ -842,13 +796,15 @@
install_plan->partitions.clear();
state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameRoot, install_plan->source_slot, state->a_img);
+ kPartitionNameRoot, install_plan->source_slot, state->a_img->path());
+ state->fake_boot_control_.SetPartitionDevice(kPartitionNameKernel,
+ install_plan->source_slot,
+ state->old_kernel->path());
state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameKernel, install_plan->source_slot, state->old_kernel);
- state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameRoot, install_plan->target_slot, state->result_img);
- state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameKernel, install_plan->target_slot, state->result_kernel);
+ kPartitionNameRoot, install_plan->target_slot, state->result_img->path());
+ state->fake_boot_control_.SetPartitionDevice(kPartitionNameKernel,
+ install_plan->target_slot,
+ state->result_kernel->path());
ErrorCode expected_error, actual_error;
bool continue_writing;
@@ -927,12 +883,15 @@
return;
}
+ CompareFilesByBlock(state->result_kernel->path(),
+ state->new_kernel->path(),
+ state->kernel_size);
CompareFilesByBlock(
- state->result_kernel, state->new_kernel, state->kernel_size);
- CompareFilesByBlock(state->result_img, state->b_img, state->image_size);
+ state->result_img->path(), state->b_img->path(), state->image_size);
brillo::Blob updated_kernel_partition;
- EXPECT_TRUE(utils::ReadFile(state->result_kernel, &updated_kernel_partition));
+ EXPECT_TRUE(
+ utils::ReadFile(state->result_kernel->path(), &updated_kernel_partition));
ASSERT_GE(updated_kernel_partition.size(), base::size(kNewData));
EXPECT_TRUE(std::equal(std::begin(kNewData),
std::end(kNewData),
@@ -951,9 +910,10 @@
EXPECT_EQ(state->image_size, partitions[0].target_size);
brillo::Blob expected_new_rootfs_hash;
- EXPECT_EQ(static_cast<off_t>(state->image_size),
- HashCalculator::RawHashOfFile(
- state->b_img, state->image_size, &expected_new_rootfs_hash));
+ EXPECT_EQ(
+ static_cast<off_t>(state->image_size),
+ HashCalculator::RawHashOfFile(
+ state->b_img->path(), state->image_size, &expected_new_rootfs_hash));
EXPECT_EQ(expected_new_rootfs_hash, partitions[0].target_hash);
}
@@ -991,13 +951,6 @@
&state,
minor_version);
- ScopedPathUnlinker a_img_unlinker(state.a_img);
- ScopedPathUnlinker b_img_unlinker(state.b_img);
- ScopedPathUnlinker new_img_unlinker(state.result_img);
- ScopedPathUnlinker delta_unlinker(state.delta_path);
- ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
- ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
- ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
ApplyDeltaFile(full_kernel,
full_rootfs,
signature_test,
@@ -1015,11 +968,6 @@
DeltaState state;
uint64_t minor_version = kFullPayloadMinorVersion;
GenerateDeltaFile(true, true, -1, kSignatureGenerated, &state, minor_version);
- ScopedPathUnlinker a_img_unlinker(state.a_img);
- ScopedPathUnlinker b_img_unlinker(state.b_img);
- ScopedPathUnlinker delta_unlinker(state.delta_path);
- ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
- ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
DeltaPerformer* performer = nullptr;
ApplyDeltaFile(true,
true,
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index a5eb538..74f17d2 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -41,10 +41,10 @@
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/mock_download_action.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/fake_file_descriptor.h"
-#include "update_engine/payload_consumer/mock_download_action.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_consumer/payload_metadata.h"
#include "update_engine/payload_generator/bzip.h"
@@ -202,7 +202,7 @@
uint64_t major_version,
uint32_t minor_version,
PartitionConfig* old_part = nullptr) {
- test_utils::ScopedTempFile blob_file("Blob-XXXXXX");
+ ScopedTempFile blob_file("Blob-XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(blob_file.path(), blob_data));
PayloadGenerationConfig config;
@@ -228,15 +228,15 @@
new_part.path = "/dev/zero";
new_part.size = 1234;
- payload.AddPartition(*old_part, new_part, aops, {});
+ payload.AddPartition(*old_part, new_part, aops, {}, 0);
// We include a kernel partition without operations.
old_part->name = kPartitionNameKernel;
new_part.name = kPartitionNameKernel;
new_part.size = 0;
- payload.AddPartition(*old_part, new_part, {}, {});
+ payload.AddPartition(*old_part, new_part, {}, {}, 0);
- test_utils::ScopedTempFile payload_file("Payload-XXXXXX");
+ ScopedTempFile payload_file("Payload-XXXXXX");
string private_key =
sign_payload ? GetBuildArtifactsPath(kUnittestPrivateKeyPath) : "";
EXPECT_TRUE(payload.WritePayload(payload_file.path(),
@@ -287,7 +287,7 @@
const string& source_path,
const brillo::Blob& target_data,
bool expect_success) {
- test_utils::ScopedTempFile new_part("Partition-XXXXXX");
+ ScopedTempFile new_part("Partition-XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(new_part.path(), target_data));
payload_.size = payload_data.size();
@@ -576,7 +576,7 @@
EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());
- test_utils::ScopedTempFile source("Source-XXXXXX");
+ ScopedTempFile source("Source-XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(source.path(), expected_data));
PartitionConfig old_part(kPartitionNameRoot);
@@ -604,7 +604,7 @@
EXPECT_TRUE(HashCalculator::RawHashOfData(src, &src_hash));
aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());
- test_utils::ScopedTempFile source("Source-XXXXXX");
+ ScopedTempFile source("Source-XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(source.path(), src));
PartitionConfig old_part(kPartitionNameRoot);
@@ -632,7 +632,7 @@
EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());
- test_utils::ScopedTempFile source("Source-XXXXXX");
+ ScopedTempFile source("Source-XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(source.path(), actual_data));
PartitionConfig old_part(kPartitionNameRoot);
@@ -645,9 +645,6 @@
EXPECT_EQ(actual_data, ApplyPayload(payload_data, source.path(), false));
}
-
-
-
TEST_F(DeltaPerformerTest, ExtentsToByteStringTest) {
uint64_t test[] = {1, 1, 4, 2, 0, 1};
static_assert(base::size(test) % 2 == 0, "Array size uneven");
diff --git a/payload_consumer/extent_reader.cc b/payload_consumer/extent_reader.cc
index ad983ae..3c7329d 100644
--- a/payload_consumer/extent_reader.cc
+++ b/payload_consumer/extent_reader.cc
@@ -77,7 +77,7 @@
std::min(count - bytes_read, cur_extent_bytes_left);
ssize_t out_bytes_read;
- TEST_AND_RETURN_FALSE(utils::PReadAll(
+ TEST_AND_RETURN_FALSE(utils::ReadAll(
fd_,
bytes + bytes_read,
bytes_to_read,
diff --git a/payload_consumer/extent_reader_unittest.cc b/payload_consumer/extent_reader_unittest.cc
index b7059bc..686f14d 100644
--- a/payload_consumer/extent_reader_unittest.cc
+++ b/payload_consumer/extent_reader_unittest.cc
@@ -72,7 +72,7 @@
}
FileDescriptorPtr fd_;
- test_utils::ScopedTempFile temp_file_{"ExtentReaderTest-file.XXXXXX"};
+ ScopedTempFile temp_file_{"ExtentReaderTest-file.XXXXXX"};
brillo::Blob sample_;
};
diff --git a/payload_consumer/extent_writer_unittest.cc b/payload_consumer/extent_writer_unittest.cc
index aef856b..afebb1a 100644
--- a/payload_consumer/extent_writer_unittest.cc
+++ b/payload_consumer/extent_writer_unittest.cc
@@ -59,7 +59,7 @@
void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
FileDescriptorPtr fd_;
- test_utils::ScopedTempFile temp_file_{"ExtentWriterTest-file.XXXXXX"};
+ ScopedTempFile temp_file_{"ExtentWriterTest-file.XXXXXX"};
};
TEST_F(ExtentWriterTest, SimpleTest) {
diff --git a/payload_consumer/file_descriptor.cc b/payload_consumer/file_descriptor.cc
index 1de615c..7c69c1b 100644
--- a/payload_consumer/file_descriptor.cc
+++ b/payload_consumer/file_descriptor.cc
@@ -21,6 +21,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <base/posix/eintr_wrapper.h>
@@ -28,6 +29,12 @@
namespace chromeos_update_engine {
+EintrSafeFileDescriptor::~EintrSafeFileDescriptor() {
+ if (IsOpen()) {
+ Close();
+ }
+}
+
bool EintrSafeFileDescriptor::Open(const char* path, int flags, mode_t mode) {
CHECK_EQ(fd_, -1);
return ((fd_ = HANDLE_EINTR(open(path, flags, mode))) >= 0);
@@ -125,11 +132,17 @@
bool EintrSafeFileDescriptor::Flush() {
CHECK_GE(fd_, 0);
+ // Implemented as a No-Op, as delta_performer typically uses |O_DSYNC|, except
+ // in interactive settings.
+ fsync(fd_);
return true;
}
bool EintrSafeFileDescriptor::Close() {
CHECK_GE(fd_, 0);
+ // https://stackoverflow.com/questions/705454/does-linux-guarantee-the-contents-of-a-file-is-flushed-to-disc-after-close
+ // |close()| doesn't imply |fsync()|, we need to do it manually.
+ fsync(fd_);
if (IGNORE_EINTR(close(fd_)))
return false;
fd_ = -1;
diff --git a/payload_consumer/file_descriptor.h b/payload_consumer/file_descriptor.h
index fb07ff0..faebcc1 100644
--- a/payload_consumer/file_descriptor.h
+++ b/payload_consumer/file_descriptor.h
@@ -111,6 +111,7 @@
class EintrSafeFileDescriptor : public FileDescriptor {
public:
EintrSafeFileDescriptor() : fd_(-1) {}
+ ~EintrSafeFileDescriptor();
// Interface methods.
bool Open(const char* path, int flags, mode_t mode) override;
diff --git a/payload_consumer/file_descriptor_utils_unittest.cc b/payload_consumer/file_descriptor_utils_unittest.cc
index 48e610f..478893d 100644
--- a/payload_consumer/file_descriptor_utils_unittest.cc
+++ b/payload_consumer/file_descriptor_utils_unittest.cc
@@ -52,14 +52,13 @@
class FileDescriptorUtilsTest : public ::testing::Test {
protected:
void SetUp() override {
- EXPECT_TRUE(utils::MakeTempFile("fd_tgt.XXXXXX", &tgt_path_, nullptr));
- EXPECT_TRUE(target_->Open(tgt_path_.c_str(), O_RDWR));
+ EXPECT_TRUE(target_->Open(tgt_file_.path().c_str(), O_RDWR));
}
// Check that the |target_| file contains |expected_contents|.
void ExpectTarget(const std::string& expected_contents) {
std::string target_contents;
- EXPECT_TRUE(utils::ReadFile(tgt_path_, &target_contents));
+ EXPECT_TRUE(utils::ReadFile(tgt_file_.path(), &target_contents));
EXPECT_EQ(expected_contents.size(), target_contents.size());
if (target_contents != expected_contents) {
ADD_FAILURE() << "Contents don't match.";
@@ -70,8 +69,7 @@
}
}
- // Path to the target temporary file.
- std::string tgt_path_;
+ ScopedTempFile tgt_file_{"fd_tgt.XXXXXX"};
// Source and target file descriptor used for testing the tools.
FakeFileDescriptor* fake_source_{new FakeFileDescriptor()};
diff --git a/payload_consumer/file_writer_unittest.cc b/payload_consumer/file_writer_unittest.cc
index 59cfe2b..3b959f3 100644
--- a/payload_consumer/file_writer_unittest.cc
+++ b/payload_consumer/file_writer_unittest.cc
@@ -35,8 +35,7 @@
class FileWriterTest : public ::testing::Test {};
TEST(FileWriterTest, SimpleTest) {
- // Create a uniquely named file for testing.
- test_utils::ScopedTempFile file("FileWriterTest-XXXXXX");
+ ScopedTempFile file("FileWriterTest-XXXXXX");
DirectFileWriter file_writer;
EXPECT_EQ(0,
file_writer.Open(file.path().c_str(),
@@ -60,7 +59,7 @@
TEST(FileWriterTest, WriteErrorTest) {
// Create a uniquely named file for testing.
- test_utils::ScopedTempFile file("FileWriterTest-XXXXXX");
+ ScopedTempFile file("FileWriterTest-XXXXXX");
DirectFileWriter file_writer;
EXPECT_EQ(0,
file_writer.Open(file.path().c_str(),
diff --git a/payload_consumer/filesystem_verifier_action.cc b/payload_consumer/filesystem_verifier_action.cc
index 61917ea..634f03f 100644
--- a/payload_consumer/filesystem_verifier_action.cc
+++ b/payload_consumer/filesystem_verifier_action.cc
@@ -20,17 +20,22 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <algorithm>
#include <cstdlib>
+#include <memory>
#include <string>
+#include <utility>
#include <base/bind.h>
-#include <brillo/data_encoding.h>
-#include <brillo/streams/file_stream.h>
#include <base/strings/string_util.h>
+#include <brillo/data_encoding.h>
+#include <brillo/message_loops/message_loop.h>
+#include <brillo/streams/file_stream.h>
#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
using brillo::data_encoding::Base64Encode;
using std::string;
@@ -59,18 +64,19 @@
return;
}
install_plan_.Dump();
-
StartPartitionHashing();
abort_action_completer.set_should_complete(false);
}
void FilesystemVerifierAction::TerminateProcessing() {
+ brillo::MessageLoop::current()->CancelTask(pending_task_id_);
cancelled_ = true;
Cleanup(ErrorCode::kSuccess); // error code is ignored if canceled_ is true.
}
void FilesystemVerifierAction::Cleanup(ErrorCode code) {
- src_stream_.reset();
+ read_fd_.reset();
+ write_fd_.reset();
// This memory is not used anymore.
buffer_.clear();
@@ -88,6 +94,43 @@
}
}
+bool FilesystemVerifierAction::InitializeFdVABC() {
+ const InstallPlan::Partition& partition =
+ install_plan_.partitions[partition_index_];
+
+ read_fd_ = dynamic_control_->OpenCowReader(
+ partition.name, partition.source_path, true);
+ if (!read_fd_) {
+ LOG(ERROR) << "OpenCowReader(" << partition.name << ", "
+ << partition.source_path << ") failed.";
+ return false;
+ }
+ partition_size_ = partition.target_size;
+ // TODO(b/173432386): Support Verity writes for VABC.
+ CHECK_EQ(partition.fec_size, 0U);
+ CHECK_EQ(partition.hash_tree_size, 0U);
+ return true;
+}
+
+bool FilesystemVerifierAction::InitializeFd(const std::string& part_path) {
+ read_fd_ = FileDescriptorPtr(new EintrSafeFileDescriptor());
+ if (!read_fd_->Open(part_path.c_str(), O_RDONLY)) {
+ LOG(ERROR) << "Unable to open " << part_path << " for reading.";
+ return false;
+ }
+
+ // Can't re-use |read_fd_|, as verity writer may call `seek` to modify state
+ // of a file descriptor.
+ if (ShouldWriteVerity()) {
+ write_fd_ = FileDescriptorPtr(new EintrSafeFileDescriptor());
+ if (!write_fd_->Open(part_path.c_str(), O_RDWR)) {
+ LOG(ERROR) << "Unable to open " << part_path << " for Read/Write.";
+ return false;
+ }
+ }
+ return true;
+}
+
void FilesystemVerifierAction::StartPartitionHashing() {
if (partition_index_ == install_plan_.partitions.size()) {
if (!install_plan_.untouched_dynamic_partitions.empty()) {
@@ -109,7 +152,6 @@
}
const InstallPlan::Partition& partition =
install_plan_.partitions[partition_index_];
-
string part_path;
switch (verifier_step_) {
case VerifierStep::kVerifySourceHash:
@@ -122,44 +164,40 @@
break;
}
- if (part_path.empty()) {
- if (partition_size_ == 0) {
- LOG(INFO) << "Skip hashing partition " << partition_index_ << " ("
- << partition.name << ") because size is 0.";
- partition_index_++;
- StartPartitionHashing();
- return;
- }
- LOG(ERROR) << "Cannot hash partition " << partition_index_ << " ("
- << partition.name
- << ") because its device path cannot be determined.";
- Cleanup(ErrorCode::kFilesystemVerifierError);
- return;
- }
-
LOG(INFO) << "Hashing partition " << partition_index_ << " ("
<< partition.name << ") on device " << part_path;
-
- brillo::ErrorPtr error;
- src_stream_ =
- brillo::FileStream::Open(base::FilePath(part_path),
- brillo::Stream::AccessMode::READ,
- brillo::FileStream::Disposition::OPEN_EXISTING,
- &error);
-
- if (!src_stream_) {
- LOG(ERROR) << "Unable to open " << part_path << " for reading";
+ auto success = false;
+ if (dynamic_control_->GetVirtualAbCompressionFeatureFlag().IsEnabled() &&
+ dynamic_control_->IsDynamicPartition(partition.name) &&
+ verifier_step_ == VerifierStep::kVerifyTargetHash) {
+ success = InitializeFdVABC();
+ } else {
+ if (part_path.empty()) {
+ if (partition_size_ == 0) {
+ LOG(INFO) << "Skip hashing partition " << partition_index_ << " ("
+ << partition.name << ") because size is 0.";
+ partition_index_++;
+ StartPartitionHashing();
+ return;
+ }
+ LOG(ERROR) << "Cannot hash partition " << partition_index_ << " ("
+ << partition.name
+ << ") because its device path cannot be determined.";
+ Cleanup(ErrorCode::kFilesystemVerifierError);
+ return;
+ }
+ success = InitializeFd(part_path);
+ }
+ if (!success) {
Cleanup(ErrorCode::kFilesystemVerifierError);
return;
}
-
buffer_.resize(kReadFileBufferSize);
hasher_ = std::make_unique<HashCalculator>();
offset_ = 0;
- if (verifier_step_ == VerifierStep::kVerifyTargetHash &&
- install_plan_.write_verity) {
- if (!verity_writer_->Init(partition)) {
+ if (ShouldWriteVerity()) {
+ if (!verity_writer_->Init(partition, read_fd_, write_fd_)) {
Cleanup(ErrorCode::kVerityCalculationError);
return;
}
@@ -169,6 +207,14 @@
ScheduleRead();
}
+bool FilesystemVerifierAction::ShouldWriteVerity() {
+ const InstallPlan::Partition& partition =
+ install_plan_.partitions[partition_index_];
+ return verifier_step_ == VerifierStep::kVerifyTargetHash &&
+ install_plan_.write_verity &&
+ (partition.hash_tree_size > 0 || partition.fec_size > 0);
+}
+
void FilesystemVerifierAction::ScheduleRead() {
const InstallPlan::Partition& partition =
install_plan_.partitions[partition_index_];
@@ -190,22 +236,21 @@
return;
}
- bool read_async_ok = src_stream_->ReadAsync(
- buffer_.data(),
- bytes_to_read,
- base::Bind(&FilesystemVerifierAction::OnReadDoneCallback,
- base::Unretained(this)),
- base::Bind(&FilesystemVerifierAction::OnReadErrorCallback,
- base::Unretained(this)),
- nullptr);
-
- if (!read_async_ok) {
+ auto bytes_read = read_fd_->Read(buffer_.data(), bytes_to_read);
+ if (bytes_read < 0) {
LOG(ERROR) << "Unable to schedule an asynchronous read from the stream.";
Cleanup(ErrorCode::kError);
+ } else {
+ // We could just invoke |OnReadDoneCallback()|, it works. But |PostTask|
+ // is used so that users can cancel updates.
+ pending_task_id_ = brillo::MessageLoop::current()->PostTask(
+ base::Bind(&FilesystemVerifierAction::OnReadDone,
+ base::Unretained(this),
+ bytes_read));
}
}
-void FilesystemVerifierAction::OnReadDoneCallback(size_t bytes_read) {
+void FilesystemVerifierAction::OnReadDone(size_t bytes_read) {
if (cancelled_) {
Cleanup(ErrorCode::kError);
return;
@@ -231,8 +276,7 @@
UpdateProgress(
(static_cast<double>(offset_) / partition_size_ + partition_index_) /
install_plan_.partitions.size());
- if (verifier_step_ == VerifierStep::kVerifyTargetHash &&
- install_plan_.write_verity) {
+ if (ShouldWriteVerity()) {
if (!verity_writer_->Update(offset_, buffer_.data(), bytes_read)) {
Cleanup(ErrorCode::kVerityCalculationError);
return;
@@ -249,12 +293,6 @@
ScheduleRead();
}
-void FilesystemVerifierAction::OnReadErrorCallback(const brillo::Error* error) {
- // TODO(deymo): Transform the read-error into an specific ErrorCode.
- LOG(ERROR) << "Asynchronous read failed.";
- Cleanup(ErrorCode::kError);
-}
-
void FilesystemVerifierAction::FinishPartitionHashing() {
if (!hasher_->Finalize()) {
LOG(ERROR) << "Unable to finalize the hash.";
@@ -278,8 +316,8 @@
}
// If we have not verified source partition yet, now that the target
// partition does not match, and it's not a full payload, we need to
- // switch to kVerifySourceHash step to check if it's because the source
- // partition does not match either.
+ // switch to kVerifySourceHash step to check if it's because the
+ // source partition does not match either.
verifier_step_ = VerifierStep::kVerifySourceHash;
} else {
partition_index_++;
@@ -315,17 +353,22 @@
}
// The action will skip kVerifySourceHash step if target partition hash
// matches, if we are in this step, it means target hash does not match,
- // and now that the source partition hash matches, we should set the error
- // code to reflect the error in target partition.
- // We only need to verify the source partition which the target hash does
- // not match, the rest of the partitions don't matter.
+ // and now that the source partition hash matches, we should set the
+ // error code to reflect the error in target partition. We only need to
+ // verify the source partition which the target hash does not match, the
+ // rest of the partitions don't matter.
Cleanup(ErrorCode::kNewRootfsVerificationError);
return;
}
// Start hashing the next partition, if any.
hasher_.reset();
buffer_.clear();
- src_stream_->CloseBlocking(nullptr);
+ if (read_fd_) {
+ read_fd_.reset();
+ }
+ if (write_fd_) {
+ write_fd_.reset();
+ }
StartPartitionHashing();
}
diff --git a/payload_consumer/filesystem_verifier_action.h b/payload_consumer/filesystem_verifier_action.h
index 6a8823a..b6df4b8 100644
--- a/payload_consumer/filesystem_verifier_action.h
+++ b/payload_consumer/filesystem_verifier_action.h
@@ -24,10 +24,11 @@
#include <string>
#include <vector>
-#include <brillo/streams/stream.h>
+#include <brillo/message_loops/message_loop.h>
#include "update_engine/common/action.h"
#include "update_engine/common/hash_calculator.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/payload_consumer/verity_writer_interface.h"
@@ -83,6 +84,9 @@
private:
friend class FilesystemVerifierActionTestDelegate;
+
+ // Return true if we need to write verity bytes.
+ bool ShouldWriteVerity();
// Starts the hashing of the current partition. If there aren't any partitions
// remaining to be hashed, it finishes the action.
void StartPartitionHashing();
@@ -92,8 +96,7 @@
// Called from the main loop when a single read from |src_stream_| succeeds or
// fails, calling OnReadDoneCallback() and OnReadErrorCallback() respectively.
- void OnReadDoneCallback(size_t bytes_read);
- void OnReadErrorCallback(const brillo::Error* error);
+ void OnReadDone(size_t bytes_read);
// When the read is done, finalize the hash checking of the current partition
// and continue checking the next one.
@@ -107,6 +110,10 @@
// Invoke delegate callback to report progress, if delegate is not null
void UpdateProgress(double progress);
+ // Initialize read_fd_ and write_fd_
+ bool InitializeFd(const std::string& part_path);
+ bool InitializeFdVABC();
+
// The type of the partition that we are verifying.
VerifierStep verifier_step_ = VerifierStep::kVerifyTargetHash;
@@ -114,8 +121,15 @@
// being hashed.
size_t partition_index_{0};
- // If not null, the FileStream used to read from the device.
- brillo::StreamPtr src_stream_;
+ // If not null, the FileDescriptor used to read from the device.
+ // |read_fd_| and |write_fd_| will be initialized when we begin hashing a
+ // partition. They will be deallocated once we encounter an error or
+ // successfully finished hashing.
+ FileDescriptorPtr read_fd_;
+ // If not null, the FileDescriptor used to write to the device.
+ // For VABC, this will be different from |read_fd_|. For other cases
+ // this can be the same as |read_fd_|.
+ FileDescriptorPtr write_fd_;
// Buffer for storing data we read.
brillo::Blob buffer_;
@@ -144,6 +158,11 @@
// An observer that observes progress updates of this action.
FilesystemVerifyDelegate* delegate_{};
+ // Callback that should be cancelled on |TerminateProcessing|. Usually this
+ // points to pending read callbacks from async stream.
+ brillo::MessageLoop::TaskId pending_task_id_{
+ brillo::MessageLoop::kTaskIdNull};
+
DISALLOW_COPY_AND_ASSIGN(FilesystemVerifierAction);
};
diff --git a/payload_consumer/filesystem_verifier_action_unittest.cc b/payload_consumer/filesystem_verifier_action_unittest.cc
index 2971849..925fdab 100644
--- a/payload_consumer/filesystem_verifier_action_unittest.cc
+++ b/payload_consumer/filesystem_verifier_action_unittest.cc
@@ -72,7 +72,7 @@
if (action->Type() == FilesystemVerifierAction::StaticType()) {
ran_ = true;
code_ = code;
- EXPECT_FALSE(static_cast<FilesystemVerifierAction*>(action)->src_stream_);
+ EXPECT_FALSE(static_cast<FilesystemVerifierAction*>(action)->read_fd_);
} else if (action->Type() ==
ObjectCollectorAction<InstallPlan>::StaticType()) {
auto collector_action =
@@ -92,7 +92,7 @@
bool FilesystemVerifierActionTest::DoTest(bool terminate_early,
bool hash_fail) {
- test_utils::ScopedTempFile a_loop_file("a_loop_file.XXXXXX");
+ ScopedTempFile a_loop_file("a_loop_file.XXXXXX");
// Make random data for a.
const size_t kLoopFileSize = 10 * 1024 * 1024 + 512;
@@ -278,7 +278,7 @@
#ifdef __ANDROID__
TEST_F(FilesystemVerifierActionTest, RunAsRootWriteVerityTest) {
- test_utils::ScopedTempFile part_file("part_file.XXXXXX");
+ ScopedTempFile part_file("part_file.XXXXXX");
constexpr size_t filesystem_size = 200 * 4096;
constexpr size_t part_size = 256 * 4096;
brillo::Blob part_data(filesystem_size, 0x1);
@@ -340,7 +340,7 @@
#endif // __ANDROID__
TEST_F(FilesystemVerifierActionTest, RunAsRootSkipWriteVerityTest) {
- test_utils::ScopedTempFile part_file("part_file.XXXXXX");
+ ScopedTempFile part_file("part_file.XXXXXX");
constexpr size_t filesystem_size = 200 * 4096;
constexpr size_t part_size = 256 * 4096;
brillo::Blob part_data(part_size);
@@ -384,4 +384,5 @@
EXPECT_TRUE(delegate.ran());
EXPECT_EQ(ErrorCode::kSuccess, delegate.code());
}
+
} // namespace chromeos_update_engine
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
index a313627..4a37836 100644
--- a/payload_consumer/install_plan.cc
+++ b/payload_consumer/install_plan.cc
@@ -82,11 +82,6 @@
}
string version_str = base::StringPrintf(", version: %s", version.c_str());
- if (!system_version.empty()) {
- version_str +=
- base::StringPrintf(", system_version: %s", system_version.c_str());
- }
-
string url_str = download_url;
if (base::StartsWith(
url_str, "fd://", base::CompareCase::INSENSITIVE_ASCII)) {
@@ -98,8 +93,8 @@
<< version_str
<< ", source_slot: " << BootControlInterface::SlotName(source_slot)
<< ", target_slot: " << BootControlInterface::SlotName(target_slot)
- << ", initial url: " << url_str << payloads_str
- << partitions_str << ", hash_checks_mandatory: "
+ << ", initial url: " << url_str << payloads_str << partitions_str
+ << ", hash_checks_mandatory: "
<< utils::ToString(hash_checks_mandatory)
<< ", powerwash_required: " << utils::ToString(powerwash_required)
<< ", switch_slot_on_reboot: "
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
index f04c650..ee1a72b 100644
--- a/payload_consumer/install_plan.h
+++ b/payload_consumer/install_plan.h
@@ -54,13 +54,11 @@
bool is_resume{false};
std::string download_url; // url to download from
std::string version; // version we are installing.
- // system version, if present and separate from version
- std::string system_version;
struct Payload {
std::vector<std::string> payload_urls; // URLs to download the payload
- uint64_t size = 0; // size of the payload
- uint64_t metadata_size = 0; // size of the metadata
+ uint64_t size = 0; // size of the payload
+ uint64_t metadata_size = 0; // size of the metadata
std::string metadata_signature; // signature of the metadata in base64
brillo::Blob hash; // SHA256 hash of the payload
InstallPayloadType type{InstallPayloadType::kUnknown};
diff --git a/mock_file_writer.h b/payload_consumer/mock_file_writer.h
similarity index 100%
rename from mock_file_writer.h
rename to payload_consumer/mock_file_writer.h
diff --git a/payload_consumer/mount_history.cc b/payload_consumer/mount_history.cc
index 43a75b3..1d2ec76 100644
--- a/payload_consumer/mount_history.cc
+++ b/payload_consumer/mount_history.cc
@@ -37,7 +37,7 @@
brillo::Blob block0_buffer(kBlockSize);
ssize_t bytes_read;
- if (!utils::PReadAll(
+ if (!utils::ReadAll(
blockdevice_fd, block0_buffer.data(), kBlockSize, 0, &bytes_read)) {
LOG(WARNING) << "PReadAll failed";
return;
diff --git a/payload_consumer/partition_update_generator_android.cc b/payload_consumer/partition_update_generator_android.cc
index d5d5313..4467182 100644
--- a/payload_consumer/partition_update_generator_android.cc
+++ b/payload_consumer/partition_update_generator_android.cc
@@ -32,10 +32,8 @@
namespace chromeos_update_engine {
PartitionUpdateGeneratorAndroid::PartitionUpdateGeneratorAndroid(
- BootControlInterface* boot_control,
- size_t block_size)
- : boot_control_(boot_control),
- block_size_(block_size) {}
+ BootControlInterface* boot_control, size_t block_size)
+ : boot_control_(boot_control), block_size_(block_size) {}
bool PartitionUpdateGeneratorAndroid::
GenerateOperationsForPartitionsNotInPayload(
@@ -43,6 +41,11 @@
BootControlInterface::Slot target_slot,
const std::set<std::string>& partitions_in_payload,
std::vector<PartitionUpdate>* update_list) {
+#ifndef __ANDROID__
+ // Skip copying partitions for host verification.
+ return true;
+#endif
+
auto ab_partitions = GetAbPartitionsOnDevice();
if (ab_partitions.empty()) {
LOG(ERROR) << "Failed to load static a/b partitions";
diff --git a/payload_consumer/partition_writer.cc b/payload_consumer/partition_writer.cc
index d47ebee..6f06dd2 100644
--- a/payload_consumer/partition_writer.cc
+++ b/payload_consumer/partition_writer.cc
@@ -253,27 +253,37 @@
Close();
}
+bool PartitionWriter::OpenSourcePartition(uint32_t source_slot,
+ bool source_may_exist) {
+ source_path_.clear();
+ if (!source_may_exist) {
+ return true;
+ }
+ if (install_part_.source_size > 0 && !install_part_.source_path.empty()) {
+ source_path_ = install_part_.source_path;
+ int err;
+ source_fd_ = OpenFile(source_path_.c_str(), O_RDONLY, false, &err);
+ if (source_fd_ == nullptr) {
+ LOG(ERROR) << "Unable to open source partition " << install_part_.name
+ << " on slot " << BootControlInterface::SlotName(source_slot)
+ << ", file " << source_path_;
+ return false;
+ }
+ }
+ return true;
+}
+
bool PartitionWriter::Init(const InstallPlan* install_plan,
- bool source_may_exist) {
+ bool source_may_exist,
+ size_t next_op_index) {
const PartitionUpdate& partition = partition_update_;
uint32_t source_slot = install_plan->source_slot;
uint32_t target_slot = install_plan->target_slot;
+ TEST_AND_RETURN_FALSE(OpenSourcePartition(source_slot, source_may_exist));
// We shouldn't open the source partition in certain cases, e.g. some dynamic
// partitions in delta payload, partitions included in the full payload for
// partial updates. Use the source size as the indicator.
- if (source_may_exist && install_part_.source_size > 0) {
- source_path_ = install_part_.source_path;
- int err;
- source_fd_ = OpenFile(source_path_.c_str(), O_RDONLY, false, &err);
- if (!source_fd_) {
- LOG(ERROR) << "Unable to open source partition "
- << partition.partition_name() << " on slot "
- << BootControlInterface::SlotName(source_slot) << ", file "
- << source_path_;
- return false;
- }
- }
target_path_ = install_part_.target_path;
int err;
@@ -308,7 +318,7 @@
const void* data,
size_t count) {
// Setup the ExtentWriter stack based on the operation type.
- std::unique_ptr<ExtentWriter> writer = std::make_unique<DirectExtentWriter>();
+ std::unique_ptr<ExtentWriter> writer = CreateBaseExtentWriter();
if (operation.type() == InstallOperation::REPLACE_BZ) {
writer.reset(new BzipExtentWriter(std::move(writer)));
@@ -320,7 +330,7 @@
writer->Init(target_fd_, operation.dst_extents(), block_size_));
TEST_AND_RETURN_FALSE(writer->Write(data, operation.data_length()));
- return target_fd_->Flush();
+ return true;
}
bool PartitionWriter::PerformZeroOrDiscardOperation(
@@ -349,11 +359,11 @@
for (uint64_t offset = 0; offset < length; offset += zeros.size()) {
uint64_t chunk_length =
std::min(length - offset, static_cast<uint64_t>(zeros.size()));
- TEST_AND_RETURN_FALSE(utils::PWriteAll(
+ TEST_AND_RETURN_FALSE(utils::WriteAll(
target_fd_, zeros.data(), chunk_length, start + offset));
}
}
- return target_fd_->Flush();
+ return true;
}
bool PartitionWriter::PerformSourceCopyOperation(
@@ -464,8 +474,9 @@
block_size_,
nullptr));
}
- return target_fd_->Flush();
+ return true;
}
+
bool PartitionWriter::PerformSourceBsdiffOperation(
const InstallOperation& operation,
ErrorCode* error,
@@ -481,7 +492,7 @@
std::move(reader),
utils::BlocksInExtents(operation.src_extents()) * block_size_);
- auto writer = std::make_unique<DirectExtentWriter>();
+ auto writer = CreateBaseExtentWriter();
TEST_AND_RETURN_FALSE(
writer->Init(target_fd_, operation.dst_extents(), block_size_));
auto dst_file = std::make_unique<BsdiffExtentFile>(
@@ -492,7 +503,7 @@
std::move(dst_file),
reinterpret_cast<const uint8_t*>(data),
count) == 0);
- return target_fd_->Flush();
+ return true;
}
bool PartitionWriter::PerformPuffDiffOperation(
@@ -510,7 +521,7 @@
std::move(reader),
utils::BlocksInExtents(operation.src_extents()) * block_size_));
- auto writer = std::make_unique<DirectExtentWriter>();
+ auto writer = CreateBaseExtentWriter();
TEST_AND_RETURN_FALSE(
writer->Init(target_fd_, operation.dst_extents(), block_size_));
puffin::UniqueStreamPtr dst_stream(new PuffinExtentStream(
@@ -524,7 +535,7 @@
reinterpret_cast<const uint8_t*>(data),
count,
kMaxCacheSize));
- return target_fd_->Flush();
+ return true;
}
FileDescriptorPtr PartitionWriter::ChooseSourceFD(
@@ -641,4 +652,13 @@
source_ecc_open_failure_ = false;
return -err;
}
+
+void PartitionWriter::CheckpointUpdateProgress(size_t next_op_index) {
+ target_fd_->Flush();
+}
+
+std::unique_ptr<ExtentWriter> PartitionWriter::CreateBaseExtentWriter() {
+ return std::make_unique<DirectExtentWriter>();
+}
+
} // namespace chromeos_update_engine
diff --git a/payload_consumer/partition_writer.h b/payload_consumer/partition_writer.h
index 624a411..4b420d2 100644
--- a/payload_consumer/partition_writer.h
+++ b/payload_consumer/partition_writer.h
@@ -18,12 +18,14 @@
#define UPDATE_ENGINE_PARTITION_WRITER_H_
#include <cstdint>
+#include <memory>
#include <string>
#include <brillo/secure_blob.h>
#include <gtest/gtest_prod.h>
#include "update_engine/common/dynamic_partition_control_interface.h"
+#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/update_metadata.pb.h"
@@ -35,7 +37,7 @@
DynamicPartitionControlInterface* dynamic_control,
size_t block_size,
bool is_interactive);
- ~PartitionWriter();
+ virtual ~PartitionWriter();
static bool ValidateSourceHash(const brillo::Blob& calculated_hash,
const InstallOperation& operation,
const FileDescriptorPtr source_fd,
@@ -43,36 +45,54 @@
// Perform necessary initialization work before InstallOperation can be
// applied to this partition
- [[nodiscard]] bool Init(const InstallPlan* install_plan,
- bool source_may_exist);
+ [[nodiscard]] virtual bool Init(const InstallPlan* install_plan,
+ bool source_may_exist,
+ size_t next_op_index);
+ // |CheckpointUpdateProgress| will be called after SetNextOpIndex(), but it's
+ // optional. DeltaPerformer may or may not call this everytime an operation is
+ // applied.
+ // |next_op_index| is index of next operation that should be applied.
+ // |next_op_index-1| is the last operation that is already applied.
+ virtual void CheckpointUpdateProgress(size_t next_op_index);
+
+ // Close partition writer, when calling this function there's no guarantee
+ // that all |InstallOperations| are sent to |PartitionWriter|. This function
+ // will be called even if we are pausing/aborting the update.
int Close();
// These perform a specific type of operation and return true on success.
// |error| will be set if source hash mismatch, otherwise |error| might not be
// set even if it fails.
- [[nodiscard]] bool PerformReplaceOperation(const InstallOperation& operation,
- const void* data,
- size_t count);
- [[nodiscard]] bool PerformZeroOrDiscardOperation(
+ [[nodiscard]] virtual bool PerformReplaceOperation(
+ const InstallOperation& operation, const void* data, size_t count);
+ [[nodiscard]] virtual bool PerformZeroOrDiscardOperation(
const InstallOperation& operation);
- [[nodiscard]] bool PerformSourceCopyOperation(
+ [[nodiscard]] virtual bool PerformSourceCopyOperation(
const InstallOperation& operation, ErrorCode* error);
- [[nodiscard]] bool PerformSourceBsdiffOperation(
+ [[nodiscard]] virtual bool PerformSourceBsdiffOperation(
const InstallOperation& operation,
ErrorCode* error,
const void* data,
size_t count);
- [[nodiscard]] bool PerformPuffDiffOperation(const InstallOperation& operation,
- ErrorCode* error,
- const void* data,
- size_t count);
+ [[nodiscard]] virtual bool PerformPuffDiffOperation(
+ const InstallOperation& operation,
+ ErrorCode* error,
+ const void* data,
+ size_t count);
- private:
+ // |DeltaPerformer| calls this when all Install Ops are sent to partition
+ // writer. No |Perform*Operation| methods will be called in the future, and
+ // the partition writer is expected to be closed soon.
+ [[nodiscard]] virtual bool FinishedInstallOps() { return true; }
+
+ protected:
friend class PartitionWriterTest;
FRIEND_TEST(PartitionWriterTest, ChooseSourceFDTest);
+ bool OpenSourcePartition(uint32_t source_slot, bool source_may_exist);
+
bool OpenCurrentECCPartition();
// For a given operation, choose the source fd to be used (raw device or error
// correction device) based on the source operation hash.
@@ -80,6 +100,7 @@
// the |error| accordingly.
FileDescriptorPtr ChooseSourceFD(const InstallOperation& operation,
ErrorCode* error);
+ [[nodiscard]] virtual std::unique_ptr<ExtentWriter> CreateBaseExtentWriter();
const PartitionUpdate& partition_update_;
const InstallPlan::Partition& install_part_;
@@ -108,6 +129,18 @@
// error corrected.
bool source_ecc_open_failure_{false};
};
+
+namespace partition_writer {
+// Return a PartitionWriter instance for perform InstallOps on this partition.
+// Uses VABCPartitionWriter for Virtual AB Compression
+std::unique_ptr<PartitionWriter> CreatePartitionWriter(
+ const PartitionUpdate& partition_update,
+ const InstallPlan::Partition& install_part,
+ DynamicPartitionControlInterface* dynamic_control,
+ size_t block_size,
+ bool is_interactive,
+ bool is_dynamic_partition);
+} // namespace partition_writer
} // namespace chromeos_update_engine
#endif
diff --git a/payload_consumer/partition_writer_factory_android.cc b/payload_consumer/partition_writer_factory_android.cc
new file mode 100644
index 0000000..0c9f7ea
--- /dev/null
+++ b/payload_consumer/partition_writer_factory_android.cc
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <cstddef>
+#include <memory>
+
+#include <base/logging.h>
+
+#include "update_engine/payload_consumer/vabc_partition_writer.h"
+
+namespace chromeos_update_engine::partition_writer {
+
+std::unique_ptr<PartitionWriter> CreatePartitionWriter(
+ const PartitionUpdate& partition_update,
+ const InstallPlan::Partition& install_part,
+ DynamicPartitionControlInterface* dynamic_control,
+ size_t block_size,
+ bool is_interactive,
+ bool is_dynamic_partition) {
+ if (dynamic_control &&
+ dynamic_control->GetVirtualAbCompressionFeatureFlag().IsEnabled() &&
+ is_dynamic_partition) {
+ LOG(INFO)
+ << "Virtual AB Compression Enabled, using VABC Partition Writer for `"
+ << install_part.name << '`';
+ return std::make_unique<VABCPartitionWriter>(partition_update,
+ install_part,
+ dynamic_control,
+ block_size,
+ is_interactive);
+ } else {
+ LOG(INFO) << "Virtual AB Compression disabled, using Partition Writer for `"
+ << install_part.name << '`';
+ return std::make_unique<PartitionWriter>(partition_update,
+ install_part,
+ dynamic_control,
+ block_size,
+ is_interactive);
+ }
+}
+} // namespace chromeos_update_engine::partition_writer
diff --git a/payload_consumer/partition_writer_factory_chromeos.cc b/payload_consumer/partition_writer_factory_chromeos.cc
new file mode 100644
index 0000000..609f043
--- /dev/null
+++ b/payload_consumer/partition_writer_factory_chromeos.cc
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <cstddef>
+#include <memory>
+
+#include <base/logging.h>
+
+#include "update_engine/payload_consumer/partition_writer.h"
+
+namespace chromeos_update_engine::partition_writer {
+std::unique_ptr<PartitionWriter> CreatePartitionWriter(
+ const PartitionUpdate& partition_update,
+ const InstallPlan::Partition& install_part,
+ DynamicPartitionControlInterface* dynamic_control,
+ size_t block_size,
+ bool is_interactive,
+ bool is_dynamic_partition) {
+ return std::make_unique<PartitionWriter>(partition_update,
+ install_part,
+ dynamic_control,
+ block_size,
+ is_interactive);
+}
+} // namespace chromeos_update_engine::partition_writer
diff --git a/payload_consumer/partition_writer_unittest.cc b/payload_consumer/partition_writer_unittest.cc
index c1ff4f4..91e5e26 100644
--- a/payload_consumer/partition_writer_unittest.cc
+++ b/payload_consumer/partition_writer_unittest.cc
@@ -81,14 +81,14 @@
brillo::Blob PerformSourceCopyOp(const InstallOperation& op,
const brillo::Blob blob_data) {
- test_utils::ScopedTempFile source_partition("Blob-XXXXXX");
+ ScopedTempFile source_partition("Blob-XXXXXX");
DirectExtentWriter extent_writer;
FileDescriptorPtr fd(new EintrSafeFileDescriptor());
EXPECT_TRUE(fd->Open(source_partition.path().c_str(), O_RDWR));
EXPECT_TRUE(extent_writer.Init(fd, op.src_extents(), kBlockSize));
EXPECT_TRUE(extent_writer.Write(blob_data.data(), blob_data.size()));
- test_utils::ScopedTempFile target_partition("Blob-XXXXXX");
+ ScopedTempFile target_partition("Blob-XXXXXX");
install_part_.source_path = source_partition.path();
install_part_.target_path = target_partition.path();
@@ -96,8 +96,9 @@
install_part_.target_size = blob_data.size();
ErrorCode error;
- EXPECT_TRUE(writer_.Init(&install_plan_, true));
+ EXPECT_TRUE(writer_.Init(&install_plan_, true, 0));
EXPECT_TRUE(writer_.PerformSourceCopyOperation(op, &error));
+ writer_.CheckpointUpdateProgress(1);
brillo::Blob output_data;
EXPECT_TRUE(utils::ReadFile(target_partition.path(), &output_data));
@@ -120,7 +121,7 @@
// file descriptor when the size of the error corrected one is too small.
TEST_F(PartitionWriterTest, ErrorCorrectionSourceCopyWhenNoHashFallbackTest) {
constexpr size_t kCopyOperationSize = 4 * 4096;
- test_utils::ScopedTempFile source("Source-XXXXXX");
+ ScopedTempFile source("Source-XXXXXX");
// Setup the source path with the right expected data.
brillo::Blob expected_data = FakeFileDescriptorData(kCopyOperationSize);
EXPECT_TRUE(test_utils::WriteFileVector(source.path(), expected_data));
@@ -172,7 +173,7 @@
TEST_F(PartitionWriterTest, ChooseSourceFDTest) {
constexpr size_t kSourceSize = 4 * 4096;
- test_utils::ScopedTempFile source("Source-XXXXXX");
+ ScopedTempFile source("Source-XXXXXX");
// Write invalid data to the source image, which doesn't match the expected
// hash.
brillo::Blob invalid_data(kSourceSize, 0x55);
diff --git a/payload_consumer/payload_verifier.cc b/payload_consumer/payload_verifier.cc
index 24e337e..85902c8 100644
--- a/payload_consumer/payload_verifier.cc
+++ b/payload_consumer/payload_verifier.cc
@@ -203,7 +203,7 @@
//
// openssl rsautl -verify -pubin -inkey <(echo pem_public_key)
// -in |sig_data| -out |out_hash_data|
- RSA* rsa = EVP_PKEY_get0_RSA(public_key);
+ RSA* rsa = EVP_PKEY_get0_RSA(const_cast<EVP_PKEY*>(public_key));
TEST_AND_RETURN_FALSE(rsa != nullptr);
unsigned int keysize = RSA_size(rsa);
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index e8fa81b..d51241f 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -56,16 +56,29 @@
void PostinstallRunnerAction::PerformAction() {
CHECK(HasInputObject());
+ CHECK(boot_control_);
install_plan_ = GetInputObject();
+ auto dynamic_control = boot_control_->GetDynamicPartitionControl();
+ CHECK(dynamic_control);
+
+ // Mount snapshot partitions for Virtual AB Compression Compression.
+ if (dynamic_control->GetVirtualAbCompressionFeatureFlag().IsEnabled()) {
+ // Before calling MapAllPartitions to map snapshot devices, all CowWriters
+ // must be closed, and MapAllPartitions() should be called.
+ dynamic_control->UnmapAllPartitions();
+ if (!dynamic_control->MapAllPartitions()) {
+ return CompletePostinstall(ErrorCode::kPostInstallMountError);
+ }
+ }
+
// We always powerwash when rolling back, however policy can determine
// if this is a full/normal powerwash, or a special rollback powerwash
// that retains a small amount of system state such as enrollment and
// network configuration. In both cases all user accounts are deleted.
if (install_plan_.powerwash_required || install_plan_.is_rollback) {
- bool save_rollback_data =
- install_plan_.is_rollback && install_plan_.rollback_data_save_requested;
- if (hardware_->SchedulePowerwash(save_rollback_data)) {
+ if (hardware_->SchedulePowerwash(
+ install_plan_.rollback_data_save_requested)) {
powerwash_scheduled_ = true;
} else {
return CompletePostinstall(ErrorCode::kPostinstallPowerwashError);
diff --git a/payload_consumer/postinstall_runner_action_unittest.cc b/payload_consumer/postinstall_runner_action_unittest.cc
index cf5158b..cce86e9 100644
--- a/payload_consumer/postinstall_runner_action_unittest.cc
+++ b/payload_consumer/postinstall_runner_action_unittest.cc
@@ -26,9 +26,14 @@
#include <base/bind.h>
#include <base/files/file_util.h>
+#if BASE_VER < 780000 // Android
#include <base/message_loop/message_loop.h>
+#endif // BASE_VER < 780000
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
+#if BASE_VER >= 780000 // CrOS
+#include <base/task/single_thread_task_executor.h>
+#endif // BASE_VER >= 780000
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop_utils.h>
#include <gmock/gmock.h>
@@ -40,7 +45,7 @@
#include "update_engine/common/subprocess.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/mock_payload_state.h"
+#include "update_engine/cros/mock_payload_state.h"
using brillo::MessageLoop;
using chromeos_update_engine::test_utils::ScopedLoopbackDeviceBinder;
@@ -156,8 +161,13 @@
}
protected:
+#if BASE_VER < 780000 // Android
base::MessageLoopForIO base_loop_;
brillo::BaseMessageLoop loop_{&base_loop_};
+#else // CrOS
+ base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO};
+ brillo::BaseMessageLoop loop_{base_loop_.task_runner()};
+#endif // BASE_VER < 780000
brillo::AsynchronousSignalHandler async_signal_handler_;
Subprocess subprocess_;
diff --git a/payload_consumer/snapshot_extent_writer.cc b/payload_consumer/snapshot_extent_writer.cc
new file mode 100644
index 0000000..5693c9b
--- /dev/null
+++ b/payload_consumer/snapshot_extent_writer.cc
@@ -0,0 +1,113 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/payload_consumer/snapshot_extent_writer.h"
+
+#include <algorithm>
+#include <cstdint>
+
+#include <libsnapshot/cow_writer.h>
+
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+SnapshotExtentWriter::SnapshotExtentWriter(
+ android::snapshot::ICowWriter* cow_writer)
+ : cow_writer_(cow_writer) {
+ CHECK_NE(cow_writer, nullptr);
+}
+
+SnapshotExtentWriter::~SnapshotExtentWriter() {
+ CHECK(buffer_.empty()) << buffer_.size();
+}
+
+bool SnapshotExtentWriter::Init(
+ FileDescriptorPtr /*fd*/,
+ const google::protobuf::RepeatedPtrField<Extent>& extents,
+ uint32_t block_size) {
+ extents_ = extents;
+ cur_extent_idx_ = 0;
+ buffer_.clear();
+ buffer_.reserve(block_size);
+ block_size_ = block_size;
+ return true;
+}
+
+size_t SnapshotExtentWriter::ConsumeWithBuffer(const uint8_t* data,
+ size_t count) {
+ CHECK_LT(cur_extent_idx_, static_cast<size_t>(extents_.size()));
+ const auto& cur_extent = extents_[cur_extent_idx_];
+ const auto cur_extent_size = cur_extent.num_blocks() * block_size_;
+
+ if (buffer_.empty() && count >= cur_extent_size) {
+ TEST_AND_RETURN_FALSE(cow_writer_->AddRawBlocks(
+ cur_extent.start_block(), data, cur_extent_size));
+ if (!next_extent()) {
+ CHECK_EQ(count, cur_extent_size)
+ << "Exhausted all blocks, but still have " << count - cur_extent_size
+ << " bytes left";
+ }
+ return cur_extent_size;
+ }
+ CHECK_LT(buffer_.size(), cur_extent_size)
+ << "Data left in buffer should never be >= cur_extent_size, otherwise "
+ "we should have send that data to CowWriter. Buffer size: "
+ << buffer_.size() << " current extent size: " << cur_extent_size;
+ size_t bytes_to_copy =
+ std::min<size_t>(count, cur_extent_size - buffer_.size());
+ CHECK_GT(bytes_to_copy, 0U);
+
+ buffer_.insert(buffer_.end(), data, data + bytes_to_copy);
+ CHECK_LE(buffer_.size(), cur_extent_size);
+
+ if (buffer_.size() == cur_extent_size) {
+ TEST_AND_RETURN_FALSE(cow_writer_->AddRawBlocks(
+ cur_extent.start_block(), buffer_.data(), buffer_.size()));
+ buffer_.clear();
+ if (!next_extent()) {
+ CHECK_EQ(count, bytes_to_copy) << "Exhausted all blocks, but still have "
+ << count - bytes_to_copy << " bytes left";
+ }
+ }
+ return bytes_to_copy;
+}
+
+// Returns true on success.
+// This will construct a COW_REPLACE operation and forward it to CowWriter. It
+// is important that caller does not perform SOURCE_COPY operation on this
+// class, otherwise raw data will be stored. Caller should find ways to use
+// COW_COPY whenever possible.
+bool SnapshotExtentWriter::Write(const void* bytes, size_t count) {
+ if (count == 0) {
+ return true;
+ }
+ CHECK_NE(extents_.size(), 0);
+
+ auto data = static_cast<const uint8_t*>(bytes);
+ while (count > 0) {
+ auto bytes_written = ConsumeWithBuffer(data, count);
+ data += bytes_written;
+ count -= bytes_written;
+ }
+ return true;
+}
+
+bool SnapshotExtentWriter::next_extent() {
+ cur_extent_idx_++;
+ return cur_extent_idx_ < static_cast<size_t>(extents_.size());
+}
+} // namespace chromeos_update_engine
diff --git a/payload_consumer/snapshot_extent_writer.h b/payload_consumer/snapshot_extent_writer.h
new file mode 100644
index 0000000..fb4b548
--- /dev/null
+++ b/payload_consumer/snapshot_extent_writer.h
@@ -0,0 +1,55 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <cstdint>
+#include <vector>
+
+#include <libsnapshot/cow_writer.h>
+
+#include "update_engine/payload_consumer/extent_writer.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+class SnapshotExtentWriter : public chromeos_update_engine::ExtentWriter {
+ public:
+ explicit SnapshotExtentWriter(android::snapshot::ICowWriter* cow_writer);
+ ~SnapshotExtentWriter();
+ // Returns true on success.
+ bool Init(FileDescriptorPtr fd,
+ const google::protobuf::RepeatedPtrField<Extent>& extents,
+ uint32_t block_size) override;
+ // Returns true on success.
+ // This will construct a COW_REPLACE operation and forward it to CowWriter. It
+ // is important that caller does not perform SOURCE_COPY operation on this
+ // class, otherwise raw data will be stored. Caller should find ways to use
+ // COW_COPY whenever possible.
+ bool Write(const void* bytes, size_t count) override;
+
+ private:
+ bool next_extent();
+ size_t ConsumeWithBuffer(const uint8_t* bytes, size_t count);
+ // It's a non-owning pointer, because PartitionWriter owns the CowWruter. This
+ // allows us to use a single instance of CowWriter for all operations applied
+ // to the same partition.
+ android::snapshot::ICowWriter* cow_writer_;
+ google::protobuf::RepeatedPtrField<Extent> extents_;
+ size_t cur_extent_idx_;
+ std::vector<uint8_t> buffer_;
+ size_t block_size_;
+};
+
+} // namespace chromeos_update_engine
diff --git a/payload_consumer/snapshot_extent_writer_unittest.cc b/payload_consumer/snapshot_extent_writer_unittest.cc
new file mode 100644
index 0000000..0e22482
--- /dev/null
+++ b/payload_consumer/snapshot_extent_writer_unittest.cc
@@ -0,0 +1,180 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <array>
+#include <cstring>
+#include <map>
+#include <numeric>
+#include <vector>
+
+#include <gtest/gtest.h>
+#include <google/protobuf/message_lite.h>
+#include <libsnapshot/cow_writer.h>
+
+#include "update_engine/payload_consumer/snapshot_extent_writer.h"
+#include "update_engine/payload_generator/delta_diff_generator.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+class FakeCowWriter : public android::snapshot::ICowWriter {
+ public:
+ struct CowOp {
+ enum { COW_COPY, COW_REPLACE, COW_ZERO } type;
+ std::vector<unsigned char> data;
+ union {
+ size_t source_block;
+ size_t num_blocks;
+ };
+ };
+ using ICowWriter::ICowWriter;
+ ~FakeCowWriter() = default;
+
+ bool EmitCopy(uint64_t new_block, uint64_t old_block) override {
+ operations_[new_block] = {.type = CowOp::COW_COPY,
+ .source_block = static_cast<size_t>(old_block)};
+ return true;
+ }
+ bool EmitRawBlocks(uint64_t new_block_start,
+ const void* data,
+ size_t size) override {
+ auto&& op = operations_[new_block_start];
+ const auto uint8_ptr = static_cast<const unsigned char*>(data);
+ op.data.insert(op.data.end(), uint8_ptr, uint8_ptr + size);
+ return true;
+ }
+ bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override {
+ operations_[new_block_start] = {.type = CowOp::COW_ZERO};
+ return true;
+ }
+ bool Finalize() override {
+ finalize_called_ = true;
+ return true;
+ }
+
+ bool EmitLabel(uint64_t label) {
+ label_count_++;
+ return true;
+ }
+
+ // Return number of bytes the cow image occupies on disk.
+ uint64_t GetCowSize() override {
+ return std::accumulate(
+ operations_.begin(), operations_.end(), 0, [](auto&& acc, auto&& op) {
+ return acc + op.second.data.size();
+ });
+ }
+ bool Contains(size_t block) {
+ return operations_.find(block) != operations_.end();
+ }
+ bool finalize_called_ = true;
+ size_t label_count_ = 0;
+ std::map<size_t, CowOp> operations_;
+};
+
+class SnapshotExtentWriterTest : public ::testing::Test {
+ public:
+ void SetUp() override {}
+
+ protected:
+ android::snapshot::CowOptions options_ = {
+ .block_size = static_cast<uint32_t>(kBlockSize)};
+ FakeCowWriter cow_writer_{options_};
+ SnapshotExtentWriter writer_{&cow_writer_};
+};
+
+void AddExtent(google::protobuf::RepeatedPtrField<Extent>* extents,
+ size_t start_block,
+ size_t num_blocks) {
+ auto&& extent = extents->Add();
+ extent->set_start_block(start_block);
+ extent->set_num_blocks(num_blocks);
+}
+
+TEST_F(SnapshotExtentWriterTest, BufferWrites) {
+ google::protobuf::RepeatedPtrField<Extent> extents;
+ AddExtent(&extents, 123, 1);
+ writer_.Init(nullptr, extents, kBlockSize);
+
+ std::vector<uint8_t> buf(kBlockSize, 0);
+ buf[123] = 231;
+ buf[231] = 123;
+ buf[buf.size() - 1] = 255;
+
+ writer_.Write(buf.data(), kBlockSize - 1);
+ ASSERT_TRUE(cow_writer_.operations_.empty())
+ << "Haven't send data of a complete block yet, CowWriter should not be "
+ "invoked.";
+ writer_.Write(buf.data() + kBlockSize - 1, 1);
+ ASSERT_TRUE(cow_writer_.Contains(123))
+ << "Once a block of data is sent to SnapshotExtentWriter, it should "
+ "forward data to cow_writer.";
+ ASSERT_EQ(cow_writer_.operations_.size(), 1U);
+ ASSERT_EQ(buf, cow_writer_.operations_[123].data);
+}
+
+TEST_F(SnapshotExtentWriterTest, NonBufferedWrites) {
+ google::protobuf::RepeatedPtrField<Extent> extents;
+ AddExtent(&extents, 123, 1);
+ AddExtent(&extents, 125, 1);
+ writer_.Init(nullptr, extents, kBlockSize);
+
+ std::vector<uint8_t> buf(kBlockSize * 2, 0);
+ buf[123] = 231;
+ buf[231] = 123;
+ buf[buf.size() - 1] = 255;
+
+ writer_.Write(buf.data(), buf.size());
+ ASSERT_TRUE(cow_writer_.Contains(123));
+ ASSERT_TRUE(cow_writer_.Contains(125));
+
+ ASSERT_EQ(cow_writer_.operations_.size(), 2U);
+ auto actual_data = cow_writer_.operations_[123].data;
+ actual_data.insert(actual_data.end(),
+ cow_writer_.operations_[125].data.begin(),
+ cow_writer_.operations_[125].data.end());
+ ASSERT_EQ(buf, actual_data);
+}
+
+TEST_F(SnapshotExtentWriterTest, WriteAcrossBlockBoundary) {
+ google::protobuf::RepeatedPtrField<Extent> extents;
+ AddExtent(&extents, 123, 1);
+ AddExtent(&extents, 125, 2);
+ writer_.Init(nullptr, extents, kBlockSize);
+
+ std::vector<uint8_t> buf(kBlockSize * 3);
+ std::memset(buf.data(), 0, buf.size());
+ buf[123] = 231;
+ buf[231] = 123;
+ buf[buf.size() - 1] = 255;
+ buf[kBlockSize - 1] = 254;
+
+ writer_.Write(buf.data(), kBlockSize - 1);
+ ASSERT_TRUE(cow_writer_.operations_.empty())
+ << "Haven't send data of a complete block yet, CowWriter should not be "
+ "invoked.";
+ writer_.Write(buf.data() + kBlockSize - 1, 1 + kBlockSize * 2);
+ ASSERT_TRUE(cow_writer_.Contains(123));
+ ASSERT_TRUE(cow_writer_.Contains(125));
+
+ ASSERT_EQ(cow_writer_.operations_.size(), 2U);
+ auto actual_data = cow_writer_.operations_[123].data;
+ actual_data.insert(actual_data.end(),
+ cow_writer_.operations_[125].data.begin(),
+ cow_writer_.operations_[125].data.end());
+ ASSERT_EQ(buf, actual_data);
+}
+} // namespace chromeos_update_engine
diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc
new file mode 100644
index 0000000..5cb7989
--- /dev/null
+++ b/payload_consumer/vabc_partition_writer.cc
@@ -0,0 +1,166 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/payload_consumer/vabc_partition_writer.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <libsnapshot/cow_writer.h>
+
+#include "update_engine/common/cow_operation_convert.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/extent_writer.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/payload_consumer/partition_writer.h"
+#include "update_engine/payload_consumer/snapshot_extent_writer.h"
+
+namespace chromeos_update_engine {
+// Expected layout of COW file:
+// === Beginning of Cow Image ===
+// All Source Copy Operations
+// ========== Label 0 ==========
+// Operation 0 in PartitionUpdate
+// ========== Label 1 ==========
+// Operation 1 in PartitionUpdate
+// ========== label 2 ==========
+// Operation 2 in PartitionUpdate
+// ========== label 3 ==========
+// .
+// .
+// .
+
+// When resuming, pass |next_op_index_| as label to
+// |InitializeWithAppend|.
+// For example, suppose we finished writing SOURCE_COPY, and we finished writing
+// operation 2 completely. Update is suspended when we are half way through
+// operation 3.
+// |cnext_op_index_| would be 3, so we pass 3 as
+// label to |InitializeWithAppend|. The CowWriter will retain all data before
+// label 3, Which contains all operation 2's data, but none of operation 3's
+// data.
+
+bool VABCPartitionWriter::Init(const InstallPlan* install_plan,
+ bool source_may_exist,
+ size_t next_op_index) {
+ TEST_AND_RETURN_FALSE(install_plan != nullptr);
+ TEST_AND_RETURN_FALSE(
+ OpenSourcePartition(install_plan->source_slot, source_may_exist));
+ std::optional<std::string> source_path;
+ if (!install_part_.source_path.empty()) {
+ // TODO(zhangkelvin) Make |source_path| a std::optional<std::string>
+ source_path = install_part_.source_path;
+ }
+ cow_writer_ = dynamic_control_->OpenCowWriter(
+ install_part_.name, source_path, install_plan->is_resume);
+ TEST_AND_RETURN_FALSE(cow_writer_ != nullptr);
+
+ // ===== Resume case handling code goes here ====
+ // It is possible that the SOURCE_COPY are already written but
+ // |next_op_index_| is still 0. In this case we discard previously written
+ // SOURCE_COPY, and start over.
+ if (install_plan->is_resume && next_op_index > 0) {
+ LOG(INFO) << "Resuming update on partition `"
+ << partition_update_.partition_name() << "` op index "
+ << next_op_index;
+ TEST_AND_RETURN_FALSE(cow_writer_->InitializeAppend(next_op_index));
+ return true;
+ } else {
+ TEST_AND_RETURN_FALSE(cow_writer_->Initialize());
+ }
+
+ // ==============================================
+
+ // TODO(zhangkelvin) Rewrite this in C++20 coroutine once that's available.
+ auto converted = ConvertToCowOperations(partition_update_.operations(),
+ partition_update_.merge_operations());
+
+ WriteAllCowOps(block_size_, converted, cow_writer_.get(), source_fd_);
+ return true;
+}
+
+bool VABCPartitionWriter::WriteAllCowOps(
+ size_t block_size,
+ const std::vector<CowOperation>& converted,
+ android::snapshot::ICowWriter* cow_writer,
+ FileDescriptorPtr source_fd) {
+ std::vector<uint8_t> buffer(block_size);
+
+ for (const auto& cow_op : converted) {
+ switch (cow_op.op) {
+ case CowOperation::CowCopy:
+ TEST_AND_RETURN_FALSE(
+ cow_writer->AddCopy(cow_op.dst_block, cow_op.src_block));
+ break;
+ case CowOperation::CowReplace:
+ ssize_t bytes_read = 0;
+ TEST_AND_RETURN_FALSE(utils::ReadAll(source_fd,
+ buffer.data(),
+ block_size,
+ cow_op.src_block * block_size,
+ &bytes_read));
+ if (bytes_read <= 0 || static_cast<size_t>(bytes_read) != block_size) {
+ LOG(ERROR) << "source_fd->Read failed: " << bytes_read;
+ return false;
+ }
+ TEST_AND_RETURN_FALSE(cow_writer->AddRawBlocks(
+ cow_op.dst_block, buffer.data(), block_size));
+ break;
+ }
+ }
+
+ return true;
+}
+
+std::unique_ptr<ExtentWriter> VABCPartitionWriter::CreateBaseExtentWriter() {
+ return std::make_unique<SnapshotExtentWriter>(cow_writer_.get());
+}
+
+[[nodiscard]] bool VABCPartitionWriter::PerformZeroOrDiscardOperation(
+ const InstallOperation& operation) {
+ for (const auto& extent : operation.dst_extents()) {
+ TEST_AND_RETURN_FALSE(
+ cow_writer_->AddZeroBlocks(extent.start_block(), extent.num_blocks()));
+ }
+ return true;
+}
+
+[[nodiscard]] bool VABCPartitionWriter::PerformSourceCopyOperation(
+ const InstallOperation& operation, ErrorCode* error) {
+ // TODO(zhangkelvin) Probably just ignore SOURCE_COPY? They should be taken
+ // care of during Init();
+ return true;
+}
+
+void VABCPartitionWriter::CheckpointUpdateProgress(size_t next_op_index) {
+ // No need to call fsync/sync, as CowWriter flushes after a label is added
+ // added.
+ cow_writer_->AddLabel(next_op_index);
+}
+
+[[nodiscard]] bool VABCPartitionWriter::FinishedInstallOps() {
+ // Add a hardcoded magic label to indicate end of all install ops. This label
+ // is needed by filesystem verification, don't remove.
+ return cow_writer_->AddLabel(kEndOfInstallLabel);
+}
+
+VABCPartitionWriter::~VABCPartitionWriter() {
+ cow_writer_->Finalize();
+}
+
+} // namespace chromeos_update_engine
diff --git a/payload_consumer/vabc_partition_writer.h b/payload_consumer/vabc_partition_writer.h
new file mode 100644
index 0000000..7fb2a2c
--- /dev/null
+++ b/payload_consumer/vabc_partition_writer.h
@@ -0,0 +1,63 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_VABC_PARTITION_WRITER_H_
+#define UPDATE_ENGINE_VABC_PARTITION_WRITER_H_
+
+#include <memory>
+#include <vector>
+
+#include <libsnapshot/snapshot_writer.h>
+
+#include "update_engine/common/cow_operation_convert.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/payload_consumer/partition_writer.h"
+
+namespace chromeos_update_engine {
+class VABCPartitionWriter final : public PartitionWriter {
+ public:
+ using PartitionWriter::PartitionWriter;
+ [[nodiscard]] bool Init(const InstallPlan* install_plan,
+ bool source_may_exist,
+ size_t next_op_index) override;
+ ~VABCPartitionWriter() override;
+
+ [[nodiscard]] std::unique_ptr<ExtentWriter> CreateBaseExtentWriter() override;
+
+ // Only ZERO and SOURCE_COPY InstallOperations are treated special by VABC
+ // Partition Writer. These operations correspond to COW_ZERO and COW_COPY. All
+ // other operations just get converted to COW_REPLACE.
+ [[nodiscard]] bool PerformZeroOrDiscardOperation(
+ const InstallOperation& operation) override;
+ [[nodiscard]] bool PerformSourceCopyOperation(
+ const InstallOperation& operation, ErrorCode* error) override;
+
+ void CheckpointUpdateProgress(size_t next_op_index) override;
+
+ static bool WriteAllCowOps(size_t block_size,
+ const std::vector<CowOperation>& converted,
+ android::snapshot::ICowWriter* cow_writer,
+ FileDescriptorPtr source_fd);
+
+ [[nodiscard]] bool FinishedInstallOps() override;
+
+ private:
+ std::unique_ptr<android::snapshot::ISnapshotWriter> cow_writer_;
+};
+
+} // namespace chromeos_update_engine
+
+#endif
diff --git a/payload_consumer/verity_writer_android.cc b/payload_consumer/verity_writer_android.cc
index d5437b6..864d9a1 100644
--- a/payload_consumer/verity_writer_android.cc
+++ b/payload_consumer/verity_writer_android.cc
@@ -29,6 +29,7 @@
}
#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
namespace chromeos_update_engine {
@@ -39,7 +40,16 @@
} // namespace verity_writer
bool VerityWriterAndroid::Init(const InstallPlan::Partition& partition) {
+ auto read_fd = FileDescriptorPtr(new EintrSafeFileDescriptor());
+ TEST_AND_RETURN_FALSE(read_fd->Open(partition.target_path.c_str(), O_RDWR));
+ return Init(partition, read_fd, read_fd);
+}
+bool VerityWriterAndroid::Init(const InstallPlan::Partition& partition,
+ FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd) {
partition_ = &partition;
+ read_fd_ = read_fd;
+ write_fd_ = write_fd;
if (partition_->hash_tree_size != 0 || partition_->fec_size != 0) {
utils::SetBlockDeviceReadOnly(partition_->target_path, false);
@@ -82,18 +92,18 @@
if (end_offset == hash_tree_data_end) {
// All hash tree data blocks has been hashed, write hash tree to disk.
- int fd = HANDLE_EINTR(open(partition_->target_path.c_str(), O_WRONLY));
- if (fd < 0) {
- PLOG(ERROR) << "Failed to open " << partition_->target_path
- << " to write hash tree.";
- return false;
- }
- ScopedFdCloser fd_closer(&fd);
-
LOG(INFO) << "Writing verity hash tree to " << partition_->target_path;
TEST_AND_RETURN_FALSE(hash_tree_builder_->BuildHashTree());
- TEST_AND_RETURN_FALSE(hash_tree_builder_->WriteHashTreeToFd(
- fd, partition_->hash_tree_offset));
+ TEST_AND_RETURN_FALSE_ERRNO(
+ write_fd_->Seek(partition_->hash_tree_offset, SEEK_SET));
+ auto success = hash_tree_builder_->WriteHashTree(
+ [write_fd_(this->write_fd_)](auto data, auto size) {
+ return utils::WriteAll(write_fd_, data, size);
+ });
+ // hashtree builder already prints error messages.
+ if (!success) {
+ return false;
+ }
hash_tree_builder_.reset();
}
}
@@ -103,7 +113,8 @@
partition_->fec_data_offset + partition_->fec_data_size;
if (offset < fec_data_end && offset + size >= fec_data_end) {
LOG(INFO) << "Writing verity FEC to " << partition_->target_path;
- TEST_AND_RETURN_FALSE(EncodeFEC(partition_->target_path,
+ TEST_AND_RETURN_FALSE(EncodeFEC(read_fd_,
+ write_fd_,
partition_->fec_data_offset,
partition_->fec_data_size,
partition_->fec_offset,
@@ -116,7 +127,8 @@
return true;
}
-bool VerityWriterAndroid::EncodeFEC(const std::string& path,
+bool VerityWriterAndroid::EncodeFEC(FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd,
uint64_t data_offset,
uint64_t data_size,
uint64_t fec_offset,
@@ -135,13 +147,6 @@
init_rs_char(FEC_PARAMS(fec_roots)), &free_rs_char);
TEST_AND_RETURN_FALSE(rs_char != nullptr);
- int fd = HANDLE_EINTR(open(path.c_str(), verify_mode ? O_RDONLY : O_RDWR));
- if (fd < 0) {
- PLOG(ERROR) << "Failed to open " << path << " to write FEC.";
- return false;
- }
- ScopedFdCloser fd_closer(&fd);
-
for (size_t i = 0; i < rounds; i++) {
// Encodes |block_size| number of rs blocks each round so that we can read
// one block each time instead of 1 byte to increase random read
@@ -154,13 +159,13 @@
// Don't read past |data_size|, treat them as 0.
if (offset < data_size) {
ssize_t bytes_read = 0;
- TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
+ TEST_AND_RETURN_FALSE(utils::PReadAll(read_fd,
buffer.data(),
buffer.size(),
data_offset + offset,
&bytes_read));
- TEST_AND_RETURN_FALSE(bytes_read ==
- static_cast<ssize_t>(buffer.size()));
+ TEST_AND_RETURN_FALSE(bytes_read >= 0);
+ TEST_AND_RETURN_FALSE(static_cast<size_t>(bytes_read) == buffer.size());
}
for (size_t k = 0; k < buffer.size(); k++) {
rs_blocks[k * rs_n + j] = buffer[k];
@@ -179,17 +184,42 @@
brillo::Blob fec_read(fec.size());
ssize_t bytes_read = 0;
TEST_AND_RETURN_FALSE(utils::PReadAll(
- fd, fec_read.data(), fec_read.size(), fec_offset, &bytes_read));
- TEST_AND_RETURN_FALSE(bytes_read ==
- static_cast<ssize_t>(fec_read.size()));
+ read_fd, fec_read.data(), fec_read.size(), fec_offset, &bytes_read));
+ TEST_AND_RETURN_FALSE(bytes_read >= 0);
+ TEST_AND_RETURN_FALSE(static_cast<size_t>(bytes_read) == fec_read.size());
TEST_AND_RETURN_FALSE(fec == fec_read);
} else {
- TEST_AND_RETURN_FALSE(
- utils::PWriteAll(fd, fec.data(), fec.size(), fec_offset));
+ CHECK(write_fd);
+ if (!utils::PWriteAll(write_fd, fec.data(), fec.size(), fec_offset)) {
+ PLOG(ERROR) << "EncodeFEC write() failed";
+ return false;
+ }
}
fec_offset += fec.size();
}
return true;
}
+
+bool VerityWriterAndroid::EncodeFEC(const std::string& path,
+ uint64_t data_offset,
+ uint64_t data_size,
+ uint64_t fec_offset,
+ uint64_t fec_size,
+ uint32_t fec_roots,
+ uint32_t block_size,
+ bool verify_mode) {
+ FileDescriptorPtr fd(new EintrSafeFileDescriptor());
+ TEST_AND_RETURN_FALSE(
+ fd->Open(path.c_str(), verify_mode ? O_RDONLY : O_RDWR));
+ return EncodeFEC(fd,
+ fd,
+ data_offset,
+ data_size,
+ fec_offset,
+ fec_size,
+ fec_roots,
+ block_size,
+ verify_mode);
+}
} // namespace chromeos_update_engine
diff --git a/payload_consumer/verity_writer_android.h b/payload_consumer/verity_writer_android.h
index 05a5856..7dfac0f 100644
--- a/payload_consumer/verity_writer_android.h
+++ b/payload_consumer/verity_writer_android.h
@@ -22,6 +22,7 @@
#include <verity/hash_tree_builder.h>
+#include "payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/verity_writer_interface.h"
namespace chromeos_update_engine {
@@ -31,7 +32,10 @@
VerityWriterAndroid() = default;
~VerityWriterAndroid() override = default;
- bool Init(const InstallPlan::Partition& partition) override;
+ bool Init(const InstallPlan::Partition& partition,
+ FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd) override;
+ bool Init(const InstallPlan::Partition& partition);
bool Update(uint64_t offset, const uint8_t* buffer, size_t size) override;
// Read [data_offset : data_offset + data_size) from |path| and encode FEC
@@ -40,6 +44,15 @@
// in each Update() like hash tree, because for every rs block, its data are
// spreaded across entire |data_size|, unless we can cache all data in
// memory, we have to re-read them from disk.
+ static bool EncodeFEC(FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd,
+ uint64_t data_offset,
+ uint64_t data_size,
+ uint64_t fec_offset,
+ uint64_t fec_size,
+ uint32_t fec_roots,
+ uint32_t block_size,
+ bool verify_mode);
static bool EncodeFEC(const std::string& path,
uint64_t data_offset,
uint64_t data_size,
@@ -52,6 +65,8 @@
private:
const InstallPlan::Partition* partition_ = nullptr;
+ FileDescriptorPtr read_fd_;
+ FileDescriptorPtr write_fd_;
std::unique_ptr<HashTreeBuilder> hash_tree_builder_;
DISALLOW_COPY_AND_ASSIGN(VerityWriterAndroid);
diff --git a/payload_consumer/verity_writer_android_unittest.cc b/payload_consumer/verity_writer_android_unittest.cc
index f943ce8..ec22ffb 100644
--- a/payload_consumer/verity_writer_android_unittest.cc
+++ b/payload_consumer/verity_writer_android_unittest.cc
@@ -39,7 +39,7 @@
VerityWriterAndroid verity_writer_;
InstallPlan::Partition partition_;
- test_utils::ScopedTempFile temp_file_;
+ ScopedTempFile temp_file_;
};
TEST_F(VerityWriterAndroidTest, SimpleTest) {
diff --git a/payload_consumer/verity_writer_interface.h b/payload_consumer/verity_writer_interface.h
index a3ecef3..db7988e 100644
--- a/payload_consumer/verity_writer_interface.h
+++ b/payload_consumer/verity_writer_interface.h
@@ -22,6 +22,7 @@
#include <base/macros.h>
+#include "payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/install_plan.h"
namespace chromeos_update_engine {
@@ -30,6 +31,9 @@
public:
virtual ~VerityWriterInterface() = default;
+ virtual bool Init(const InstallPlan::Partition& partition,
+ FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd) = 0;
virtual bool Init(const InstallPlan::Partition& partition) = 0;
// Update partition data at [offset : offset + size) stored in |buffer|.
// Data not in |hash_tree_data_extent| or |fec_data_extent| is ignored.
diff --git a/payload_consumer/verity_writer_stub.cc b/payload_consumer/verity_writer_stub.cc
index a0e2467..314ec7e 100644
--- a/payload_consumer/verity_writer_stub.cc
+++ b/payload_consumer/verity_writer_stub.cc
@@ -26,7 +26,9 @@
}
} // namespace verity_writer
-bool VerityWriterStub::Init(const InstallPlan::Partition& partition) {
+bool VerityWriterStub::Init(const InstallPlan::Partition& partition,
+ FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd) {
return partition.hash_tree_size == 0 && partition.fec_size == 0;
}
diff --git a/payload_consumer/verity_writer_stub.h b/payload_consumer/verity_writer_stub.h
index ea5e574..f8d68ca 100644
--- a/payload_consumer/verity_writer_stub.h
+++ b/payload_consumer/verity_writer_stub.h
@@ -26,7 +26,9 @@
VerityWriterStub() = default;
~VerityWriterStub() override = default;
- bool Init(const InstallPlan::Partition& partition) override;
+ bool Init(const InstallPlan::Partition& partition,
+ FileDescriptorPtr read_fd,
+ FileDescriptorPtr write_fd) override;
bool Update(uint64_t offset, const uint8_t* buffer, size_t size) override;
private:
diff --git a/payload_generator/ab_generator_unittest.cc b/payload_generator/ab_generator_unittest.cc
index 7a95284..84eeb77 100644
--- a/payload_generator/ab_generator_unittest.cc
+++ b/payload_generator/ab_generator_unittest.cc
@@ -70,8 +70,7 @@
part_data.push_back(dis(gen));
}
ASSERT_EQ(part_size, part_data.size());
- test_utils::ScopedTempFile part_file(
- "SplitReplaceOrReplaceXzTest_part.XXXXXX");
+ ScopedTempFile part_file("SplitReplaceOrReplaceXzTest_part.XXXXXX");
ASSERT_TRUE(test_utils::WriteFileVector(part_file.path(), part_data));
// Create original operation and blob data.
@@ -107,8 +106,7 @@
aop.name = "SplitTestOp";
// Create the data file.
- test_utils::ScopedTempFile data_file(
- "SplitReplaceOrReplaceXzTest_data.XXXXXX");
+ ScopedTempFile data_file("SplitReplaceOrReplaceXzTest_data.XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(data_file.path(), op_blob));
int data_fd = open(data_file.path().c_str(), O_RDWR, 000);
EXPECT_GE(data_fd, 0);
@@ -220,8 +218,7 @@
part_data.push_back(dis(gen));
}
ASSERT_EQ(part_size, part_data.size());
- test_utils::ScopedTempFile part_file(
- "MergeReplaceOrReplaceXzTest_part.XXXXXX");
+ ScopedTempFile part_file("MergeReplaceOrReplaceXzTest_part.XXXXXX");
ASSERT_TRUE(test_utils::WriteFileVector(part_file.path(), part_data));
// Create original operations and blob data.
@@ -271,8 +268,7 @@
aops.push_back(second_aop);
// Create the data file.
- test_utils::ScopedTempFile data_file(
- "MergeReplaceOrReplaceXzTest_data.XXXXXX");
+ ScopedTempFile data_file("MergeReplaceOrReplaceXzTest_data.XXXXXX");
EXPECT_TRUE(test_utils::WriteFileVector(data_file.path(), blob_data));
int data_fd = open(data_file.path().c_str(), O_RDWR, 000);
EXPECT_GE(data_fd, 0);
@@ -561,7 +557,7 @@
second_aop.op = second_op;
aops.push_back(second_aop);
- test_utils::ScopedTempFile src_part_file("AddSourceHashTest_src_part.XXXXXX");
+ ScopedTempFile src_part_file("AddSourceHashTest_src_part.XXXXXX");
brillo::Blob src_data(kBlockSize);
test_utils::FillWithData(&src_data);
ASSERT_TRUE(test_utils::WriteFileVector(src_part_file.path(), src_data));
diff --git a/payload_generator/blob_file_writer_unittest.cc b/payload_generator/blob_file_writer_unittest.cc
index 487bc73..f4dcafb 100644
--- a/payload_generator/blob_file_writer_unittest.cc
+++ b/payload_generator/blob_file_writer_unittest.cc
@@ -31,24 +31,21 @@
class BlobFileWriterTest : public ::testing::Test {};
TEST(BlobFileWriterTest, SimpleTest) {
- string blob_path;
- int blob_fd;
- EXPECT_TRUE(
- utils::MakeTempFile("BlobFileWriterTest.XXXXXX", &blob_path, &blob_fd));
+ ScopedTempFile blob_file("BlobFileWriterTest.XXXXXX", true);
off_t blob_file_size = 0;
- BlobFileWriter blob_file(blob_fd, &blob_file_size);
+ BlobFileWriter blob_file_writer(blob_file.fd(), &blob_file_size);
- off_t blob_size = 1024;
- brillo::Blob blob(blob_size);
+ const off_t kBlobSize = 1024;
+ brillo::Blob blob(kBlobSize);
FillWithData(&blob);
- EXPECT_EQ(0, blob_file.StoreBlob(blob));
- EXPECT_EQ(blob_size, blob_file.StoreBlob(blob));
+ EXPECT_EQ(0, blob_file_writer.StoreBlob(blob));
+ EXPECT_EQ(kBlobSize, blob_file_writer.StoreBlob(blob));
- brillo::Blob stored_blob(blob_size);
+ brillo::Blob stored_blob(kBlobSize);
ssize_t bytes_read;
- ASSERT_TRUE(
- utils::PReadAll(blob_fd, stored_blob.data(), blob_size, 0, &bytes_read));
- EXPECT_EQ(bytes_read, blob_size);
+ ASSERT_TRUE(utils::PReadAll(
+ blob_file.fd(), stored_blob.data(), kBlobSize, 0, &bytes_read));
+ EXPECT_EQ(bytes_read, kBlobSize);
EXPECT_EQ(blob, stored_blob);
}
diff --git a/payload_generator/block_mapping_unittest.cc b/payload_generator/block_mapping_unittest.cc
index 9b9b4f1..017548a 100644
--- a/payload_generator/block_mapping_unittest.cc
+++ b/payload_generator/block_mapping_unittest.cc
@@ -36,8 +36,8 @@
class BlockMappingTest : public ::testing::Test {
protected:
// Old new partition files used in testing.
- test_utils::ScopedTempFile old_part_{"BlockMappingTest_old.XXXXXX"};
- test_utils::ScopedTempFile new_part_{"BlockMappingTest_new.XXXXXX"};
+ ScopedTempFile old_part_{"BlockMappingTest_old.XXXXXX"};
+ ScopedTempFile new_part_{"BlockMappingTest_new.XXXXXX"};
size_t block_size_{1024};
BlockMapping bm_{block_size_}; // BlockMapping under test.
diff --git a/payload_generator/boot_img_filesystem_unittest.cc b/payload_generator/boot_img_filesystem_unittest.cc
index 0b115e0..7805156 100644
--- a/payload_generator/boot_img_filesystem_unittest.cc
+++ b/payload_generator/boot_img_filesystem_unittest.cc
@@ -63,7 +63,7 @@
return boot_img;
}
- test_utils::ScopedTempFile boot_file_;
+ ScopedTempFile boot_file_;
};
TEST_F(BootImgFilesystemTest, SimpleTest) {
diff --git a/payload_generator/cow_size_estimator.cc b/payload_generator/cow_size_estimator.cc
new file mode 100644
index 0000000..3eb0aca
--- /dev/null
+++ b/payload_generator/cow_size_estimator.cc
@@ -0,0 +1,110 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/payload_generator/cow_size_estimator.h"
+
+#include <utility>
+#include <vector>
+
+#include <libsnapshot/cow_writer.h>
+
+#include "android-base/unique_fd.h"
+#include "update_engine/common/cow_operation_convert.h"
+#include "update_engine/payload_consumer/vabc_partition_writer.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+using android::snapshot::CowWriter;
+
+void PerformReplaceOp(const InstallOperation& op,
+ CowWriter* writer,
+ FileDescriptorPtr target_fd,
+ size_t block_size) {
+ std::vector<unsigned char> buffer;
+ for (const auto& extent : op.dst_extents()) {
+ buffer.resize(extent.num_blocks() * block_size);
+ // No need to read from payload.bin then decompress, just read from target
+ // directly.
+ ssize_t bytes_read = 0;
+ auto success = utils::ReadAll(target_fd,
+ buffer.data(),
+ buffer.size(),
+ extent.start_block() * block_size,
+ &bytes_read);
+ CHECK(success);
+ CHECK_EQ(static_cast<size_t>(bytes_read), buffer.size());
+ writer->AddRawBlocks(extent.start_block(), buffer.data(), buffer.size());
+ }
+}
+
+void PerformZeroOp(const InstallOperation& op,
+ CowWriter* writer,
+ size_t block_size) {
+ for (const auto& extent : op.dst_extents()) {
+ writer->AddZeroBlocks(extent.start_block(), extent.num_blocks());
+ }
+}
+
+size_t EstimateCowSize(
+ FileDescriptorPtr source_fd,
+ FileDescriptorPtr target_fd,
+ const google::protobuf::RepeatedPtrField<InstallOperation>& operations,
+ const google::protobuf::RepeatedPtrField<CowMergeOperation>&
+ merge_operations,
+ size_t block_size) {
+ android::snapshot::CowWriter cow_writer{
+ {.block_size = static_cast<uint32_t>(block_size), .compression = "gz"}};
+ // CowWriter treats -1 as special value, will discard all the data but still
+ // reports Cow size. Good for estimation purposes
+ cow_writer.Initialize(android::base::borrowed_fd{-1});
+
+ const auto converted = ConvertToCowOperations(operations, merge_operations);
+ VABCPartitionWriter::WriteAllCowOps(
+ block_size, converted, &cow_writer, source_fd);
+ cow_writer.AddLabel(0);
+ for (const auto& op : operations) {
+ switch (op.type()) {
+ case InstallOperation::REPLACE:
+ case InstallOperation::REPLACE_BZ:
+ case InstallOperation::REPLACE_XZ:
+ PerformReplaceOp(op, &cow_writer, target_fd, block_size);
+ break;
+ case InstallOperation::ZERO:
+ case InstallOperation::DISCARD:
+ PerformZeroOp(op, &cow_writer, block_size);
+ break;
+ case InstallOperation::SOURCE_COPY:
+ case InstallOperation::MOVE:
+ // Already handeled by WriteAllCowOps,
+ break;
+ case InstallOperation::SOURCE_BSDIFF:
+ case InstallOperation::BROTLI_BSDIFF:
+ case InstallOperation::PUFFDIFF:
+ case InstallOperation::BSDIFF:
+ // We might do something special by adding CowBsdiff to CowWriter.
+ // For now proceed the same way as normal REPLACE operation.
+ PerformReplaceOp(op, &cow_writer, target_fd, block_size);
+ break;
+ }
+ // Arbitrary label number, we won't be resuming use these labels here.
+ // They are emitted just to keep size estimates accurate. As update_engine
+ // emits 1 label for every op.
+ cow_writer.AddLabel(2);
+ }
+ // TODO(zhangkelvin) Take FEC extents into account once VABC stabilizes
+ return cow_writer.GetCowSize();
+}
+} // namespace chromeos_update_engine
diff --git a/payload_generator/cow_size_estimator.h b/payload_generator/cow_size_estimator.h
new file mode 100644
index 0000000..cba89b5
--- /dev/null
+++ b/payload_generator/cow_size_estimator.h
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include <cstddef>
+
+#include <update_engine/update_metadata.pb.h>
+
+#include "update_engine/payload_consumer/file_descriptor.h"
+
+namespace chromeos_update_engine {
+// Given file descriptor to the source image, target image, and list of
+// operations, estimate the size of COW image if the operations are applied on
+// Virtual AB Compression enabled device. This is intended to be used by update
+// generators to put an estimate cow size in OTA payload. When installing an OTA
+// update, libsnapshot will take this estimate as a hint to allocate spaces.
+size_t EstimateCowSize(
+ FileDescriptorPtr source_fd,
+ FileDescriptorPtr target_fd,
+ const google::protobuf::RepeatedPtrField<InstallOperation>& operations,
+ const google::protobuf::RepeatedPtrField<CowMergeOperation>&
+ merge_operations,
+ size_t block_size);
+
+} // namespace chromeos_update_engine
diff --git a/metrics_reporter_stub.cc b/payload_generator/cow_size_estimator_stub.cc
similarity index 60%
copy from metrics_reporter_stub.cc
copy to payload_generator/cow_size_estimator_stub.cc
index 81664a5..9d94d63 100644
--- a/metrics_reporter_stub.cc
+++ b/payload_generator/cow_size_estimator_stub.cc
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2017 The Android Open Source Project
+// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,18 +14,18 @@
// limitations under the License.
//
-#include "update_engine/metrics_reporter_stub.h"
-
-#include <memory>
+#include "update_engine/payload_generator/cow_size_estimator.h"
namespace chromeos_update_engine {
-namespace metrics {
-
-std::unique_ptr<MetricsReporterInterface> CreateMetricsReporter() {
- return std::make_unique<MetricsReporterStub>();
+size_t EstimateCowSize(
+ FileDescriptorPtr source_fd,
+ FileDescriptorPtr target_fd,
+ const google::protobuf::RepeatedPtrField<InstallOperation>& operations,
+ const google::protobuf::RepeatedPtrField<CowMergeOperation>&
+ merge_operations,
+ size_t block_size) {
+ return 0;
}
-} // namespace metrics
-
} // namespace chromeos_update_engine
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index c2b35ee..74d43fd 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -33,14 +33,17 @@
#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/delta_performer.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/ab_generator.h"
#include "update_engine/payload_generator/annotated_operation.h"
#include "update_engine/payload_generator/blob_file_writer.h"
+#include "update_engine/payload_generator/cow_size_estimator.h"
#include "update_engine/payload_generator/delta_diff_utils.h"
#include "update_engine/payload_generator/full_update_generator.h"
#include "update_engine/payload_generator/merge_sequence_generator.h"
#include "update_engine/payload_generator/payload_file.h"
+#include "update_engine/update_metadata.pb.h"
using std::string;
using std::unique_ptr;
@@ -53,6 +56,18 @@
const size_t kBlockSize = 4096; // bytes
class PartitionProcessor : public base::DelegateSimpleThread::Delegate {
+ bool IsDynamicPartition(const std::string& partition_name) {
+ for (const auto& group :
+ config_.target.dynamic_partition_metadata->groups()) {
+ const auto& names = group.partition_names();
+ if (std::find(names.begin(), names.end(), partition_name) !=
+ names.end()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public:
explicit PartitionProcessor(
const PayloadGenerationConfig& config,
@@ -61,6 +76,7 @@
BlobFileWriter* file_writer,
std::vector<AnnotatedOperation>* aops,
std::vector<CowMergeOperation>* cow_merge_sequence,
+ size_t* cow_size,
std::unique_ptr<chromeos_update_engine::OperationsGenerator> strategy)
: config_(config),
old_part_(old_part),
@@ -68,11 +84,13 @@
file_writer_(file_writer),
aops_(aops),
cow_merge_sequence_(cow_merge_sequence),
+ cow_size_(cow_size),
strategy_(std::move(strategy)) {}
PartitionProcessor(PartitionProcessor&&) noexcept = default;
+
void Run() override {
LOG(INFO) << "Started an async task to process partition "
- << old_part_.name;
+ << new_part_.name;
bool success = strategy_->GenerateOperations(
config_, old_part_, new_part_, file_writer_, aops_);
if (!success) {
@@ -85,13 +103,38 @@
bool snapshot_enabled =
config_.target.dynamic_partition_metadata &&
config_.target.dynamic_partition_metadata->snapshot_enabled();
- if (old_part_.path.empty() || !snapshot_enabled) {
+ if (!snapshot_enabled || !IsDynamicPartition(new_part_.name)) {
return;
}
- auto generator = MergeSequenceGenerator::Create(*aops_);
- if (!generator || !generator->Generate(cow_merge_sequence_)) {
- LOG(FATAL) << "Failed to generate merge sequence";
+ if (!old_part_.path.empty()) {
+ auto generator = MergeSequenceGenerator::Create(*aops_);
+ if (!generator || !generator->Generate(cow_merge_sequence_)) {
+ LOG(FATAL) << "Failed to generate merge sequence";
+ }
}
+
+ LOG(INFO) << "Estimating COW size for partition: " << new_part_.name;
+ // Need the contents of source/target image bytes when doing
+ // dry run.
+ FileDescriptorPtr source_fd{new EintrSafeFileDescriptor()};
+ source_fd->Open(old_part_.path.c_str(), O_RDONLY);
+
+ auto target_fd = std::make_unique<EintrSafeFileDescriptor>();
+ target_fd->Open(new_part_.path.c_str(), O_RDONLY);
+
+ google::protobuf::RepeatedPtrField<InstallOperation> operations;
+
+ for (const AnnotatedOperation& aop : *aops_) {
+ *operations.Add() = aop.op;
+ }
+ *cow_size_ = EstimateCowSize(
+ source_fd,
+ std::move(target_fd),
+ operations,
+ {cow_merge_sequence_->begin(), cow_merge_sequence_->end()},
+ config_.block_size);
+ LOG(INFO) << "Estimated COW size for partition: " << new_part_.name << " "
+ << *cow_size_;
}
private:
@@ -101,6 +144,7 @@
BlobFileWriter* file_writer_;
std::vector<AnnotatedOperation>* aops_;
std::vector<CowMergeOperation>* cow_merge_sequence_;
+ size_t* cow_size_;
std::unique_ptr<chromeos_update_engine::OperationsGenerator> strategy_;
DISALLOW_COPY_AND_ASSIGN(PartitionProcessor);
};
@@ -119,18 +163,10 @@
PayloadFile payload;
TEST_AND_RETURN_FALSE(payload.Init(config));
- const string kTempFileTemplate("CrAU_temp_data.XXXXXX");
- string temp_file_path;
- int data_file_fd;
- TEST_AND_RETURN_FALSE(
- utils::MakeTempFile(kTempFileTemplate, &temp_file_path, &data_file_fd));
- ScopedPathUnlinker temp_file_unlinker(temp_file_path);
- TEST_AND_RETURN_FALSE(data_file_fd >= 0);
-
+ ScopedTempFile data_file("CrAU_temp_data.XXXXXX", true);
{
off_t data_file_size = 0;
- ScopedFdCloser data_file_fd_closer(&data_file_fd);
- BlobFileWriter blob_file(data_file_fd, &data_file_size);
+ BlobFileWriter blob_file(data_file.fd(), &data_file_size);
if (config.is_delta) {
TEST_AND_RETURN_FALSE(config.source.partitions.size() ==
config.target.partitions.size());
@@ -138,8 +174,12 @@
PartitionConfig empty_part("");
std::vector<std::vector<AnnotatedOperation>> all_aops;
all_aops.resize(config.target.partitions.size());
+
std::vector<std::vector<CowMergeOperation>> all_merge_sequences;
all_merge_sequences.resize(config.target.partitions.size());
+
+ std::vector<size_t> all_cow_sizes(config.target.partitions.size(), 0);
+
std::vector<PartitionProcessor> partition_tasks{};
auto thread_count = std::min<int>(diff_utils::GetMaxThreads(),
config.target.partitions.size());
@@ -157,10 +197,12 @@
unique_ptr<OperationsGenerator> strategy;
if (!old_part.path.empty()) {
// Delta update.
- LOG(INFO) << "Using generator ABGenerator().";
+ LOG(INFO) << "Using generator ABGenerator() for partition "
+ << new_part.name;
strategy.reset(new ABGenerator());
} else {
- LOG(INFO) << "Using generator FullUpdateGenerator().";
+ LOG(INFO) << "Using generator FullUpdateGenerator() for partition "
+ << new_part.name;
strategy.reset(new FullUpdateGenerator());
}
@@ -171,6 +213,7 @@
&blob_file,
&all_aops[i],
&all_merge_sequences[i],
+ &all_cow_sizes[i],
std::move(strategy)));
}
thread_pool.Start();
@@ -187,14 +230,16 @@
payload.AddPartition(old_part,
new_part,
std::move(all_aops[i]),
- std::move(all_merge_sequences[i])));
+ std::move(all_merge_sequences[i]),
+ all_cow_sizes[i]));
}
}
+ data_file.CloseFd();
LOG(INFO) << "Writing payload file...";
// Write payload file to disk.
TEST_AND_RETURN_FALSE(payload.WritePayload(
- output_path, temp_file_path, private_key_path, metadata_size));
+ output_path, data_file.path(), private_key_path, metadata_size));
LOG(INFO) << "All done. Successfully created delta file with "
<< "metadata size = " << *metadata_size;
diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc
index 220c7ae..3c025e1 100644
--- a/payload_generator/delta_diff_utils.cc
+++ b/payload_generator/delta_diff_utils.cc
@@ -822,17 +822,13 @@
// Only Puffdiff if both files have at least one deflate left.
if (!src_deflates.empty() && !dst_deflates.empty()) {
brillo::Blob puffdiff_delta;
- string temp_file_path;
- TEST_AND_RETURN_FALSE(utils::MakeTempFile(
- "puffdiff-delta.XXXXXX", &temp_file_path, nullptr));
- ScopedPathUnlinker temp_file_unlinker(temp_file_path);
-
+ ScopedTempFile temp_file("puffdiff-delta.XXXXXX");
// Perform PuffDiff operation.
TEST_AND_RETURN_FALSE(puffin::PuffDiff(old_data,
new_data,
src_deflates,
dst_deflates,
- temp_file_path,
+ temp_file.path(),
&puffdiff_delta));
TEST_AND_RETURN_FALSE(puffdiff_delta.size() > 0);
if (IsDiffOperationBetter(operation,
diff --git a/payload_generator/delta_diff_utils_unittest.cc b/payload_generator/delta_diff_utils_unittest.cc
index 0857f9c..f2db1bd 100644
--- a/payload_generator/delta_diff_utils_unittest.cc
+++ b/payload_generator/delta_diff_utils_unittest.cc
@@ -69,13 +69,12 @@
// Create a fake filesystem of the given |size| and initialize the partition
// holding it in the PartitionConfig |part|.
void CreatePartition(PartitionConfig* part,
- const string& pattern,
+ ScopedTempFile* part_file,
uint64_t block_size,
off_t size) {
- int fd = -1;
- ASSERT_TRUE(utils::MakeTempFile(pattern.c_str(), &part->path, &fd));
- ASSERT_EQ(0, ftruncate(fd, size));
- ASSERT_EQ(0, close(fd));
+ part->path = part_file->path();
+ ASSERT_EQ(0, ftruncate(part_file->fd(), size));
+ part_file->CloseFd();
part->fs_interface.reset(new FakeFilesystem(block_size, size / block_size));
part->size = size;
}
@@ -112,30 +111,20 @@
void SetUp() override {
CreatePartition(&old_part_,
- "DeltaDiffUtilsTest-old_part-XXXXXX",
+ &old_part_file_,
block_size_,
block_size_ * kDefaultBlockCount);
CreatePartition(&new_part_,
- "DeltaDiffUtilsTest-old_part-XXXXXX",
+ &new_part_file_,
block_size_,
block_size_ * kDefaultBlockCount);
- ASSERT_TRUE(utils::MakeTempFile(
- "DeltaDiffUtilsTest-blob-XXXXXX", &blob_path_, &blob_fd_));
- }
-
- void TearDown() override {
- unlink(old_part_.path.c_str());
- unlink(new_part_.path.c_str());
- if (blob_fd_ != -1)
- close(blob_fd_);
- unlink(blob_path_.c_str());
}
// Helper function to call DeltaMovedAndZeroBlocks() using this class' data
// members. This simply avoids repeating all the arguments that never change.
bool RunDeltaMovedAndZeroBlocks(ssize_t chunk_blocks,
uint32_t minor_version) {
- BlobFileWriter blob_file(blob_fd_, &blob_size_);
+ BlobFileWriter blob_file(tmp_blob_file_.fd(), &blob_size_);
PayloadVersion version(kBrilloMajorPayloadVersion, minor_version);
ExtentRanges old_zero_blocks;
return diff_utils::DeltaMovedAndZeroBlocks(&aops_,
@@ -155,10 +144,11 @@
// with
PartitionConfig old_part_{"part"};
PartitionConfig new_part_{"part"};
+ ScopedTempFile old_part_file_{"DeltaDiffUtilsTest-old_part-XXXXXX", true};
+ ScopedTempFile new_part_file_{"DeltaDiffUtilsTest-new_part-XXXXXX", true};
// The file holding the output blob from the various diff utils functions.
- string blob_path_;
- int blob_fd_{-1};
+ ScopedTempFile tmp_blob_file_{"DeltaDiffUtilsTest-blob-XXXXXX", true};
off_t blob_size_{0};
size_t block_size_{kBlockSize};
@@ -173,7 +163,7 @@
new_part_.verity.hash_tree_extent = ExtentForRange(20, 30);
new_part_.verity.fec_extent = ExtentForRange(40, 50);
- BlobFileWriter blob_file(blob_fd_, &blob_size_);
+ BlobFileWriter blob_file(tmp_blob_file_.fd(), &blob_size_);
EXPECT_TRUE(diff_utils::DeltaReadPartition(
&aops_,
old_part_,
diff --git a/payload_generator/ext2_filesystem_unittest.cc b/payload_generator/ext2_filesystem_unittest.cc
index 54600e9..88e1538 100644
--- a/payload_generator/ext2_filesystem_unittest.cc
+++ b/payload_generator/ext2_filesystem_unittest.cc
@@ -62,7 +62,7 @@
class Ext2FilesystemTest : public ::testing::Test {};
TEST_F(Ext2FilesystemTest, InvalidFilesystem) {
- test_utils::ScopedTempFile fs_filename_{"Ext2FilesystemTest-XXXXXX"};
+ ScopedTempFile fs_filename_{"Ext2FilesystemTest-XXXXXX"};
ASSERT_EQ(0, truncate(fs_filename_.path().c_str(), kDefaultFilesystemSize));
unique_ptr<Ext2Filesystem> fs =
Ext2Filesystem::CreateFromFile(fs_filename_.path());
diff --git a/payload_generator/extent_ranges_unittest.cc b/payload_generator/extent_ranges_unittest.cc
index 326e936..f55bb73 100644
--- a/payload_generator/extent_ranges_unittest.cc
+++ b/payload_generator/extent_ranges_unittest.cc
@@ -52,8 +52,8 @@
}
}
-#define EXPECT_RANGE_EQ(ranges, var) \
- do { \
+#define EXPECT_RANGE_EQ(ranges, var) \
+ do { \
ExpectRangeEq(ranges, var, base::size(var), __LINE__); \
} while (0)
diff --git a/payload_generator/extent_utils.h b/payload_generator/extent_utils.h
index 9763b1f..f870b29 100644
--- a/payload_generator/extent_utils.h
+++ b/payload_generator/extent_utils.h
@@ -20,6 +20,8 @@
#include <string>
#include <vector>
+#include <base/logging.h>
+
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/update_metadata.pb.h"
@@ -83,6 +85,43 @@
bool operator==(const Extent& a, const Extent& b);
+// TODO(zhangkelvin) This is ugly. Rewrite using C++20's coroutine once
+// that's available. Unfortunately with C++17 this is the best I could do.
+
+// An iterator that takes a sequence of extents, and iterate over blocks
+// inside this sequence of extents.
+// Example usage:
+
+// BlockIterator it1{src_extents};
+// while(!it1.is_end()) {
+// auto block = *it1;
+// Do stuff with |block|
+// }
+struct BlockIterator {
+ explicit BlockIterator(
+ const google::protobuf::RepeatedPtrField<Extent>& src_extents)
+ : src_extents_(src_extents) {}
+
+ BlockIterator& operator++() {
+ CHECK_LT(cur_extent_, src_extents_.size());
+ block_offset_++;
+ if (block_offset_ >= src_extents_[cur_extent_].num_blocks()) {
+ cur_extent_++;
+ block_offset_ = 0;
+ }
+ return *this;
+ }
+
+ [[nodiscard]] bool is_end() { return cur_extent_ >= src_extents_.size(); }
+ [[nodiscard]] uint64_t operator*() {
+ return src_extents_[cur_extent_].start_block() + block_offset_;
+ }
+
+ const google::protobuf::RepeatedPtrField<Extent>& src_extents_;
+ int cur_extent_ = 0;
+ size_t block_offset_ = 0;
+};
+
} // namespace chromeos_update_engine
#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_EXTENT_UTILS_H_
diff --git a/payload_generator/full_update_generator_unittest.cc b/payload_generator/full_update_generator_unittest.cc
index 5f39e8b..d3b3491 100644
--- a/payload_generator/full_update_generator_unittest.cc
+++ b/payload_generator/full_update_generator_unittest.cc
@@ -41,11 +41,9 @@
config_.block_size = 4096;
new_part_conf.path = part_file_.path();
- EXPECT_TRUE(utils::MakeTempFile(
- "FullUpdateTest_blobs.XXXXXX", &out_blobs_path_, &out_blobs_fd_));
- blob_file_.reset(new BlobFileWriter(out_blobs_fd_, &out_blobs_length_));
- out_blobs_unlinker_.reset(new ScopedPathUnlinker(out_blobs_path_));
+ blob_file_writer_.reset(
+ new BlobFileWriter(blob_file_.fd(), &out_blobs_length_));
}
PayloadGenerationConfig config_;
@@ -54,14 +52,11 @@
vector<AnnotatedOperation> aops;
// Output file holding the payload blobs.
- string out_blobs_path_;
- int out_blobs_fd_{-1};
off_t out_blobs_length_{0};
- ScopedFdCloser out_blobs_fd_closer_{&out_blobs_fd_};
- test_utils::ScopedTempFile part_file_{"FullUpdateTest_partition.XXXXXX"};
+ ScopedTempFile part_file_{"FullUpdateTest_partition.XXXXXX"};
- std::unique_ptr<BlobFileWriter> blob_file_;
- std::unique_ptr<ScopedPathUnlinker> out_blobs_unlinker_;
+ ScopedTempFile blob_file_{"FullUpdateTest_blobs.XXXXXX", true};
+ std::unique_ptr<BlobFileWriter> blob_file_writer_;
// FullUpdateGenerator under test.
FullUpdateGenerator generator_;
@@ -77,7 +72,7 @@
EXPECT_TRUE(generator_.GenerateOperations(config_,
new_part_conf, // this is ignored
new_part_conf,
- blob_file_.get(),
+ blob_file_writer_.get(),
&aops));
int64_t new_part_chunks = new_part_conf.size / config_.hard_chunk_size;
EXPECT_EQ(new_part_chunks, static_cast<int64_t>(aops.size()));
@@ -108,7 +103,7 @@
EXPECT_TRUE(generator_.GenerateOperations(config_,
new_part_conf, // this is ignored
new_part_conf,
- blob_file_.get(),
+ blob_file_writer_.get(),
&aops));
// new_part has one chunk and a half.
EXPECT_EQ(2U, aops.size());
@@ -129,7 +124,7 @@
EXPECT_TRUE(generator_.GenerateOperations(config_,
new_part_conf, // this is ignored
new_part_conf,
- blob_file_.get(),
+ blob_file_writer_.get(),
&aops));
// new_part has less than one chunk.
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index dd41a29..5bbeee4 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
@@ -29,13 +30,13 @@
#include <brillo/message_loops/base_message_loop.h>
#include <xz.h>
+#include "update_engine/common/download_action.h"
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/file_fetcher.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/terminator.h"
#include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/download_action.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/delta_diff_generator.h"
@@ -74,38 +75,6 @@
}
}
-bool ParseImageInfo(const string& channel,
- const string& board,
- const string& version,
- const string& key,
- const string& build_channel,
- const string& build_version,
- ImageInfo* image_info) {
- // All of these arguments should be present or missing.
- bool empty = channel.empty();
-
- CHECK_EQ(channel.empty(), empty);
- CHECK_EQ(board.empty(), empty);
- CHECK_EQ(version.empty(), empty);
- CHECK_EQ(key.empty(), empty);
-
- if (empty)
- return false;
-
- image_info->set_channel(channel);
- image_info->set_board(board);
- image_info->set_version(version);
- image_info->set_key(key);
-
- image_info->set_build_channel(build_channel.empty() ? channel
- : build_channel);
-
- image_info->set_build_version(build_version.empty() ? version
- : build_version);
-
- return true;
-}
-
void CalculateHashForSigning(const vector<size_t>& sizes,
const string& out_hash_file,
const string& out_metadata_hash_file,
@@ -214,8 +183,11 @@
install_plan.source_slot =
config.is_delta ? 0 : BootControlInterface::kInvalidSlot;
install_plan.target_slot = 1;
- payload.type =
- config.is_delta ? InstallPayloadType::kDelta : InstallPayloadType::kFull;
+ // For partial updates, we always write kDelta to the payload. Make it
+ // consistent for host simulation.
+ payload.type = config.is_delta || config.is_partial_update
+ ? InstallPayloadType::kDelta
+ : InstallPayloadType::kFull;
payload.size = utils::FileSize(payload_file);
// TODO(senj): This hash is only correct for unsigned payload, need to support
// signed payload using PayloadSigner.
@@ -266,7 +238,9 @@
processor.EnqueueAction(std::move(install_plan_action));
processor.EnqueueAction(std::move(download_action));
processor.EnqueueAction(std::move(filesystem_verifier_action));
- processor.StartProcessing();
+ loop.PostTask(FROM_HERE,
+ base::Bind(&ActionProcessor::StartProcessing,
+ base::Unretained(&processor)));
loop.Run();
CHECK_EQ(delegate.code_, ErrorCode::kSuccess);
LOG(INFO) << "Completed applying " << (config.is_delta ? "delta" : "full")
@@ -426,51 +400,6 @@
"The per-partition maximum timestamps which the OS allowed to apply this "
"payload. Passed in comma separated pairs, e.x. system:1234,vendor:5678");
- DEFINE_string(old_channel,
- "",
- "The channel for the old image. 'dev-channel', 'npo-channel', "
- "etc. Ignored, except during delta generation.");
- DEFINE_string(old_board,
- "",
- "The board for the old image. 'x86-mario', 'lumpy', "
- "etc. Ignored, except during delta generation.");
- DEFINE_string(
- old_version, "", "The build version of the old image. 1.2.3, etc.");
- DEFINE_string(old_key,
- "",
- "The key used to sign the old image. 'premp', 'mp', 'mp-v3',"
- " etc");
- DEFINE_string(old_build_channel,
- "",
- "The channel for the build of the old image. 'dev-channel', "
- "etc, but will never contain special channels such as "
- "'npo-channel'. Ignored, except during delta generation.");
- DEFINE_string(old_build_version,
- "",
- "The version of the build containing the old image.");
-
- DEFINE_string(new_channel,
- "",
- "The channel for the new image. 'dev-channel', 'npo-channel', "
- "etc. Ignored, except during delta generation.");
- DEFINE_string(new_board,
- "",
- "The board for the new image. 'x86-mario', 'lumpy', "
- "etc. Ignored, except during delta generation.");
- DEFINE_string(
- new_version, "", "The build version of the new image. 1.2.3, etc.");
- DEFINE_string(new_key,
- "",
- "The key used to sign the new image. 'premp', 'mp', 'mp-v3',"
- " etc");
- DEFINE_string(new_build_channel,
- "",
- "The channel for the build of the new image. 'dev-channel', "
- "etc, but will never contain special channels such as "
- "'npo-channel'. Ignored, except during delta generation.");
- DEFINE_string(new_build_version,
- "",
- "The version of the build containing the new image.");
DEFINE_string(new_postinstall_config_file,
"",
"A config file specifying postinstall related metadata. "
@@ -501,7 +430,11 @@
Terminator::Init();
logging::LoggingSettings log_settings;
+#if BASE_VER < 780000
log_settings.log_file = "delta_generator.log";
+#else
+ log_settings.log_file_path = "delta_generator.log";
+#endif
log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
log_settings.lock_log = logging::LOCK_LOG_FILE;
log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
@@ -646,6 +579,10 @@
}
}
+ if (FLAGS_is_partial_update) {
+ payload_config.is_partial_update = true;
+ }
+
if (!FLAGS_in_file.empty()) {
return ApplyPayload(FLAGS_in_file, payload_config) ? 0 : 1;
}
@@ -674,30 +611,8 @@
CHECK(payload_config.target.ValidateDynamicPartitionMetadata());
}
- if (FLAGS_is_partial_update) {
- payload_config.is_partial_update = true;
- }
-
CHECK(!FLAGS_out_file.empty());
- // Ignore failures. These are optional arguments.
- ParseImageInfo(FLAGS_new_channel,
- FLAGS_new_board,
- FLAGS_new_version,
- FLAGS_new_key,
- FLAGS_new_build_channel,
- FLAGS_new_build_version,
- &payload_config.target.image_info);
-
- // Ignore failures. These are optional arguments.
- ParseImageInfo(FLAGS_old_channel,
- FLAGS_old_board,
- FLAGS_old_version,
- FLAGS_old_key,
- FLAGS_old_build_channel,
- FLAGS_old_build_version,
- &payload_config.source.image_info);
-
payload_config.rootfs_partition_size = FLAGS_rootfs_partition_size;
if (payload_config.is_delta) {
diff --git a/payload_generator/mapfile_filesystem_unittest.cc b/payload_generator/mapfile_filesystem_unittest.cc
index 36ae3bf..57b672b 100644
--- a/payload_generator/mapfile_filesystem_unittest.cc
+++ b/payload_generator/mapfile_filesystem_unittest.cc
@@ -55,8 +55,8 @@
class MapfileFilesystemTest : public ::testing::Test {
protected:
- test_utils::ScopedTempFile temp_file_{"mapfile_file.XXXXXX"};
- test_utils::ScopedTempFile temp_mapfile_{"mapfile_mapfile.XXXXXX"};
+ ScopedTempFile temp_file_{"mapfile_file.XXXXXX"};
+ ScopedTempFile temp_mapfile_{"mapfile_mapfile.XXXXXX"};
};
TEST_F(MapfileFilesystemTest, EmptyFilesystem) {
diff --git a/payload_generator/merge_sequence_generator_unittest.cc b/payload_generator/merge_sequence_generator_unittest.cc
index 567ede1..1f0c2ea 100644
--- a/payload_generator/merge_sequence_generator_unittest.cc
+++ b/payload_generator/merge_sequence_generator_unittest.cc
@@ -116,6 +116,20 @@
merge_after.at(transfers[2]));
}
+TEST_F(MergeSequenceGeneratorTest, FindDependencyEdgeCase) {
+ std::vector<CowMergeOperation> transfers = {
+ CreateCowMergeOperation(ExtentForRange(10, 10), ExtentForRange(15, 10)),
+ CreateCowMergeOperation(ExtentForRange(40, 10), ExtentForRange(50, 10)),
+ CreateCowMergeOperation(ExtentForRange(59, 10), ExtentForRange(60, 10)),
+ };
+
+ std::map<CowMergeOperation, std::set<CowMergeOperation>> merge_after;
+ FindDependency(transfers, &merge_after);
+ ASSERT_EQ(std::set<CowMergeOperation>(), merge_after.at(transfers[0]));
+ ASSERT_EQ(std::set<CowMergeOperation>(), merge_after.at(transfers[1]));
+ ASSERT_EQ(merge_after[transfers[2]].size(), 1U);
+}
+
TEST_F(MergeSequenceGeneratorTest, FindDependency_ReusedSourceBlocks) {
std::vector<CowMergeOperation> transfers = {
CreateCowMergeOperation(ExtentForRange(5, 10), ExtentForRange(15, 10)),
diff --git a/payload_generator/payload_file.cc b/payload_generator/payload_file.cc
index 49dff4e..33c0749 100644
--- a/payload_generator/payload_file.cc
+++ b/payload_generator/payload_file.cc
@@ -64,13 +64,6 @@
TEST_AND_RETURN_FALSE(config.version.Validate());
major_version_ = config.version.major;
manifest_.set_minor_version(config.version.minor);
-
- if (!config.source.ImageInfoIsEmpty())
- *(manifest_.mutable_old_image_info()) = config.source.image_info;
-
- if (!config.target.ImageInfoIsEmpty())
- *(manifest_.mutable_new_image_info()) = config.target.image_info;
-
manifest_.set_block_size(config.block_size);
manifest_.set_max_timestamp(config.max_timestamp);
@@ -87,8 +80,10 @@
bool PayloadFile::AddPartition(const PartitionConfig& old_conf,
const PartitionConfig& new_conf,
vector<AnnotatedOperation> aops,
- vector<CowMergeOperation> merge_sequence) {
+ vector<CowMergeOperation> merge_sequence,
+ size_t cow_size) {
Partition part;
+ part.cow_size = cow_size;
part.name = new_conf.name;
part.aops = std::move(aops);
part.cow_merge_sequence = std::move(merge_sequence);
@@ -110,11 +105,9 @@
const string& private_key_path,
uint64_t* metadata_size_out) {
// Reorder the data blobs with the manifest_.
- string ordered_blobs_path;
- TEST_AND_RETURN_FALSE(utils::MakeTempFile(
- "CrAU_temp_data.ordered.XXXXXX", &ordered_blobs_path, nullptr));
- ScopedPathUnlinker ordered_blobs_unlinker(ordered_blobs_path);
- TEST_AND_RETURN_FALSE(ReorderDataBlobs(data_blobs_path, ordered_blobs_path));
+ ScopedTempFile ordered_blobs_file("CrAU_temp_data.ordered.XXXXXX");
+ TEST_AND_RETURN_FALSE(
+ ReorderDataBlobs(data_blobs_path, ordered_blobs_file.path()));
// Check that install op blobs are in order.
uint64_t next_blob_offset = 0;
@@ -138,6 +131,9 @@
if (!part.version.empty()) {
partition->set_version(part.version);
}
+ if (part.cow_size > 0) {
+ partition->set_estimate_cow_size(part.cow_size);
+ }
if (part.postinstall.run) {
partition->set_run_postinstall(true);
if (!part.postinstall.path.empty())
@@ -238,7 +234,7 @@
// Append the data blobs.
LOG(INFO) << "Writing final delta file data blobs...";
- int blobs_fd = open(ordered_blobs_path.c_str(), O_RDONLY, 0);
+ int blobs_fd = open(ordered_blobs_file.path().c_str(), O_RDONLY, 0);
ScopedFdCloser blobs_fd_closer(&blobs_fd);
TEST_AND_RETURN_FALSE(blobs_fd >= 0);
for (;;) {
diff --git a/payload_generator/payload_file.h b/payload_generator/payload_file.h
index 8b17956..3a45793 100644
--- a/payload_generator/payload_file.h
+++ b/payload_generator/payload_file.h
@@ -44,7 +44,8 @@
bool AddPartition(const PartitionConfig& old_conf,
const PartitionConfig& new_conf,
std::vector<AnnotatedOperation> aops,
- std::vector<CowMergeOperation> merge_sequence);
+ std::vector<CowMergeOperation> merge_sequence,
+ size_t cow_size);
// Write the payload to the |payload_file| file. The operations reference
// blobs in the |data_blobs_path| file and the blobs will be reordered in the
@@ -100,6 +101,7 @@
VerityConfig verity;
// Per partition timestamp.
std::string version;
+ size_t cow_size;
};
std::vector<Partition> part_vec_;
diff --git a/payload_generator/payload_file_unittest.cc b/payload_generator/payload_file_unittest.cc
index 45faebb9..1fd36f5 100644
--- a/payload_generator/payload_file_unittest.cc
+++ b/payload_generator/payload_file_unittest.cc
@@ -36,7 +36,7 @@
};
TEST_F(PayloadFileTest, ReorderBlobsTest) {
- test_utils::ScopedTempFile orig_blobs("ReorderBlobsTest.orig.XXXXXX");
+ ScopedTempFile orig_blobs("ReorderBlobsTest.orig.XXXXXX");
// The operations have three blob and one gap (the whitespace):
// Rootfs operation 1: [8, 3] bcd
@@ -45,7 +45,7 @@
string orig_data = "kernel abcd";
EXPECT_TRUE(test_utils::WriteFileString(orig_blobs.path(), orig_data));
- test_utils::ScopedTempFile new_blobs("ReorderBlobsTest.new.XXXXXX");
+ ScopedTempFile new_blobs("ReorderBlobsTest.new.XXXXXX");
payload_.part_vec_.resize(2);
diff --git a/payload_generator/payload_generation_config.cc b/payload_generator/payload_generation_config.cc
index 9c5832d..ef2f240 100644
--- a/payload_generator/payload_generation_config.cc
+++ b/payload_generator/payload_generation_config.cc
@@ -103,7 +103,6 @@
}
bool ImageConfig::ValidateIsEmpty() const {
- TEST_AND_RETURN_FALSE(ImageInfoIsEmpty());
return partitions.empty();
}
@@ -215,13 +214,6 @@
return true;
}
-bool ImageConfig::ImageInfoIsEmpty() const {
- return image_info.board().empty() && image_info.key().empty() &&
- image_info.channel().empty() && image_info.version().empty() &&
- image_info.build_channel().empty() &&
- image_info.build_version().empty();
-}
-
PayloadVersion::PayloadVersion(uint64_t major_version, uint32_t minor_version) {
major = major_version;
minor = minor_version;
@@ -293,9 +285,6 @@
TEST_AND_RETURN_FALSE(part.verity.IsEmpty());
}
- // If new_image_info is present, old_image_info must be present.
- TEST_AND_RETURN_FALSE(source.ImageInfoIsEmpty() ==
- target.ImageInfoIsEmpty());
} else {
// All the "source" image fields must be empty for full payloads.
TEST_AND_RETURN_FALSE(source.ValidateIsEmpty());
diff --git a/payload_generator/payload_generation_config.h b/payload_generator/payload_generation_config.h
index ec63043..1d88101 100644
--- a/payload_generator/payload_generation_config.h
+++ b/payload_generator/payload_generation_config.h
@@ -149,13 +149,6 @@
// Validate |dynamic_partition_metadata| against |partitions|.
bool ValidateDynamicPartitionMetadata() const;
- // Returns whether the |image_info| field is empty.
- bool ImageInfoIsEmpty() const;
-
- // The ImageInfo message defined in the update_metadata.proto file describes
- // the metadata of the image.
- ImageInfo image_info;
-
// The updated partitions.
std::vector<PartitionConfig> partitions;
diff --git a/payload_generator/payload_generation_config_android_unittest.cc b/payload_generator/payload_generation_config_android_unittest.cc
index 44eaf55..e87b034 100644
--- a/payload_generator/payload_generation_config_android_unittest.cc
+++ b/payload_generator/payload_generation_config_android_unittest.cc
@@ -138,8 +138,7 @@
}
ImageConfig image_config_;
- test_utils::ScopedTempFile temp_file_{
- "PayloadGenerationConfigAndroidTest.XXXXXX"};
+ ScopedTempFile temp_file_{"PayloadGenerationConfigAndroidTest.XXXXXX"};
};
TEST_F(PayloadGenerationConfigAndroidTest, LoadVerityConfigSimpleTest) {
diff --git a/payload_generator/payload_properties.cc b/payload_generator/payload_properties.cc
index bc82eb7..bcf4fbd 100644
--- a/payload_generator/payload_properties.cc
+++ b/payload_generator/payload_properties.cc
@@ -47,8 +47,6 @@
// These are needed by the Nebraska and devserver.
const char kPayloadPropertyJsonPayloadSize[] = "size";
const char kPayloadPropertyJsonIsDelta[] = "is_delta";
-const char kPayloadPropertyJsonTargetVersion[] = "target_version";
-const char kPayloadPropertyJsonSourceVersion[] = "source_version";
} // namespace
PayloadProperties::PayloadProperties(const string& payload_path)
@@ -65,10 +63,6 @@
properties.SetInteger(kPayloadPropertyJsonPayloadSize, payload_size_);
properties.SetString(kPayloadPropertyJsonPayloadHash, payload_hash_);
properties.SetBoolean(kPayloadPropertyJsonIsDelta, is_delta_);
- properties.SetString(kPayloadPropertyJsonTargetVersion, target_version_);
- if (is_delta_) {
- properties.SetString(kPayloadPropertyJsonSourceVersion, source_version_);
- }
return base::JSONWriter::Write(properties, json_str);
}
@@ -119,23 +113,11 @@
metadata_signatures_ = base::JoinString(base64_signatures, ":");
}
- is_delta_ = manifest.has_old_image_info() ||
- std::any_of(manifest.partitions().begin(),
+ is_delta_ = std::any_of(manifest.partitions().begin(),
manifest.partitions().end(),
[](const PartitionUpdate& part) {
return part.has_old_partition_info();
});
-
- if (manifest.has_new_image_info()) {
- target_version_ = manifest.new_image_info().version();
- } else {
- target_version_ = "99999.0.0";
- }
-
- // No need to set the source version if it was not a delta payload.
- if (is_delta_ && manifest.has_old_image_info()) {
- source_version_ = manifest.old_image_info().version();
- }
return true;
}
diff --git a/payload_generator/payload_properties.h b/payload_generator/payload_properties.h
index 3b34511..846b181 100644
--- a/payload_generator/payload_properties.h
+++ b/payload_generator/payload_properties.h
@@ -62,9 +62,6 @@
// Whether the payload is a delta (true) or full (false).
bool is_delta_;
- std::string target_version_;
- std::string source_version_;
-
DISALLOW_COPY_AND_ASSIGN(PayloadProperties);
};
diff --git a/payload_generator/payload_properties_unittest.cc b/payload_generator/payload_properties_unittest.cc
index e0072fc..0ff364f 100644
--- a/payload_generator/payload_properties_unittest.cc
+++ b/payload_generator/payload_properties_unittest.cc
@@ -40,7 +40,6 @@
#include "update_engine/payload_generator/payload_file.h"
#include "update_engine/payload_generator/payload_generation_config.h"
-using chromeos_update_engine::test_utils::ScopedTempFile;
using std::string;
using std::unique_ptr;
using std::vector;
@@ -57,19 +56,9 @@
PayloadGenerationConfig config;
config.version.major = kBrilloMajorPayloadVersion;
config.version.minor = kSourceMinorPayloadVersion;
- config.source.image_info.set_version("123.0.0");
- config.target.image_info.set_version("456.7.8");
PayloadFile payload;
EXPECT_TRUE(payload.Init(config));
- const string kTempFileTemplate = "temp_data.XXXXXX";
- int data_file_fd;
- string temp_file_path;
- EXPECT_TRUE(
- utils::MakeTempFile(kTempFileTemplate, &temp_file_path, &data_file_fd));
- ScopedPathUnlinker temp_file_unlinker(temp_file_path);
- EXPECT_LE(0, data_file_fd);
-
const auto SetupPartitionConfig =
[](PartitionConfig* config, const string& path, size_t size) {
config->path = path;
@@ -79,8 +68,8 @@
string zeros(size, '\0');
EXPECT_TRUE(utils::WriteFile(path, zeros.c_str(), zeros.size()));
};
- ScopedTempFile old_part_file;
- ScopedTempFile new_part_file;
+ ScopedTempFile old_part_file("old_part.XXXXXX");
+ ScopedTempFile new_part_file("new_part.XXXXXX");
PartitionConfig old_part(kPartitionNameRoot);
PartitionConfig new_part(kPartitionNameRoot);
SetupPartitionConfig(&old_part, old_part_file.path(), 0);
@@ -93,19 +82,20 @@
vector<AnnotatedOperation> aops;
off_t data_file_size = 0;
- BlobFileWriter blob_file_writer(data_file_fd, &data_file_size);
+ ScopedTempFile data_file("temp_data.XXXXXX", true);
+ BlobFileWriter blob_file_writer(data_file.fd(), &data_file_size);
// Generate the operations using the strategy we selected above.
EXPECT_TRUE(strategy->GenerateOperations(
config, old_part, new_part, &blob_file_writer, &aops));
- payload.AddPartition(old_part, new_part, aops, {});
+ payload.AddPartition(old_part, new_part, aops, {}, 0);
uint64_t metadata_size;
EXPECT_TRUE(payload.WritePayload(
- payload_file.path(), temp_file_path, "", &metadata_size));
+ payload_file_.path(), data_file.path(), "", &metadata_size));
}
- ScopedTempFile payload_file;
+ ScopedTempFile payload_file_{"payload_file.XXXXXX"};
};
// Validate the hash of file exists within the output.
@@ -114,28 +104,26 @@
"{"
R"("is_delta":true,)"
R"("metadata_signature":"",)"
- R"("metadata_size":187,)"
- R"("sha256_hex":"Rtrj9v3xXhrAi1741HAojtGxAQEOZ7mDyhzskIF4PJc=",)"
- R"("size":233,)"
- R"("source_version":"123.0.0",)"
- R"("target_version":"456.7.8",)"
+ R"("metadata_size":165,)"
+ R"("sha256_hex":"cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=",)"
+ R"("size":211,)"
R"("version":2)"
"}";
string json;
EXPECT_TRUE(
- PayloadProperties(payload_file.path()).GetPropertiesAsJson(&json));
+ PayloadProperties(payload_file_.path()).GetPropertiesAsJson(&json));
EXPECT_EQ(kJsonProperties, json) << "JSON contents:\n" << json;
}
// Validate the hash of file and metadata are within the output.
TEST_F(PayloadPropertiesTest, GetPropertiesAsKeyValueTestHash) {
constexpr char kKeyValueProperties[] =
- "FILE_HASH=Rtrj9v3xXhrAi1741HAojtGxAQEOZ7mDyhzskIF4PJc=\n"
- "FILE_SIZE=233\n"
- "METADATA_HASH=kiXTexy/s2aPttf4+r8KRZWYZ6FYvwhU6rJGcnnI+U0=\n"
- "METADATA_SIZE=187\n";
+ "FILE_HASH=cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=\n"
+ "FILE_SIZE=211\n"
+ "METADATA_HASH=aEKYyzJt2E8Gz8fzB+gmekN5mriotZCSq6R+kDfdeV4=\n"
+ "METADATA_SIZE=165\n";
string key_value;
- EXPECT_TRUE(PayloadProperties{payload_file.path()}.GetPropertiesAsKeyValue(
+ EXPECT_TRUE(PayloadProperties{payload_file_.path()}.GetPropertiesAsKeyValue(
&key_value));
EXPECT_EQ(kKeyValueProperties, key_value) << "Key Value contents:\n"
<< key_value;
diff --git a/payload_generator/payload_signer.cc b/payload_generator/payload_signer.cc
index c3264c1..d9f0dd7 100644
--- a/payload_generator/payload_signer.cc
+++ b/payload_generator/payload_signer.cc
@@ -241,8 +241,6 @@
DeltaArchiveManifest* manifest) {
LOG(INFO) << "Making room for signature in file";
manifest->set_signatures_offset(signature_blob_offset);
- LOG(INFO) << "set? " << manifest->has_signatures_offset();
- manifest->set_signatures_offset(signature_blob_offset);
manifest->set_signatures_size(signature_blob_length);
}
@@ -321,7 +319,6 @@
signature.data(),
rsa,
RSA_NO_PADDING);
-
if (signature_size < 0) {
LOG(ERROR) << "Signing hash failed: "
<< ERR_error_string(ERR_get_error(), nullptr);
diff --git a/payload_generator/payload_signer_unittest.cc b/payload_generator/payload_signer_unittest.cc
index fe62997..2a0b394 100644
--- a/payload_generator/payload_signer_unittest.cc
+++ b/payload_generator/payload_signer_unittest.cc
@@ -167,7 +167,7 @@
}
TEST_F(PayloadSignerTest, SkipMetadataSignatureTest) {
- test_utils::ScopedTempFile payload_file("payload.XXXXXX");
+ ScopedTempFile payload_file("payload.XXXXXX");
PayloadGenerationConfig config;
config.version.major = kBrilloMajorPayloadVersion;
PayloadFile payload;
@@ -194,7 +194,7 @@
}
TEST_F(PayloadSignerTest, VerifySignedPayloadTest) {
- test_utils::ScopedTempFile payload_file("payload.XXXXXX");
+ ScopedTempFile payload_file("payload.XXXXXX");
PayloadGenerationConfig config;
config.version.major = kBrilloMajorPayloadVersion;
PayloadFile payload;
diff --git a/payload_generator/squashfs_filesystem.cc b/payload_generator/squashfs_filesystem.cc
index 6152d7d..a41e283 100644
--- a/payload_generator/squashfs_filesystem.cc
+++ b/payload_generator/squashfs_filesystem.cc
@@ -72,15 +72,10 @@
}
bool GetFileMapContent(const string& sqfs_path, string* map) {
- // Create a tmp file
- string map_file;
- TEST_AND_RETURN_FALSE(
- utils::MakeTempFile("squashfs_file_map.XXXXXX", &map_file, nullptr));
- ScopedPathUnlinker map_unlinker(map_file);
-
+ ScopedTempFile map_file("squashfs_file_map.XXXXXX");
// Run unsquashfs to get the system file map.
// unsquashfs -m <map-file> <squashfs-file>
- vector<string> cmd = {"unsquashfs", "-m", map_file, sqfs_path};
+ vector<string> cmd = {"unsquashfs", "-m", map_file.path(), sqfs_path};
string stdout, stderr;
int exit_code;
if (!Subprocess::SynchronousExec(cmd, &exit_code, &stdout, &stderr) ||
@@ -89,7 +84,7 @@
<< stdout << " and stderr content: " << stderr;
return false;
}
- TEST_AND_RETURN_FALSE(utils::ReadFile(map_file, map));
+ TEST_AND_RETURN_FALSE(utils::ReadFile(map_file.path(), map));
return true;
}
diff --git a/power_manager_android.cc b/power_manager_android.cc
deleted file mode 100644
index 63a0351..0000000
--- a/power_manager_android.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/power_manager_android.h"
-
-#include <memory>
-
-#include <base/logging.h>
-
-namespace chromeos_update_engine {
-
-namespace power_manager {
-std::unique_ptr<PowerManagerInterface> CreatePowerManager() {
- return std::unique_ptr<PowerManagerInterface>(new PowerManagerAndroid());
-}
-} // namespace power_manager
-
-bool PowerManagerAndroid::RequestReboot() {
- LOG(WARNING) << "PowerManager not implemented.";
- return false;
-}
-
-} // namespace chromeos_update_engine
diff --git a/power_manager_android.h b/power_manager_android.h
deleted file mode 100644
index 86399ab..0000000
--- a/power_manager_android.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_POWER_MANAGER_ANDROID_H_
-#define UPDATE_ENGINE_POWER_MANAGER_ANDROID_H_
-
-#include <base/macros.h>
-
-#include "update_engine/power_manager_interface.h"
-
-namespace chromeos_update_engine {
-
-class PowerManagerAndroid : public PowerManagerInterface {
- public:
- PowerManagerAndroid() = default;
- ~PowerManagerAndroid() override = default;
-
- // PowerManagerInterface overrides.
- bool RequestReboot() override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PowerManagerAndroid);
-};
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_POWER_MANAGER_ANDROID_H_
diff --git a/sample_images/generate_payloads.sh b/sample_images/generate_payloads.sh
new file mode 100755
index 0000000..ee64229
--- /dev/null
+++ b/sample_images/generate_payloads.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This script generates some sample payloads from the images in
+# sample_images.tar.bz2. and packages them in the sample_payloads.tar.xz file.
+# The payloads are then used in paycheck_unittests.py. The file names
+# must match the ones used in update_payload ebuild and paycheck_unittests.py.
+
+set -e
+
+TEMP_IMG_DIR=./sample_images
+OLD_KERNEL="${TEMP_IMG_DIR}/disk_ext2_4k_empty.img"
+OLD_ROOT="${TEMP_IMG_DIR}/disk_sqfs_empty.img"
+NEW_KERNEL="${TEMP_IMG_DIR}/disk_ext2_4k.img"
+NEW_ROOT="${TEMP_IMG_DIR}/disk_sqfs_default.img"
+
+
+mkdir -p "${TEMP_IMG_DIR}"
+tar -xvf sample_images.tar.bz2 -C "${TEMP_IMG_DIR}"
+
+echo "Generating full payload"
+delta_generator --out_file=full_payload.bin \
+ --partition_names=kernel:root \
+ --new_partitions="${NEW_KERNEL}":"${NEW_ROOT}"
+
+echo "Generating delta payload"
+delta_generator --out_file=delta_payload.bin \
+ --partition_names=kernel:root \
+ --new_partitions="${NEW_KERNEL}":"${NEW_ROOT}" \
+ --old_partitions="${OLD_KERNEL}":"${OLD_ROOT}" --minor_version=6
+
+echo "Creating sample_payloads.tar"
+tar -cJf sample_payloads.tar.xz {delta,full}_payload.bin
+
+rm -rf "${TEMP_IMG_DIR}" {delta,full}_payload.bin
+
+echo "Done"
diff --git a/sample_images/sample_payloads.tar.xz b/sample_images/sample_payloads.tar.xz
new file mode 100644
index 0000000..d0bf6d9
--- /dev/null
+++ b/sample_images/sample_payloads.tar.xz
Binary files differ
diff --git a/scripts/brillo_update_payload b/scripts/brillo_update_payload
index 3bc87bd..32bb92c 100755
--- a/scripts/brillo_update_payload
+++ b/scripts/brillo_update_payload
@@ -196,6 +196,7 @@
DEFINE_string is_partial_update "" \
"Optional: True if the payload is for partial update. i.e. it only updates \
a subset of partitions on device."
+ DEFINE_string full_boot "" "Will include full boot image"
fi
if [[ "${COMMAND}" == "hash" || "${COMMAND}" == "sign" ]]; then
DEFINE_string unsigned_payload "" "Path to the input unsigned payload."
@@ -649,7 +650,12 @@
fi
partition_names+="${part}"
new_partitions+="${DST_PARTITIONS[${part}]}"
- old_partitions+="${SRC_PARTITIONS[${part}]:-}"
+ if [ "${FLAGS_full_boot}" == "true" ] && [ "${part}" == "boot" ]; then
+ # Skip boot partition.
+ old_partitions+=""
+ else
+ old_partitions+="${SRC_PARTITIONS[${part}]:-}"
+ fi
new_mapfiles+="${DST_PARTITIONS_MAP[${part}]:-}"
old_mapfiles+="${SRC_PARTITIONS_MAP[${part}]:-}"
done
diff --git a/scripts/paycheck.py b/scripts/paycheck.py
index f4ccca2..cb1713f 100755
--- a/scripts/paycheck.py
+++ b/scripts/paycheck.py
@@ -27,6 +27,7 @@
import sys
import tempfile
+# pylint: disable=redefined-builtin
from six.moves import zip
from update_payload import error
@@ -92,9 +93,6 @@
check_args.add_argument('-c', '--check', action='store_true', default=False,
help=('force payload integrity check (e.g. before '
'applying)'))
- check_args.add_argument('-D', '--describe', action='store_true',
- default=False,
- help='Print a friendly description of the payload.')
check_args.add_argument('-r', '--report', metavar='FILE',
help="dump payload report (`-' for stdout)")
check_args.add_argument('-t', '--type', dest='assert_type',
@@ -209,9 +207,6 @@
# Initialize payload.
payload.Init()
- if args.describe:
- payload.Describe()
-
# Perform payload integrity checks.
if args.check:
report_file = None
diff --git a/scripts/paycheck_unittest.py b/scripts/paycheck_unittest.py
new file mode 100755
index 0000000..a90d269
--- /dev/null
+++ b/scripts/paycheck_unittest.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Unit testing paycheck.py."""
+
+# This test requires new (Y) and old (X) images, as well as a full payload
+# from image Y and a delta payload from Y to X for each partition.
+# Payloads are from sample_images/generate_payloads.
+#
+# The test performs the following:
+#
+# - It statically applies the full and delta payloads.
+#
+# - It applies full_payload to yield a new kernel (kern.part) and rootfs
+# (root.part) and compares them to the new image partitions.
+#
+# - It applies delta_payload to the old image to yield a new kernel and rootfs
+# and compares them to the new image partitions.
+#
+# Previously test_paycheck.sh. Run with update_payload ebuild.
+
+# Disable check for function names to avoid errors based on old code
+# pylint: disable=invalid-name
+
+import filecmp
+import os
+import subprocess
+import unittest
+
+
+class PaycheckTest(unittest.TestCase):
+ """Test paycheck functions."""
+
+ def setUp(self):
+ self.tmpdir = os.getenv('T')
+
+ self._full_payload = os.path.join(self.tmpdir, 'full_payload.bin')
+ self._delta_payload = os.path.join(self.tmpdir, 'delta_payload.bin')
+
+ self._new_kernel = os.path.join(self.tmpdir, 'disk_ext2_4k.img')
+ self._new_root = os.path.join(self.tmpdir, 'disk_sqfs_default.img')
+ self._old_kernel = os.path.join(self.tmpdir,
+ 'disk_ext2_4k_empty.img')
+ self._old_root = os.path.join(self.tmpdir, 'disk_sqfs_empty.img')
+
+ # Temp output files.
+ self._kernel_part = os.path.join(self.tmpdir, 'kern.part')
+ self._root_part = os.path.join(self.tmpdir, 'root.part')
+
+ def checkPayload(self, type_arg, payload):
+ """Checks Payload."""
+ self.assertEqual(0, subprocess.check_call(['./paycheck.py', '-t',
+ type_arg, payload]))
+
+ def testFullPayload(self):
+ """Checks the full payload statically."""
+ self.checkPayload('full', self._full_payload)
+
+ def testDeltaPayload(self):
+ """Checks the delta payload statically."""
+ self.checkPayload('delta', self._delta_payload)
+
+ def testApplyFullPayload(self):
+ """Applies full payloads and compares results to new sample images."""
+ self.assertEqual(0, subprocess.check_call(['./paycheck.py',
+ self._full_payload,
+ '--part_names', 'kernel', 'root',
+ '--out_dst_part_paths',
+ self._kernel_part,
+ self._root_part]))
+
+ # Check if generated full image is equal to sample image.
+ self.assertTrue(filecmp.cmp(self._kernel_part, self._new_kernel))
+ self.assertTrue(filecmp.cmp(self._root_part, self._new_root))
+
+ def testApplyDeltaPayload(self):
+ """Applies delta to old image and checks against new sample images."""
+ self.assertEqual(0, subprocess.check_call(['./paycheck.py',
+ self._delta_payload,
+ '--part_names', 'kernel', 'root',
+ '--src_part_paths',
+ self._old_kernel, self._old_root,
+ '--out_dst_part_paths',
+ self._kernel_part,
+ self._root_part]))
+
+ self.assertTrue(filecmp.cmp(self._kernel_part, self._new_kernel))
+ self.assertTrue(filecmp.cmp(self._root_part, self._new_root))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/scripts/payload_info.py b/scripts/payload_info.py
index 7625ee8..8343d21 100755
--- a/scripts/payload_info.py
+++ b/scripts/payload_info.py
@@ -75,8 +75,11 @@
DisplayValue(' Number of "%s" ops' % partition.partition_name,
len(partition.operations))
for partition in manifest.partitions:
- DisplayValue("Timestamp for " +
+ DisplayValue(" Timestamp for " +
partition.partition_name, partition.version)
+ for partition in manifest.partitions:
+ DisplayValue(" COW Size for " +
+ partition.partition_name, partition.estimate_cow_size)
DisplayValue('Block size', manifest.block_size)
DisplayValue('Minor version', manifest.minor_version)
diff --git a/scripts/run_unittests b/scripts/run_unittests
index 0d301ba..db5ed73 100755
--- a/scripts/run_unittests
+++ b/scripts/run_unittests
@@ -26,5 +26,6 @@
done
./payload_info_unittest.py
+./paycheck_unittest.py
exit 0
diff --git a/scripts/test_paycheck.sh b/scripts/test_paycheck.sh
deleted file mode 100755
index 239b984..0000000
--- a/scripts/test_paycheck.sh
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# A test script for paycheck.py and the update_payload.py library.
-#
-# This script requires three payload files, along with a metadata signature for
-# each, and a public key for verifying signatures. Payload include:
-#
-# - A full payload for release X (old_full_payload)
-#
-# - A full payload for release Y (new_full_payload), where Y > X
-#
-# - A delta payload from X to Y (delta_payload)
-#
-# The test performs the following:
-#
-# - It verifies each payload against its metadata signature, also asserting the
-# payload type. Another artifact is a human-readable payload report, which
-# is output to stdout to be inspected by the user.
-#
-# - It applies old_full_payload to yield old kernel (old_kern.part) and rootfs
-# (old_root.part) partitions.
-#
-# - It applies delta_payload to old_{kern,root}.part to yield new kernel
-# (new_delta_kern.part) and rootfs (new_delta_root.part) partitions.
-#
-# - It applies new_full_payload to yield reference new kernel
-# (new_full_kern.part) and rootfs (new_full_root.part) partitions.
-#
-# - It compares new_{delta,full}_kern.part and new_{delta,full}_root.part to
-# ensure that they are binary identical.
-#
-# If all steps have completed successfully we know with high certainty that
-# paycheck.py (and hence update_payload.py) correctly parses both full and delta
-# payloads, and applies them to yield the expected result. Finally, each
-# paycheck.py execution is timed.
-
-
-# Stop on errors, unset variables.
-set -e
-set -u
-
-# Temporary image files.
-OLD_KERN_PART=old_kern.part
-OLD_ROOT_PART=old_root.part
-NEW_DELTA_KERN_PART=new_delta_kern.part
-NEW_DELTA_ROOT_PART=new_delta_root.part
-NEW_FULL_KERN_PART=new_full_kern.part
-NEW_FULL_ROOT_PART=new_full_root.part
-CROS_PARTS="kernel root"
-
-
-log() {
- echo "$@" >&2
-}
-
-die() {
- log "$@"
- exit 1
-}
-
-usage_and_exit() {
- cat >&2 <<EOF
-Usage: ${0##*/} old_full_payload delta_payload new_full_payload
-EOF
- exit
-}
-
-check_payload() {
- payload_file=$1
- payload_type=$2
-
- time ${paycheck} -t ${payload_type} ${payload_file}
-}
-
-apply_full_payload() {
- payload_file=$1
- out_dst_kern_part="$2/$3"
- out_dst_root_part="$2/$4"
-
- time ${paycheck} ${payload_file} \
- --part_names ${CROS_PARTS} \
- --out_dst_part_paths ${out_dst_kern_part} ${out_dst_root_part}
-}
-
-apply_delta_payload() {
- payload_file=$1
- out_dst_kern_part="$2/$3"
- out_dst_root_part="$2/$4"
- dst_kern_part="$2/$5"
- dst_root_part="$2/$6"
- src_kern_part="$2/$7"
- src_root_part="$2/$8"
-
- time ${paycheck} ${payload_file} \
- --part_names ${CROS_PARTS} \
- --out_dst_part_paths ${out_dst_kern_part} ${out_dst_root_part} \
- --dst_part_paths ${dst_kern_part} ${dst_root_part} \
- --src_part_paths ${src_kern_part} ${src_root_part}
-}
-
-main() {
- # Read command-line arguments.
- if [ $# == 1 ] && [ "$1" == "-h" ]; then
- usage_and_exit
- elif [ $# != 3 ]; then
- die "Error: unexpected number of arguments"
- fi
- old_full_payload="$1"
- delta_payload="$2"
- new_full_payload="$3"
-
- # Find paycheck.py
- paycheck=${0%/*}/paycheck.py
- if [ -z "${paycheck}" ] || [ ! -x ${paycheck} ]; then
- die "cannot find ${paycheck} or file is not executable"
- fi
-
- # Check the payloads statically.
- log "Checking payloads..."
- check_payload "${old_full_payload}" full
- check_payload "${new_full_payload}" full
- check_payload "${delta_payload}" delta
- log "Done"
-
- # Apply full/delta payloads and verify results are identical.
- tmpdir="$(mktemp -d --tmpdir test_paycheck.XXXXXXXX)"
- log "Initiating application of payloads at $tmpdir"
-
- log "Applying old full payload..."
- apply_full_payload "${old_full_payload}" "${tmpdir}" "${OLD_KERN_PART}" \
- "${OLD_ROOT_PART}"
- log "Done"
-
- log "Applying new full payload..."
- apply_full_payload "${new_full_payload}" "${tmpdir}" "${NEW_FULL_KERN_PART}" \
- "${NEW_FULL_ROOT_PART}"
- log "Done"
-
- log "Applying delta payload to old partitions..."
- apply_delta_payload "${delta_payload}" "${tmpdir}" "${NEW_DELTA_KERN_PART}" \
- "${NEW_DELTA_ROOT_PART}" "${NEW_FULL_KERN_PART}" \
- "${NEW_FULL_ROOT_PART}" "${OLD_KERN_PART}" "${OLD_ROOT_PART}"
- log "Done"
-
- log "Comparing results of delta and new full updates..."
- diff "${tmpdir}/${NEW_FULL_KERN_PART}" "${tmpdir}/${NEW_DELTA_KERN_PART}"
- diff "${tmpdir}/${NEW_FULL_ROOT_PART}" "${tmpdir}/${NEW_DELTA_ROOT_PART}"
- log "Done"
-
- log "Cleaning up"
- rm -fr "${tmpdir}"
-}
-
-main "$@"
diff --git a/scripts/update_device.py b/scripts/update_device.py
index 1cd4b6a..757c147 100755
--- a/scripts/update_device.py
+++ b/scripts/update_device.py
@@ -17,6 +17,7 @@
"""Send an A/B update to an Android device over adb."""
+from __future__ import print_function
from __future__ import absolute_import
import argparse
@@ -305,6 +306,7 @@
logging.info('Server Terminated')
def StopServer(self):
+ self._httpd.shutdown()
self._httpd.socket.close()
@@ -318,13 +320,13 @@
"""Return the command to run to start the update in the Android device."""
ota = AndroidOTAPackage(ota_filename, secondary)
headers = ota.properties
- headers += 'USER_AGENT=Dalvik (something, something)\n'
- headers += 'NETWORK_ID=0\n'
- headers += extra_headers
+ headers += b'USER_AGENT=Dalvik (something, something)\n'
+ headers += b'NETWORK_ID=0\n'
+ headers += extra_headers.encode()
return ['update_engine_client', '--update', '--follow',
'--payload=%s' % payload_url, '--offset=%d' % ota.offset,
- '--size=%d' % ota.size, '--headers="%s"' % headers]
+ '--size=%d' % ota.size, '--headers="%s"' % headers.decode()]
def OmahaUpdateCommand(omaha_url):
@@ -401,6 +403,8 @@
help='Extra headers to pass to the device.')
parser.add_argument('--secondary', action='store_true',
help='Update with the secondary payload in the package.')
+ parser.add_argument('--no-slot-switch', action='store_true',
+ help='Do not perform slot switch after the update.')
args = parser.parse_args()
logging.basicConfig(
level=logging.WARNING if args.no_verbose else logging.INFO)
@@ -418,6 +422,9 @@
help_cmd = ['shell', 'su', '0', 'update_engine_client', '--help']
use_omaha = 'omaha' in dut.adb_output(help_cmd)
+ if args.no_slot_switch:
+ args.extra_headers += "\nSWITCH_SLOT_ON_REBOOT=0"
+
if args.file:
# Update via pushing a file to /data.
device_ota_file = os.path.join(OTA_PACKAGE_PATH, 'debug.zip')
diff --git a/scripts/update_payload/checker.py b/scripts/update_payload/checker.py
index 4c65516..56a9370 100644
--- a/scripts/update_payload/checker.py
+++ b/scripts/update_payload/checker.py
@@ -35,6 +35,7 @@
import os
import subprocess
+# pylint: disable=redefined-builtin
from six.moves import range
from update_payload import common
@@ -71,6 +72,7 @@
4: (_TYPE_DELTA,),
5: (_TYPE_DELTA,),
6: (_TYPE_DELTA,),
+ 7: (_TYPE_DELTA,),
}
@@ -1148,17 +1150,13 @@
sig_report = report.AddSubReport(sig_name)
# Check: Signature contains mandatory fields.
- self._CheckMandatoryField(sig, 'version', sig_report, sig_name)
self._CheckMandatoryField(sig, 'data', None, sig_name)
sig_report.AddField('data len', len(sig.data))
# Check: Signatures pertains to actual payload hash.
- if sig.version == 1:
+ if sig.data:
self._CheckSha256Signature(sig.data, pubkey_file_name,
payload_hasher.digest(), sig_name)
- else:
- raise error.PayloadError('Unknown signature version (%d).' %
- sig.version)
def Run(self, pubkey_file_name=None, metadata_sig_file=None, metadata_size=0,
part_sizes=None, report_out_file=None):
diff --git a/scripts/update_payload/payload.py b/scripts/update_payload/payload.py
index 78b8e2c..fe3a450 100644
--- a/scripts/update_payload/payload.py
+++ b/scripts/update_payload/payload.py
@@ -232,31 +232,6 @@
self.is_init = True
- def Describe(self):
- """Emits the payload embedded description data to standard output."""
- def _DescribeImageInfo(description, image_info):
- """Display info about the image."""
- def _DisplayIndentedValue(name, value):
- print(' {:<14} {}'.format(name+':', value))
-
- print('%s:' % description)
- _DisplayIndentedValue('Channel', image_info.channel)
- _DisplayIndentedValue('Board', image_info.board)
- _DisplayIndentedValue('Version', image_info.version)
- _DisplayIndentedValue('Key', image_info.key)
-
- if image_info.build_channel != image_info.channel:
- _DisplayIndentedValue('Build channel', image_info.build_channel)
-
- if image_info.build_version != image_info.version:
- _DisplayIndentedValue('Build version', image_info.build_version)
-
- if self.manifest.HasField('old_image_info'):
- _DescribeImageInfo('Old Image', self.manifest.old_image_info)
-
- if self.manifest.HasField('new_image_info'):
- _DescribeImageInfo('New Image', self.manifest.new_image_info)
-
def _AssertInit(self):
"""Raises an exception if the object was not initialized."""
if not self.is_init:
diff --git a/scripts/update_payload/update_metadata_pb2.py b/scripts/update_payload/update_metadata_pb2.py
index 841cd22..ea4bc59 100644
--- a/scripts/update_payload/update_metadata_pb2.py
+++ b/scripts/update_payload/update_metadata_pb2.py
@@ -18,7 +18,7 @@
package='chromeos_update_engine',
syntax='proto2',
serialized_options=b'H\003',
- serialized_pb=b'\n\x15update_metadata.proto\x12\x16\x63hromeos_update_engine\"1\n\x06\x45xtent\x12\x13\n\x0bstart_block\x18\x01 \x01(\x04\x12\x12\n\nnum_blocks\x18\x02 \x01(\x04\"\x9f\x01\n\nSignatures\x12@\n\nsignatures\x18\x01 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x1aO\n\tSignature\x12\x13\n\x07version\x18\x01 \x01(\rB\x02\x18\x01\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x1f\n\x17unpadded_signature_size\x18\x03 \x01(\x07\"+\n\rPartitionInfo\x12\x0c\n\x04size\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"w\n\tImageInfo\x12\r\n\x05\x62oard\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x15\n\rbuild_channel\x18\x05 \x01(\t\x12\x15\n\rbuild_version\x18\x06 \x01(\t\"\xee\x03\n\x10InstallOperation\x12;\n\x04type\x18\x01 \x02(\x0e\x32-.chromeos_update_engine.InstallOperation.Type\x12\x13\n\x0b\x64\x61ta_offset\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_length\x18\x03 \x01(\x04\x12\x33\n\x0bsrc_extents\x18\x04 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\nsrc_length\x18\x05 \x01(\x04\x12\x33\n\x0b\x64st_extents\x18\x06 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\ndst_length\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_sha256_hash\x18\x08 \x01(\x0c\x12\x17\n\x0fsrc_sha256_hash\x18\t \x01(\x0c\"\xad\x01\n\x04Type\x12\x0b\n\x07REPLACE\x10\x00\x12\x0e\n\nREPLACE_BZ\x10\x01\x12\x0c\n\x04MOVE\x10\x02\x1a\x02\x08\x01\x12\x0e\n\x06\x42SDIFF\x10\x03\x1a\x02\x08\x01\x12\x0f\n\x0bSOURCE_COPY\x10\x04\x12\x11\n\rSOURCE_BSDIFF\x10\x05\x12\x0e\n\nREPLACE_XZ\x10\x08\x12\x08\n\x04ZERO\x10\x06\x12\x0b\n\x07\x44ISCARD\x10\x07\x12\x11\n\rBROTLI_BSDIFF\x10\n\x12\x0c\n\x08PUFFDIFF\x10\t\"\xe8\x05\n\x0fPartitionUpdate\x12\x16\n\x0epartition_name\x18\x01 \x02(\t\x12\x17\n\x0frun_postinstall\x18\x02 \x01(\x08\x12\x18\n\x10postinstall_path\x18\x03 \x01(\t\x12\x17\n\x0f\x66ilesystem_type\x18\x04 \x01(\t\x12M\n\x17new_partition_signature\x18\x05 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x12\x41\n\x12old_partition_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x41\n\x12new_partition_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12<\n\noperations\x18\x08 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x1c\n\x14postinstall_optional\x18\t \x01(\x08\x12=\n\x15hash_tree_data_extent\x18\n \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x38\n\x10hash_tree_extent\x18\x0b \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x1b\n\x13hash_tree_algorithm\x18\x0c \x01(\t\x12\x16\n\x0ehash_tree_salt\x18\r \x01(\x0c\x12\x37\n\x0f\x66\x65\x63_data_extent\x18\x0e \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x32\n\nfec_extent\x18\x0f \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x14\n\tfec_roots\x18\x10 \x01(\r:\x01\x32\x12\x0f\n\x07version\x18\x11 \x01(\t\"L\n\x15\x44ynamicPartitionGroup\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x17\n\x0fpartition_names\x18\x03 \x03(\t\"s\n\x18\x44ynamicPartitionMetadata\x12=\n\x06groups\x18\x01 \x03(\x0b\x32-.chromeos_update_engine.DynamicPartitionGroup\x12\x18\n\x10snapshot_enabled\x18\x02 \x01(\x08\"\xe1\x06\n\x14\x44\x65ltaArchiveManifest\x12H\n\x12install_operations\x18\x01 \x03(\x0b\x32(.chromeos_update_engine.InstallOperationB\x02\x18\x01\x12O\n\x19kernel_install_operations\x18\x02 \x03(\x0b\x32(.chromeos_update_engine.InstallOperationB\x02\x18\x01\x12\x18\n\nblock_size\x18\x03 \x01(\r:\x04\x34\x30\x39\x36\x12\x19\n\x11signatures_offset\x18\x04 \x01(\x04\x12\x17\n\x0fsignatures_size\x18\x05 \x01(\x04\x12\x42\n\x0fold_kernel_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fnew_kernel_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fold_rootfs_info\x18\x08 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fnew_rootfs_info\x18\t \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x39\n\x0eold_image_info\x18\n \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x39\n\x0enew_image_info\x18\x0b \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x18\n\rminor_version\x18\x0c \x01(\r:\x01\x30\x12;\n\npartitions\x18\r \x03(\x0b\x32\'.chromeos_update_engine.PartitionUpdate\x12\x15\n\rmax_timestamp\x18\x0e \x01(\x03\x12T\n\x1a\x64ynamic_partition_metadata\x18\x0f \x01(\x0b\x32\x30.chromeos_update_engine.DynamicPartitionMetadata\x12\x16\n\x0epartial_update\x18\x10 \x01(\x08\x42\x02H\x03'
+ serialized_pb=b'\n\x15update_metadata.proto\x12\x16\x63hromeos_update_engine\"1\n\x06\x45xtent\x12\x13\n\x0bstart_block\x18\x01 \x01(\x04\x12\x12\n\nnum_blocks\x18\x02 \x01(\x04\"\x9f\x01\n\nSignatures\x12@\n\nsignatures\x18\x01 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x1aO\n\tSignature\x12\x13\n\x07version\x18\x01 \x01(\rB\x02\x18\x01\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x1f\n\x17unpadded_signature_size\x18\x03 \x01(\x07\"+\n\rPartitionInfo\x12\x0c\n\x04size\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"w\n\tImageInfo\x12\r\n\x05\x62oard\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x15\n\rbuild_channel\x18\x05 \x01(\t\x12\x15\n\rbuild_version\x18\x06 \x01(\t\"\xee\x03\n\x10InstallOperation\x12;\n\x04type\x18\x01 \x02(\x0e\x32-.chromeos_update_engine.InstallOperation.Type\x12\x13\n\x0b\x64\x61ta_offset\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_length\x18\x03 \x01(\x04\x12\x33\n\x0bsrc_extents\x18\x04 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\nsrc_length\x18\x05 \x01(\x04\x12\x33\n\x0b\x64st_extents\x18\x06 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\ndst_length\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_sha256_hash\x18\x08 \x01(\x0c\x12\x17\n\x0fsrc_sha256_hash\x18\t \x01(\x0c\"\xad\x01\n\x04Type\x12\x0b\n\x07REPLACE\x10\x00\x12\x0e\n\nREPLACE_BZ\x10\x01\x12\x0c\n\x04MOVE\x10\x02\x1a\x02\x08\x01\x12\x0e\n\x06\x42SDIFF\x10\x03\x1a\x02\x08\x01\x12\x0f\n\x0bSOURCE_COPY\x10\x04\x12\x11\n\rSOURCE_BSDIFF\x10\x05\x12\x0e\n\nREPLACE_XZ\x10\x08\x12\x08\n\x04ZERO\x10\x06\x12\x0b\n\x07\x44ISCARD\x10\x07\x12\x11\n\rBROTLI_BSDIFF\x10\n\x12\x0c\n\x08PUFFDIFF\x10\t\"\xcf\x01\n\x11\x43owMergeOperation\x12<\n\x04type\x18\x01 \x01(\x0e\x32..chromeos_update_engine.CowMergeOperation.Type\x12\x32\n\nsrc_extent\x18\x02 \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x32\n\ndst_extent\x18\x03 \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\"\x14\n\x04Type\x12\x0c\n\x08\x43OW_COPY\x10\x00\"\xc8\x06\n\x0fPartitionUpdate\x12\x16\n\x0epartition_name\x18\x01 \x02(\t\x12\x17\n\x0frun_postinstall\x18\x02 \x01(\x08\x12\x18\n\x10postinstall_path\x18\x03 \x01(\t\x12\x17\n\x0f\x66ilesystem_type\x18\x04 \x01(\t\x12M\n\x17new_partition_signature\x18\x05 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x12\x41\n\x12old_partition_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x41\n\x12new_partition_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12<\n\noperations\x18\x08 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x1c\n\x14postinstall_optional\x18\t \x01(\x08\x12=\n\x15hash_tree_data_extent\x18\n \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x38\n\x10hash_tree_extent\x18\x0b \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x1b\n\x13hash_tree_algorithm\x18\x0c \x01(\t\x12\x16\n\x0ehash_tree_salt\x18\r \x01(\x0c\x12\x37\n\x0f\x66\x65\x63_data_extent\x18\x0e \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x32\n\nfec_extent\x18\x0f \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x14\n\tfec_roots\x18\x10 \x01(\r:\x01\x32\x12\x0f\n\x07version\x18\x11 \x01(\t\x12\x43\n\x10merge_operations\x18\x12 \x03(\x0b\x32).chromeos_update_engine.CowMergeOperation\x12\x19\n\x11\x65stimate_cow_size\x18\x13 \x01(\x04\"L\n\x15\x44ynamicPartitionGroup\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x17\n\x0fpartition_names\x18\x03 \x03(\t\"s\n\x18\x44ynamicPartitionMetadata\x12=\n\x06groups\x18\x01 \x03(\x0b\x32-.chromeos_update_engine.DynamicPartitionGroup\x12\x18\n\x10snapshot_enabled\x18\x02 \x01(\x08\"\xe1\x06\n\x14\x44\x65ltaArchiveManifest\x12H\n\x12install_operations\x18\x01 \x03(\x0b\x32(.chromeos_update_engine.InstallOperationB\x02\x18\x01\x12O\n\x19kernel_install_operations\x18\x02 \x03(\x0b\x32(.chromeos_update_engine.InstallOperationB\x02\x18\x01\x12\x18\n\nblock_size\x18\x03 \x01(\r:\x04\x34\x30\x39\x36\x12\x19\n\x11signatures_offset\x18\x04 \x01(\x04\x12\x17\n\x0fsignatures_size\x18\x05 \x01(\x04\x12\x42\n\x0fold_kernel_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fnew_kernel_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fold_rootfs_info\x18\x08 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x42\n\x0fnew_rootfs_info\x18\t \x01(\x0b\x32%.chromeos_update_engine.PartitionInfoB\x02\x18\x01\x12\x39\n\x0eold_image_info\x18\n \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x39\n\x0enew_image_info\x18\x0b \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x18\n\rminor_version\x18\x0c \x01(\r:\x01\x30\x12;\n\npartitions\x18\r \x03(\x0b\x32\'.chromeos_update_engine.PartitionUpdate\x12\x15\n\rmax_timestamp\x18\x0e \x01(\x03\x12T\n\x1a\x64ynamic_partition_metadata\x18\x0f \x01(\x0b\x32\x30.chromeos_update_engine.DynamicPartitionMetadata\x12\x16\n\x0epartial_update\x18\x10 \x01(\x08\x42\x02H\x03'
)
@@ -81,6 +81,24 @@
)
_sym_db.RegisterEnumDescriptor(_INSTALLOPERATION_TYPE)
+_COWMERGEOPERATION_TYPE = _descriptor.EnumDescriptor(
+ name='Type',
+ full_name='chromeos_update_engine.CowMergeOperation.Type',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='COW_COPY', index=0, number=0,
+ serialized_options=None,
+ type=None),
+ ],
+ containing_type=None,
+ serialized_options=None,
+ serialized_start=1113,
+ serialized_end=1133,
+)
+_sym_db.RegisterEnumDescriptor(_COWMERGEOPERATION_TYPE)
+
_EXTENT = _descriptor.Descriptor(
name='Extent',
@@ -387,6 +405,52 @@
)
+_COWMERGEOPERATION = _descriptor.Descriptor(
+ name='CowMergeOperation',
+ full_name='chromeos_update_engine.CowMergeOperation',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='type', full_name='chromeos_update_engine.CowMergeOperation.type', index=0,
+ number=1, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='src_extent', full_name='chromeos_update_engine.CowMergeOperation.src_extent', index=1,
+ number=2, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='dst_extent', full_name='chromeos_update_engine.CowMergeOperation.dst_extent', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _COWMERGEOPERATION_TYPE,
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto2',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=926,
+ serialized_end=1133,
+)
+
+
_PARTITIONUPDATE = _descriptor.Descriptor(
name='PartitionUpdate',
full_name='chromeos_update_engine.PartitionUpdate',
@@ -513,6 +577,20 @@
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='merge_operations', full_name='chromeos_update_engine.PartitionUpdate.merge_operations', index=17,
+ number=18, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='estimate_cow_size', full_name='chromeos_update_engine.PartitionUpdate.estimate_cow_size', index=18,
+ number=19, type=4, cpp_type=4, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
@@ -525,8 +603,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=926,
- serialized_end=1670,
+ serialized_start=1136,
+ serialized_end=1976,
)
@@ -570,8 +648,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=1672,
- serialized_end=1748,
+ serialized_start=1978,
+ serialized_end=2054,
)
@@ -608,8 +686,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=1750,
- serialized_end=1865,
+ serialized_start=2056,
+ serialized_end=2171,
)
@@ -744,8 +822,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=1868,
- serialized_end=2733,
+ serialized_start=2174,
+ serialized_end=3039,
)
_SIGNATURES_SIGNATURE.containing_type = _SIGNATURES
@@ -754,6 +832,10 @@
_INSTALLOPERATION.fields_by_name['src_extents'].message_type = _EXTENT
_INSTALLOPERATION.fields_by_name['dst_extents'].message_type = _EXTENT
_INSTALLOPERATION_TYPE.containing_type = _INSTALLOPERATION
+_COWMERGEOPERATION.fields_by_name['type'].enum_type = _COWMERGEOPERATION_TYPE
+_COWMERGEOPERATION.fields_by_name['src_extent'].message_type = _EXTENT
+_COWMERGEOPERATION.fields_by_name['dst_extent'].message_type = _EXTENT
+_COWMERGEOPERATION_TYPE.containing_type = _COWMERGEOPERATION
_PARTITIONUPDATE.fields_by_name['new_partition_signature'].message_type = _SIGNATURES_SIGNATURE
_PARTITIONUPDATE.fields_by_name['old_partition_info'].message_type = _PARTITIONINFO
_PARTITIONUPDATE.fields_by_name['new_partition_info'].message_type = _PARTITIONINFO
@@ -762,6 +844,7 @@
_PARTITIONUPDATE.fields_by_name['hash_tree_extent'].message_type = _EXTENT
_PARTITIONUPDATE.fields_by_name['fec_data_extent'].message_type = _EXTENT
_PARTITIONUPDATE.fields_by_name['fec_extent'].message_type = _EXTENT
+_PARTITIONUPDATE.fields_by_name['merge_operations'].message_type = _COWMERGEOPERATION
_DYNAMICPARTITIONMETADATA.fields_by_name['groups'].message_type = _DYNAMICPARTITIONGROUP
_DELTAARCHIVEMANIFEST.fields_by_name['install_operations'].message_type = _INSTALLOPERATION
_DELTAARCHIVEMANIFEST.fields_by_name['kernel_install_operations'].message_type = _INSTALLOPERATION
@@ -778,6 +861,7 @@
DESCRIPTOR.message_types_by_name['PartitionInfo'] = _PARTITIONINFO
DESCRIPTOR.message_types_by_name['ImageInfo'] = _IMAGEINFO
DESCRIPTOR.message_types_by_name['InstallOperation'] = _INSTALLOPERATION
+DESCRIPTOR.message_types_by_name['CowMergeOperation'] = _COWMERGEOPERATION
DESCRIPTOR.message_types_by_name['PartitionUpdate'] = _PARTITIONUPDATE
DESCRIPTOR.message_types_by_name['DynamicPartitionGroup'] = _DYNAMICPARTITIONGROUP
DESCRIPTOR.message_types_by_name['DynamicPartitionMetadata'] = _DYNAMICPARTITIONMETADATA
@@ -827,6 +911,13 @@
})
_sym_db.RegisterMessage(InstallOperation)
+CowMergeOperation = _reflection.GeneratedProtocolMessageType('CowMergeOperation', (_message.Message,), {
+ 'DESCRIPTOR' : _COWMERGEOPERATION,
+ '__module__' : 'update_metadata_pb2'
+ # @@protoc_insertion_point(class_scope:chromeos_update_engine.CowMergeOperation)
+ })
+_sym_db.RegisterMessage(CowMergeOperation)
+
PartitionUpdate = _reflection.GeneratedProtocolMessageType('PartitionUpdate', (_message.Message,), {
'DESCRIPTOR' : _PARTITIONUPDATE,
'__module__' : 'update_metadata_pb2'
diff --git a/stable/Android.bp b/stable/Android.bp
index 337ae96..a415ac5 100644
--- a/stable/Android.bp
+++ b/stable/Android.bp
@@ -18,6 +18,13 @@
// ========================================================
aidl_interface {
name: "libupdate_engine_stable",
+
+ // This header library is available to core and product modules.
+ // Right now, vendor_available is the only way to specify this.
+ // vendor modules should NOT use this library.
+ // TODO(b/150902910): change this to product_available.
+ vendor_available: true,
+
srcs: [
"android/os/IUpdateEngineStable.aidl",
"android/os/IUpdateEngineStableCallback.aidl",
@@ -40,10 +47,10 @@
// update_engine_stable_client (type: executable)
// ========================================================
-// update_engine console client installed to APEXes
+// update_engine console client installed to APEXes.
cc_binary {
name: "update_engine_stable_client",
-
+ product_specific: true,
header_libs: [
"libupdate_engine_headers",
],
diff --git a/stable/update_engine_stable_client.cc b/stable/update_engine_stable_client.cc
index da203c4..17f66b6 100644
--- a/stable/update_engine_stable_client.cc
+++ b/stable/update_engine_stable_client.cc
@@ -32,7 +32,6 @@
#include <android/binder_ibinder.h>
#include <common/error_code.h>
#include <gflags/gflags.h>
-#include <utils/StrongPointer.h>
namespace chromeos_update_engine::internal {
diff --git a/test_http_server.cc b/test_http_server.cc
index 1c3a2e0..a2f1e05 100644
--- a/test_http_server.cc
+++ b/test_http_server.cc
@@ -190,7 +190,7 @@
string("HTTP/1.1 ") + Itoa(return_code) + " " +
GetHttpResponseDescription(return_code) +
EOL "Content-Type: application/octet-stream" EOL
- "Connection: close" EOL);
+ "Connection: close" EOL);
if (ret < 0)
return -1;
written += ret;
@@ -409,7 +409,6 @@
return;
WriteString(fd, "Connection: close" EOL);
WriteString(fd, "Location: " + url + EOL);
-
}
// Generate a page not found error response with actual text payload. Return
diff --git a/update_boot_flags_action_unittest.cc b/update_boot_flags_action_unittest.cc
index 1b2bfa5..26cbe90 100644
--- a/update_boot_flags_action_unittest.cc
+++ b/update_boot_flags_action_unittest.cc
@@ -22,18 +22,17 @@
#include <base/bind.h>
#include <gtest/gtest.h>
-#include "update_engine/fake_system_state.h"
+#include "update_engine/common/fake_boot_control.h"
namespace chromeos_update_engine {
class UpdateBootFlagsActionTest : public ::testing::Test {
- public:
- FakeSystemState fake_system_state_;
+ protected:
+ FakeBootControl boot_control_;
};
TEST_F(UpdateBootFlagsActionTest, SimpleTest) {
- auto boot_control = fake_system_state_.fake_boot_control();
- auto action = std::make_unique<UpdateBootFlagsAction>(boot_control);
+ auto action = std::make_unique<UpdateBootFlagsAction>(&boot_control_);
ActionProcessor processor;
processor.EnqueueAction(std::move(action));
@@ -49,9 +48,8 @@
UpdateBootFlagsAction::updated_boot_flags_ = false;
UpdateBootFlagsAction::is_running_ = false;
- auto boot_control = fake_system_state_.fake_boot_control();
- auto action1 = std::make_unique<UpdateBootFlagsAction>(boot_control);
- auto action2 = std::make_unique<UpdateBootFlagsAction>(boot_control);
+ auto action1 = std::make_unique<UpdateBootFlagsAction>(&boot_control_);
+ auto action2 = std::make_unique<UpdateBootFlagsAction>(&boot_control_);
ActionProcessor processor1, processor2;
processor1.EnqueueAction(std::move(action1));
processor2.EnqueueAction(std::move(action2));
diff --git a/update_engine.conf.chromeos b/update_engine.conf.chromeos
new file mode 100644
index 0000000..af213ad
--- /dev/null
+++ b/update_engine.conf.chromeos
@@ -0,0 +1,2 @@
+PAYLOAD_MAJOR_VERSION=2
+PAYLOAD_MINOR_VERSION=6
diff --git a/update_manager/android_things_policy.cc b/update_manager/android_things_policy.cc
index a76ea48..c4fa75a 100644
--- a/update_manager/android_things_policy.cc
+++ b/update_manager/android_things_policy.cc
@@ -58,10 +58,12 @@
// Set the default return values.
result->updates_enabled = true;
result->target_channel.clear();
+ result->lts_tag.clear();
result->target_version_prefix.clear();
result->rollback_allowed = false;
result->rollback_data_save_requested = false;
result->rollback_allowed_milestones = -1;
+ result->rollback_on_channel_downgrade = false;
result->interactive = false;
// Build a list of policies to consult. Note that each policy may modify the
diff --git a/update_manager/boxed_value.cc b/update_manager/boxed_value.cc
index b031dfc..907eb95 100644
--- a/update_manager/boxed_value.cc
+++ b/update_manager/boxed_value.cc
@@ -23,9 +23,10 @@
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
+#include <base/version.h>
+#include "update_engine/common/connection_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_utils.h"
#include "update_engine/update_manager/rollback_prefs.h"
#include "update_engine/update_manager/shill_provider.h"
#include "update_engine/update_manager/updater_provider.h"
@@ -234,4 +235,30 @@
return retval;
}
+template <>
+string BoxedValue::ValuePrinter<ChannelDowngradeBehavior>(const void* value) {
+ const ChannelDowngradeBehavior* val =
+ reinterpret_cast<const ChannelDowngradeBehavior*>(value);
+ switch (*val) {
+ case ChannelDowngradeBehavior::kUnspecified:
+ return "Unspecified";
+ case ChannelDowngradeBehavior::kWaitForVersionToCatchUp:
+ return "Wait for the target channel to catch up";
+ case ChannelDowngradeBehavior::kRollback:
+ return "Roll back and powerwash on channel downgrade";
+ case ChannelDowngradeBehavior::kAllowUserToConfigure:
+ return "User decides on channel downgrade behavior";
+ }
+ NOTREACHED();
+ return "Unknown";
+}
+
+template <>
+string BoxedValue::ValuePrinter<base::Version>(const void* value) {
+ const base::Version* val = reinterpret_cast<const base::Version*>(value);
+ if (val->IsValid())
+ return val->GetString();
+ return "Unknown";
+}
+
} // namespace chromeos_update_manager
diff --git a/update_manager/chromeos_policy.cc b/update_manager/chromeos_policy.cc
index be5f914..4c651b7 100644
--- a/update_manager/chromeos_policy.cc
+++ b/update_manager/chromeos_policy.cc
@@ -156,6 +156,7 @@
case ErrorCode::kUnresolvedHostRecovered:
case ErrorCode::kNotEnoughSpace:
case ErrorCode::kDeviceCorrupted:
+ case ErrorCode::kPackageExcludedFromUpdate:
LOG(INFO) << "Not changing URL index or failure count due to error "
<< chromeos_update_engine::utils::ErrorCodeToString(err_code)
<< " (" << static_cast<int>(err_code) << ")";
@@ -216,9 +217,11 @@
// Set the default return values.
result->updates_enabled = true;
result->target_channel.clear();
+ result->lts_tag.clear();
result->target_version_prefix.clear();
result->rollback_allowed = false;
result->rollback_allowed_milestones = -1;
+ result->rollback_on_channel_downgrade = false;
result->interactive = false;
EnoughSlotsAbUpdatesPolicyImpl enough_slots_ab_updates_policy;
diff --git a/update_manager/chromeos_policy_unittest.cc b/update_manager/chromeos_policy_unittest.cc
index 414ac0d..996db2b 100644
--- a/update_manager/chromeos_policy_unittest.cc
+++ b/update_manager/chromeos_policy_unittest.cc
@@ -262,6 +262,8 @@
new bool(false));
fake_state_.device_policy_provider()->var_release_channel()->reset(
new string("foo-channel"));
+ fake_state_.device_policy_provider()->var_release_lts_tag()->reset(
+ new string("foo-hint"));
UpdateCheckParams result;
ExpectPolicyStatus(
@@ -270,6 +272,7 @@
EXPECT_EQ("1.2", result.target_version_prefix);
EXPECT_EQ(5, result.rollback_allowed_milestones);
EXPECT_EQ("foo-channel", result.target_channel);
+ EXPECT_EQ("foo-hint", result.lts_tag);
EXPECT_FALSE(result.interactive);
}
@@ -338,6 +341,26 @@
EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
}
+TEST_F(UmChromeOSPolicyTest, TestUpdateCheckIntervalTimeout) {
+ fake_state_.updater_provider()
+ ->var_test_update_check_interval_timeout()
+ ->reset(new int64_t(10));
+ fake_state_.system_provider()->var_is_official_build()->reset(
+ new bool(false));
+
+ // The first time, update should not be allowed.
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
+
+ // After moving the time forward more than the update check interval, it
+ // should now allow for update.
+ fake_clock_.SetWallclockTime(fake_clock_.GetWallclockTime() +
+ TimeDelta::FromSeconds(11));
+ ExpectPolicyStatus(
+ EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
+}
+
TEST_F(UmChromeOSPolicyTest,
UpdateCheckAllowedUpdatesDisabledWhenNotEnoughSlotsAbUpdates) {
// UpdateCheckAllowed should return false (kSucceeded) if the image booted
diff --git a/update_manager/default_policy.cc b/update_manager/default_policy.cc
index 81ab795..7ca414b 100644
--- a/update_manager/default_policy.cc
+++ b/update_manager/default_policy.cc
@@ -40,9 +40,11 @@
UpdateCheckParams* result) const {
result->updates_enabled = true;
result->target_channel.clear();
+ result->lts_tag.clear();
result->target_version_prefix.clear();
result->rollback_allowed = false;
result->rollback_allowed_milestones = -1; // No version rolls should happen.
+ result->rollback_on_channel_downgrade = false;
result->interactive = false;
// Ensure that the minimum interval is set. If there's no clock, this defaults
diff --git a/update_manager/device_policy_provider.h b/update_manager/device_policy_provider.h
index b68fe96..a59f2a3 100644
--- a/update_manager/device_policy_provider.h
+++ b/update_manager/device_policy_provider.h
@@ -21,6 +21,7 @@
#include <string>
#include <base/time/time.h>
+#include <base/version.h>
#include <policy/libpolicy.h>
#include "update_engine/update_manager/provider.h"
@@ -44,6 +45,8 @@
virtual Variable<bool>* var_release_channel_delegated() = 0;
+ virtual Variable<std::string>* var_release_lts_tag() = 0;
+
virtual Variable<bool>* var_update_disabled() = 0;
virtual Variable<std::string>* var_target_version_prefix() = 0;
@@ -85,6 +88,15 @@
virtual Variable<WeeklyTimeIntervalVector>*
var_disallowed_time_intervals() = 0;
+ // Variable that determins whether we should powerwash and rollback on channel
+ // downgrade for enrolled devices.
+ virtual Variable<ChannelDowngradeBehavior>*
+ var_channel_downgrade_behavior() = 0;
+
+ // Variable that contains Chrome OS minimum required version. It contains a
+ // Chrome OS version number.
+ virtual Variable<base::Version>* var_device_minimum_version() = 0;
+
protected:
DevicePolicyProvider() {}
diff --git a/update_manager/enterprise_device_policy_impl.cc b/update_manager/enterprise_device_policy_impl.cc
index dea38ba..ce8150e 100644
--- a/update_manager/enterprise_device_policy_impl.cc
+++ b/update_manager/enterprise_device_policy_impl.cc
@@ -62,13 +62,37 @@
ec->GetValue(system_provider->var_kiosk_required_platform_version());
if (!kiosk_required_platform_version_p) {
LOG(INFO) << "Kiosk app required platform version is not fetched, "
- "blocking update checks";
+ "blocking update checks.";
return EvalStatus::kAskMeAgainLater;
+ } else if (kiosk_required_platform_version_p->empty()) {
+ // The platform version could not be fetched several times. Update
+ // based on |DeviceMinimumVersion| instead (crbug.com/1048931).
+ const base::Version* device_minimum_version_p =
+ ec->GetValue(dp_provider->var_device_minimum_version());
+ const base::Version* current_version_p(
+ ec->GetValue(system_provider->var_chromeos_version()));
+ if (device_minimum_version_p && device_minimum_version_p->IsValid() &&
+ current_version_p && current_version_p->IsValid() &&
+ *current_version_p > *device_minimum_version_p) {
+ // Do not update if the current version is newer than the minimum
+ // version.
+ LOG(INFO) << "Reading kiosk app required platform version failed "
+ "repeatedly but current version is newer than "
+ "DeviceMinimumVersion. Blocking update checks. "
+ "Current version: "
+ << *current_version_p
+ << " DeviceMinimumVersion: " << *device_minimum_version_p;
+ return EvalStatus::kAskMeAgainLater;
+ }
+ LOG(WARNING) << "Reading kiosk app required platform version failed "
+ "repeatedly. Attempting an update without it now.";
+ // An empty string for |target_version_prefix| allows arbitrary updates.
+ result->target_version_prefix = "";
+ } else {
+ result->target_version_prefix = *kiosk_required_platform_version_p;
+ LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
+ << "target version is " << result->target_version_prefix;
}
-
- result->target_version_prefix = *kiosk_required_platform_version_p;
- LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
- << "target version is " << result->target_version_prefix;
// TODO(hunyadym): Add support for allowing rollback using the manifest
// (if policy doesn't specify otherwise).
} else {
@@ -117,14 +141,29 @@
if (rollback_allowed_milestones_p)
result->rollback_allowed_milestones = *rollback_allowed_milestones_p;
- // Determine whether a target channel is dictated by policy.
+ // Determine whether a target channel is dictated by policy and whether we
+ // should rollback in case that channel is more stable.
const bool* release_channel_delegated_p =
ec->GetValue(dp_provider->var_release_channel_delegated());
if (release_channel_delegated_p && !(*release_channel_delegated_p)) {
const string* release_channel_p =
ec->GetValue(dp_provider->var_release_channel());
- if (release_channel_p)
+ if (release_channel_p) {
result->target_channel = *release_channel_p;
+ const ChannelDowngradeBehavior* channel_downgrade_behavior_p =
+ ec->GetValue(dp_provider->var_channel_downgrade_behavior());
+ if (channel_downgrade_behavior_p &&
+ *channel_downgrade_behavior_p ==
+ ChannelDowngradeBehavior::kRollback) {
+ result->rollback_on_channel_downgrade = true;
+ }
+ }
+ }
+
+ const string* release_lts_tag_p =
+ ec->GetValue(dp_provider->var_release_lts_tag());
+ if (release_lts_tag_p) {
+ result->lts_tag = *release_lts_tag_p;
}
}
return EvalStatus::kContinue;
diff --git a/update_manager/enterprise_device_policy_impl_unittest.cc b/update_manager/enterprise_device_policy_impl_unittest.cc
new file mode 100644
index 0000000..f27715e
--- /dev/null
+++ b/update_manager/enterprise_device_policy_impl_unittest.cc
@@ -0,0 +1,161 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "update_engine/update_manager/enterprise_device_policy_impl.h"
+
+#include <memory>
+
+#include "update_engine/update_manager/policy_test_utils.h"
+
+namespace chromeos_update_manager {
+
+class UmEnterpriseDevicePolicyImplTest : public UmPolicyTestBase {
+ protected:
+ UmEnterpriseDevicePolicyImplTest() : UmPolicyTestBase() {
+ policy_ = std::make_unique<EnterpriseDevicePolicyImpl>();
+ }
+
+ void SetUpDefaultState() override {
+ UmPolicyTestBase::SetUpDefaultState();
+
+ fake_state_.device_policy_provider()->var_device_policy_is_loaded()->reset(
+ new bool(true));
+ }
+};
+
+TEST_F(UmEnterpriseDevicePolicyImplTest, KioskAppVersionSet) {
+ fake_state_.device_policy_provider()->var_update_disabled()->reset(
+ new bool(true));
+ fake_state_.device_policy_provider()
+ ->var_allow_kiosk_app_control_chrome_version()
+ ->reset(new bool(true));
+
+ fake_state_.system_provider()->var_kiosk_required_platform_version()->reset(
+ new std::string("1234.5.6"));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+ EXPECT_EQ(result.target_version_prefix, "1234.5.6");
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest, KioskAppVersionUnreadableNoUpdate) {
+ fake_state_.device_policy_provider()->var_update_disabled()->reset(
+ new bool(true));
+ fake_state_.device_policy_provider()
+ ->var_allow_kiosk_app_control_chrome_version()
+ ->reset(new bool(true));
+
+ fake_state_.system_provider()->var_kiosk_required_platform_version()->reset(
+ nullptr);
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest, KioskAppVersionUnreadableUpdate) {
+ fake_state_.device_policy_provider()->var_update_disabled()->reset(
+ new bool(true));
+ fake_state_.device_policy_provider()
+ ->var_allow_kiosk_app_control_chrome_version()
+ ->reset(new bool(true));
+
+ // The real variable returns an empty string after several unsuccessful
+ // reading attempts. Fake this by setting it directly to empty string.
+ fake_state_.system_provider()->var_kiosk_required_platform_version()->reset(
+ new std::string(""));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+ EXPECT_EQ(result.target_version_prefix, "");
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest,
+ KioskAppVersionUnreadableUpdateWithMinVersion) {
+ fake_state_.device_policy_provider()->var_update_disabled()->reset(
+ new bool(true));
+ fake_state_.device_policy_provider()
+ ->var_allow_kiosk_app_control_chrome_version()
+ ->reset(new bool(true));
+
+ // The real variable returns an empty string after several unsuccessful
+ // reading attempts. Fake this by setting it directly to empty string.
+ fake_state_.system_provider()->var_kiosk_required_platform_version()->reset(
+ new std::string(""));
+ // Update if the minimum version is above the current OS version.
+ fake_state_.device_policy_provider()->var_device_minimum_version()->reset(
+ new base::Version("2.0.0"));
+ fake_state_.system_provider()->var_chromeos_version()->reset(
+ new base::Version("1.0.0"));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+ EXPECT_EQ(result.target_version_prefix, "");
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest,
+ KioskAppVersionUnreadableNoUpdateWithMinVersion) {
+ fake_state_.device_policy_provider()->var_update_disabled()->reset(
+ new bool(true));
+ fake_state_.device_policy_provider()
+ ->var_allow_kiosk_app_control_chrome_version()
+ ->reset(new bool(true));
+
+ // The real variable returns an empty string after several unsuccessful
+ // reading attempts. Fake this by setting it directly to empty string.
+ fake_state_.system_provider()->var_kiosk_required_platform_version()->reset(
+ new std::string(""));
+ // Block update if the minimum version is below the current OS version.
+ fake_state_.device_policy_provider()->var_device_minimum_version()->reset(
+ new base::Version("1.0.0"));
+ fake_state_.system_provider()->var_chromeos_version()->reset(
+ new base::Version("2.0.0"));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest, ChannelDowngradeBehaviorNoRollback) {
+ fake_state_.device_policy_provider()->var_release_channel_delegated()->reset(
+ new bool(false));
+ fake_state_.device_policy_provider()->var_release_channel()->reset(
+ new std::string("stable-channel"));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+ EXPECT_FALSE(result.rollback_on_channel_downgrade);
+}
+
+TEST_F(UmEnterpriseDevicePolicyImplTest, ChannelDowngradeBehaviorRollback) {
+ fake_state_.device_policy_provider()->var_release_channel_delegated()->reset(
+ new bool(false));
+ fake_state_.device_policy_provider()->var_release_channel()->reset(
+ new std::string("stable-channel"));
+ fake_state_.device_policy_provider()->var_channel_downgrade_behavior()->reset(
+ new ChannelDowngradeBehavior(ChannelDowngradeBehavior::kRollback));
+
+ UpdateCheckParams result;
+ ExpectPolicyStatus(
+ EvalStatus::kContinue, &Policy::UpdateCheckAllowed, &result);
+ EXPECT_TRUE(result.rollback_on_channel_downgrade);
+}
+
+} // namespace chromeos_update_manager
diff --git a/update_manager/evaluation_context-inl.h b/update_manager/evaluation_context-inl.h
index 59d85da..82861fa 100644
--- a/update_manager/evaluation_context-inl.h
+++ b/update_manager/evaluation_context-inl.h
@@ -39,7 +39,7 @@
std::string errmsg;
const T* result =
var->GetValue(RemainingTime(evaluation_monotonic_deadline_), &errmsg);
- if (result == nullptr) {
+ if (result == nullptr && !var->IsMissingOk()) {
LOG(WARNING) << "Error reading Variable " << var->GetName() << ": \""
<< errmsg << "\"";
}
diff --git a/update_manager/fake_device_policy_provider.h b/update_manager/fake_device_policy_provider.h
index 86bdef1..55d66b3 100644
--- a/update_manager/fake_device_policy_provider.h
+++ b/update_manager/fake_device_policy_provider.h
@@ -42,6 +42,10 @@
return &var_release_channel_delegated_;
}
+ FakeVariable<std::string>* var_release_lts_tag() override {
+ return &var_release_lts_tag_;
+ }
+
FakeVariable<bool>* var_update_disabled() override {
return &var_update_disabled_;
}
@@ -91,6 +95,15 @@
return &var_disallowed_time_intervals_;
}
+ FakeVariable<ChannelDowngradeBehavior>* var_channel_downgrade_behavior()
+ override {
+ return &var_channel_downgrade_behavior_;
+ }
+
+ FakeVariable<base::Version>* var_device_minimum_version() override {
+ return &var_device_minimum_version_;
+ }
+
private:
FakeVariable<bool> var_device_policy_is_loaded_{"policy_is_loaded",
kVariableModePoll};
@@ -98,6 +111,8 @@
kVariableModePoll};
FakeVariable<bool> var_release_channel_delegated_{"release_channel_delegated",
kVariableModePoll};
+ FakeVariable<std::string> var_release_lts_tag_{"release_lts_tag",
+ kVariableModePoll};
FakeVariable<bool> var_update_disabled_{"update_disabled", kVariableModePoll};
FakeVariable<std::string> var_target_version_prefix_{"target_version_prefix",
kVariableModePoll};
@@ -120,6 +135,10 @@
"auto_launched_kiosk_app_id", kVariableModePoll};
FakeVariable<WeeklyTimeIntervalVector> var_disallowed_time_intervals_{
"disallowed_time_intervals", kVariableModePoll};
+ FakeVariable<ChannelDowngradeBehavior> var_channel_downgrade_behavior_{
+ "channel_downgrade_behavior", kVariableModePoll};
+ FakeVariable<base::Version> var_device_minimum_version_{
+ "device_minimum_version", kVariableModePoll};
DISALLOW_COPY_AND_ASSIGN(FakeDevicePolicyProvider);
};
diff --git a/update_manager/fake_system_provider.h b/update_manager/fake_system_provider.h
index f54951b..b320c01 100644
--- a/update_manager/fake_system_provider.h
+++ b/update_manager/fake_system_provider.h
@@ -50,6 +50,10 @@
return &var_kiosk_required_platform_version_;
}
+ FakeVariable<base::Version>* var_chromeos_version() override {
+ return &var_version_;
+ }
+
private:
FakeVariable<bool> var_is_normal_boot_mode_{"is_normal_boot_mode",
kVariableModeConst};
@@ -60,6 +64,8 @@
FakeVariable<unsigned int> var_num_slots_{"num_slots", kVariableModePoll};
FakeVariable<std::string> var_kiosk_required_platform_version_{
"kiosk_required_platform_version", kVariableModePoll};
+ FakeVariable<base::Version> var_version_{"chromeos_version",
+ kVariableModePoll};
DISALLOW_COPY_AND_ASSIGN(FakeSystemProvider);
};
diff --git a/update_manager/fake_updater_provider.h b/update_manager/fake_updater_provider.h
index 7295765..d967f42 100644
--- a/update_manager/fake_updater_provider.h
+++ b/update_manager/fake_updater_provider.h
@@ -83,6 +83,10 @@
return &var_update_restrictions_;
}
+ FakeVariable<int64_t>* var_test_update_check_interval_timeout() override {
+ return &var_test_update_check_interval_timeout_;
+ }
+
private:
FakeVariable<base::Time> var_updater_started_time_{"updater_started_time",
kVariableModePoll};
@@ -108,6 +112,8 @@
"forced_update_requested", kVariableModeAsync};
FakeVariable<UpdateRestrictions> var_update_restrictions_{
"update_restrictions", kVariableModePoll};
+ FakeVariable<int64_t> var_test_update_check_interval_timeout_{
+ "test_update_check_interval_timeout", kVariableModePoll};
DISALLOW_COPY_AND_ASSIGN(FakeUpdaterProvider);
};
diff --git a/update_manager/next_update_check_policy_impl.cc b/update_manager/next_update_check_policy_impl.cc
index 6f9748e..0a78718 100644
--- a/update_manager/next_update_check_policy_impl.cc
+++ b/update_manager/next_update_check_policy_impl.cc
@@ -72,6 +72,11 @@
ec->GetValue(updater_provider->var_updater_started_time());
POLICY_CHECK_VALUE_AND_FAIL(updater_started_time, error);
+ // This value is used for testing only and it will get deleted after the first
+ // time it is read.
+ const int64_t* interval_timeout =
+ ec->GetValue(updater_provider->var_test_update_check_interval_timeout());
+
const Time* last_checked_time =
ec->GetValue(updater_provider->var_last_checked_time());
@@ -83,13 +88,21 @@
// If this is the first attempt, compute and return an initial value.
if (last_checked_time == nullptr ||
*last_checked_time < *updater_started_time) {
- *next_update_check = *updater_started_time +
- FuzzedInterval(&prng,
- constants.timeout_initial_interval,
- constants.timeout_regular_fuzz);
+ TimeDelta time_diff =
+ interval_timeout == nullptr
+ ? FuzzedInterval(&prng,
+ constants.timeout_initial_interval,
+ constants.timeout_regular_fuzz)
+ : TimeDelta::FromSeconds(*interval_timeout);
+ *next_update_check = *updater_started_time + time_diff;
return EvalStatus::kSucceeded;
}
+ if (interval_timeout != nullptr) {
+ *next_update_check =
+ *last_checked_time + TimeDelta::FromSeconds(*interval_timeout);
+ return EvalStatus::kSucceeded;
+ }
// Check whether the server is enforcing a poll interval; if not, this value
// will be zero.
const unsigned int* server_dictated_poll_interval =
diff --git a/update_manager/official_build_check_policy_impl.cc b/update_manager/official_build_check_policy_impl.cc
index 096f7bf..e80c09f 100644
--- a/update_manager/official_build_check_policy_impl.cc
+++ b/update_manager/official_build_check_policy_impl.cc
@@ -27,8 +27,16 @@
const bool* is_official_build_p =
ec->GetValue(state->system_provider()->var_is_official_build());
if (is_official_build_p != nullptr && !(*is_official_build_p)) {
- LOG(INFO) << "Unofficial build, blocking periodic update checks.";
- return EvalStatus::kAskMeAgainLater;
+ const int64_t* interval_timeout_p = ec->GetValue(
+ state->updater_provider()->var_test_update_check_interval_timeout());
+ // The |interval_timeout | is used for testing only to test periodic
+ // update checks on unofficial images.
+ if (interval_timeout_p == nullptr) {
+ LOG(INFO) << "Unofficial build, blocking periodic update checks.";
+ return EvalStatus::kAskMeAgainLater;
+ }
+ LOG(INFO) << "Unofficial build, but periodic update check interval "
+ << "timeout is defined, so update is not blocked.";
}
return EvalStatus::kContinue;
}
diff --git a/update_manager/policy.h b/update_manager/policy.h
index 844a4d0..ad6994c 100644
--- a/update_manager/policy.h
+++ b/update_manager/policy.h
@@ -43,26 +43,32 @@
// Parameters of an update check. These parameters are determined by the
// UpdateCheckAllowed policy.
struct UpdateCheckParams {
- bool updates_enabled; // Whether the auto-updates are enabled on this build.
+ // Whether the auto-updates are enabled on this build.
+ bool updates_enabled{true};
// Attributes pertaining to the case where update checks are allowed.
//
// A target version prefix, if imposed by policy; otherwise, an empty string.
std::string target_version_prefix;
// Specifies whether rollback images are allowed by device policy.
- bool rollback_allowed;
+ bool rollback_allowed{false};
// Specifies if rollbacks should attempt to preserve some system state.
- bool rollback_data_save_requested;
+ bool rollback_data_save_requested{false};
// Specifies the number of Chrome milestones rollback should be allowed,
// starting from the stable version at any time. Value is -1 if unspecified
// (e.g. no device policy is available yet), in this case no version
// roll-forward should happen.
- int rollback_allowed_milestones;
+ int rollback_allowed_milestones{0};
+ // Whether a rollback with data save should be initiated on channel
+ // downgrade (e.g. beta to stable).
+ bool rollback_on_channel_downgrade{false};
// A target channel, if so imposed by policy; otherwise, an empty string.
std::string target_channel;
+ // Specifies if the channel hint, e.g. LTS (Long Term Support) updates.
+ std::string lts_tag;
// Whether the allowed update is interactive (user-initiated) or periodic.
- bool interactive;
+ bool interactive{false};
};
// Input arguments to UpdateCanStart.
diff --git a/update_manager/policy_utils.h b/update_manager/policy_utils.h
index 3204780..dc606f2 100644
--- a/update_manager/policy_utils.h
+++ b/update_manager/policy_utils.h
@@ -55,7 +55,6 @@
EvalStatus status =
(policy->*policy_method)(ec, state, error, result, args...);
if (status != EvalStatus::kContinue) {
- LOG(INFO) << "decision by " << policy->PolicyRequestName(policy_method);
return status;
}
}
diff --git a/update_manager/real_device_policy_provider.cc b/update_manager/real_device_policy_provider.cc
index 781e2ac..05091d9 100644
--- a/update_manager/real_device_policy_provider.cc
+++ b/update_manager/real_device_policy_provider.cc
@@ -25,8 +25,8 @@
#include <base/time/time.h>
#include <policy/device_policy.h>
+#include "update_engine/common/connection_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/connection_utils.h"
#include "update_engine/update_manager/generic_variables.h"
using base::TimeDelta;
@@ -104,9 +104,10 @@
}
template <typename T>
-void RealDevicePolicyProvider::UpdateVariable(AsyncCopyVariable<T>* var,
- bool (DevicePolicy::*getter)(T*)
- const) {
+void RealDevicePolicyProvider::UpdateVariable(
+ AsyncCopyVariable<T>* var,
+ // NOLINTNEXTLINE(readability/casting)
+ bool (DevicePolicy::*getter)(T*) const) {
T new_value;
if (policy_provider_->device_policy_is_loaded() &&
(policy_provider_->GetDevicePolicy().*getter)(&new_value)) {
@@ -208,6 +209,21 @@
return true;
}
+bool RealDevicePolicyProvider::ConvertChannelDowngradeBehavior(
+ ChannelDowngradeBehavior* channel_downgrade_behavior) const {
+ int behavior;
+ if (!policy_provider_->GetDevicePolicy().GetChannelDowngradeBehavior(
+ &behavior)) {
+ return false;
+ }
+ if (behavior < static_cast<int>(ChannelDowngradeBehavior::kFirstValue) ||
+ behavior > static_cast<int>(ChannelDowngradeBehavior::kLastValue)) {
+ return false;
+ }
+ *channel_downgrade_behavior = static_cast<ChannelDowngradeBehavior>(behavior);
+ return true;
+}
+
void RealDevicePolicyProvider::RefreshDevicePolicy() {
if (!policy_provider_->Reload()) {
LOG(INFO) << "No device policies/settings present.";
@@ -219,6 +235,7 @@
UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel);
UpdateVariable(&var_release_channel_delegated_,
&DevicePolicy::GetReleaseChannelDelegated);
+ UpdateVariable(&var_release_lts_tag_, &DevicePolicy::GetReleaseLtsTag);
UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled);
UpdateVariable(&var_target_version_prefix_,
&DevicePolicy::GetTargetVersionPrefix);
@@ -245,6 +262,10 @@
&DevicePolicy::GetAutoLaunchedKioskAppId);
UpdateVariable(&var_disallowed_time_intervals_,
&RealDevicePolicyProvider::ConvertDisallowedTimeIntervals);
+ UpdateVariable(&var_channel_downgrade_behavior_,
+ &RealDevicePolicyProvider::ConvertChannelDowngradeBehavior);
+ UpdateVariable(&var_device_minimum_version_,
+ &DevicePolicy::GetHighestDeviceMinimumVersion);
}
} // namespace chromeos_update_manager
diff --git a/update_manager/real_device_policy_provider.h b/update_manager/real_device_policy_provider.h
index 9da052d..ebda8fd 100644
--- a/update_manager/real_device_policy_provider.h
+++ b/update_manager/real_device_policy_provider.h
@@ -64,6 +64,10 @@
return &var_release_channel_delegated_;
}
+ Variable<std::string>* var_release_lts_tag() override {
+ return &var_release_lts_tag_;
+ }
+
Variable<bool>* var_update_disabled() override {
return &var_update_disabled_;
}
@@ -109,6 +113,15 @@
return &var_disallowed_time_intervals_;
}
+ Variable<ChannelDowngradeBehavior>* var_channel_downgrade_behavior()
+ override {
+ return &var_channel_downgrade_behavior_;
+ }
+
+ Variable<base::Version>* var_device_minimum_version() override {
+ return &var_device_minimum_version_;
+ }
+
private:
FRIEND_TEST(UmRealDevicePolicyProviderTest, RefreshScheduledTest);
FRIEND_TEST(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded);
@@ -170,6 +183,11 @@
// devices do not have an owner).
bool ConvertHasOwner(bool* has_owner) const;
+ // Wrapper for |DevicePolicy::GetChannelDowngradeBehavior| that converts the
+ // result to |ChannelDowngradeBehavior|.
+ bool ConvertChannelDowngradeBehavior(
+ ChannelDowngradeBehavior* channel_downgrade_behavior) const;
+
// Used for fetching information about the device policy.
policy::PolicyProvider* policy_provider_;
@@ -191,6 +209,7 @@
AsyncCopyVariable<std::string> var_release_channel_{"release_channel"};
AsyncCopyVariable<bool> var_release_channel_delegated_{
"release_channel_delegated"};
+ AsyncCopyVariable<std::string> var_release_lts_tag_{"release_lts_tag"};
AsyncCopyVariable<bool> var_update_disabled_{"update_disabled"};
AsyncCopyVariable<std::string> var_target_version_prefix_{
"target_version_prefix"};
@@ -211,6 +230,10 @@
"update_time_restrictions"};
AsyncCopyVariable<std::string> var_auto_launched_kiosk_app_id_{
"auto_launched_kiosk_app_id"};
+ AsyncCopyVariable<ChannelDowngradeBehavior> var_channel_downgrade_behavior_{
+ "channel_downgrade_behavior"};
+ AsyncCopyVariable<base::Version> var_device_minimum_version_{
+ "device_minimum_version"};
DISALLOW_COPY_AND_ASSIGN(RealDevicePolicyProvider);
};
diff --git a/update_manager/real_device_policy_provider_unittest.cc b/update_manager/real_device_policy_provider_unittest.cc
index 84debd1..32396d6 100644
--- a/update_manager/real_device_policy_provider_unittest.cc
+++ b/update_manager/real_device_policy_provider_unittest.cc
@@ -34,7 +34,7 @@
#include "update_engine/common/test_utils.h"
#if USE_DBUS
-#include "update_engine/dbus_test_utils.h"
+#include "update_engine/cros/dbus_test_utils.h"
#endif // USE_DBUS
#include "update_engine/update_manager/umtest_utils.h"
@@ -177,6 +177,7 @@
UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel());
UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel_delegated());
+ UmTestUtils::ExpectVariableNotSet(provider_->var_release_lts_tag());
UmTestUtils::ExpectVariableNotSet(provider_->var_update_disabled());
UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix());
UmTestUtils::ExpectVariableNotSet(
@@ -194,6 +195,8 @@
UmTestUtils::ExpectVariableNotSet(
provider_->var_auto_launched_kiosk_app_id());
UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals());
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
}
TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
@@ -376,4 +379,70 @@
provider_->var_disallowed_time_intervals());
}
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorConverted) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(static_cast<int>(
+ ChannelDowngradeBehavior::kRollback)),
+ Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableHasValue(
+ ChannelDowngradeBehavior::kRollback,
+ provider_->var_channel_downgrade_behavior());
+}
+
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooSmall) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
+}
+
+TEST_F(UmRealDevicePolicyProviderTest, ChannelDowngradeBehaviorTooLarge) {
+ SetUpExistentDevicePolicy();
+ EXPECT_CALL(mock_device_policy_, GetChannelDowngradeBehavior(_))
+#if USE_DBUS
+ .Times(2)
+#else
+ .Times(1)
+#endif // USE_DBUS
+ .WillRepeatedly(DoAll(SetArgPointee<0>(10), Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_channel_downgrade_behavior());
+}
+
+TEST_F(UmRealDevicePolicyProviderTest, DeviceMinimumVersionPolicySet) {
+ SetUpExistentDevicePolicy();
+
+ base::Version device_minimum_version("13315.60.12");
+
+ EXPECT_CALL(mock_device_policy_, GetHighestDeviceMinimumVersion(_))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<0>(device_minimum_version), Return(true)));
+ EXPECT_TRUE(provider_->Init());
+ loop_.RunOnce(false);
+
+ UmTestUtils::ExpectVariableHasValue(device_minimum_version,
+ provider_->var_device_minimum_version());
+}
+
} // namespace chromeos_update_manager
diff --git a/update_manager/real_shill_provider.h b/update_manager/real_shill_provider.h
index ec5c570..baa2cdc 100644
--- a/update_manager/real_shill_provider.h
+++ b/update_manager/real_shill_provider.h
@@ -28,7 +28,7 @@
#include <dbus/object_path.h>
#include "update_engine/common/clock_interface.h"
-#include "update_engine/shill_proxy_interface.h"
+#include "update_engine/cros/shill_proxy_interface.h"
#include "update_engine/update_manager/generic_variables.h"
#include "update_engine/update_manager/shill_provider.h"
diff --git a/update_manager/real_shill_provider_unittest.cc b/update_manager/real_shill_provider_unittest.cc
index 505f2f8..682c233 100644
--- a/update_manager/real_shill_provider_unittest.cc
+++ b/update_manager/real_shill_provider_unittest.cc
@@ -29,8 +29,8 @@
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/test_utils.h"
-#include "update_engine/dbus_test_utils.h"
-#include "update_engine/fake_shill_proxy.h"
+#include "update_engine/cros/dbus_test_utils.h"
+#include "update_engine/cros/fake_shill_proxy.h"
#include "update_engine/update_manager/umtest_utils.h"
using base::Time;
diff --git a/update_manager/real_system_provider.cc b/update_manager/real_system_provider.cc
index a900071..4e88b07 100644
--- a/update_manager/real_system_provider.cc
+++ b/update_manager/real_system_provider.cc
@@ -24,7 +24,10 @@
#include <kiosk-app/dbus-proxies.h>
#endif // USE_CHROME_KIOSK_APP
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/utils.h"
+#include "update_engine/cros/omaha_request_params.h"
#include "update_engine/update_manager/generic_variables.h"
#include "update_engine/update_manager/variable.h"
@@ -64,9 +67,10 @@
std::unique_ptr<T> result(new T());
if (!func_.Run(result.get())) {
if (failed_attempts_ >= kRetryPollVariableMaxRetry) {
- // Give up on the retries, set back the desired polling interval and
- // return the default.
+ // Give up on the retries and set back the desired polling interval.
this->SetPollInterval(base_interval_);
+ // Release the result instead of returning a |nullptr| to indicate that
+ // the result could not be fetched.
return result.release();
}
this->SetPollInterval(
@@ -96,19 +100,19 @@
bool RealSystemProvider::Init() {
var_is_normal_boot_mode_.reset(new ConstCopyVariable<bool>(
- "is_normal_boot_mode", hardware_->IsNormalBootMode()));
+ "is_normal_boot_mode", system_state_->hardware()->IsNormalBootMode()));
var_is_official_build_.reset(new ConstCopyVariable<bool>(
- "is_official_build", hardware_->IsOfficialBuild()));
+ "is_official_build", system_state_->hardware()->IsOfficialBuild()));
var_is_oobe_complete_.reset(new CallCopyVariable<bool>(
"is_oobe_complete",
base::Bind(&chromeos_update_engine::HardwareInterface::IsOOBEComplete,
- base::Unretained(hardware_),
+ base::Unretained(system_state_->hardware()),
nullptr)));
var_num_slots_.reset(new ConstCopyVariable<unsigned int>(
- "num_slots", boot_control_->GetNumSlots()));
+ "num_slots", system_state_->boot_control()->GetNumSlots()));
var_kiosk_required_platform_version_.reset(new RetryPollVariable<string>(
"kiosk_required_platform_version",
@@ -116,6 +120,10 @@
base::Bind(&RealSystemProvider::GetKioskAppRequiredPlatformVersion,
base::Unretained(this))));
+ var_chromeos_version_.reset(new ConstCopyVariable<base::Version>(
+ "chromeos_version",
+ base::Version(system_state_->request_params()->app_version())));
+
return true;
}
diff --git a/update_manager/real_system_provider.h b/update_manager/real_system_provider.h
index 114c6ea..ffa1467 100644
--- a/update_manager/real_system_provider.h
+++ b/update_manager/real_system_provider.h
@@ -20,8 +20,9 @@
#include <memory>
#include <string>
-#include "update_engine/common/boot_control_interface.h"
-#include "update_engine/common/hardware_interface.h"
+#include <base/version.h>
+
+#include "update_engine/common/system_state.h"
#include "update_engine/update_manager/system_provider.h"
namespace org {
@@ -36,16 +37,13 @@
class RealSystemProvider : public SystemProvider {
public:
RealSystemProvider(
- chromeos_update_engine::HardwareInterface* hardware,
- chromeos_update_engine::BootControlInterface* boot_control,
+ chromeos_update_engine::SystemState* system_state,
org::chromium::KioskAppServiceInterfaceProxyInterface* kiosk_app_proxy)
- : hardware_(hardware),
#if USE_CHROME_KIOSK_APP
- boot_control_(boot_control),
- kiosk_app_proxy_(kiosk_app_proxy) {
+ : system_state_(system_state), kiosk_app_proxy_(kiosk_app_proxy) {
}
#else
- boot_control_(boot_control) {
+ system_state_(system_state) {
}
#endif // USE_CHROME_KIOSK_APP
@@ -72,6 +70,10 @@
return var_kiosk_required_platform_version_.get();
}
+ Variable<base::Version>* var_chromeos_version() override {
+ return var_chromeos_version_.get();
+ }
+
private:
bool GetKioskAppRequiredPlatformVersion(
std::string* required_platform_version);
@@ -81,9 +83,9 @@
std::unique_ptr<Variable<bool>> var_is_oobe_complete_;
std::unique_ptr<Variable<unsigned int>> var_num_slots_;
std::unique_ptr<Variable<std::string>> var_kiosk_required_platform_version_;
+ std::unique_ptr<Variable<base::Version>> var_chromeos_version_;
- chromeos_update_engine::HardwareInterface* const hardware_;
- chromeos_update_engine::BootControlInterface* const boot_control_;
+ chromeos_update_engine::SystemState* const system_state_;
#if USE_CHROME_KIOSK_APP
org::chromium::KioskAppServiceInterfaceProxyInterface* const kiosk_app_proxy_;
#endif // USE_CHROME_KIOSK_APP
diff --git a/update_manager/real_system_provider_unittest.cc b/update_manager/real_system_provider_unittest.cc
index f654f7a..8add690 100644
--- a/update_manager/real_system_provider_unittest.cc
+++ b/update_manager/real_system_provider_unittest.cc
@@ -24,6 +24,7 @@
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_hardware.h"
+#include "update_engine/cros/fake_system_state.h"
#include "update_engine/update_manager/umtest_utils.h"
#if USE_CHROME_KIOSK_APP
#include "kiosk-app/dbus-proxies.h"
@@ -54,17 +55,15 @@
.WillByDefault(
DoAll(SetArgPointee<0>(kRequiredPlatformVersion), Return(true)));
- provider_.reset(new RealSystemProvider(
- &fake_hardware_, &fake_boot_control_, kiosk_app_proxy_mock_.get()));
+ provider_.reset(new RealSystemProvider(&fake_system_state_,
+ kiosk_app_proxy_mock_.get()));
#else
- provider_.reset(
- new RealSystemProvider(&fake_hardware_, &fake_boot_control_, nullptr));
+ provider_.reset(new RealSystemProvider(&fake_system_state, nullptr));
#endif // USE_CHROME_KIOSK_APP
EXPECT_TRUE(provider_->Init());
}
- chromeos_update_engine::FakeHardware fake_hardware_;
- chromeos_update_engine::FakeBootControl fake_boot_control_;
+ chromeos_update_engine::FakeSystemState fake_system_state_;
unique_ptr<RealSystemProvider> provider_;
#if USE_CHROME_KIOSK_APP
@@ -77,18 +76,29 @@
EXPECT_NE(nullptr, provider_->var_is_official_build());
EXPECT_NE(nullptr, provider_->var_is_oobe_complete());
EXPECT_NE(nullptr, provider_->var_kiosk_required_platform_version());
+ EXPECT_NE(nullptr, provider_->var_chromeos_version());
}
TEST_F(UmRealSystemProviderTest, IsOOBECompleteTrue) {
- fake_hardware_.SetIsOOBEComplete(base::Time());
+ fake_system_state_.fake_hardware()->SetIsOOBEComplete(base::Time());
UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_oobe_complete());
}
TEST_F(UmRealSystemProviderTest, IsOOBECompleteFalse) {
- fake_hardware_.UnsetIsOOBEComplete();
+ fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_oobe_complete());
}
+TEST_F(UmRealSystemProviderTest, VersionFromRequestParams) {
+ fake_system_state_.request_params()->set_app_version("1.2.3");
+ // Call |Init| again to pick up the version.
+ EXPECT_TRUE(provider_->Init());
+
+ base::Version version("1.2.3");
+ UmTestUtils::ExpectVariableHasValue(version,
+ provider_->var_chromeos_version());
+}
+
#if USE_CHROME_KIOSK_APP
TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersion) {
UmTestUtils::ExpectVariableHasValue(
@@ -119,6 +129,22 @@
std::string(kRequiredPlatformVersion),
provider_->var_kiosk_required_platform_version());
}
+
+TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersionRepeatedFailure) {
+ // Simulate unreadable platform version. The variable should return a
+ // null pointer |kRetryPollVariableMaxRetry| times and then return an empty
+ // string to indicate that it gave up.
+ constexpr int kNumMethodCalls = 5;
+ EXPECT_CALL(*kiosk_app_proxy_mock_, GetRequiredPlatformVersion)
+ .Times(kNumMethodCalls + 1)
+ .WillRepeatedly(Return(false));
+ for (int i = 0; i < kNumMethodCalls; ++i) {
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_kiosk_required_platform_version());
+ }
+ UmTestUtils::ExpectVariableHasValue(
+ std::string(""), provider_->var_kiosk_required_platform_version());
+}
#else
TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersion) {
UmTestUtils::ExpectVariableHasValue(
diff --git a/update_manager/real_updater_provider.cc b/update_manager/real_updater_provider.cc
index 1f9af0d..e975b80 100644
--- a/update_manager/real_updater_provider.cc
+++ b/update_manager/real_updater_provider.cc
@@ -18,6 +18,7 @@
#include <inttypes.h>
+#include <algorithm>
#include <string>
#include <base/bind.h>
@@ -28,8 +29,8 @@
#include "update_engine/client_library/include/update_engine/update_status.h"
#include "update_engine/common/clock_interface.h"
#include "update_engine/common/prefs.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/update_attempter.h"
+#include "update_engine/cros/omaha_request_params.h"
+#include "update_engine/cros/update_attempter.h"
#include "update_engine/update_status_utils.h"
using base::StringPrintf;
@@ -441,6 +442,46 @@
DISALLOW_COPY_AND_ASSIGN(UpdateRestrictionsVariable);
};
+// A variable class for reading timeout interval prefs value.
+class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
+ public:
+ TestUpdateCheckIntervalTimeoutVariable(
+ const string& name, chromeos_update_engine::PrefsInterface* prefs)
+ : Variable<int64_t>(name, kVariableModePoll),
+ prefs_(prefs),
+ read_count_(0) {
+ SetMissingOk();
+ }
+ ~TestUpdateCheckIntervalTimeoutVariable() = default;
+
+ private:
+ const int64_t* GetValue(TimeDelta /* timeout */,
+ string* /* errmsg */) override {
+ auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
+ int64_t result;
+ if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
+ // This specific value is used for testing only. So it should not be kept
+ // around and should be deleted after a few reads.
+ if (++read_count_ > 5)
+ prefs_->Delete(key);
+
+ // Limit the timeout interval to 10 minutes so it is not abused if it is
+ // seen on official images.
+ return new int64_t(std::min(result, static_cast<int64_t>(10 * 60)));
+ }
+ return nullptr;
+ }
+
+ chromeos_update_engine::PrefsInterface* prefs_;
+
+ // Counts how many times this variable is read. This is used to delete the
+ // underlying file defining the variable after a certain number of reads in
+ // order to prevent any abuse of this variable.
+ int read_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestUpdateCheckIntervalTimeoutVariable);
+};
+
// RealUpdaterProvider methods.
RealUpdaterProvider::RealUpdaterProvider(SystemState* system_state)
@@ -474,6 +515,9 @@
"server_dictated_poll_interval", system_state_)),
var_forced_update_requested_(new ForcedUpdateRequestedVariable(
"forced_update_requested", system_state_)),
- var_update_restrictions_(new UpdateRestrictionsVariable(
- "update_restrictions", system_state_)) {}
+ var_update_restrictions_(
+ new UpdateRestrictionsVariable("update_restrictions", system_state_)),
+ var_test_update_check_interval_timeout_(
+ new TestUpdateCheckIntervalTimeoutVariable(
+ "test_update_check_interval_timeout", system_state_->prefs())) {}
} // namespace chromeos_update_manager
diff --git a/update_manager/real_updater_provider.h b/update_manager/real_updater_provider.h
index 1b46895..a32e7e9 100644
--- a/update_manager/real_updater_provider.h
+++ b/update_manager/real_updater_provider.h
@@ -20,7 +20,7 @@
#include <memory>
#include <string>
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/update_manager/generic_variables.h"
#include "update_engine/update_manager/updater_provider.h"
@@ -94,6 +94,10 @@
return var_update_restrictions_.get();
}
+ Variable<int64_t>* var_test_update_check_interval_timeout() override {
+ return var_test_update_check_interval_timeout_.get();
+ }
+
private:
// A pointer to the update engine's system state aggregator.
chromeos_update_engine::SystemState* system_state_;
@@ -114,6 +118,7 @@
std::unique_ptr<Variable<unsigned int>> var_server_dictated_poll_interval_;
std::unique_ptr<Variable<UpdateRequestStatus>> var_forced_update_requested_;
std::unique_ptr<Variable<UpdateRestrictions>> var_update_restrictions_;
+ std::unique_ptr<Variable<int64_t>> var_test_update_check_interval_timeout_;
DISALLOW_COPY_AND_ASSIGN(RealUpdaterProvider);
};
diff --git a/update_manager/real_updater_provider_unittest.cc b/update_manager/real_updater_provider_unittest.cc
index fb7a763..0dc56ac 100644
--- a/update_manager/real_updater_provider_unittest.cc
+++ b/update_manager/real_updater_provider_unittest.cc
@@ -25,9 +25,9 @@
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_prefs.h"
-#include "update_engine/fake_system_state.h"
-#include "update_engine/mock_update_attempter.h"
-#include "update_engine/omaha_request_params.h"
+#include "update_engine/cros/fake_system_state.h"
+#include "update_engine/cros/mock_update_attempter.h"
+#include "update_engine/cros/omaha_request_params.h"
#include "update_engine/update_manager/umtest_utils.h"
using base::Time;
@@ -327,7 +327,7 @@
TEST_F(UmRealUpdaterProviderTest, GetCurrChannelOkay) {
const string kChannelName("foo-channel");
OmahaRequestParams request_params(&fake_sys_state_);
- request_params.Init("", "", false);
+ request_params.Init("", "", {});
request_params.set_current_channel(kChannelName);
fake_sys_state_.set_request_params(&request_params);
UmTestUtils::ExpectVariableHasValue(kChannelName,
@@ -336,7 +336,7 @@
TEST_F(UmRealUpdaterProviderTest, GetCurrChannelFailEmpty) {
OmahaRequestParams request_params(&fake_sys_state_);
- request_params.Init("", "", false);
+ request_params.Init("", "", {});
request_params.set_current_channel("");
fake_sys_state_.set_request_params(&request_params);
UmTestUtils::ExpectVariableNotSet(provider_->var_curr_channel());
@@ -345,7 +345,7 @@
TEST_F(UmRealUpdaterProviderTest, GetNewChannelOkay) {
const string kChannelName("foo-channel");
OmahaRequestParams request_params(&fake_sys_state_);
- request_params.Init("", "", false);
+ request_params.Init("", "", {});
request_params.set_target_channel(kChannelName);
fake_sys_state_.set_request_params(&request_params);
UmTestUtils::ExpectVariableHasValue(kChannelName,
@@ -354,7 +354,7 @@
TEST_F(UmRealUpdaterProviderTest, GetNewChannelFailEmpty) {
OmahaRequestParams request_params(&fake_sys_state_);
- request_params.Init("", "", false);
+ request_params.Init("", "", {});
request_params.set_target_channel("");
fake_sys_state_.set_request_params(&request_params);
UmTestUtils::ExpectVariableNotSet(provider_->var_new_channel());
@@ -445,4 +445,29 @@
UmTestUtils::ExpectVariableHasValue(UpdateRestrictions::kNone,
provider_->var_update_restrictions());
}
+
+TEST_F(UmRealUpdaterProviderTest, TestUpdateCheckIntervalTimeout) {
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_test_update_check_interval_timeout());
+ fake_prefs_.SetInt64(
+ chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout, 1);
+ UmTestUtils::ExpectVariableHasValue(
+ static_cast<int64_t>(1),
+ provider_->var_test_update_check_interval_timeout());
+
+ // Make sure the value does not exceed a threshold of 10 minutes.
+ fake_prefs_.SetInt64(
+ chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout, 11 * 60);
+ // The next 5 reads should return valid values.
+ for (int i = 0; i < 5; ++i)
+ UmTestUtils::ExpectVariableHasValue(
+ static_cast<int64_t>(10 * 60),
+ provider_->var_test_update_check_interval_timeout());
+
+ // Just to make sure it is not cached anywhere and deleted. The variable is
+ // allowd to be read 6 times.
+ UmTestUtils::ExpectVariableNotSet(
+ provider_->var_test_update_check_interval_timeout());
+}
+
} // namespace chromeos_update_manager
diff --git a/update_manager/rollback_prefs.h b/update_manager/rollback_prefs.h
index 9567701..6cbc447 100644
--- a/update_manager/rollback_prefs.h
+++ b/update_manager/rollback_prefs.h
@@ -35,6 +35,19 @@
kMaxValue = 4
};
+// Whether the device should do rollback and powerwash on channel downgrade.
+// Matches chrome_device_policy.proto's
+// |AutoUpdateSettingsProto::ChannelDowngradeBehavior|.
+enum class ChannelDowngradeBehavior {
+ kUnspecified = 0,
+ kWaitForVersionToCatchUp = 1,
+ kRollback = 2,
+ kAllowUserToConfigure = 3,
+ // These values must be kept up to date.
+ kFirstValue = kUnspecified,
+ kLastValue = kAllowUserToConfigure
+};
+
} // namespace chromeos_update_manager
#endif // UPDATE_ENGINE_UPDATE_MANAGER_ROLLBACK_PREFS_H_
diff --git a/update_manager/shill_provider.h b/update_manager/shill_provider.h
index c7bb2e2..ebe7a3a 100644
--- a/update_manager/shill_provider.h
+++ b/update_manager/shill_provider.h
@@ -19,7 +19,7 @@
#include <base/time/time.h>
-#include "update_engine/connection_utils.h"
+#include "update_engine/common/connection_utils.h"
#include "update_engine/update_manager/provider.h"
#include "update_engine/update_manager/variable.h"
diff --git a/update_manager/staging_utils.cc b/update_manager/staging_utils.cc
index f4f685c..e8f07bb 100644
--- a/update_manager/staging_utils.cc
+++ b/update_manager/staging_utils.cc
@@ -27,7 +27,7 @@
#include "update_engine/common/constants.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
using base::TimeDelta;
using chromeos_update_engine::kPrefsWallClockStagingWaitPeriod;
diff --git a/update_manager/state_factory.cc b/update_manager/state_factory.cc
index 78cec6a..a95a5a8 100644
--- a/update_manager/state_factory.cc
+++ b/update_manager/state_factory.cc
@@ -25,7 +25,7 @@
#include "update_engine/common/clock_interface.h"
#if USE_DBUS
-#include "update_engine/dbus_connection.h"
+#include "update_engine/cros/dbus_connection.h"
#endif // USE_DBUS
#include "update_engine/update_manager/fake_shill_provider.h"
#include "update_engine/update_manager/real_config_provider.h"
@@ -36,7 +36,7 @@
#include "update_engine/update_manager/real_time_provider.h"
#include "update_engine/update_manager/real_updater_provider.h"
#if USE_SHILL
-#include "update_engine/shill_proxy.h"
+#include "update_engine/cros/shill_proxy.h"
#include "update_engine/update_manager/real_shill_provider.h"
#endif // USE_SHILL
@@ -69,8 +69,8 @@
unique_ptr<FakeShillProvider> shill_provider(new FakeShillProvider());
#endif // USE_SHILL
unique_ptr<RealRandomProvider> random_provider(new RealRandomProvider());
- unique_ptr<RealSystemProvider> system_provider(new RealSystemProvider(
- system_state->hardware(), system_state->boot_control(), kiosk_app_proxy));
+ unique_ptr<RealSystemProvider> system_provider(
+ new RealSystemProvider(system_state, kiosk_app_proxy));
unique_ptr<RealTimeProvider> time_provider(new RealTimeProvider(clock));
unique_ptr<RealUpdaterProvider> updater_provider(
diff --git a/update_manager/state_factory.h b/update_manager/state_factory.h
index 1c1c1d9..ac3bf6b 100644
--- a/update_manager/state_factory.h
+++ b/update_manager/state_factory.h
@@ -17,7 +17,7 @@
#ifndef UPDATE_ENGINE_UPDATE_MANAGER_STATE_FACTORY_H_
#define UPDATE_ENGINE_UPDATE_MANAGER_STATE_FACTORY_H_
-#include "update_engine/system_state.h"
+#include "update_engine/common/system_state.h"
#include "update_engine/update_manager/state.h"
namespace org {
diff --git a/update_manager/system_provider.h b/update_manager/system_provider.h
index 13e188b..8eb14e3 100644
--- a/update_manager/system_provider.h
+++ b/update_manager/system_provider.h
@@ -17,6 +17,10 @@
#ifndef UPDATE_ENGINE_UPDATE_MANAGER_SYSTEM_PROVIDER_H_
#define UPDATE_ENGINE_UPDATE_MANAGER_SYSTEM_PROVIDER_H_
+#include <string>
+
+#include <base/version.h>
+
#include "update_engine/update_manager/provider.h"
#include "update_engine/update_manager/variable.h"
@@ -46,6 +50,9 @@
// with zero delay kiosk app if any.
virtual Variable<std::string>* var_kiosk_required_platform_version() = 0;
+ // Chrome OS version number as provided by |ImagePropeties|.
+ virtual Variable<base::Version>* var_chromeos_version() = 0;
+
protected:
SystemProvider() {}
diff --git a/update_manager/update_manager-inl.h b/update_manager/update_manager-inl.h
index a1d172d..550642c 100644
--- a/update_manager/update_manager-inl.h
+++ b/update_manager/update_manager-inl.h
@@ -49,7 +49,6 @@
ec->ResetEvaluation();
const std::string policy_name = policy_->PolicyRequestName(policy_method);
- LOG(INFO) << policy_name << ": START";
// First try calling the actual policy.
std::string error;
@@ -71,8 +70,6 @@
}
}
- LOG(INFO) << policy_name << ": END";
-
return status;
}
diff --git a/update_manager/updater_provider.h b/update_manager/updater_provider.h
index 81ffb41..86af1c8 100644
--- a/update_manager/updater_provider.h
+++ b/update_manager/updater_provider.h
@@ -116,6 +116,10 @@
// for all updates.
virtual Variable<UpdateRestrictions>* var_update_restrictions() = 0;
+ // A variable that returns the number of seconds for the first update check to
+ // happen.
+ virtual Variable<int64_t>* var_test_update_check_interval_timeout() = 0;
+
protected:
UpdaterProvider() {}
diff --git a/update_manager/variable.h b/update_manager/variable.h
index 6c7d350..9ac7dae 100644
--- a/update_manager/variable.h
+++ b/update_manager/variable.h
@@ -83,6 +83,10 @@
// variable. In other case, it returns 0.
base::TimeDelta GetPollInterval() const { return poll_interval_; }
+ // Returns true, if the value for this variable is expected to be missing
+ // sometimes so we can avoid printing confusing error logs.
+ bool IsMissingOk() const { return missing_ok_; }
+
// Adds and removes observers for value changes on the variable. This only
// works for kVariableAsync variables since the other modes don't track value
// changes. Adding the same observer twice has no effect.
@@ -115,6 +119,8 @@
poll_interval_ = poll_interval;
}
+ void SetMissingOk() { missing_ok_ = true; }
+
// Calls ValueChanged on all the observers.
void NotifyValueChanged() {
// Fire all the observer methods from the main loop as single call. In order
@@ -140,7 +146,8 @@
: name_(name),
mode_(mode),
poll_interval_(mode == kVariableModePoll ? poll_interval
- : base::TimeDelta()) {}
+ : base::TimeDelta()),
+ missing_ok_(false) {}
void OnValueChangedNotification() {
// A ValueChanged() method can change the list of observers, for example
@@ -174,6 +181,9 @@
// The list of value changes observers.
std::list<BaseVariable::ObserverInterface*> observer_list_;
+ // Defines whether this variable is expected to have no value.
+ bool missing_ok_;
+
DISALLOW_COPY_AND_ASSIGN(BaseVariable);
};
diff --git a/update_metadata.proto b/update_metadata.proto
index 373ee5e..452b89d 100644
--- a/update_metadata.proto
+++ b/update_metadata.proto
@@ -153,16 +153,16 @@
//
// All fields will be set, if this message is present.
message ImageInfo {
- optional string board = 1;
- optional string key = 2;
- optional string channel = 3;
- optional string version = 4;
+ optional string board = 1 [deprecated = true];
+ optional string key = 2 [deprecated = true];
+ optional string channel = 3 [deprecated = true];
+ optional string version = 4 [deprecated = true];
// If these values aren't present, they should be assumed to match
// the equivalent value above. They are normally only different for
// special image types such as nplusone images.
- optional string build_channel = 5;
- optional string build_version = 6;
+ optional string build_channel = 5 [deprecated = true];
+ optional string build_version = 6 [deprecated = true];
}
message InstallOperation {
@@ -173,15 +173,15 @@
BSDIFF = 3 [deprecated = true]; // The data is a bsdiff binary diff.
// On minor version 2 or newer, these operations are supported:
- SOURCE_COPY = 4; // Copy from source to target partition
- SOURCE_BSDIFF = 5; // Like BSDIFF, but read from source partition
+ SOURCE_COPY = 4; // Copy from source to target partition
+ SOURCE_BSDIFF = 5; // Like BSDIFF, but read from source partition
// On minor version 3 or newer and on major version 2 or newer, these
// operations are supported:
- REPLACE_XZ = 8; // Replace destination extents w/ attached xz data.
+ REPLACE_XZ = 8; // Replace destination extents w/ attached xz data.
// On minor version 4 or newer, these operations are supported:
- ZERO = 6; // Write zeros in the destination.
+ ZERO = 6; // Write zeros in the destination.
DISCARD = 7; // Discard the destination blocks, reading as undefined.
BROTLI_BSDIFF = 10; // Like SOURCE_BSDIFF, but compressed with brotli.
@@ -314,6 +314,11 @@
// skip writing the raw bytes for these extents. During snapshot merge, the
// bytes will read from the source partitions instead.
repeated CowMergeOperation merge_operations = 18;
+
+ // Estimated size for COW image. This is used by libsnapshot
+ // as a hint. If set to 0, libsnapshot should use alternative
+ // methods for estimating size.
+ optional uint64 estimate_cow_size = 19;
}
message DynamicPartitionGroup {
@@ -371,9 +376,9 @@
optional PartitionInfo new_rootfs_info = 9 [deprecated = true];
// old_image_info will only be present for delta images.
- optional ImageInfo old_image_info = 10;
+ optional ImageInfo old_image_info = 10 [deprecated = true];
- optional ImageInfo new_image_info = 11;
+ optional ImageInfo new_image_info = 11 [deprecated = true];
// The minor version, also referred as "delta version", of the payload.
// Minor version 0 is full payload, everything else is delta payload.