Introduce brillo binder interface
This is more or less an exact analogue of the DBus interface, but
available over binder. We also add support to the client library and let
update_engine_client build with binder. We don't yet support an
equivalent of the status signal/the HandleStatusUpdate method. That will
come in a future CL.
Bug: 25908638
TEST=Verified update_engine_client functionality
Change-Id: Ic793619c8019b0d50aa184e0f592b6a9ab71e0b0
diff --git a/Android.mk b/Android.mk
index aa20b29..eefcec1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,6 +17,7 @@
LOCAL_PATH := $(my-dir)
# Default values for the USE flags. Override these USE flags from your product.
+BRILLO_USE_BINDER ?= 1
BRILLO_USE_DBUS ?= 1
BRILLO_USE_HWID_OVERRIDE ?= 0
BRILLO_USE_MTD ?= 0
@@ -24,6 +25,7 @@
BRILLO_USE_WEAVE ?= 0
ue_common_cflags := \
+ -DUSE_BINDER=$(BRILLO_USE_BINDER) \
-DUSE_DBUS=$(BRILLO_USE_DBUS) \
-DUSE_HWID_OVERRIDE=$(BRILLO_USE_HWID_OVERRIDE) \
-DUSE_MTD=$(BRILLO_USE_MTD) \
@@ -287,6 +289,7 @@
chrome_browser_proxy_resolver.cc \
connection_manager.cc \
daemon.cc \
+ common_service.cc \
dbus_service.cc \
hardware_android.cc \
image_properties_android.cc \
@@ -322,6 +325,21 @@
LOCAL_SRC_FILES += \
weave_service.cc
endif # BRILLO_USE_WEAVE == 1
+
+ifeq ($(BRILLO_USE_BINDER),1)
+LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/binder_bindings
+
+LOCAL_SRC_FILES += \
+ binder_bindings/android/brillo/IUpdateEngine.aidl \
+ binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl \
+ binder_service.cc \
+ parcelable_update_engine_status.cc
+
+LOCAL_SHARED_LIBRARIES += \
+ libbinder \
+ libutils
+endif # BRILLO_USE_BINDER == 1
+
include $(BUILD_STATIC_LIBRARY)
endif # BRILLO_USE_DBUS == 1
@@ -371,10 +389,17 @@
binder_bindings/android/os/IUpdateEngine.aidl \
binder_bindings/android/os/IUpdateEngineCallback.aidl \
binder_main.cc \
- binder_service.cc
+ binder_service_android.cc
endif # defined(BRILLO)
+ifeq ($(BRILLO_USE_BINDER),1)
+LOCAL_SHARED_LIBRARIES += \
+ libbinder \
+ libutils
+endif # BRILLO_USE_BINDER == 1
+
+
LOCAL_INIT_RC := update_engine.rc
include $(BUILD_EXECUTABLE)
@@ -553,7 +578,8 @@
LOCAL_CFLAGS := \
-Wall \
-Werror \
- -Wno-unused-parameter
+ -Wno-unused-parameter \
+ -DUSE_BINDER=$(BRILLO_USE_BINDER)
LOCAL_CLANG := true
LOCAL_CPP_EXTENSION := .cc
LOCAL_C_INCLUDES := \
@@ -571,8 +597,22 @@
update_engine_client-dbus-proxies
LOCAL_SRC_FILES := \
client_library/client.cc \
- client_library/client_impl.cc \
update_status_utils.cc
+
+ifeq ($(BRILLO_USE_BINDER),1)
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings
+LOCAL_SRC_FILES += \
+ client_library/client_binder.cc \
+ parcelable_update_engine_status.cc \
+ binder_bindings/android/brillo/IUpdateEngine.aidl \
+ binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
+LOCAL_SHARED_LIBRARIES += \
+ libbinder \
+ libutils
+else # BRILLO_USE_BINDER != 1
+LOCAL_SRC_FILES += client_library/client_dbus.cc
+endif # BRILLO_USE_BINDER == 1
+
include $(BUILD_SHARED_LIBRARY)
endif # BRILLO_USE_DBUS == 1
diff --git a/binder_bindings/android/brillo/IUpdateEngine.aidl b/binder_bindings/android/brillo/IUpdateEngine.aidl
new file mode 100644
index 0000000..9399ce3
--- /dev/null
+++ b/binder_bindings/android/brillo/IUpdateEngine.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package android.brillo;
+
+import android.brillo.IUpdateEngineStatusCallback;
+import android.brillo.ParcelableUpdateEngineStatus;
+
+interface IUpdateEngine {
+ void AttemptUpdate(in String app_version, in String omaha_url, in int flags);
+ void AttemptRollback(in boolean powerwash);
+ boolean CanRollback();
+ void ResetStatus();
+ ParcelableUpdateEngineStatus GetStatus();
+ void RebootIfNeeded();
+ void SetChannel(in String target_channel, in boolean powewash);
+ String GetChannel(in boolean get_current_channel);
+ void SetP2PUpdatePermission(in boolean enabled);
+ boolean GetP2PUpdatePermission();
+ void SetUpdateOverCellularPermission(in boolean enabled);
+ boolean GetUpdateOverCellularPermission();
+ long GetDurationSinceUpdate();
+ String GetPrevVersion();
+ String GetRollbackPartition();
+ void RegisterStatusCallback(in IUpdateEngineStatusCallback callback);
+}
diff --git a/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl b/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
new file mode 100644
index 0000000..385e0aa
--- /dev/null
+++ b/binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+package android.brillo;
+
+interface IUpdateEngineStatusCallback {
+ void HandleStatusUpdate(in long last_checked_time, in double progress,
+ in String current_operation, in String new_version, in long new_size);
+}
diff --git a/binder_bindings/android/brillo/ParcelableUpdateEngineStatus.aidl b/binder_bindings/android/brillo/ParcelableUpdateEngineStatus.aidl
new file mode 100644
index 0000000..fc10505
--- /dev/null
+++ b/binder_bindings/android/brillo/ParcelableUpdateEngineStatus.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+package android.brillo;
+
+parcelable ParcelableUpdateEngineStatus cpp_header
+ "update_engine/parcelable_update_engine_status.h";
diff --git a/binder_main.cc b/binder_main.cc
index 7d5c975..a4817b4 100644
--- a/binder_main.cc
+++ b/binder_main.cc
@@ -22,7 +22,7 @@
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
-#include "update_engine/binder_service.h"
+#include "update_engine/binder_service_android.h"
// Log to logcat as update_engine.
#undef LOG_TAG
diff --git a/binder_service.cc b/binder_service.cc
index f412d42..19acf6e 100644
--- a/binder_service.cc
+++ b/binder_service.cc
@@ -16,37 +16,156 @@
#include "update_engine/binder_service.h"
-using android::OK;
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
using android::String16;
-using android::os::IUpdateEngineCallback;
-using android::sp;
+using android::String8;
using android::binder::Status;
-using std::vector;
+using android::brillo::IUpdateEngineStatusCallback;
+using android::brillo::ParcelableUpdateEngineStatus;
+using android::sp;
+using brillo::ErrorPtr;
+using std::string;
namespace chromeos_update_engine {
-Status BinderService::bind(
- const sp<IUpdateEngineCallback>& callback,
- bool* return_value) {
- *return_value = true;
- return Status::ok();
+namespace {
+string NormalString(const String16& in) {
+ return string{String8{in}.string()};
}
-Status BinderService::applyPayload(
- const String16& url,
- const vector<String16>& header_kv_pairs) {
- return Status::ok();
+Status ToStatus(ErrorPtr* error) {
+ return Status::fromServiceSpecificError(
+ 1, String8{error->get()->GetMessage().c_str()});
+}
+} // namespace
+
+template<typename... Parameters, typename... Arguments>
+Status BinderUpdateEngineService::CallCommonHandler(
+ bool (UpdateEngineService::*Handler)(ErrorPtr*, Parameters...),
+ Arguments... arguments) {
+ ErrorPtr error;
+ if (((common_.get())->*Handler)(&error, arguments...)) return Status::ok();
+ return ToStatus(&error);
}
-Status BinderService::suspend() {
- return Status::ok();
+Status BinderUpdateEngineService::AttemptUpdate(const String16& app_version,
+ const String16& omaha_url,
+ int flags) {
+ return CallCommonHandler(
+ &UpdateEngineService::AttemptUpdate, NormalString(app_version),
+ NormalString(omaha_url), flags);
}
-Status BinderService::resume() {
- return Status::ok();
+Status BinderUpdateEngineService::AttemptRollback(bool powerwash) {
+ return CallCommonHandler(&UpdateEngineService::AttemptRollback, powerwash);
}
-Status BinderService::cancel() {
+Status BinderUpdateEngineService::CanRollback(bool* out_can_rollback) {
+ return CallCommonHandler(&UpdateEngineService::CanRollback,
+ out_can_rollback);
+}
+
+Status BinderUpdateEngineService::ResetStatus() {
+ return CallCommonHandler(&UpdateEngineService::ResetStatus);
+}
+
+Status BinderUpdateEngineService::GetStatus(
+ ParcelableUpdateEngineStatus* status) {
+ string current_op;
+ string new_version;
+
+ auto ret = CallCommonHandler(&UpdateEngineService::GetStatus,
+ &status->last_checked_time_,
+ &status->progress_,
+ ¤t_op,
+ &new_version,
+ &status->new_size_);
+
+ if (ret.isOk()) {
+ status->current_operation_ = String16{current_op.c_str()};
+ status->new_version_ = String16{new_version.c_str()};
+ }
+
+ return ret;
+}
+
+Status BinderUpdateEngineService::RebootIfNeeded() {
+ return CallCommonHandler(&UpdateEngineService::RebootIfNeeded);
+}
+
+Status BinderUpdateEngineService::SetChannel(const String16& target_channel,
+ bool powerwash) {
+ return CallCommonHandler(&UpdateEngineService::SetChannel,
+ NormalString(target_channel), powerwash);
+}
+
+Status BinderUpdateEngineService::GetChannel(bool get_current_channel,
+ String16* out_channel) {
+ string channel_string;
+ auto ret = CallCommonHandler(&UpdateEngineService::GetChannel,
+ get_current_channel,
+ &channel_string);
+
+ *out_channel = String16(channel_string.c_str());
+ return ret;
+}
+
+Status BinderUpdateEngineService::SetP2PUpdatePermission(bool enabled) {
+ return CallCommonHandler(&UpdateEngineService::SetP2PUpdatePermission,
+ enabled);
+}
+
+Status BinderUpdateEngineService::GetP2PUpdatePermission(
+ bool* out_p2p_permission) {
+ return CallCommonHandler(&UpdateEngineService::GetP2PUpdatePermission,
+ out_p2p_permission);
+}
+
+Status BinderUpdateEngineService::SetUpdateOverCellularPermission(
+ bool enabled) {
+ return CallCommonHandler(
+ &UpdateEngineService::SetUpdateOverCellularPermission, enabled);
+}
+
+Status BinderUpdateEngineService::GetUpdateOverCellularPermission(
+ bool* out_cellular_permission) {
+ return CallCommonHandler(
+ &UpdateEngineService::GetUpdateOverCellularPermission,
+ out_cellular_permission);
+}
+
+Status BinderUpdateEngineService::GetDurationSinceUpdate(
+ int64_t* out_duration) {
+ return CallCommonHandler(&UpdateEngineService::GetDurationSinceUpdate,
+ out_duration);
+}
+
+Status BinderUpdateEngineService::GetPrevVersion(String16* out_prev_version) {
+ string version_string;
+ auto ret = CallCommonHandler(&UpdateEngineService::GetPrevVersion,
+ &version_string);
+
+ *out_prev_version = String16(version_string.c_str());
+ return ret;
+}
+
+Status BinderUpdateEngineService::GetRollbackPartition(
+ String16* out_rollback_partition) {
+ string partition_string;
+ auto ret = CallCommonHandler(&UpdateEngineService::GetRollbackPartition,
+ &partition_string);
+
+ if (ret.isOk()) {
+ *out_rollback_partition = String16(partition_string.c_str());
+ }
+
+ return ret;
+}
+
+Status BinderUpdateEngineService::RegisterStatusCallback(
+ const sp<IUpdateEngineStatusCallback>& callback) {
return Status::ok();
}
diff --git a/binder_service.h b/binder_service.h
index 71b9778..ddbd147 100644
--- a/binder_service.h
+++ b/binder_service.h
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2015 The Android Open Source Project
+// 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.
@@ -17,35 +17,60 @@
#ifndef UPDATE_ENGINE_BINDER_SERVICE_H_
#define UPDATE_ENGINE_BINDER_SERVICE_H_
-#include <vector>
-
#include <utils/Errors.h>
-#include <utils/String16.h>
-#include <utils/StrongPointer.h>
-#include "android/os/BnUpdateEngine.h"
-#include "android/os/IUpdateEngineCallback.h"
+#include "update_engine/common_service.h"
+#include "update_engine/parcelable_update_engine_status.h"
+
+#include "android/brillo/BnUpdateEngine.h"
+#include "android/brillo/IUpdateEngineStatusCallback.h"
namespace chromeos_update_engine {
-class BinderService : public android::os::BnUpdateEngine {
+class BinderUpdateEngineService : public android::brillo::BnUpdateEngine {
public:
- BinderService() = default;
- virtual ~BinderService() = default;
+ BinderUpdateEngineService(SystemState* system_state)
+ : common_(new UpdateEngineService(system_state)) {}
+ virtual ~BinderUpdateEngineService() = default;
- android::binder::Status applyPayload(
- const android::String16& url,
- const std::vector<android::String16>& header_kv_pairs) override;
+ // android::brillo::BnUpdateEngine overrides.
+ android::binder::Status AttemptUpdate(const android::String16& app_version,
+ const android::String16& omaha_url,
+ int flags) override;
+ android::binder::Status AttemptRollback(bool powerwash) override;
+ android::binder::Status CanRollback(bool* out_can_rollback) override;
+ android::binder::Status ResetStatus() override;
+ android::binder::Status GetStatus(
+ android::brillo::ParcelableUpdateEngineStatus* status);
+ android::binder::Status RebootIfNeeded() override;
+ android::binder::Status SetChannel(const android::String16& target_channel,
+ bool powerwash) override;
+ android::binder::Status GetChannel(bool get_current_channel,
+ android::String16* out_channel) override;
+ android::binder::Status SetP2PUpdatePermission(bool enabled) override;
+ android::binder::Status GetP2PUpdatePermission(
+ bool* out_p2p_permission) override;
+ android::binder::Status SetUpdateOverCellularPermission(
+ bool enabled) override;
+ android::binder::Status GetUpdateOverCellularPermission(
+ bool* out_cellular_permission) override;
+ android::binder::Status GetDurationSinceUpdate(
+ int64_t* out_duration) override;
+ android::binder::Status GetPrevVersion(
+ android::String16* out_prev_version) override;
+ android::binder::Status GetRollbackPartition(
+ android::String16* out_rollback_partition) override;
+ android::binder::Status RegisterStatusCallback(
+ const android::sp<android::brillo::IUpdateEngineStatusCallback>& callback)
+ override;
- android::binder::Status bind(
- const android::sp<android::os::IUpdateEngineCallback>& callback,
- bool* return_value) override;
+ private:
+ template<typename... Parameters, typename... Arguments>
+ android::binder::Status CallCommonHandler(
+ bool (UpdateEngineService::*Handler)(brillo::ErrorPtr*, Parameters...),
+ Arguments... arguments);
- android::binder::Status suspend() override;
-
- android::binder::Status resume() override;
-
- android::binder::Status cancel() override;
+ std::unique_ptr<UpdateEngineService> common_;
}; // class BinderService
} // namespace chromeos_update_engine
diff --git a/binder_service_android.cc b/binder_service_android.cc
new file mode 100644
index 0000000..df0f0c6
--- /dev/null
+++ b/binder_service_android.cc
@@ -0,0 +1,50 @@
+//
+// 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/binder_service_android.h"
+
+using android::String16;
+using android::binder::Status;
+using android::os::IUpdateEngineCallback;
+using android::sp;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+Status BinderService::bind(const sp<IUpdateEngineCallback>& callback,
+ bool* return_value) {
+ *return_value = true;
+ return Status::ok();
+}
+
+Status BinderService::applyPayload(const String16& url,
+ const vector<String16>& header_kv_pairs) {
+ return Status::ok();
+}
+
+Status BinderService::suspend() {
+ return Status::ok();
+}
+
+Status BinderService::resume() {
+ return Status::ok();
+}
+
+Status BinderService::cancel() {
+ return Status::ok();
+}
+
+} // namespace chromeos_update_engine
diff --git a/binder_service_android.h b/binder_service_android.h
new file mode 100644
index 0000000..3c4939a
--- /dev/null
+++ b/binder_service_android.h
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+
+#ifndef UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
+#define UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
+
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/os/BnUpdateEngine.h"
+#include "android/os/IUpdateEngineCallback.h"
+
+namespace chromeos_update_engine {
+
+class BinderService : public android::os::BnUpdateEngine {
+ public:
+ BinderService() = default;
+ virtual ~BinderService() = default;
+
+ android::binder::Status applyPayload(
+ const android::String16& url,
+ const std::vector<android::String16>& header_kv_pairs) override;
+
+ android::binder::Status bind(
+ const android::sp<android::os::IUpdateEngineCallback>& callback,
+ bool* return_value) override;
+
+ android::binder::Status suspend() override;
+
+ android::binder::Status resume() override;
+
+ android::binder::Status cancel() override;
+}; // class BinderService
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_BINDER_SERVICE_ANDROID_H_
diff --git a/client_library/client.cc b/client_library/client.cc
index f4a24cf..9a42696 100644
--- a/client_library/client.cc
+++ b/client_library/client.cc
@@ -18,14 +18,22 @@
#include <memory>
-#include "update_engine/client_library/client_impl.h"
+#if USE_BINDER
+#include "update_engine/client_library/client_binder.h"
+#else // !USE_BINDER
+#include "update_engine/client_library/client_dbus.h"
+#endif // USE_BINDER
using std::unique_ptr;
namespace update_engine {
-std::unique_ptr<UpdateEngineClient> UpdateEngineClient::CreateInstance() {
- auto update_engine_client_impl = new internal::UpdateEngineClientImpl{};
+unique_ptr<UpdateEngineClient> UpdateEngineClient::CreateInstance() {
+#if USE_BINDER
+ auto update_engine_client_impl = new internal::BinderUpdateEngineClient{};
+#else // !USE_BINDER
+ auto update_engine_client_impl = new internal::DBusUpdateEngineClient{};
+#endif // USE_BINDER
auto ret = unique_ptr<UpdateEngineClient>{update_engine_client_impl};
if (!update_engine_client_impl->Init()) {
diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc
new file mode 100644
index 0000000..b3bd3e7
--- /dev/null
+++ b/client_library/client_binder.cc
@@ -0,0 +1,157 @@
+//
+// 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/client_library/client_binder.h"
+
+#include <binder/IServiceManager.h>
+
+#include <base/message_loop/message_loop.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#include "update_engine/parcelable_update_engine_status.h"
+#include "update_engine/update_status_utils.h"
+
+using android::OK;
+using android::String16;
+using android::String8;
+using android::brillo::ParcelableUpdateEngineStatus;
+using android::getService;
+using chromeos_update_engine::StringToUpdateStatus;
+using std::string;
+
+namespace update_engine {
+namespace internal {
+
+bool BinderUpdateEngineClient::Init() {
+ return getService(String16{"android.brillo.UpdateEngineService"},
+ &service_) == OK;
+}
+
+bool BinderUpdateEngineClient::AttemptUpdate(const string& in_app_version,
+ const string& in_omaha_url,
+ bool at_user_request) {
+ return service_->AttemptUpdate(String16{in_app_version.c_str()},
+ String16{in_omaha_url.c_str()},
+ at_user_request ? 1 : 0).isOk();
+}
+
+bool BinderUpdateEngineClient::GetStatus(int64_t* out_last_checked_time,
+ double* out_progress,
+ UpdateStatus* out_update_status,
+ string* out_new_version,
+ int64_t* out_new_size) const {
+ ParcelableUpdateEngineStatus status;
+
+ if (!service_->GetStatus(&status).isOk())
+ return false;
+
+ *out_last_checked_time = status.last_checked_time_;
+ *out_progress = status.progress_;
+ StringToUpdateStatus(String8{status.current_operation_}.string(),
+ out_update_status);
+ *out_new_version = String8{status.new_version_}.string();
+ *out_new_size = status.new_size_;
+ return true;
+}
+
+bool BinderUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
+ return service_->SetUpdateOverCellularPermission(allowed).isOk();
+}
+
+bool BinderUpdateEngineClient::GetUpdateOverCellularPermission(
+ bool* allowed) const {
+ return service_->GetUpdateOverCellularPermission(allowed).isOk();
+}
+
+bool BinderUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
+ return service_->SetP2PUpdatePermission(enabled).isOk();
+}
+
+bool BinderUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
+ return service_->GetP2PUpdatePermission(enabled).isOk();
+}
+
+bool BinderUpdateEngineClient::Rollback(bool powerwash) {
+ return service_->AttemptRollback(powerwash).isOk();
+}
+
+bool BinderUpdateEngineClient::GetRollbackPartition(
+ string* rollback_partition) const {
+ String16 out_as_string16;
+
+ if (!service_->GetRollbackPartition(&out_as_string16).isOk())
+ return false;
+
+ *rollback_partition = String8{out_as_string16}.string();
+ return true;
+}
+
+bool BinderUpdateEngineClient::GetPrevVersion(string* prev_version) const {
+ String16 out_as_string16;
+
+ if (!service_->GetPrevVersion(&out_as_string16).isOk())
+ return false;
+
+ *prev_version = String8{out_as_string16}.string();
+ return true;
+}
+
+void BinderUpdateEngineClient::RebootIfNeeded() {
+ if (!service_->RebootIfNeeded().isOk()) {
+ // Reboot error code doesn't necessarily mean that a reboot
+ // failed. For example, D-Bus may be shutdown before we receive the
+ // result.
+ LOG(INFO) << "RebootIfNeeded() failure ignored.";
+ }
+}
+
+bool BinderUpdateEngineClient::ResetStatus() {
+ return service_->ResetStatus().isOk();
+}
+
+void BinderUpdateEngineClient::RegisterStatusUpdateHandler(
+ StatusUpdateHandler* handler) {
+}
+
+bool BinderUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
+ bool allow_powerwash) {
+ return service_->SetChannel(String16{in_target_channel.c_str()},
+ allow_powerwash).isOk();
+}
+
+bool BinderUpdateEngineClient::GetTargetChannel(string* out_channel) const {
+ String16 out_as_string16;
+
+ if (!service_->GetChannel(false, &out_as_string16).isOk())
+ return false;
+
+ *out_channel = String8{out_as_string16}.string();
+ return true;
+}
+
+bool BinderUpdateEngineClient::GetChannel(string* out_channel) const {
+ String16 out_as_string16;
+
+ if (!service_->GetChannel(true, &out_as_string16).isOk())
+ return false;
+
+ *out_channel = String8{out_as_string16}.string();
+ return true;
+}
+
+} // namespace internal
+} // namespace update_engine
diff --git a/client_library/client_impl.h b/client_library/client_binder.h
similarity index 64%
copy from client_library/client_impl.h
copy to client_library/client_binder.h
index cfd5395..22d1cf0 100644
--- a/client_library/client_impl.h
+++ b/client_library/client_binder.h
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2015 The Android Open Source Project
+// 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.
@@ -14,27 +14,29 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
-#define UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
+#ifndef UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_BINDER_H_
+#define UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_BINDER_H_
#include <cstdint>
#include <memory>
#include <string>
#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+#include "android/brillo/IUpdateEngine.h"
#include "update_engine/client_library/include/update_engine/client.h"
-#include "update_engine/dbus-proxies.h"
namespace update_engine {
namespace internal {
-class UpdateEngineClientImpl : public UpdateEngineClient {
+class BinderUpdateEngineClient : public UpdateEngineClient {
public:
- explicit UpdateEngineClientImpl() = default;
+ BinderUpdateEngineClient() = default;
bool Init();
- virtual ~UpdateEngineClientImpl() = default;
+ virtual ~BinderUpdateEngineClient() = default;
bool AttemptUpdate(const std::string& app_version,
const std::string& omaha_url,
@@ -72,24 +74,12 @@
void RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
private:
- std::unique_ptr<org::chromium::UpdateEngineInterfaceProxy> proxy_;
+ android::sp<android::brillo::IUpdateEngine> service_;
- void StatusUpdateHandlerRegistered(StatusUpdateHandler* handler,
- const std::string& interface,
- const std::string& signal_name,
- bool success) const;
-
- void RunStatusUpdateHandler(StatusUpdateHandler* handler,
- int64_t last_checked_time,
- double progress,
- const std::string& current_operation,
- const std::string& new_version,
- int64_t new_size);
-
- DISALLOW_COPY_AND_ASSIGN(UpdateEngineClientImpl);
-}; // class UpdateEngineClientImpl
+ DISALLOW_COPY_AND_ASSIGN(BinderUpdateEngineClient);
+}; // class BinderUpdateEngineClient
} // namespace internal
} // namespace update_engine
-#endif // UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
+#endif // UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_BINDER_H_
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
new file mode 100644
index 0000000..0d02936
--- /dev/null
+++ b/client_library/client_dbus.cc
@@ -0,0 +1,196 @@
+//
+// 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/client_library/client_dbus.h"
+
+#include <base/message_loop/message_loop.h>
+
+#include <dbus/bus.h>
+#include <update_engine/dbus-constants.h>
+
+#include "update_engine/update_status_utils.h"
+
+using chromeos_update_engine::StringToUpdateStatus;
+using dbus::Bus;
+using org::chromium::UpdateEngineInterfaceProxy;
+using std::string;
+
+namespace update_engine {
+namespace internal {
+
+bool DBusUpdateEngineClient::Init() {
+ Bus::Options options;
+ options.bus_type = Bus::SYSTEM;
+ scoped_refptr<Bus> bus{new Bus{options}};
+
+ if (!bus->Connect())
+ return false;
+
+ proxy_.reset(new UpdateEngineInterfaceProxy{bus});
+ return true;
+}
+
+bool DBusUpdateEngineClient::AttemptUpdate(const string& in_app_version,
+ const string& in_omaha_url,
+ bool at_user_request) {
+ return proxy_->AttemptUpdateWithFlags(
+ in_app_version,
+ in_omaha_url,
+ (at_user_request) ? 0 : kAttemptUpdateFlagNonInteractive,
+ nullptr);
+}
+
+bool DBusUpdateEngineClient::GetStatus(int64_t* out_last_checked_time,
+ double* out_progress,
+ UpdateStatus* out_update_status,
+ string* out_new_version,
+ int64_t* out_new_size) const {
+ string status_as_string;
+ const bool success = proxy_->GetStatus(out_last_checked_time,
+ out_progress,
+ &status_as_string,
+ out_new_version,
+ out_new_size,
+ nullptr);
+ if (!success) {
+ return false;
+ }
+
+ return StringToUpdateStatus(status_as_string, out_update_status);
+}
+
+bool DBusUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
+ return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetUpdateOverCellularPermission(
+ bool* allowed) const {
+ return proxy_->GetUpdateOverCellularPermission(allowed, nullptr);
+}
+
+bool DBusUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
+ return proxy_->SetP2PUpdatePermission(enabled, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
+ return proxy_->GetP2PUpdatePermission(enabled, nullptr);
+}
+
+bool DBusUpdateEngineClient::Rollback(bool powerwash) {
+ return proxy_->AttemptRollback(powerwash, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetRollbackPartition(
+ string* rollback_partition) const {
+ return proxy_->GetRollbackPartition(rollback_partition, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetPrevVersion(string* prev_version) const {
+ return proxy_->GetPrevVersion(prev_version, nullptr);
+}
+
+void DBusUpdateEngineClient::RebootIfNeeded() {
+ bool ret = proxy_->RebootIfNeeded(nullptr);
+ if (!ret) {
+ // Reboot error code doesn't necessarily mean that a reboot
+ // failed. For example, D-Bus may be shutdown before we receive the
+ // result.
+ LOG(INFO) << "RebootIfNeeded() failure ignored.";
+ }
+}
+
+bool DBusUpdateEngineClient::ResetStatus() {
+ return proxy_->ResetStatus(nullptr);
+}
+
+void DBusUpdateEngineClient::StatusUpdateHandlerRegistered(
+ StatusUpdateHandler* handler,
+ const string& interface,
+ const string& signal_name,
+ bool success) const {
+ if (!success) {
+ handler->IPCError("Could not connect to" + signal_name);
+ return;
+ }
+
+ int64_t last_checked_time;
+ double progress;
+ UpdateStatus update_status;
+ string new_version;
+ int64_t new_size;
+
+ if (GetStatus(&last_checked_time,
+ &progress,
+ &update_status,
+ &new_version,
+ &new_size)) {
+ handler->HandleStatusUpdate(
+ last_checked_time, progress, update_status, new_version, new_size);
+ return;
+ }
+
+ handler->IPCError("Could not query current status");
+}
+
+void DBusUpdateEngineClient::RunStatusUpdateHandler(
+ StatusUpdateHandler* h,
+ int64_t last_checked_time,
+ double progress,
+ const string& current_operation,
+ const string& new_version,
+ int64_t new_size) {
+ UpdateStatus status;
+ StringToUpdateStatus(current_operation, &status);
+
+ h->HandleStatusUpdate(
+ last_checked_time, progress, status, new_version, new_size);
+}
+
+void DBusUpdateEngineClient::RegisterStatusUpdateHandler(
+ StatusUpdateHandler* handler) {
+ if (!base::MessageLoopForIO::current()) {
+ LOG(FATAL) << "Cannot get UpdateEngineClient outside of message loop.";
+ return;
+ }
+
+ proxy_->RegisterStatusUpdateSignalHandler(
+ base::Bind(&DBusUpdateEngineClient::RunStatusUpdateHandler,
+ base::Unretained(this),
+ base::Unretained(handler)),
+ base::Bind(&DBusUpdateEngineClient::StatusUpdateHandlerRegistered,
+ base::Unretained(this),
+ base::Unretained(handler)));
+}
+
+bool DBusUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
+ bool allow_powerwash) {
+ return proxy_->SetChannel(in_target_channel, allow_powerwash, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetTargetChannel(string* out_channel) const {
+ return proxy_->GetChannel(false, // Get the target channel.
+ out_channel,
+ nullptr);
+}
+
+bool DBusUpdateEngineClient::GetChannel(string* out_channel) const {
+ return proxy_->GetChannel(true, // Get the current channel.
+ out_channel,
+ nullptr);
+}
+
+} // namespace internal
+} // namespace update_engine
diff --git a/client_library/client_impl.h b/client_library/client_dbus.h
similarity index 87%
rename from client_library/client_impl.h
rename to client_library/client_dbus.h
index cfd5395..3590a21 100644
--- a/client_library/client_impl.h
+++ b/client_library/client_dbus.h
@@ -14,8 +14,8 @@
// limitations under the License.
//
-#ifndef UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
-#define UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
+#ifndef UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_DBUS_H_
+#define UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_DBUS_H_
#include <cstdint>
#include <memory>
@@ -29,12 +29,12 @@
namespace update_engine {
namespace internal {
-class UpdateEngineClientImpl : public UpdateEngineClient {
+class DBusUpdateEngineClient : public UpdateEngineClient {
public:
- explicit UpdateEngineClientImpl() = default;
+ DBusUpdateEngineClient() = default;
bool Init();
- virtual ~UpdateEngineClientImpl() = default;
+ virtual ~DBusUpdateEngineClient() = default;
bool AttemptUpdate(const std::string& app_version,
const std::string& omaha_url,
@@ -86,10 +86,10 @@
const std::string& new_version,
int64_t new_size);
- DISALLOW_COPY_AND_ASSIGN(UpdateEngineClientImpl);
-}; // class UpdateEngineClientImpl
+ DISALLOW_COPY_AND_ASSIGN(DBusUpdateEngineClient);
+}; // class DBusUpdateEngineClient
} // namespace internal
} // namespace update_engine
-#endif // UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_IMPL_H_
+#endif // UPDATE_ENGINE_CLIENT_LIBRARY_CLIENT_DBUS_H_
diff --git a/client_library/client_impl.cc b/client_library/client_impl.cc
deleted file mode 100644
index 186301f..0000000
--- a/client_library/client_impl.cc
+++ /dev/null
@@ -1,176 +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/client_library/client_impl.h"
-
-#include <base/message_loop/message_loop.h>
-
-#include <dbus/bus.h>
-#include <update_engine/dbus-constants.h>
-
-#include "update_engine/update_status_utils.h"
-
-using chromeos_update_engine::StringToUpdateStatus;
-using std::string;
-using dbus::Bus;
-using org::chromium::UpdateEngineInterfaceProxy;
-
-namespace update_engine {
-namespace internal {
-
-bool UpdateEngineClientImpl::Init() {
- Bus::Options options;
- options.bus_type = Bus::SYSTEM;
- scoped_refptr<Bus> bus{new Bus{options}};
-
- if (!bus->Connect()) return false;
-
- proxy_.reset(new UpdateEngineInterfaceProxy{bus});
- return true;
-}
-
-bool UpdateEngineClientImpl::AttemptUpdate(const string& in_app_version,
- const string& in_omaha_url,
- bool at_user_request) {
- return proxy_->AttemptUpdateWithFlags(
- in_app_version, in_omaha_url,
- (at_user_request) ? 0 : kAttemptUpdateFlagNonInteractive, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetStatus(int64_t* out_last_checked_time,
- double* out_progress,
- UpdateStatus* out_update_status,
- string* out_new_version,
- int64_t* out_new_size) const {
- string status_as_string;
- const bool success =
- proxy_->GetStatus(out_last_checked_time, out_progress, &status_as_string,
- out_new_version, out_new_size, nullptr);
- if (!success) {
- return false;
- }
-
- return StringToUpdateStatus(status_as_string, out_update_status);
-}
-
-bool UpdateEngineClientImpl::SetUpdateOverCellularPermission(bool allowed) {
- return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetUpdateOverCellularPermission(bool* allowed) const {
- return proxy_->GetUpdateOverCellularPermission(allowed, nullptr);
-}
-
-bool UpdateEngineClientImpl::SetP2PUpdatePermission(bool enabled) {
- return proxy_->SetP2PUpdatePermission(enabled, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetP2PUpdatePermission(bool* enabled) const {
- return proxy_->GetP2PUpdatePermission(enabled, nullptr);
-}
-
-bool UpdateEngineClientImpl::Rollback(bool powerwash) {
- return proxy_->AttemptRollback(powerwash, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetRollbackPartition(string* rollback_partition) const {
- return proxy_->GetRollbackPartition(rollback_partition, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetPrevVersion(string* prev_version) const {
- return proxy_->GetPrevVersion(prev_version, nullptr);
-}
-
-void UpdateEngineClientImpl::RebootIfNeeded() {
- bool ret = proxy_->RebootIfNeeded(nullptr);
- if (!ret) {
- // Reboot error code doesn't necessarily mean that a reboot
- // failed. For example, D-Bus may be shutdown before we receive the
- // result.
- LOG(INFO) << "RebootIfNeeded() failure ignored.";
- }
-}
-
-bool UpdateEngineClientImpl::ResetStatus() {
- return proxy_->ResetStatus(nullptr);
-}
-
-void UpdateEngineClientImpl::StatusUpdateHandlerRegistered(
- StatusUpdateHandler* handler, const std::string& interface,
- const std::string& signal_name, bool success) const {
- if (!success) {
- handler->IPCError("Could not connect to" + signal_name);
- return;
- }
-
- int64_t last_checked_time;
- double progress;
- UpdateStatus update_status;
- string new_version;
- int64_t new_size;
-
- if (GetStatus(&last_checked_time, &progress, &update_status, &new_version,
- &new_size)) {
- handler->HandleStatusUpdate(last_checked_time, progress, update_status,
- new_version, new_size);
- return;
- }
-
- handler->IPCError("Could not query current status");
-}
-
-void UpdateEngineClientImpl::RunStatusUpdateHandler(
- StatusUpdateHandler* h, int64_t last_checked_time, double progress,
- const std::string& current_operation, const std::string& new_version,
- int64_t new_size) {
- UpdateStatus status;
- StringToUpdateStatus(current_operation, &status);
-
- h->HandleStatusUpdate(last_checked_time, progress, status, new_version,
- new_size);
-}
-
-void UpdateEngineClientImpl::RegisterStatusUpdateHandler(
- StatusUpdateHandler* handler) {
- if (!base::MessageLoopForIO::current()) {
- LOG(FATAL) << "Cannot get UpdateEngineClient outside of message loop.";
- return;
- }
-
- proxy_->RegisterStatusUpdateSignalHandler(
- base::Bind(&UpdateEngineClientImpl::RunStatusUpdateHandler,
- base::Unretained(this), base::Unretained(handler)),
- base::Bind(&UpdateEngineClientImpl::StatusUpdateHandlerRegistered,
- base::Unretained(this), base::Unretained(handler)));
-}
-
-bool UpdateEngineClientImpl::SetTargetChannel(const string& in_target_channel,
- bool allow_powerwash) {
- return proxy_->SetChannel(in_target_channel, allow_powerwash, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetTargetChannel(string* out_channel) const {
- return proxy_->GetChannel(false, // Get the target channel.
- out_channel, nullptr);
-}
-
-bool UpdateEngineClientImpl::GetChannel(string* out_channel) const {
- return proxy_->GetChannel(true, // Get the current channel.
- out_channel, nullptr);
-}
-
-} // namespace internal
-} // namespace update_engine
diff --git a/common_service.cc b/common_service.cc
new file mode 100644
index 0000000..77bdf7c
--- /dev/null
+++ b/common_service.cc
@@ -0,0 +1,322 @@
+//
+// 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/common_service.h"
+
+#include <set>
+#include <string>
+
+#include <base/location.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/bind_lambda.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/connection_manager_interface.h"
+#include "update_engine/omaha_request_params.h"
+#include "update_engine/p2p_manager.h"
+#include "update_engine/update_attempter.h"
+
+using base::StringPrintf;
+using brillo::ErrorPtr;
+using brillo::string_utils::ToString;
+using std::set;
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace {
+// Log and set the error on the passed ErrorPtr.
+void LogAndSetError(ErrorPtr* error,
+ const tracked_objects::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::AttemptUpdate(ErrorPtr* /* error */,
+ const string& in_app_version,
+ const string& in_omaha_url,
+ int32_t in_flags_as_int) {
+ AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(in_flags_as_int);
+ bool interactive = !(flags & kAttemptUpdateFlagNonInteractive);
+
+ LOG(INFO) << "Attempt update: app_version=\"" << in_app_version << "\" "
+ << "omaha_url=\"" << in_omaha_url << "\" "
+ << "flags=0x" << std::hex << flags << " "
+ << "interactive=" << (interactive ? "yes" : "no");
+ system_state_->update_attempter()->CheckForUpdate(
+ in_app_version, in_omaha_url, interactive);
+ 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::GetStatus(ErrorPtr* error,
+ int64_t* out_last_checked_time,
+ double* out_progress,
+ string* out_current_operation,
+ string* out_new_version,
+ int64_t* out_new_size) {
+ if (!system_state_->update_attempter()->GetStatus(out_last_checked_time,
+ out_progress,
+ out_current_operation,
+ out_new_version,
+ out_new_size)) {
+ 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;
+ }
+ // Update the weave state because updated the target channel.
+ if (system_state_->weave_service())
+ system_state_->weave_service()->UpdateWeaveState();
+ 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::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) {
+ set<string> allowed_types;
+ 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();
+ }
+ }
+
+ // Check if this setting is allowed by the device policy.
+ if (device_policy &&
+ device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
+ 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->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::GetUpdateOverCellularPermission(ErrorPtr* /* error */,
+ bool* out_allowed) {
+ ConnectionManagerInterface* cm = system_state_->connection_manager();
+
+ // The device_policy is loaded in a lazy way before an update check and is
+ // used to determine if an update is allowed over cellular. Load the device
+ // policy now from the libbrillo cache if it wasn't already loaded.
+ if (!system_state_->device_policy()) {
+ UpdateAttempter* update_attempter = system_state_->update_attempter();
+ if (update_attempter)
+ update_attempter->RefreshDevicePolicy();
+ }
+
+ // Return the current setting based on the same logic used while checking for
+ // updates. A log message could be printed as the result of this test.
+ LOG(INFO) << "Checking if updates over cellular networks are allowed:";
+ *out_allowed = cm->IsUpdateAllowedOver(
+ chromeos_update_engine::NetworkConnectionType::kCellular,
+ chromeos_update_engine::NetworkTethering::kUnknown);
+ 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;
+}
+
+} // namespace chromeos_update_engine
diff --git a/common_service.h b/common_service.h
new file mode 100644
index 0000000..e08b4fd
--- /dev/null
+++ b/common_service.h
@@ -0,0 +1,136 @@
+//
+// 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_COMMON_SERVICE_H_
+#define UPDATE_ENGINE_COMMON_SERVICE_H_
+
+#include <inttypes.h>
+
+#include <string>
+
+#include <base/memory/ref_counted.h>
+#include <brillo/errors/error.h>
+
+#include "update_engine/system_state.h"
+
+namespace chromeos_update_engine {
+
+class UpdateEngineService {
+ public:
+ // Flags used in the AttemptUpdateWithFlags() D-Bus method.
+ typedef enum {
+ kAttemptUpdateFlagNonInteractive = (1<<0)
+ } AttemptUpdateFlags;
+
+ // Error domain for all the service errors.
+ static const char* const kErrorDomain;
+
+ // Generic service error.
+ static const char* const kErrorFailed;
+
+ explicit UpdateEngineService(SystemState* system_state);
+ virtual ~UpdateEngineService() = default;
+
+ bool AttemptUpdate(brillo::ErrorPtr* error,
+ const std::string& in_app_version,
+ const std::string& in_omaha_url,
+ int32_t in_flags_as_int);
+
+ bool AttemptRollback(brillo::ErrorPtr* error, bool in_powerwash);
+
+ // Checks if the system rollback is available by verifying if the secondary
+ // system partition is valid and bootable.
+ bool CanRollback(brillo::ErrorPtr* error, bool* out_can_rollback);
+
+ // Resets the status of the update_engine to idle, ignoring any applied
+ // update. This is used for development only.
+ bool ResetStatus(brillo::ErrorPtr* error);
+
+ // Returns the current status of the Update Engine. If an update is in
+ // progress, the number of operations, size to download and overall progress
+ // is reported.
+ bool GetStatus(brillo::ErrorPtr* error,
+ int64_t* out_last_checked_time,
+ double* out_progress,
+ std::string* out_current_operation,
+ std::string* out_new_version,
+ int64_t* out_new_size);
+
+ // Reboots the device if an update is applied and a reboot is required.
+ bool RebootIfNeeded(brillo::ErrorPtr* error);
+
+ // Changes the current channel of the device to the target channel. If the
+ // target channel is a less stable channel than the current channel, then the
+ // channel change happens immediately (at the next update check). If the
+ // target channel is a more stable channel, then if is_powerwash_allowed is
+ // set to true, then also the change happens immediately but with a powerwash
+ // if required. Otherwise, the change takes effect eventually (when the
+ // version on the target channel goes above the version number of what the
+ // device currently has).
+ bool SetChannel(brillo::ErrorPtr* error,
+ const std::string& in_target_channel,
+ bool in_is_powerwash_allowed);
+
+ // If get_current_channel is set to true, populates |channel| with the name of
+ // the channel that the device is currently on. Otherwise, it populates it
+ // with the name of the channel the device is supposed to be (in case of a
+ // pending channel change).
+ bool GetChannel(brillo::ErrorPtr* error,
+ bool in_get_current_channel,
+ std::string* out_channel);
+
+ // Enables or disables the sharing and consuming updates over P2P feature
+ // according to the |enabled| argument passed.
+ bool SetP2PUpdatePermission(brillo::ErrorPtr* error, bool in_enabled);
+
+ // Returns the current value for the P2P enabled setting. This involves both
+ // sharing and consuming updates over P2P.
+ bool GetP2PUpdatePermission(brillo::ErrorPtr* error, bool* out_enabled);
+
+ // If there's no device policy installed, sets the update over cellular
+ // networks permission to the |allowed| value. Otherwise, this method returns
+ // with an error since this setting is overridden by the applied policy.
+ bool SetUpdateOverCellularPermission(brillo::ErrorPtr* error,
+ bool in_allowed);
+
+ // Returns the current value of the update over cellular network setting,
+ // either forced by the device policy if the device is enrolled or the current
+ // user preference otherwise.
+ bool GetUpdateOverCellularPermission(brillo::ErrorPtr* error,
+ bool* out_allowed);
+
+ // Returns the duration since the last successful update, as the
+ // duration on the wallclock. Returns an error if the device has not
+ // updated.
+ bool GetDurationSinceUpdate(brillo::ErrorPtr* error,
+ int64_t* out_usec_wallclock);
+
+ // Returns the version string of OS that was used before the last reboot
+ // into an updated version. This is available only when rebooting into an
+ // update from previous version, otherwise an empty string is returned.
+ bool GetPrevVersion(brillo::ErrorPtr* error, std::string* out_prev_version);
+
+ // Returns the name of kernel partition that can be rolled back into.
+ bool GetRollbackPartition(brillo::ErrorPtr* error,
+ std::string* out_rollback_partition_name);
+
+ private:
+ SystemState* system_state_;
+};
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_COMMON_SERVICE_H_
diff --git a/dbus_service_unittest.cc b/common_service_unittest.cc
similarity index 76%
rename from dbus_service_unittest.cc
rename to common_service_unittest.cc
index db63b2d..1c144d1 100644
--- a/dbus_service_unittest.cc
+++ b/common_service_unittest.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#include "update_engine/dbus_service.h"
+#include "update_engine/common_service.h"
#include <gtest/gtest.h>
#include <string>
@@ -22,16 +22,13 @@
#include <brillo/errors/error.h>
#include <policy/libpolicy.h>
#include <policy/mock_device_policy.h>
-#include <update_engine/dbus-constants.h>
#include "update_engine/fake_system_state.h"
-using brillo::errors::dbus::kDomain;
using std::string;
using testing::Return;
using testing::SetArgumentPointee;
using testing::_;
-using update_engine::kUpdateEngineServiceErrorFailed;
namespace chromeos_update_engine {
@@ -39,7 +36,7 @@
protected:
UpdateEngineServiceTest()
: mock_update_attempter_(fake_system_state_.mock_update_attempter()),
- dbus_service_(&fake_system_state_) {}
+ common_service_(&fake_system_state_) {}
void SetUp() override {
fake_system_state_.set_device_policy(nullptr);
@@ -53,24 +50,16 @@
MockUpdateAttempter* mock_update_attempter_;
brillo::ErrorPtr error_;
- UpdateEngineService dbus_service_;
+ UpdateEngineService common_service_;
};
TEST_F(UpdateEngineServiceTest, AttemptUpdate) {
- // Simple test to ensure that the default is an interactive check.
- EXPECT_CALL(*mock_update_attempter_,
- CheckForUpdate("app_ver", "url", true /* interactive */));
- EXPECT_TRUE(dbus_service_.AttemptUpdate(&error_, "app_ver", "url"));
- EXPECT_EQ(nullptr, error_);
-}
-
-TEST_F(UpdateEngineServiceTest, AttemptUpdateWithFlags) {
EXPECT_CALL(*mock_update_attempter_, CheckForUpdate(
"app_ver", "url", false /* interactive */));
// The update is non-interactive when we pass the non-interactive flag.
- EXPECT_TRUE(dbus_service_.AttemptUpdateWithFlags(
+ EXPECT_TRUE(common_service_.AttemptUpdate(
&error_, "app_ver", "url",
- update_engine::kAttemptUpdateFlagNonInteractive));
+ UpdateEngineService::kAttemptUpdateFlagNonInteractive));
EXPECT_EQ(nullptr, error_);
}
@@ -82,7 +71,7 @@
EXPECT_CALL(*fake_system_state_.mock_request_params(),
SetTargetChannel("stable-channel", true, _))
.WillOnce(Return(true));
- EXPECT_TRUE(dbus_service_.SetChannel(&error_, "stable-channel", true));
+ EXPECT_TRUE(common_service_.SetChannel(&error_, "stable-channel", true));
ASSERT_EQ(nullptr, error_);
}
@@ -96,7 +85,7 @@
SetTargetChannel("beta-channel", true, _))
.WillOnce(Return(true));
- EXPECT_TRUE(dbus_service_.SetChannel(&error_, "beta-channel", true));
+ EXPECT_TRUE(common_service_.SetChannel(&error_, "beta-channel", true));
ASSERT_EQ(nullptr, error_);
}
@@ -107,21 +96,22 @@
EXPECT_CALL(*fake_system_state_.mock_request_params(),
SetTargetChannel("foo-channel", true, _)).WillOnce(Return(false));
- EXPECT_FALSE(dbus_service_.SetChannel(&error_, "foo-channel", true));
+ EXPECT_FALSE(common_service_.SetChannel(&error_, "foo-channel", true));
ASSERT_NE(nullptr, error_);
- EXPECT_TRUE(error_->HasError(kDomain, kUpdateEngineServiceErrorFailed));
+ EXPECT_TRUE(error_->HasError(UpdateEngineService::kErrorDomain,
+ UpdateEngineService::kErrorFailed));
}
TEST_F(UpdateEngineServiceTest, GetChannel) {
fake_system_state_.mock_request_params()->set_current_channel("current");
fake_system_state_.mock_request_params()->set_target_channel("target");
string channel;
- EXPECT_TRUE(dbus_service_.GetChannel(
+ EXPECT_TRUE(common_service_.GetChannel(
&error_, true /* get_current_channel */, &channel));
EXPECT_EQ(nullptr, error_);
EXPECT_EQ("current", channel);
- EXPECT_TRUE(dbus_service_.GetChannel(
+ EXPECT_TRUE(common_service_.GetChannel(
&error_, false /* get_current_channel */, &channel));
EXPECT_EQ(nullptr, error_);
EXPECT_EQ("target", channel);
@@ -129,15 +119,16 @@
TEST_F(UpdateEngineServiceTest, ResetStatusSucceeds) {
EXPECT_CALL(*mock_update_attempter_, ResetStatus()).WillOnce(Return(true));
- EXPECT_TRUE(dbus_service_.ResetStatus(&error_));
+ EXPECT_TRUE(common_service_.ResetStatus(&error_));
EXPECT_EQ(nullptr, error_);
}
TEST_F(UpdateEngineServiceTest, ResetStatusFails) {
EXPECT_CALL(*mock_update_attempter_, ResetStatus()).WillOnce(Return(false));
- EXPECT_FALSE(dbus_service_.ResetStatus(&error_));
+ EXPECT_FALSE(common_service_.ResetStatus(&error_));
ASSERT_NE(nullptr, error_);
- EXPECT_TRUE(error_->HasError(kDomain, kUpdateEngineServiceErrorFailed));
+ EXPECT_TRUE(error_->HasError(UpdateEngineService::kErrorDomain,
+ UpdateEngineService::kErrorFailed));
}
} // namespace chromeos_update_engine
diff --git a/daemon.cc b/daemon.cc
index f7f2170..cc528a4 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -21,9 +21,9 @@
#include <base/bind.h>
#include <base/location.h>
#include <base/time/time.h>
-#if USE_WEAVE
+#if USE_WEAVE || USE_BINDER
#include <binderwrapper/binder_wrapper.h>
-#endif // USE_WEAVE
+#endif // USE_WEAVE || USE_BINDER
#include <brillo/message_loops/message_loop.h>
#include "update_engine/update_attempter.h"
@@ -45,10 +45,10 @@
if (exit_code != EX_OK)
return exit_code;
-#if USE_WEAVE
+#if USE_WEAVE || USE_BINDER
android::BinderWrapper::Create();
binder_watcher_.Init();
-#endif // USE_WEAVE
+#endif // USE_WEAVE || USE_BINDER
// We wait for the D-Bus connection for up two minutes to avoid re-spawning
// the daemon too fast causing thrashing if dbus-daemon is not running.
@@ -71,6 +71,18 @@
UpdateAttempter* update_attempter = real_system_state_->update_attempter();
CHECK(update_attempter);
+#if USE_BINDER
+ // Create the Binder Service
+ service_ = new BinderUpdateEngineService{real_system_state_.get()};
+ auto binder_wrapper = android::BinderWrapper::Get();
+ sleep(10);
+ if (!binder_wrapper->RegisterService("android.brillo.UpdateEngineService",
+ service_)) {
+ LOG(ERROR) << "Failed to register binder service.";
+ }
+
+#endif // USE_BINDER
+
// Create the DBus service.
dbus_adaptor_.reset(new UpdateEngineAdaptor(real_system_state_.get(), bus));
update_attempter->set_dbus_adaptor(dbus_adaptor_.get());
diff --git a/daemon.h b/daemon.h
index 31c4bf4..6233064 100644
--- a/daemon.h
+++ b/daemon.h
@@ -20,12 +20,15 @@
#include <memory>
#include <string>
-#if USE_WEAVE
+#if USE_WEAVE || USE_BINDER
#include <brillo/binder_watcher.h>
-#endif // USE_WEAVE
+#endif // USE_WEAVE || USE_BINDER
#include <brillo/daemons/daemon.h>
#include <brillo/dbus/dbus_connection.h>
+#if USE_BINDER
+#include "update_engine/binder_service.h"
+#endif // USE_BINDER
#include "update_engine/common/subprocess.h"
#include "update_engine/dbus_service.h"
#include "update_engine/real_system_state.h"
@@ -54,9 +57,13 @@
// the main() function.
Subprocess subprocess_;
-#if USE_WEAVE
+#if USE_WEAVE || USE_BINDER
brillo::BinderWatcher binder_watcher_;
-#endif // USE_WEAVE
+#endif // USE_WEAVE || USE_BINDER
+
+#if USE_BINDER
+ android::sp<BinderUpdateEngineService> service_;
+#endif // USE_BINDER
// The RealSystemState uses the previous classes so it should be defined last.
std::unique_ptr<RealSystemState> real_system_state_;
diff --git a/dbus_service.cc b/dbus_service.cc
index 062c17d..81a6efd 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -15,311 +15,119 @@
//
#include "update_engine/dbus_service.h"
-
-#include <set>
-#include <string>
-
-#include <base/location.h>
-#include <base/logging.h>
-#include <base/strings/stringprintf.h>
-#include <brillo/bind_lambda.h>
-#include <brillo/message_loops/message_loop.h>
-#include <brillo/strings/string_utils.h>
-#include <policy/device_policy.h>
-#include <update_engine/dbus-constants.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/connection_manager_interface.h"
-#include "update_engine/omaha_request_params.h"
-#include "update_engine/p2p_manager.h"
-#include "update_engine/update_attempter.h"
-
-using base::StringPrintf;
-using brillo::ErrorPtr;
-using brillo::string_utils::ToString;
-using std::set;
-using std::string;
-using update_engine::AttemptUpdateFlags;
-using update_engine::kAttemptUpdateFlagNonInteractive;
-
-namespace {
-// Log and set the error on the passed ErrorPtr.
-void LogAndSetError(ErrorPtr *error,
- const tracked_objects::Location& location,
- const string& reason) {
- brillo::Error::AddTo(
- error, location,
- brillo::errors::dbus::kDomain,
- update_engine::kUpdateEngineServiceErrorFailed, reason);
- LOG(ERROR) << "Sending DBus Failure: " << location.ToString() << ": "
- << reason;
-}
-} // namespace
+#include "update_engine/dbus-constants.h"
namespace chromeos_update_engine {
-UpdateEngineService::UpdateEngineService(SystemState* system_state)
- : system_state_(system_state) {}
+using brillo::ErrorPtr;
+using std::string;
+using chromeos_update_engine::UpdateEngineService;
+
+DBusUpdateEngineService::DBusUpdateEngineService(SystemState* system_state)
+ : common_(new UpdateEngineService{system_state}) {
+}
// org::chromium::UpdateEngineInterfaceInterface methods implementation.
-bool UpdateEngineService::AttemptUpdate(ErrorPtr* error,
- const string& in_app_version,
- const string& in_omaha_url) {
+bool DBusUpdateEngineService::AttemptUpdate(ErrorPtr* error,
+ const string& in_app_version,
+ const string& in_omaha_url) {
return AttemptUpdateWithFlags(
error, in_app_version, in_omaha_url, 0 /* no flags */);
}
-bool UpdateEngineService::AttemptUpdateWithFlags(ErrorPtr* /* error */,
- const string& in_app_version,
- const string& in_omaha_url,
- int32_t in_flags_as_int) {
- AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(in_flags_as_int);
- bool interactive = !(flags & kAttemptUpdateFlagNonInteractive);
+bool DBusUpdateEngineService::AttemptUpdateWithFlags(
+ ErrorPtr* error,
+ const string& in_app_version,
+ const string& in_omaha_url,
+ int32_t in_flags_as_int) {
+ update_engine::AttemptUpdateFlags flags =
+ static_cast<update_engine::AttemptUpdateFlags>(in_flags_as_int);
+ bool interactive = !(flags &
+ update_engine::kAttemptUpdateFlagNonInteractive);
- LOG(INFO) << "Attempt update: app_version=\"" << in_app_version << "\" "
- << "omaha_url=\"" << in_omaha_url << "\" "
- << "flags=0x" << std::hex << flags << " "
- << "interactive=" << (interactive? "yes" : "no");
- system_state_->update_attempter()->CheckForUpdate(
- in_app_version, in_omaha_url, interactive);
- return true;
+ return common_->AttemptUpdate(
+ error, in_app_version, in_omaha_url,
+ interactive ? 0 : UpdateEngineService::kAttemptUpdateFlagNonInteractive);
}
-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 DBusUpdateEngineService::AttemptRollback(ErrorPtr* error,
+ bool in_powerwash) {
+ return common_->AttemptRollback(error, in_powerwash);
}
-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 DBusUpdateEngineService::CanRollback(ErrorPtr* error,
+ bool* out_can_rollback) {
+ return common_->CanRollback(error, out_can_rollback);
}
-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 DBusUpdateEngineService::ResetStatus(ErrorPtr* error) {
+ return common_->ResetStatus(error);
}
-bool UpdateEngineService::GetStatus(ErrorPtr* error,
- int64_t* out_last_checked_time,
- double* out_progress,
- string* out_current_operation,
- string* out_new_version,
- int64_t* out_new_size) {
- if (!system_state_->update_attempter()->GetStatus(out_last_checked_time,
- out_progress,
- out_current_operation,
- out_new_version,
- out_new_size)) {
- LogAndSetError(error, FROM_HERE, "GetStatus failed.");
- return false;
- }
- return true;
+bool DBusUpdateEngineService::GetStatus(ErrorPtr* error,
+ int64_t* out_last_checked_time,
+ double* out_progress,
+ string* out_current_operation,
+ string* out_new_version,
+ int64_t* out_new_size) {
+ return common_->GetStatus(error,
+ out_last_checked_time,
+ out_progress,
+ out_current_operation,
+ out_new_version,
+ out_new_size);
}
-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 DBusUpdateEngineService::RebootIfNeeded(ErrorPtr* error) {
+ return common_->RebootIfNeeded(error);
}
-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;
- }
- // Update the weave state because updated the target channel.
- if (system_state_->weave_service())
- system_state_->weave_service()->UpdateWeaveState();
- return true;
+bool DBusUpdateEngineService::SetChannel(ErrorPtr* error,
+ const string& in_target_channel,
+ bool in_is_powerwash_allowed) {
+ return common_->SetChannel(error, in_target_channel, in_is_powerwash_allowed);
}
-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 DBusUpdateEngineService::GetChannel(ErrorPtr* error,
+ bool in_get_current_channel,
+ string* out_channel) {
+ return common_->GetChannel(error, in_get_current_channel, out_channel);
}
-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 DBusUpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
+ bool in_enabled) {
+ return common_->SetP2PUpdatePermission(error, in_enabled);
}
-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 DBusUpdateEngineService::GetP2PUpdatePermission(ErrorPtr* error,
+ bool* out_enabled) {
+ return common_->GetP2PUpdatePermission(error, out_enabled);
}
-bool UpdateEngineService::SetUpdateOverCellularPermission(ErrorPtr* error,
- bool in_allowed) {
- set<string> allowed_types;
- 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();
- }
- }
-
- // Check if this setting is allowed by the device policy.
- if (device_policy &&
- device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
- 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->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 DBusUpdateEngineService::SetUpdateOverCellularPermission(ErrorPtr* error,
+ bool in_allowed) {
+ return common_->SetUpdateOverCellularPermission(error, in_allowed);
}
-bool UpdateEngineService::GetUpdateOverCellularPermission(ErrorPtr* /* error */,
- bool* out_allowed) {
- ConnectionManagerInterface* cm = system_state_->connection_manager();
-
- // The device_policy is loaded in a lazy way before an update check and is
- // used to determine if an update is allowed over cellular. Load the device
- // policy now from the libbrillo cache if it wasn't already loaded.
- if (!system_state_->device_policy()) {
- UpdateAttempter* update_attempter = system_state_->update_attempter();
- if (update_attempter)
- update_attempter->RefreshDevicePolicy();
- }
-
- // Return the current setting based on the same logic used while checking for
- // updates. A log message could be printed as the result of this test.
- LOG(INFO) << "Checking if updates over cellular networks are allowed:";
- *out_allowed = cm->IsUpdateAllowedOver(
- chromeos_update_engine::NetworkConnectionType::kCellular,
- chromeos_update_engine::NetworkTethering::kUnknown);
- return true;
+bool DBusUpdateEngineService::GetUpdateOverCellularPermission(
+ ErrorPtr* error, bool* out_allowed) {
+ return common_->GetUpdateOverCellularPermission(error, out_allowed);
}
-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 DBusUpdateEngineService::GetDurationSinceUpdate(
+ ErrorPtr* error, int64_t* out_usec_wallclock) {
+ return common_->GetDurationSinceUpdate(error, out_usec_wallclock);
}
-bool UpdateEngineService::GetPrevVersion(ErrorPtr* /* error */,
- string* out_prev_version) {
- *out_prev_version = system_state_->update_attempter()->GetPrevVersion();
- return true;
+bool DBusUpdateEngineService::GetPrevVersion(ErrorPtr* error,
+ string* out_prev_version) {
+ return common_->GetPrevVersion(error, out_prev_version);
}
-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 DBusUpdateEngineService::GetRollbackPartition(
+ ErrorPtr* error, string* out_rollback_partition_name) {
+ return common_->GetRollbackPartition(error, out_rollback_partition_name);
}
UpdateEngineAdaptor::UpdateEngineAdaptor(SystemState* system_state,
diff --git a/dbus_service.h b/dbus_service.h
index 88bd90a..eb05a11 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -24,17 +24,18 @@
#include <base/memory/ref_counted.h>
#include <brillo/errors/error.h>
+#include "update_engine/common_service.h"
#include "update_engine/update_attempter.h"
#include "dbus_bindings/org.chromium.UpdateEngineInterface.h"
namespace chromeos_update_engine {
-class UpdateEngineService
+class DBusUpdateEngineService
: public org::chromium::UpdateEngineInterfaceInterface {
public:
- explicit UpdateEngineService(SystemState* system_state);
- virtual ~UpdateEngineService() = default;
+ explicit DBusUpdateEngineService(SystemState* system_state);
+ virtual ~DBusUpdateEngineService() = default;
// Implementation of org::chromium::UpdateEngineInterfaceInterface.
bool AttemptUpdate(brillo::ErrorPtr* error,
@@ -128,7 +129,7 @@
std::string* out_rollback_partition_name) override;
private:
- SystemState* system_state_;
+ std::unique_ptr<UpdateEngineService> common_;
};
// The UpdateEngineAdaptor class runs the UpdateEngineInterface in the fixed
@@ -151,7 +152,7 @@
private:
scoped_refptr<dbus::Bus> bus_;
- UpdateEngineService dbus_service_;
+ DBusUpdateEngineService dbus_service_;
brillo::dbus_utils::DBusObject dbus_object_;
};
diff --git a/parcelable_update_engine_status.cc b/parcelable_update_engine_status.cc
new file mode 100644
index 0000000..d8eb6db
--- /dev/null
+++ b/parcelable_update_engine_status.cc
@@ -0,0 +1,77 @@
+//
+// 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/parcelable_update_engine_status.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace brillo {
+
+status_t ParcelableUpdateEngineStatus::writeToParcel(Parcel* parcel) const {
+ status_t status;
+
+ status = parcel->writeInt64(last_checked_time_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->writeDouble(progress_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->writeString16(current_operation_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->writeString16(new_version_);
+ if (status != OK) {
+ return status;
+ }
+
+ return parcel->writeInt64(new_size_);
+}
+
+status_t ParcelableUpdateEngineStatus::readFromParcel(const Parcel* parcel) {
+ status_t status;
+
+ status = parcel->readInt64(&last_checked_time_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->readDouble(&progress_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->readString16(¤t_operation_);
+ if (status != OK) {
+ return status;
+ }
+
+ status = parcel->readString16(&new_version_);
+ if (status != OK) {
+ return status;
+ }
+
+ return parcel->readInt64(&new_size_);
+}
+
+} // namespace brillo
+} // namespace android
diff --git a/parcelable_update_engine_status.h b/parcelable_update_engine_status.h
new file mode 100644
index 0000000..2cfedd9
--- /dev/null
+++ b/parcelable_update_engine_status.h
@@ -0,0 +1,46 @@
+//
+// 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_UPDATE_ENGINE_STATUS_H_
+#define UPDATE_ENGINE_UPDATE_ENGINE_STATUS_H_
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+
+namespace android {
+namespace brillo {
+
+// Parcelable object containing the current status of update engine, to be sent
+// over binder to clients from the server.
+class ParcelableUpdateEngineStatus : public Parcelable {
+ public:
+ ParcelableUpdateEngineStatus() = default;
+ virtual ~ParcelableUpdateEngineStatus() = default;
+
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+ int64_t last_checked_time_;
+ double progress_;
+ android::String16 current_operation_;
+ android::String16 new_version_;
+ int64_t new_size_;
+};
+
+} // namespace brillo
+} // namespace android
+
+#endif // UPDATE_ENGINE_UPDATE_ENGINE_STATUS_H_
diff --git a/update_engine.gyp b/update_engine.gyp
index 5490a2a..a44bdee 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -47,6 +47,7 @@
'defines': [
'_FILE_OFFSET_BITS=64',
'_POSIX_C_SOURCE=199309L',
+ 'USE_BINDER=0',
'USE_DBUS=<(USE_dbus)',
'USE_HWID_OVERRIDE=<(USE_hwid_override)',
'USE_MTD=<(USE_mtd)',
@@ -242,6 +243,7 @@
'sources': [
'boot_control_chromeos.cc',
'chrome_browser_proxy_resolver.cc',
+ 'common_service.cc',
'connection_manager.cc',
'daemon.cc',
'dbus_service.cc',
@@ -312,7 +314,7 @@
},
'sources': [
'client_library/client.cc',
- 'client_library/client_impl.cc',
+ 'client_library/client_dbus.cc',
'update_status_utils.cc',
],
'include_dirs': [
@@ -483,8 +485,8 @@
'common/terminator_unittest.cc',
'common/test_utils.cc',
'common/utils_unittest.cc',
+ 'common_service_unittest.cc',
'connection_manager_unittest.cc',
- 'dbus_service_unittest.cc',
'fake_shill_proxy.cc',
'fake_system_state.cc',
'metrics_utils_unittest.cc',