1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "libweaved/command.h"
16 
17 #include "android/weave/IWeaveCommand.h"
18 #include "common/binder_utils.h"
19 
20 using weaved::binder_utils::ParseDictionary;
21 using weaved::binder_utils::ToString;
22 using weaved::binder_utils::ToString16;
23 using weaved::binder_utils::StatusToError;
24 
25 namespace weaved {
26 
27 namespace {
28 
29 // Converts binder exception code into a weave error code string.
BinderExceptionString(int32_t exception_code)30 std::string BinderExceptionString(int32_t exception_code) {
31   if (exception_code == android::binder::Status::EX_NONE)
32     return "_none";
33   else if (exception_code == android::binder::Status::EX_SECURITY)
34     return "_security";
35   else if (exception_code == android::binder::Status::EX_BAD_PARCELABLE)
36     return "_bad_parcelable";
37   else if (exception_code == android::binder::Status::EX_ILLEGAL_ARGUMENT)
38     return "_illegal_argument";
39   else if (exception_code == android::binder::Status::EX_NULL_POINTER)
40     return "_null_pointer";
41   else if (exception_code == android::binder::Status::EX_ILLEGAL_STATE)
42     return "_illegal_state";
43   else if (exception_code == android::binder::Status::EX_NETWORK_MAIN_THREAD)
44     return "_network_error";
45   else if (exception_code == android::binder::Status::EX_UNSUPPORTED_OPERATION)
46     return "_unsupported_operation";
47   else if (exception_code == android::binder::Status::EX_SERVICE_SPECIFIC)
48     return "_general_failure";
49 
50   return "_unknown";
51 }
52 
53 }  // anonymous namespace
54 
Command(const android::sp<android::weave::IWeaveCommand> & proxy)55 Command::Command(const android::sp<android::weave::IWeaveCommand>& proxy)
56     : binder_proxy_{proxy} {}
57 
~Command()58 Command::~Command() {}
59 
GetID() const60 std::string Command::GetID() const {
61   std::string id;
62   android::String16 id16;
63   if (binder_proxy_->getId(&id16).isOk())
64     id.assign(ToString(id16));
65   return id;
66 }
67 
GetName() const68 std::string Command::GetName() const {
69   std::string name;
70   android::String16 name16;
71   if (binder_proxy_->getId(&name16).isOk())
72     name.assign(ToString(name16));
73   return name;
74 }
75 
GetComponent() const76 std::string Command::GetComponent() const {
77   std::string component;
78   android::String16 component16;
79   if (binder_proxy_->getId(&component16).isOk())
80     component.assign(ToString(component16));
81   return component;
82 }
83 
GetState() const84 Command::State Command::GetState() const {
85   std::string state;
86   android::String16 state16;
87   if (binder_proxy_->getState(&state16).isOk())
88     state.assign(ToString(state16));
89   if (state == "queued")
90     return Command::State::kQueued;
91   else if (state == "inProgress")
92     return Command::State::kInProgress;
93   else if (state == "paused")
94     return Command::State::kPaused;
95   else if (state == "error")
96     return Command::State::kError;
97   else if (state == "done")
98     return Command::State::kDone;
99   else if (state == "cancelled")
100     return Command::State::kCancelled;
101   else if (state == "aborted")
102     return Command::State::kAborted;
103   else if (state == "expired")
104     return Command::State::kExpired;
105   LOG(WARNING) << "Unknown command state: " << state;
106   return Command::State::kQueued;
107 }
108 
GetOrigin() const109 Command::Origin Command::GetOrigin() const {
110   std::string origin;
111   android::String16 origin16;
112   if (binder_proxy_->getState(&origin16).isOk())
113     origin.assign(ToString(origin16));
114   if (origin == "local")
115     return Command::Origin::kLocal;
116   else if (origin == "cloud")
117     return Command::Origin::kCloud;
118   LOG(WARNING) << "Unknown command origin: " << origin;
119   return Command::Origin::kLocal;
120 }
121 
GetParameters() const122 const base::DictionaryValue& Command::GetParameters() const {
123   if (!parameter_cache_) {
124     android::String16 params_string16;
125     if (!binder_proxy_->getParameters(&params_string16).isOk() ||
126         !ParseDictionary(params_string16, &parameter_cache_).isOk()) {
127       parameter_cache_.reset(new base::DictionaryValue);
128     }
129   }
130   return *parameter_cache_;
131 }
132 
SetProgress(const base::DictionaryValue & progress,brillo::ErrorPtr * error)133 bool Command::SetProgress(const base::DictionaryValue& progress,
134                           brillo::ErrorPtr* error) {
135   return StatusToError(binder_proxy_->setProgress(ToString16(progress)), error);
136 }
137 
Complete(const base::DictionaryValue & results,brillo::ErrorPtr * error)138 bool Command::Complete(const base::DictionaryValue& results,
139                        brillo::ErrorPtr* error) {
140   return StatusToError(binder_proxy_->complete(ToString16(results)), error);
141 }
142 
Abort(const std::string & error_code,const std::string & error_message,brillo::ErrorPtr * error)143 bool Command::Abort(const std::string& error_code,
144                     const std::string& error_message,
145                     brillo::ErrorPtr* error) {
146   return StatusToError(binder_proxy_->abort(ToString16(error_code),
147                                             ToString16(error_message)),
148                        error);
149 }
150 
AbortWithCustomError(const brillo::Error * command_error,brillo::ErrorPtr * error)151 bool Command::AbortWithCustomError(const brillo::Error* command_error,
152                                    brillo::ErrorPtr* error) {
153   std::string error_code = "_" + command_error->GetCode();
154   return Abort(error_code, command_error->GetMessage(), error);
155 }
156 
AbortWithCustomError(android::binder::Status status,brillo::ErrorPtr * error)157 bool Command::AbortWithCustomError(android::binder::Status status,
158                                    brillo::ErrorPtr* error) {
159   std::string error_code = BinderExceptionString(status.exceptionCode());
160   return Abort(error_code, status.exceptionMessage().string(), error);
161 }
162 
Cancel(brillo::ErrorPtr * error)163 bool Command::Cancel(brillo::ErrorPtr* error) {
164   return StatusToError(binder_proxy_->cancel(), error);
165 }
166 
Pause(brillo::ErrorPtr * error)167 bool Command::Pause(brillo::ErrorPtr* error) {
168   return StatusToError(binder_proxy_->pause(), error);
169 }
170 
SetError(const std::string & error_code,const std::string & error_message,brillo::ErrorPtr * error)171 bool Command::SetError(const std::string& error_code,
172                        const std::string& error_message,
173                        brillo::ErrorPtr* error) {
174   return StatusToError(binder_proxy_->setError(ToString16(error_code),
175                                                ToString16(error_message)),
176                        error);
177 }
178 
SetCustomError(const brillo::Error * command_error,brillo::ErrorPtr * error)179 bool Command::SetCustomError(const brillo::Error* command_error,
180                              brillo::ErrorPtr* error) {
181   std::string error_code = "_" + command_error->GetCode();
182   return SetError(error_code, command_error->GetMessage(), error);
183 }
184 
SetCustomError(android::binder::Status status,brillo::ErrorPtr * error)185 bool Command::SetCustomError(android::binder::Status status,
186                              brillo::ErrorPtr* error) {
187   std::string error_code = BinderExceptionString(status.exceptionCode());
188   return SetError(error_code, status.exceptionMessage().string(), error);
189 }
190 
191 }  // namespace weave
192