// // 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_brillo.h" #include <base/bind.h> #include <binderwrapper/binder_wrapper.h> #include <utils/String16.h> #include <utils/StrongPointer.h> #include "update_engine/update_status_utils.h" using android::String16; using android::String8; using android::binder::Status; using android::brillo::IUpdateEngineStatusCallback; using android::brillo::ParcelableUpdateEngineStatus; using android::sp; using brillo::ErrorPtr; using std::string; namespace chromeos_update_engine { namespace { string NormalString(const String16& in) { return string{String8{in}.string()}; } Status ToStatus(ErrorPtr* error) { return Status::fromServiceSpecificError( 1, String8{error->get()->GetMessage().c_str()}); } } // namespace template <typename... Parameters, typename... Arguments> Status BinderUpdateEngineBrilloService::CallCommonHandler( bool (UpdateEngineService::*Handler)(ErrorPtr*, Parameters...), Arguments... arguments) { ErrorPtr error; if (((common_.get())->*Handler)(&error, arguments...)) return Status::ok(); return ToStatus(&error); } Status BinderUpdateEngineBrilloService::AttemptUpdate( const String16& app_version, const String16& omaha_url, int flags) { return CallCommonHandler(&UpdateEngineService::AttemptUpdate, NormalString(app_version), NormalString(omaha_url), flags); } Status BinderUpdateEngineBrilloService::AttemptRollback(bool powerwash) { return CallCommonHandler(&UpdateEngineService::AttemptRollback, powerwash); } Status BinderUpdateEngineBrilloService::CanRollback(bool* out_can_rollback) { return CallCommonHandler(&UpdateEngineService::CanRollback, out_can_rollback); } Status BinderUpdateEngineBrilloService::ResetStatus() { return CallCommonHandler(&UpdateEngineService::ResetStatus); } Status BinderUpdateEngineBrilloService::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 BinderUpdateEngineBrilloService::RebootIfNeeded() { return CallCommonHandler(&UpdateEngineService::RebootIfNeeded); } Status BinderUpdateEngineBrilloService::SetChannel( const String16& target_channel, bool powerwash) { return CallCommonHandler(&UpdateEngineService::SetChannel, NormalString(target_channel), powerwash); } Status BinderUpdateEngineBrilloService::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 BinderUpdateEngineBrilloService::SetP2PUpdatePermission(bool enabled) { return CallCommonHandler(&UpdateEngineService::SetP2PUpdatePermission, enabled); } Status BinderUpdateEngineBrilloService::GetP2PUpdatePermission( bool* out_p2p_permission) { return CallCommonHandler(&UpdateEngineService::GetP2PUpdatePermission, out_p2p_permission); } Status BinderUpdateEngineBrilloService::SetUpdateOverCellularPermission( bool enabled) { return CallCommonHandler( &UpdateEngineService::SetUpdateOverCellularPermission, enabled); } Status BinderUpdateEngineBrilloService::GetUpdateOverCellularPermission( bool* out_cellular_permission) { return CallCommonHandler( &UpdateEngineService::GetUpdateOverCellularPermission, out_cellular_permission); } Status BinderUpdateEngineBrilloService::GetDurationSinceUpdate( int64_t* out_duration) { return CallCommonHandler(&UpdateEngineService::GetDurationSinceUpdate, out_duration); } Status BinderUpdateEngineBrilloService::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 BinderUpdateEngineBrilloService::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 BinderUpdateEngineBrilloService::RegisterStatusCallback( const sp<IUpdateEngineStatusCallback>& callback) { callbacks_.emplace_back(callback); auto binder_wrapper = android::BinderWrapper::Get(); binder_wrapper->RegisterForDeathNotifications( IUpdateEngineStatusCallback::asBinder(callback), base::Bind(&BinderUpdateEngineBrilloService::UnregisterStatusCallback, base::Unretained(this), base::Unretained(callback.get()))); return Status::ok(); } Status BinderUpdateEngineBrilloService::GetLastAttemptError( int* out_last_attempt_error) { return CallCommonHandler(&UpdateEngineService::GetLastAttemptError, out_last_attempt_error); } void BinderUpdateEngineBrilloService::UnregisterStatusCallback( IUpdateEngineStatusCallback* callback) { auto it = callbacks_.begin(); for (; it != callbacks_.end() && it->get() != callback; it++) ; if (it == callbacks_.end()) { LOG(ERROR) << "Got death notification for unknown callback."; return; } LOG(INFO) << "Erasing orphan callback"; callbacks_.erase(it); } void BinderUpdateEngineBrilloService::SendStatusUpdate( int64_t last_checked_time, double progress, update_engine::UpdateStatus status, const string& new_version, int64_t new_size) { const string str_status = UpdateStatusToString(status); for (auto& callback : callbacks_) { callback->HandleStatusUpdate(last_checked_time, progress, String16{str_status.c_str()}, String16{new_version.c_str()}, new_size); } } } // namespace chromeos_update_engine