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(&params_string16).isOk() ||
126e9a8385bccf042c9e80b69de18f3b58179309615Alex Vakulenko        !ParseDictionary(params_string16, &parameter_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