1 // 2 // Copyright (C) 2015 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/dbus/chromeos_manager_dbus_adaptor.h" 18 19 #include <map> 20 #include <string> 21 #include <vector> 22 23 #include "shill/callbacks.h" 24 #include "shill/dbus/dbus_service_watcher_factory.h" 25 #include "shill/device.h" 26 #include "shill/error.h" 27 #include "shill/geolocation_info.h" 28 #include "shill/key_value_store.h" 29 #include "shill/logging.h" 30 #include "shill/manager.h" 31 #include "shill/property_store.h" 32 33 using base::Unretained; 34 using std::map; 35 using std::string; 36 using std::vector; 37 38 namespace shill { 39 40 namespace Logging { 41 static auto kModuleLogScope = ScopeLogger::kDBus; 42 static string ObjectID(ChromeosManagerDBusAdaptor* m) { 43 return m->GetRpcIdentifier(); 44 } 45 } 46 47 // static 48 const char ChromeosManagerDBusAdaptor::kPath[] = "/"; 49 50 ChromeosManagerDBusAdaptor::ChromeosManagerDBusAdaptor( 51 const scoped_refptr<dbus::Bus>& adaptor_bus, 52 const scoped_refptr<dbus::Bus> proxy_bus, 53 Manager* manager) 54 : org::chromium::flimflam::ManagerAdaptor(this), 55 ChromeosDBusAdaptor(adaptor_bus, kPath), 56 manager_(manager), 57 proxy_bus_(proxy_bus), 58 dbus_service_watcher_factory_(DBusServiceWatcherFactory::GetInstance()) {} 59 60 ChromeosManagerDBusAdaptor::~ChromeosManagerDBusAdaptor() { 61 manager_ = nullptr; 62 } 63 64 void ChromeosManagerDBusAdaptor::RegisterAsync( 65 const base::Callback<void(bool)>& completion_callback) { 66 RegisterWithDBusObject(dbus_object()); 67 dbus_object()->RegisterAsync(completion_callback); 68 } 69 70 void ChromeosManagerDBusAdaptor::EmitBoolChanged(const string& name, 71 bool value) { 72 SLOG(this, 2) << __func__ << ": " << name; 73 SendPropertyChangedSignal(name, brillo::Any(value)); 74 } 75 76 void ChromeosManagerDBusAdaptor::EmitUintChanged(const string& name, 77 uint32_t value) { 78 SLOG(this, 2) << __func__ << ": " << name; 79 SendPropertyChangedSignal(name, brillo::Any(value)); 80 } 81 82 void ChromeosManagerDBusAdaptor::EmitIntChanged(const string& name, int value) { 83 SLOG(this, 2) << __func__ << ": " << name; 84 SendPropertyChangedSignal(name, brillo::Any(value)); 85 } 86 87 void ChromeosManagerDBusAdaptor::EmitStringChanged(const string& name, 88 const string& value) { 89 SLOG(this, 2) << __func__ << ": " << name; 90 SendPropertyChangedSignal(name, brillo::Any(value)); 91 } 92 93 void ChromeosManagerDBusAdaptor::EmitStringsChanged(const string& name, 94 const vector<string>& value) { 95 SLOG(this, 2) << __func__ << ": " << name; 96 SendPropertyChangedSignal(name, brillo::Any(value)); 97 } 98 99 void ChromeosManagerDBusAdaptor::EmitRpcIdentifierChanged( 100 const string& name, 101 const string& value) { 102 SLOG(this, 2) << __func__ << ": " << name; 103 SendPropertyChangedSignal(name, brillo::Any(dbus::ObjectPath(value))); 104 } 105 106 void ChromeosManagerDBusAdaptor::EmitRpcIdentifierArrayChanged( 107 const string& name, 108 const vector<string>& value) { 109 SLOG(this, 2) << __func__ << ": " << name; 110 vector<dbus::ObjectPath> paths; 111 for (const auto& element : value) { 112 paths.push_back(dbus::ObjectPath(element)); 113 } 114 115 SendPropertyChangedSignal(name, brillo::Any(paths)); 116 } 117 118 bool ChromeosManagerDBusAdaptor::GetProperties( 119 brillo::ErrorPtr* error, brillo::VariantDictionary* properties) { 120 SLOG(this, 2) << __func__; 121 return ChromeosDBusAdaptor::GetProperties(manager_->store(), 122 properties, 123 error); 124 } 125 126 bool ChromeosManagerDBusAdaptor::SetProperty(brillo::ErrorPtr* error, 127 const string& name, 128 const brillo::Any& value) { 129 SLOG(this, 2) << __func__ << ": " << name; 130 return ChromeosDBusAdaptor::SetProperty(manager_->mutable_store(), 131 name, 132 value, 133 error); 134 } 135 136 bool ChromeosManagerDBusAdaptor::GetState(brillo::ErrorPtr* /*error*/, 137 string* state) { 138 SLOG(this, 2) << __func__; 139 *state = manager_->CalculateState(nullptr); 140 return true; 141 } 142 143 bool ChromeosManagerDBusAdaptor::CreateProfile(brillo::ErrorPtr* error, 144 const string& name, 145 dbus::ObjectPath* profile_path) { 146 SLOG(this, 2) << __func__ << ": " << name; 147 Error e; 148 string path; 149 manager_->CreateProfile(name, &path, &e); 150 if (e.ToChromeosError(error)) { 151 return false; 152 } 153 *profile_path = dbus::ObjectPath(path); 154 return true; 155 } 156 157 bool ChromeosManagerDBusAdaptor::RemoveProfile(brillo::ErrorPtr* error, 158 const string& name) { 159 SLOG(this, 2) << __func__ << ": " << name; 160 Error e; 161 manager_->RemoveProfile(name, &e); 162 return !e.ToChromeosError(error); 163 } 164 165 bool ChromeosManagerDBusAdaptor::PushProfile(brillo::ErrorPtr* error, 166 const string& name, 167 dbus::ObjectPath* profile_path) { 168 SLOG(this, 2) << __func__ << ": " << name; 169 Error e; 170 string path; 171 manager_->PushProfile(name, &path, &e); 172 if (e.ToChromeosError(error)) { 173 return false; 174 } 175 *profile_path = dbus::ObjectPath(path); 176 return true; 177 } 178 179 bool ChromeosManagerDBusAdaptor::InsertUserProfile( 180 brillo::ErrorPtr* error, 181 const string& name, 182 const string& user_hash, 183 dbus::ObjectPath* profile_path) { 184 SLOG(this, 2) << __func__ << ": " << name; 185 Error e; 186 string path; 187 manager_->InsertUserProfile(name, user_hash, &path, &e); 188 if (e.ToChromeosError(error)) { 189 return false; 190 } 191 *profile_path = dbus::ObjectPath(path); 192 return true;; 193 } 194 195 bool ChromeosManagerDBusAdaptor::PopProfile(brillo::ErrorPtr* error, 196 const string& name) { 197 SLOG(this, 2) << __func__ << ": " << name; 198 Error e; 199 manager_->PopProfile(name, &e); 200 return !e.ToChromeosError(error); 201 } 202 203 bool ChromeosManagerDBusAdaptor::PopAnyProfile(brillo::ErrorPtr* error) { 204 SLOG(this, 2) << __func__; 205 Error e; 206 manager_->PopAnyProfile(&e); 207 return !e.ToChromeosError(error); 208 } 209 210 bool ChromeosManagerDBusAdaptor::PopAllUserProfiles(brillo::ErrorPtr* error) { 211 SLOG(this, 2) << __func__; 212 Error e; 213 manager_->PopAllUserProfiles(&e); 214 return !e.ToChromeosError(error); 215 } 216 217 bool ChromeosManagerDBusAdaptor::RecheckPortal(brillo::ErrorPtr* error) { 218 SLOG(this, 2) << __func__; 219 Error e; 220 manager_->RecheckPortal(&e); 221 return !e.ToChromeosError(error); 222 } 223 224 bool ChromeosManagerDBusAdaptor::RequestScan(brillo::ErrorPtr* error, 225 const string& technology) { // NOLINT 226 SLOG(this, 2) << __func__ << ": " << technology; 227 Error e; 228 manager_->RequestScan(Device::kFullScan, technology, &e); 229 return !e.ToChromeosError(error); 230 } 231 232 void ChromeosManagerDBusAdaptor::EnableTechnology( 233 DBusMethodResponsePtr<> response, const string& technology_name) { 234 SLOG(this, 2) << __func__ << ": " << technology_name; 235 Error e(Error::kOperationInitiated); 236 ResultCallback callback = GetMethodReplyCallback(std::move(response)); 237 const bool kPersistentSave = true; 238 manager_->SetEnabledStateForTechnology(technology_name, true, 239 kPersistentSave, &e, callback); 240 ReturnResultOrDefer(callback, e); 241 } 242 243 void ChromeosManagerDBusAdaptor::DisableTechnology( 244 DBusMethodResponsePtr<> response, const string& technology_name) { 245 SLOG(this, 2) << __func__ << ": " << technology_name; 246 Error e(Error::kOperationInitiated); 247 ResultCallback callback = GetMethodReplyCallback(std::move(response)); 248 const bool kPersistentSave = true; 249 manager_->SetEnabledStateForTechnology(technology_name, false, 250 kPersistentSave, &e, callback); 251 ReturnResultOrDefer(callback, e); 252 } 253 254 // Called, e.g., to get WiFiService handle for a hidden SSID. 255 bool ChromeosManagerDBusAdaptor::GetService( 256 brillo::ErrorPtr* error, 257 const brillo::VariantDictionary& args, 258 dbus::ObjectPath* service_path) { 259 SLOG(this, 2) << __func__; 260 ServiceRefPtr service; 261 KeyValueStore args_store; 262 Error e; 263 KeyValueStore::ConvertFromVariantDictionary(args, &args_store); 264 service = manager_->GetService(args_store, &e); 265 if (e.ToChromeosError(error)) { 266 return false; 267 } 268 *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); 269 return true; 270 } 271 272 // Obsolete, use GetService instead. 273 bool ChromeosManagerDBusAdaptor::GetVPNService( 274 brillo::ErrorPtr* error, 275 const brillo::VariantDictionary& args, 276 dbus::ObjectPath* service_path) { 277 SLOG(this, 2) << __func__; 278 return GetService(error, args, service_path); 279 } 280 281 // Obsolete, use GetService instead. 282 bool ChromeosManagerDBusAdaptor::GetWifiService( 283 brillo::ErrorPtr* error, 284 const brillo::VariantDictionary& args, 285 dbus::ObjectPath* service_path) { 286 SLOG(this, 2) << __func__; 287 return GetService(error, args, service_path); 288 } 289 290 291 bool ChromeosManagerDBusAdaptor::ConfigureService( 292 brillo::ErrorPtr* error, 293 const brillo::VariantDictionary& args, 294 dbus::ObjectPath* service_path) { 295 SLOG(this, 2) << __func__; 296 ServiceRefPtr service; 297 KeyValueStore args_store; 298 KeyValueStore::ConvertFromVariantDictionary(args, &args_store); 299 Error configure_error; 300 service = manager_->ConfigureService(args_store, &configure_error); 301 if (configure_error.ToChromeosError(error)) { 302 return false; 303 } 304 *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); 305 return true; 306 } 307 308 bool ChromeosManagerDBusAdaptor::ConfigureServiceForProfile( 309 brillo::ErrorPtr* error, 310 const dbus::ObjectPath& profile_rpcid, 311 const brillo::VariantDictionary& args, 312 dbus::ObjectPath* service_path) { 313 SLOG(this, 2) << __func__; 314 ServiceRefPtr service; 315 KeyValueStore args_store; 316 KeyValueStore::ConvertFromVariantDictionary(args, &args_store); 317 Error configure_error; 318 service = manager_->ConfigureServiceForProfile( 319 profile_rpcid.value(), args_store, &configure_error); 320 if (!service || configure_error.ToChromeosError(error)) { 321 return false; 322 } 323 *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); 324 return true; 325 } 326 327 bool ChromeosManagerDBusAdaptor::FindMatchingService( 328 brillo::ErrorPtr* error, 329 const brillo::VariantDictionary& args, 330 dbus::ObjectPath* service_path) { // NOLINT 331 SLOG(this, 2) << __func__; 332 KeyValueStore args_store; 333 KeyValueStore::ConvertFromVariantDictionary(args, &args_store); 334 335 Error find_error; 336 ServiceRefPtr service = 337 manager_->FindMatchingService(args_store, &find_error); 338 if (find_error.ToChromeosError(error)) { 339 return false; 340 } 341 342 *service_path = dbus::ObjectPath(service->GetRpcIdentifier()); 343 return true; 344 } 345 346 bool ChromeosManagerDBusAdaptor::GetDebugLevel(brillo::ErrorPtr* /*error*/, 347 int32_t* level) { 348 SLOG(this, 2) << __func__; 349 *level = logging::GetMinLogLevel(); 350 return true; 351 } 352 353 bool ChromeosManagerDBusAdaptor::SetDebugLevel(brillo::ErrorPtr* /*error*/, 354 int32_t level) { 355 SLOG(this, 2) << __func__ << ": " << level; 356 if (level < logging::LOG_NUM_SEVERITIES) { 357 logging::SetMinLogLevel(level); 358 // Like VLOG, SLOG uses negative verbose level. 359 ScopeLogger::GetInstance()->set_verbose_level(-level); 360 } else { 361 LOG(WARNING) << "Ignoring attempt to set log level to " << level; 362 } 363 return true; 364 } 365 366 bool ChromeosManagerDBusAdaptor::GetServiceOrder(brillo::ErrorPtr* /*error*/, 367 string* order) { 368 SLOG(this, 2) << __func__; 369 *order = manager_->GetTechnologyOrder(); 370 return true; 371 } 372 373 bool ChromeosManagerDBusAdaptor::SetServiceOrder(brillo::ErrorPtr* error, 374 const string& order) { 375 SLOG(this, 2) << __func__ << ": " << order; 376 Error e; 377 manager_->SetTechnologyOrder(order, &e); 378 return !e.ToChromeosError(error); 379 } 380 381 bool ChromeosManagerDBusAdaptor::GetDebugTags(brillo::ErrorPtr* /*error*/, 382 string* tags) { 383 SLOG(this, 2) << __func__; 384 *tags = ScopeLogger::GetInstance()->GetEnabledScopeNames(); 385 return true; 386 } 387 388 bool ChromeosManagerDBusAdaptor::SetDebugTags(brillo::ErrorPtr* /*error*/, 389 const string& tags) { 390 SLOG(this, 2) << __func__ << ": " << tags; 391 ScopeLogger::GetInstance()->EnableScopesByName(tags); 392 return true; 393 } 394 395 bool ChromeosManagerDBusAdaptor::ListDebugTags(brillo::ErrorPtr* /*error*/, 396 string* tags) { 397 SLOG(this, 2) << __func__; 398 *tags = ScopeLogger::GetInstance()->GetAllScopeNames(); 399 return true; 400 } 401 402 bool ChromeosManagerDBusAdaptor::GetNetworksForGeolocation( 403 brillo::ErrorPtr* /*error*/, 404 brillo::VariantDictionary* networks) { 405 SLOG(this, 2) << __func__; 406 for (const auto& network : manager_->GetNetworksForGeolocation()) { 407 Stringmaps value; 408 // Convert GeolocationInfos to their Stringmaps equivalent. 409 for (const auto& info : network.second) { 410 value.push_back(info.properties()); 411 } 412 networks->insert(std::make_pair(network.first, brillo::Any(value))); 413 } 414 return true; 415 } 416 417 void ChromeosManagerDBusAdaptor::VerifyDestination( 418 DBusMethodResponsePtr<bool> response, 419 const string& certificate, 420 const string& public_key, 421 const string& nonce, 422 const string& signed_data, 423 const string& destination_udn, 424 const string& hotspot_ssid, 425 const string& hotspot_bssid) { 426 SLOG(this, 2) << __func__; 427 ResultBoolCallback callback = GetBoolMethodReplyCallback(std::move(response)); 428 #if !defined(DISABLE_WIFI) 429 Error e(Error::kOperationInitiated); 430 manager_->VerifyDestination(certificate, public_key, nonce, 431 signed_data, destination_udn, 432 hotspot_ssid, hotspot_bssid, 433 callback, &e); 434 #else 435 Error e(Error::kNotImplemented); 436 #endif // DISABLE_WIFI 437 if (e.IsOngoing()) { 438 return; 439 } 440 // Command failed synchronously. 441 CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; 442 callback.Run(e, false); 443 } 444 445 void ChromeosManagerDBusAdaptor::VerifyAndEncryptCredentials( 446 DBusMethodResponsePtr<string> response, 447 const string& certificate, 448 const string& public_key, 449 const string& nonce, 450 const string& signed_data, 451 const string& destination_udn, 452 const string& hotspot_ssid, 453 const string& hotspot_bssid, 454 const dbus::ObjectPath& network) { 455 SLOG(this, 2) << __func__; 456 ResultStringCallback callback = 457 GetStringMethodReplyCallback(std::move(response)); 458 #if !defined(DISABLE_WIFI) 459 Error e(Error::kOperationInitiated); 460 manager_->VerifyAndEncryptCredentials(certificate, public_key, nonce, 461 signed_data, destination_udn, 462 hotspot_ssid, hotspot_bssid, 463 network.value(), 464 callback, 465 &e); 466 #else 467 Error e(Error::kNotImplemented); 468 #endif // DISABLE_WIFI 469 if (e.IsOngoing()) { 470 return; 471 } 472 // Command failed synchronously. 473 CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; 474 callback.Run(e, ""); 475 } 476 477 void ChromeosManagerDBusAdaptor::VerifyAndEncryptData( 478 DBusMethodResponsePtr<string> response, 479 const string& certificate, 480 const string& public_key, 481 const string& nonce, 482 const string& signed_data, 483 const string& destination_udn, 484 const string& hotspot_ssid, 485 const string& hotspot_bssid, 486 const string& data) { 487 SLOG(this, 2) << __func__; 488 ResultStringCallback callback = 489 GetStringMethodReplyCallback(std::move(response)); 490 #if !defined(DISABLE_WIFI) 491 Error e(Error::kOperationInitiated); 492 manager_->VerifyAndEncryptData(certificate, public_key, nonce, 493 signed_data, destination_udn, 494 hotspot_ssid, hotspot_bssid, 495 data, callback, 496 &e); 497 #else 498 Error e(Error::kNotImplemented); 499 #endif // DISABLE_WIFI 500 if (e.IsOngoing()) { 501 return; 502 } 503 // Command failed synchronously. 504 CHECK(e.IsFailure()) << __func__ << " should only return directly on error."; 505 callback.Run(e, ""); 506 } 507 508 bool ChromeosManagerDBusAdaptor::ConnectToBestServices( 509 brillo::ErrorPtr* error) { 510 SLOG(this, 2) << __func__; 511 Error e; 512 manager_->ConnectToBestServices(&e); 513 return !e.ToChromeosError(error); 514 } 515 516 bool ChromeosManagerDBusAdaptor::CreateConnectivityReport( 517 brillo::ErrorPtr* error) { 518 SLOG(this, 2) << __func__; 519 Error e; 520 manager_->CreateConnectivityReport(&e); 521 return !e.ToChromeosError(error); 522 } 523 524 bool ChromeosManagerDBusAdaptor::ClaimInterface( 525 brillo::ErrorPtr* error, 526 dbus::Message* message, 527 const string& claimer_name, 528 const string& interface_name) { 529 SLOG(this, 2) << __func__; 530 Error e; 531 // Empty claimer name is used to indicate default claimer. 532 // TODO(zqiu): update this API or make a new API to use a flag to indicate 533 // default claimer instead. 534 string claimer = (claimer_name == "" ? "" : message->GetSender()); 535 manager_->ClaimDevice(claimer, interface_name, &e); 536 if (e.IsSuccess() && claimer_name != "") { 537 // Only setup watcher for non-default claimer. 538 watcher_for_device_claimer_.reset( 539 dbus_service_watcher_factory_->CreateDBusServiceWatcher( 540 proxy_bus_, claimer, 541 Bind(&ChromeosManagerDBusAdaptor::OnDeviceClaimerVanished, 542 Unretained(this)))); 543 } 544 return !e.ToChromeosError(error); 545 } 546 547 bool ChromeosManagerDBusAdaptor::ReleaseInterface( 548 brillo::ErrorPtr* error, 549 dbus::Message* message, 550 const string& claimer_name, 551 const string& interface_name) { 552 SLOG(this, 2) << __func__; 553 Error e; 554 bool claimer_removed; 555 // Empty claimer name is used to indicate default claimer. 556 // TODO(zqiu): update this API or make a new API to use a flag to indicate 557 // default claimer instead. 558 manager_->ReleaseDevice( 559 claimer_name == "" ? "" : message->GetSender(), 560 interface_name, 561 &claimer_removed, 562 &e); 563 if (claimer_removed) { 564 watcher_for_device_claimer_.reset(); 565 } 566 return !e.ToChromeosError(error); 567 } 568 569 bool ChromeosManagerDBusAdaptor::SetSchedScan(brillo::ErrorPtr* error, 570 bool enable) { 571 SLOG(this, 2) << __func__ << ": " << enable; 572 Error e; 573 manager_->SetSchedScan(enable, &e); 574 return !e.ToChromeosError(error); 575 } 576 577 bool ChromeosManagerDBusAdaptor::SetupApModeInterface( 578 brillo::ErrorPtr* error, 579 dbus::Message* message, 580 string* out_interface_name) { 581 SLOG(this, 2) << __func__; 582 Error e; 583 #if !defined(DISABLE_WIFI) && defined(__BRILLO__) 584 manager_->SetupApModeInterface(out_interface_name, &e); 585 if (e.IsSuccess()) { 586 // Setup a service watcher for the caller. This will restore interface mode 587 // back to station mode if the caller vanished. 588 watcher_for_ap_mode_setter_.reset( 589 dbus_service_watcher_factory_->CreateDBusServiceWatcher( 590 proxy_bus_, message->GetSender(), 591 Bind(&ChromeosManagerDBusAdaptor::OnApModeSetterVanished, 592 Unretained(this)))); 593 } 594 #else 595 e.Populate(Error::kNotSupported); 596 #endif // !DISABLE_WIFI && __BRILLO__ 597 return !e.ToChromeosError(error); 598 } 599 600 bool ChromeosManagerDBusAdaptor::SetupStationModeInterface( 601 brillo::ErrorPtr* error, 602 string* out_interface_name) { 603 SLOG(this, 2) << __func__; 604 Error e; 605 #if !defined(DISABLE_WIFI) && defined(__BRILLO__) 606 manager_->SetupStationModeInterface(out_interface_name, &e); 607 // Remove the service watcher for the AP mode setter. 608 watcher_for_ap_mode_setter_.reset(); 609 #else 610 e.Populate(Error::kNotSupported); 611 #endif // !DISABLE_WIFI && __BRILLO__ 612 return !e.ToChromeosError(error); 613 } 614 615 void ChromeosManagerDBusAdaptor::OnApModeSetterVanished() { 616 SLOG(this, 3) << __func__; 617 #if !defined(DISABLE_WIFI) && defined(__BRILLO__) 618 manager_->OnApModeSetterVanished(); 619 #endif // !DISABLE_WIFI && __BRILLO__ 620 watcher_for_ap_mode_setter_.reset(); 621 } 622 623 void ChromeosManagerDBusAdaptor::OnDeviceClaimerVanished() { 624 SLOG(this, 3) << __func__; 625 manager_->OnDeviceClaimerVanished(); 626 watcher_for_device_claimer_.reset(); 627 } 628 629 } // namespace shill 630