update_engine: Create cros vs. aosp boundary clear
Its time to make the boundary between Chrome OS and Android code more
clear. This CL moves all CrOS only code to "chromeos" directory and the
same for Android (in "android" directory). This way we would easily know
which code is uses in which project and can keep the code cleaner and
more maintainable.
One big remaining problem is download_action* files. It seems like
DownloadAction class does a lot of things that chrome OS needs and it
depends on a lot of Chrome OS stuff, but Android is also using thie
Action in a way that circumvent the Chrome OS stuff. For example Android
checks for SystemState to be nullptr to not do things. This is really
fragile and needs to change. Probably Android Team has to implement
their own DownloadAction of some sort and not re use the Chrome OS one
in a very fragile way.
Removed a few android files that have not been used anywhere.
Changed some clang-format and lint issues in order to pass preupload.
BUG=b:171829801
TEST=cros_workon_make --board reef --test update_engine
Change-Id: I3fff1d4a100a065a5c1484a845241b5521614d9f
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2508965
Tested-by: Amin Hassani <ahassani@chromium.org>
Auto-Submit: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
Reviewed-by: Tianjie Xu <xunchang@google.com>
Reviewed-by: Kelvin Zhang <zhangkelvin@google.com>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
diff --git a/cros/common_service.cc b/cros/common_service.cc
new file mode 100644
index 0000000..aecad8b
--- /dev/null
+++ b/cros/common_service.cc
@@ -0,0 +1,421 @@
+//
+// Copyright (C) 2012 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/common_service.h"
+
+#include <string>
+
+#include <base/bind.h>
+#include <base/location.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/message_loops/message_loop.h>
+#include <brillo/strings/string_utils.h>
+#include <policy/device_policy.h>
+
+#include "update_engine/common/clock_interface.h"
+#include "update_engine/common/hardware_interface.h"
+#include "update_engine/common/prefs.h"
+#include "update_engine/common/utils.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;
+using brillo::string_utils::ToString;
+using std::string;
+using std::vector;
+using update_engine::UpdateAttemptFlags;
+using update_engine::UpdateEngineStatus;
+
+namespace chromeos_update_engine {
+
+namespace {
+// Log and set the error on the passed ErrorPtr.
+void LogAndSetError(ErrorPtr* error,
+ const base::Location& location,
+ const string& reason) {
+ brillo::Error::AddTo(error,
+ location,
+ UpdateEngineService::kErrorDomain,
+ UpdateEngineService::kErrorFailed,
+ reason);
+ LOG(ERROR) << "Sending Update Engine Failure: " << location.ToString() << ": "
+ << reason;
+}
+} // namespace
+
+const char* const UpdateEngineService::kErrorDomain = "update_engine";
+const char* const UpdateEngineService::kErrorFailed =
+ "org.chromium.UpdateEngine.Error.Failed";
+
+UpdateEngineService::UpdateEngineService(SystemState* system_state)
+ : system_state_(system_state) {}
+
+// org::chromium::UpdateEngineInterfaceInterface methods implementation.
+
+bool UpdateEngineService::SetUpdateAttemptFlags(ErrorPtr* /* error */,
+ int32_t in_flags_as_int) {
+ auto flags = static_cast<UpdateAttemptFlags>(in_flags_as_int);
+ LOG(INFO) << "Setting Update Attempt Flags: "
+ << "flags=0x" << std::hex << flags << " "
+ << "RestrictDownload="
+ << ((flags & UpdateAttemptFlags::kFlagRestrictDownload) ? "yes"
+ : "no");
+ system_state_->update_attempter()->SetUpdateAttemptFlags(flags);
+ return true;
+}
+
+bool UpdateEngineService::AttemptUpdate(ErrorPtr* /* error */,
+ const string& in_app_version,
+ const string& in_omaha_url,
+ int32_t in_flags_as_int,
+ bool* out_result) {
+ auto flags = static_cast<UpdateAttemptFlags>(in_flags_as_int);
+ bool interactive = !(flags & UpdateAttemptFlags::kFlagNonInteractive);
+ bool restrict_downloads = (flags & UpdateAttemptFlags::kFlagRestrictDownload);
+
+ LOG(INFO) << "Attempt update: app_version=\"" << in_app_version << "\" "
+ << "omaha_url=\"" << in_omaha_url << "\" "
+ << "flags=0x" << std::hex << flags << " "
+ << "interactive=" << (interactive ? "yes " : "no ")
+ << "RestrictDownload=" << (restrict_downloads ? "yes " : "no ");
+
+ *out_result = system_state_->update_attempter()->CheckForUpdate(
+ in_app_version, in_omaha_url, flags);
+ return true;
+}
+
+bool UpdateEngineService::AttemptInstall(brillo::ErrorPtr* error,
+ const string& omaha_url,
+ const vector<string>& dlc_ids) {
+ if (!system_state_->update_attempter()->CheckForInstall(dlc_ids, omaha_url)) {
+ // TODO(xiaochu): support more detailed error messages.
+ LogAndSetError(error, FROM_HERE, "Could not schedule install operation.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::AttemptRollback(ErrorPtr* error, bool in_powerwash) {
+ LOG(INFO) << "Attempting rollback to non-active partitions.";
+
+ if (!system_state_->update_attempter()->Rollback(in_powerwash)) {
+ // TODO(dgarrett): Give a more specific error code/reason.
+ LogAndSetError(error, FROM_HERE, "Rollback attempt failed.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::CanRollback(ErrorPtr* /* error */,
+ bool* out_can_rollback) {
+ bool can_rollback = system_state_->update_attempter()->CanRollback();
+ LOG(INFO) << "Checking to see if we can rollback . Result: " << can_rollback;
+ *out_can_rollback = can_rollback;
+ return true;
+}
+
+bool UpdateEngineService::ResetStatus(ErrorPtr* error) {
+ if (!system_state_->update_attempter()->ResetStatus()) {
+ // TODO(dgarrett): Give a more specific error code/reason.
+ LogAndSetError(error, FROM_HERE, "ResetStatus failed.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::SetDlcActiveValue(brillo::ErrorPtr* error,
+ bool is_active,
+ const string& dlc_id) {
+ if (!system_state_->update_attempter()->SetDlcActiveValue(is_active,
+ dlc_id)) {
+ LogAndSetError(error, FROM_HERE, "SetDlcActiveValue failed.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetStatus(ErrorPtr* error,
+ UpdateEngineStatus* out_status) {
+ if (!system_state_->update_attempter()->GetStatus(out_status)) {
+ LogAndSetError(error, FROM_HERE, "GetStatus failed.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::RebootIfNeeded(ErrorPtr* error) {
+ if (!system_state_->update_attempter()->RebootIfNeeded()) {
+ // TODO(dgarrett): Give a more specific error code/reason.
+ LogAndSetError(error, FROM_HERE, "Reboot not needed, or attempt failed.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::SetChannel(ErrorPtr* error,
+ const string& in_target_channel,
+ bool in_is_powerwash_allowed) {
+ const policy::DevicePolicy* device_policy = system_state_->device_policy();
+
+ // The device_policy is loaded in a lazy way before an update check. Load it
+ // now from the libbrillo cache if it wasn't already loaded.
+ if (!device_policy) {
+ UpdateAttempter* update_attempter = system_state_->update_attempter();
+ if (update_attempter) {
+ update_attempter->RefreshDevicePolicy();
+ device_policy = system_state_->device_policy();
+ }
+ }
+
+ bool delegated = false;
+ if (device_policy && device_policy->GetReleaseChannelDelegated(&delegated) &&
+ !delegated) {
+ LogAndSetError(error,
+ FROM_HERE,
+ "Cannot set target channel explicitly when channel "
+ "policy/settings is not delegated");
+ return false;
+ }
+
+ LOG(INFO) << "Setting destination channel to: " << in_target_channel;
+ string error_message;
+ if (!system_state_->request_params()->SetTargetChannel(
+ in_target_channel, in_is_powerwash_allowed, &error_message)) {
+ LogAndSetError(error, FROM_HERE, error_message);
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetChannel(ErrorPtr* /* error */,
+ bool in_get_current_channel,
+ string* out_channel) {
+ OmahaRequestParams* rp = system_state_->request_params();
+ *out_channel =
+ (in_get_current_channel ? rp->current_channel() : rp->target_channel());
+ return true;
+}
+
+bool UpdateEngineService::SetCohortHint(ErrorPtr* error,
+ const string& in_cohort_hint) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ // It is ok to override the cohort hint with an invalid value since it is
+ // stored in stateful partition. The code reading it should sanitize it
+ // anyway.
+ if (!prefs->SetString(kPrefsOmahaCohortHint, in_cohort_hint)) {
+ LogAndSetError(
+ error,
+ FROM_HERE,
+ StringPrintf("Error setting the cohort hint value to \"%s\".",
+ in_cohort_hint.c_str()));
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetCohortHint(ErrorPtr* error,
+ string* out_cohort_hint) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ *out_cohort_hint = "";
+ if (prefs->Exists(kPrefsOmahaCohortHint) &&
+ !prefs->GetString(kPrefsOmahaCohortHint, out_cohort_hint)) {
+ LogAndSetError(error, FROM_HERE, "Error getting the cohort hint.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
+ bool in_enabled) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ if (!prefs->SetBoolean(kPrefsP2PEnabled, in_enabled)) {
+ LogAndSetError(
+ error,
+ FROM_HERE,
+ StringPrintf("Error setting the update via p2p permission to %s.",
+ ToString(in_enabled).c_str()));
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetP2PUpdatePermission(ErrorPtr* error,
+ bool* out_enabled) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ bool p2p_pref = false; // Default if no setting is present.
+ if (prefs->Exists(kPrefsP2PEnabled) &&
+ !prefs->GetBoolean(kPrefsP2PEnabled, &p2p_pref)) {
+ LogAndSetError(error, FROM_HERE, "Error getting the P2PEnabled setting.");
+ return false;
+ }
+
+ *out_enabled = p2p_pref;
+ return true;
+}
+
+bool UpdateEngineService::SetUpdateOverCellularPermission(ErrorPtr* error,
+ bool in_allowed) {
+ ConnectionManagerInterface* connection_manager =
+ system_state_->connection_manager();
+
+ // Check if this setting is allowed by the device policy.
+ if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
+ LogAndSetError(error,
+ FROM_HERE,
+ "Ignoring the update over cellular setting since there's "
+ "a device policy enforcing this setting.");
+ return false;
+ }
+
+ // If the policy wasn't loaded yet, then it is still OK to change the local
+ // setting because the policy will be checked again during the update check.
+
+ PrefsInterface* prefs = system_state_->prefs();
+
+ if (!prefs ||
+ !prefs->SetBoolean(kPrefsUpdateOverCellularPermission, in_allowed)) {
+ LogAndSetError(error,
+ FROM_HERE,
+ string("Error setting the update over cellular to ") +
+ (in_allowed ? "true" : "false"));
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::SetUpdateOverCellularTarget(
+ brillo::ErrorPtr* error,
+ const std::string& target_version,
+ int64_t target_size) {
+ ConnectionManagerInterface* connection_manager =
+ system_state_->connection_manager();
+
+ // Check if this setting is allowed by the device policy.
+ if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
+ LogAndSetError(error,
+ FROM_HERE,
+ "Ignoring the update over cellular setting since there's "
+ "a device policy enforcing this setting.");
+ return false;
+ }
+
+ // If the policy wasn't loaded yet, then it is still OK to change the local
+ // setting because the policy will be checked again during the update check.
+
+ PrefsInterface* prefs = system_state_->prefs();
+
+ if (!prefs ||
+ !prefs->SetString(kPrefsUpdateOverCellularTargetVersion,
+ target_version) ||
+ !prefs->SetInt64(kPrefsUpdateOverCellularTargetSize, target_size)) {
+ LogAndSetError(
+ error, FROM_HERE, "Error setting the target for update over cellular.");
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetUpdateOverCellularPermission(ErrorPtr* error,
+ bool* out_allowed) {
+ ConnectionManagerInterface* connection_manager =
+ system_state_->connection_manager();
+
+ if (connection_manager->IsAllowedConnectionTypesForUpdateSet()) {
+ // We have device policy, so ignore the user preferences.
+ *out_allowed = connection_manager->IsUpdateAllowedOver(
+ ConnectionType::kCellular, ConnectionTethering::kUnknown);
+ } else {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ if (!prefs || !prefs->Exists(kPrefsUpdateOverCellularPermission)) {
+ // Update is not allowed as user preference is not set or not available.
+ *out_allowed = false;
+ return true;
+ }
+
+ bool is_allowed;
+
+ if (!prefs->GetBoolean(kPrefsUpdateOverCellularPermission, &is_allowed)) {
+ LogAndSetError(error,
+ FROM_HERE,
+ "Error getting the update over cellular preference.");
+ return false;
+ }
+ *out_allowed = is_allowed;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetDurationSinceUpdate(ErrorPtr* error,
+ int64_t* out_usec_wallclock) {
+ base::Time time;
+ if (!system_state_->update_attempter()->GetBootTimeAtUpdate(&time)) {
+ LogAndSetError(error, FROM_HERE, "No pending update.");
+ return false;
+ }
+
+ ClockInterface* clock = system_state_->clock();
+ *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
+ return true;
+}
+
+bool UpdateEngineService::GetPrevVersion(ErrorPtr* /* error */,
+ string* out_prev_version) {
+ *out_prev_version = system_state_->update_attempter()->GetPrevVersion();
+ return true;
+}
+
+bool UpdateEngineService::GetRollbackPartition(
+ ErrorPtr* /* error */, string* out_rollback_partition_name) {
+ BootControlInterface::Slot rollback_slot =
+ system_state_->update_attempter()->GetRollbackSlot();
+
+ if (rollback_slot == BootControlInterface::kInvalidSlot) {
+ out_rollback_partition_name->clear();
+ return true;
+ }
+
+ string name;
+ if (!system_state_->boot_control()->GetPartitionDevice(
+ "KERNEL", rollback_slot, &name)) {
+ LOG(ERROR) << "Invalid rollback device";
+ return false;
+ }
+
+ LOG(INFO) << "Getting rollback partition name. Result: " << name;
+ *out_rollback_partition_name = name;
+ return true;
+}
+
+bool UpdateEngineService::GetLastAttemptError(ErrorPtr* /* error */,
+ int32_t* out_last_attempt_error) {
+ ErrorCode error_code =
+ system_state_->update_attempter()->GetAttemptErrorCode();
+ *out_last_attempt_error = static_cast<int>(error_code);
+ return true;
+}
+
+} // namespace chromeos_update_engine