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. 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 55 Command::Command(const android::sp<android::weave::IWeaveCommand>& proxy) 56 : binder_proxy_{proxy} {} 57 58 Command::~Command() {} 59 60 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 68 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 76 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 84 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 109 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 122 const base::DictionaryValue& Command::GetParameters() const { 123 if (!parameter_cache_) { 124 android::String16 params_string16; 125 if (!binder_proxy_->getParameters(¶ms_string16).isOk() || 126 !ParseDictionary(params_string16, ¶meter_cache_).isOk()) { 127 parameter_cache_.reset(new base::DictionaryValue); 128 } 129 } 130 return *parameter_cache_; 131 } 132 133 bool Command::SetProgress(const base::DictionaryValue& progress, 134 brillo::ErrorPtr* error) { 135 return StatusToError(binder_proxy_->setProgress(ToString16(progress)), error); 136 } 137 138 bool Command::Complete(const base::DictionaryValue& results, 139 brillo::ErrorPtr* error) { 140 return StatusToError(binder_proxy_->complete(ToString16(results)), error); 141 } 142 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 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 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 163 bool Command::Cancel(brillo::ErrorPtr* error) { 164 return StatusToError(binder_proxy_->cancel(), error); 165 } 166 167 bool Command::Pause(brillo::ErrorPtr* error) { 168 return StatusToError(binder_proxy_->pause(), error); 169 } 170 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 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 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