1ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// Copyright 2015 The Android Open Source Project 2ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// 3ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// Licensed under the Apache License, Version 2.0 (the "License"); 4ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// you may not use this file except in compliance with the License. 5ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// You may obtain a copy of the License at 6ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// 7ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// http://www.apache.org/licenses/LICENSE-2.0 8ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// 9ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// Unless required by applicable law or agreed to in writing, software 10ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// distributed under the License is distributed on an "AS IS" BASIS, 11ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// See the License for the specific language governing permissions and 13ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko// limitations under the License. 14ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko 15ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko#include "libweaved/command.h" 16ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko 17ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko#include "android/weave/IWeaveCommand.h" 18ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko#include "common/binder_utils.h" 19ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko 20ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkousing weaved::binder_utils::ParseDictionary; 21ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkousing weaved::binder_utils::ToString; 22ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkousing weaved::binder_utils::ToString16; 23ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkousing weaved::binder_utils::StatusToError; 24abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 25abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenkonamespace weaved { 26abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 2713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkonamespace { 2813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 2913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko// Converts binder exception code into a weave error code string. 3013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkostd::string BinderExceptionString(int32_t exception_code) { 3113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko if (exception_code == android::binder::Status::EX_NONE) 3213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_none"; 3313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_SECURITY) 3413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_security"; 3513d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_BAD_PARCELABLE) 3613d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_bad_parcelable"; 3713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_ILLEGAL_ARGUMENT) 3813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_illegal_argument"; 3913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_NULL_POINTER) 4013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_null_pointer"; 4113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_ILLEGAL_STATE) 4213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_illegal_state"; 4313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_NETWORK_MAIN_THREAD) 4413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_network_error"; 4513d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_UNSUPPORTED_OPERATION) 4613d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_unsupported_operation"; 4713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko else if (exception_code == android::binder::Status::EX_SERVICE_SPECIFIC) 4813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_general_failure"; 4913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 5013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return "_unknown"; 5113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 5213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 5313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} // anonymous namespace 5413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 55ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex VakulenkoCommand::Command(const android::sp<android::weave::IWeaveCommand>& proxy) 56ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko : binder_proxy_{proxy} {} 57ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko 58ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex VakulenkoCommand::~Command() {} 59abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 60ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkostd::string Command::GetID() const { 61ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko std::string id; 62ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko android::String16 id16; 63ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko if (binder_proxy_->getId(&id16).isOk()) 64ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko id.assign(ToString(id16)); 65ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko return id; 66abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 67abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 68ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkostd::string Command::GetName() const { 69ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko std::string name; 70ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko android::String16 name16; 71ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko if (binder_proxy_->getId(&name16).isOk()) 72ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko name.assign(ToString(name16)); 73ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko return name; 74abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 75abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 76ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenkostd::string Command::GetComponent() const { 77ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko std::string component; 78ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko android::String16 component16; 79ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko if (binder_proxy_->getId(&component16).isOk()) 80ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko component.assign(ToString(component16)); 81ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko return component; 823bd3ececdd8ab45b6b2e81c8fbbbe60c850c2a2cAlex Vakulenko} 833bd3ececdd8ab45b6b2e81c8fbbbe60c850c2a2cAlex Vakulenko 84abbcdea13c174d70cc4af0abd0dadb091a698da8Alex VakulenkoCommand::State Command::GetState() const { 85ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko std::string state; 86ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko android::String16 state16; 87ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko if (binder_proxy_->getState(&state16).isOk()) 88ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko state.assign(ToString(state16)); 89abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko if (state == "queued") 90abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kQueued; 91abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "inProgress") 92abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kInProgress; 93abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "paused") 94abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kPaused; 95abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "error") 96abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kError; 97abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "done") 98abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kDone; 99abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "cancelled") 100abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kCancelled; 101abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "aborted") 102abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kAborted; 103abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (state == "expired") 104abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kExpired; 105abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko LOG(WARNING) << "Unknown command state: " << state; 106abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::State::kQueued; 107abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 108abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 109abbcdea13c174d70cc4af0abd0dadb091a698da8Alex VakulenkoCommand::Origin Command::GetOrigin() const { 110ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko std::string origin; 111ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko android::String16 origin16; 112ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko if (binder_proxy_->getState(&origin16).isOk()) 113ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko origin.assign(ToString(origin16)); 114abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko if (origin == "local") 115abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::Origin::kLocal; 116abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko else if (origin == "cloud") 117abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::Origin::kCloud; 118abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko LOG(WARNING) << "Unknown command origin: " << origin; 119abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko return Command::Origin::kLocal; 120abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 121abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 122e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenkoconst base::DictionaryValue& Command::GetParameters() const { 123e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko if (!parameter_cache_) { 124e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko android::String16 params_string16; 125e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko if (!binder_proxy_->getParameters(¶ms_string16).isOk() || 126e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko !ParseDictionary(params_string16, ¶meter_cache_).isOk()) { 127e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko parameter_cache_.reset(new base::DictionaryValue); 128e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko } 129ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko } 130e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko return *parameter_cache_; 131abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 132abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 133e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenkobool Command::SetProgress(const base::DictionaryValue& progress, 1344170585fe75d99036883229081420f2972dd4ec1Alex Vakulenko brillo::ErrorPtr* error) { 135e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko return StatusToError(binder_proxy_->setProgress(ToString16(progress)), error); 136abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 137abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 138e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenkobool Command::Complete(const base::DictionaryValue& results, 1394170585fe75d99036883229081420f2972dd4ec1Alex Vakulenko brillo::ErrorPtr* error) { 140e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko return StatusToError(binder_proxy_->complete(ToString16(results)), error); 141abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 142abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 143abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenkobool Command::Abort(const std::string& error_code, 144abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko const std::string& error_message, 1454170585fe75d99036883229081420f2972dd4ec1Alex Vakulenko brillo::ErrorPtr* error) { 146ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko return StatusToError(binder_proxy_->abort(ToString16(error_code), 147ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko ToString16(error_message)), 148ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko error); 149abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 150abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 15113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::AbortWithCustomError(const brillo::Error* command_error, 15213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko brillo::ErrorPtr* error) { 15313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko std::string error_code = "_" + command_error->GetCode(); 15413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return Abort(error_code, command_error->GetMessage(), error); 15513d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 15613d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 15713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::AbortWithCustomError(android::binder::Status status, 15813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko brillo::ErrorPtr* error) { 15913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko std::string error_code = BinderExceptionString(status.exceptionCode()); 16013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return Abort(error_code, status.exceptionMessage().string(), error); 16113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 16213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 1634170585fe75d99036883229081420f2972dd4ec1Alex Vakulenkobool Command::Cancel(brillo::ErrorPtr* error) { 164ae29f7d91a0b4178556eeb6b99fd05d90fcefd3dAlex Vakulenko return StatusToError(binder_proxy_->cancel(), error); 165abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} 166abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko 16713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::Pause(brillo::ErrorPtr* error) { 16813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return StatusToError(binder_proxy_->pause(), error); 16913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 17013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 17113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::SetError(const std::string& error_code, 17213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko const std::string& error_message, 17313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko brillo::ErrorPtr* error) { 17413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return StatusToError(binder_proxy_->setError(ToString16(error_code), 17513d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko ToString16(error_message)), 17613d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko error); 17713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 17813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 17913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::SetCustomError(const brillo::Error* command_error, 18013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko brillo::ErrorPtr* error) { 18113d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko std::string error_code = "_" + command_error->GetCode(); 18213d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return SetError(error_code, command_error->GetMessage(), error); 18313d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 18413d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 18513d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenkobool Command::SetCustomError(android::binder::Status status, 18613d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko brillo::ErrorPtr* error) { 18713d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko std::string error_code = BinderExceptionString(status.exceptionCode()); 18813d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko return SetError(error_code, status.exceptionMessage().string(), error); 18913d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko} 19013d115ca0f3961ea7084f68795f8fd887b369be4Alex Vakulenko 191abbcdea13c174d70cc4af0abd0dadb091a698da8Alex Vakulenko} // namespace weave 192