Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/service.cc

Issue 4304002: cashew: don't invoke D-Bus methods from within a D-Bus handler (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git@master
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/service.h ('k') | src/service_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/service.h" 5 #include "src/service.h"
6 6
7 #include <glog/logging.h> 7 #include <glog/logging.h>
8 8
9 #include "src/data_plan_provider.h" 9 #include "src/data_plan_provider.h"
10 #include "src/device.h" 10 #include "src/device.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 // Chromium OS Usage API status values 53 // Chromium OS Usage API status values
54 // NOTE: add new values to IsValidCrosUsageStatus below also 54 // NOTE: add new values to IsValidCrosUsageStatus below also
55 static const char *kCrosUsageStatusOk = "OK"; 55 static const char *kCrosUsageStatusOk = "OK";
56 static const char *kCrosUsageStatusError = "ERROR"; 56 static const char *kCrosUsageStatusError = "ERROR";
57 static const char *kCrosUsageStatusMalformedRequest = "MALFORMED REQUEST"; 57 static const char *kCrosUsageStatusMalformedRequest = "MALFORMED REQUEST";
58 static const char *kCrosUsageStatusInternalError = "INTERNAL ERROR"; 58 static const char *kCrosUsageStatusInternalError = "INTERNAL ERROR";
59 static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE"; 59 static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE";
60 static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED"; 60 static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED";
61 static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE"; 61 static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE";
62 62
63 // GetServiceProperties retry interval
64 static const guint kSecondsPerMinute = 60;
65 static const guint kGetServicePropertiesIntervalSeconds = 1 * kSecondsPerMinute;
66
63 Service::Service(ServiceManager * const parent, 67 Service::Service(ServiceManager * const parent,
64 DBus::Connection& connection, // NOLINT 68 DBus::Connection& connection, // NOLINT
65 const DBus::Path& path) 69 const DBus::Path& path)
66 : DBus::ObjectProxy(connection, path, kFlimflamServiceName), 70 : DBus::ObjectProxy(connection, path, kFlimflamServiceName),
67 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path), 71 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path),
68 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL), 72 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL),
69 provider_(NULL), request_in_progress_(false), 73 provider_(NULL), request_in_progress_(false),
70 update_timeout_source_(NULL), policy_(NULL), 74 update_timeout_source_(NULL), policy_(NULL),
71 is_default_service_(false) { 75 is_default_service_(false), get_properties_source_id_(0),
72 // init our state with a GetProperties() call to our Flimflam service path 76 retrying_get_properties_(false) {
73 // we'll update this state by monitoring PropertyChanged signals 77 // schedule a GetProperties() call to our Flimflam service path to init state
74 GetServiceProperties(); 78 // we'll keep trying periodically until we succeed
79 // we'll subsequently update this state by monitoring PropertyChanged signals
80 get_properties_source_id_ =
81 g_idle_add(StaticGetServicePropertiesCallback, this);
82 if (get_properties_source_id_ == 0) {
83 LOG(ERROR) << path_ << ": ctor: g_idle_add failed";
84 }
75 } 85 }
76 86
77 Service::~Service() { 87 Service::~Service() {
78 DeleteCarrierState(); 88 DeleteCarrierState();
79 DeleteDataPlans(&data_plans_); 89 DeleteDataPlans(&data_plans_);
80 if (device_ != NULL) { 90 if (device_ != NULL) {
81 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath(); 91 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath();
82 delete device_; 92 delete device_;
83 device_ = NULL; 93 device_ = NULL;
84 } 94 }
95 if (get_properties_source_id_ != 0 &&
96 !g_source_remove(get_properties_source_id_)) {
97 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed";
98 }
85 } 99 }
86 100
87 const DBus::Path& Service::GetPath() const { 101 const DBus::Path& Service::GetPath() const {
88 return path_; 102 return path_;
89 } 103 }
90 104
91 Service::State Service::GetState() const { 105 Service::State Service::GetState() const {
92 return state_; 106 return state_;
93 } 107 }
94 108
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 void Service::OnFlimflamOnline() { 355 void Service::OnFlimflamOnline() {
342 DLOG(INFO) << path_ << ": OnFlimflamOnline"; 356 DLOG(INFO) << path_ << ": OnFlimflamOnline";
343 ReconsiderSendingUsageRequests(); 357 ReconsiderSendingUsageRequests();
344 } 358 }
345 359
346 void Service::OnFlimflamOffline() { 360 void Service::OnFlimflamOffline() {
347 DLOG(INFO) << path_ << ": OnFlimflamOffline"; 361 DLOG(INFO) << path_ << ": OnFlimflamOffline";
348 ReconsiderSendingUsageRequests(); 362 ReconsiderSendingUsageRequests();
349 } 363 }
350 364
365 // glib integration interface
366
367 guint Service::GetGetPropertiesSourceId() const {
368 return get_properties_source_id_;
369 }
370
371 void Service::SetGetPropertiesSourceId(guint source_id) {
372 get_properties_source_id_ = source_id;
373 }
374
375 bool Service::RetryingGetProperties() const {
376 return retrying_get_properties_;
377 }
378
379 void Service::OnRetryingGetProperties(bool retrying) {
380 retrying_get_properties_ = retrying;
381 }
382
351 // Private methods 383 // Private methods
352 384
353 Service::State Service::StateFromString(const std::string& state) const { 385 Service::State Service::StateFromString(const std::string& state) const {
354 if (state == kFlimflamServiceStateIdle) { 386 if (state == kFlimflamServiceStateIdle) {
355 return kStateIdle; 387 return kStateIdle;
356 } 388 }
357 if (state == kFlimflamServiceStateCarrier) { 389 if (state == kFlimflamServiceStateCarrier) {
358 return kStateCarrier; 390 return kStateCarrier;
359 } 391 }
360 if (state == kFlimflamServiceStateAssociation) { 392 if (state == kFlimflamServiceStateAssociation) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 464 }
433 usage_url_ = usage_url; 465 usage_url_ = usage_url;
434 if (provider_ != NULL) { 466 if (provider_ != NULL) {
435 DCHECK(usage_url_ != provider_->GetUsageUrl()); 467 DCHECK(usage_url_ != provider_->GetUsageUrl());
436 StopSendingUsageRequests(); 468 StopSendingUsageRequests();
437 provider_->SetUsageUrl(usage_url_); 469 provider_->SetUsageUrl(usage_url_);
438 ReconsiderSendingUsageRequests(); 470 ReconsiderSendingUsageRequests();
439 } 471 }
440 } 472 }
441 473
442 void Service::GetServiceProperties() { 474 // static
475 gboolean Service::StaticGetServicePropertiesCallback(gpointer data) {
476 Service *service = reinterpret_cast<Service*>(data);
477 CHECK_NOTNULL(service);
478 DCHECK_NE(service->GetGetPropertiesSourceId(), 0);
479 if (!service->GetServiceProperties()) {
480 // call failed, so try again later
481 DLOG(WARNING) << service->GetPath()
482 << ": StaticGetServicePropertiesCallback: "
483 << "GetServiceProperties failed, will retry in "
484 << kGetServicePropertiesIntervalSeconds << " secs";
485 // if we've arrived here from our first g_idle_add call, set up a timer
486 if (!service->RetryingGetProperties()) {
487 guint source_id =
488 g_timeout_add_seconds(kGetServicePropertiesIntervalSeconds,
489 StaticGetServicePropertiesCallback, service);
490 service->SetGetPropertiesSourceId(source_id);
491 if (source_id == 0) {
492 LOG(ERROR) << service->GetPath()
493 << ": StaticGetServicePropertiesCallback: "
494 << "g_timeout_add_seconds failed";
495 return FALSE; // get rid of old glib source and give up
496 }
497 service->OnRetryingGetProperties(true);
498 // get rid of our old glib source, but our new timer will call us
499 return FALSE;
500 }
501 // otherwise, our timer is already set up
502 // return TRUE to indicate that we want to be called again later
503 return TRUE;
504 }
505 service->SetGetPropertiesSourceId(0);
506 service->OnRetryingGetProperties(false);
507 return FALSE; // we succeeded, so don't repeat
508 }
509
510 bool Service::GetServiceProperties() {
443 DLOG(INFO) << path_ << ": GetServiceProperties"; 511 DLOG(INFO) << path_ << ": GetServiceProperties";
444 PropertyMap properties; 512 PropertyMap properties;
445 // dbus-c++ throws exceptions 513 // dbus-c++ throws exceptions
446 // invoke the "Existing Non-conformant Code" clause of the style guide and 514 // invoke the "Existing Non-conformant Code" clause of the style guide and
447 // isolate the rest of the system from this 515 // isolate the rest of the system from this
448 try { 516 try {
449 // TODO(vlaviano): make this call asynchronous 517 // TODO(vlaviano): make this call asynchronous
450 properties = GetProperties(); 518 properties = GetProperties();
451 } catch (DBus::Error& error) { // NOLINT 519 } catch (DBus::Error& error) { // NOLINT
452 LOG(WARNING) << path_ 520 LOG(WARNING) << path_
453 << ": GetServiceProperties: GetProperties() -> Exception: " 521 << ": GetServiceProperties: GetProperties() -> Exception: "
454 << error.name() << ": " << error.message(); 522 << error.name() << ": " << error.message();
455 // TODO(vlaviano): schedule another attempt later 523 return false;
456 return;
457 } catch (...) { // NOLINT 524 } catch (...) { // NOLINT
458 LOG(WARNING) << path_ 525 LOG(WARNING) << path_
459 << ": GetServiceProperties: GetProperties() -> Exception"; 526 << ": GetServiceProperties: GetProperties() -> Exception";
460 // TODO(vlaviano): schedule another attempt later 527 return false;
461 return;
462 } 528 }
463 DLOG(INFO) << path_ << ": GetServiceProperties: Received " 529 DLOG(INFO) << path_ << ": GetServiceProperties: Received "
464 << properties.size() << " properties"; 530 << properties.size() << " properties";
465 531
466 // grab the properties in which we're interested 532 // grab the properties in which we're interested
467 PropertyMap::const_iterator it; 533 PropertyMap::const_iterator it;
468 it = properties.find(kFlimflamServiceDeviceProperty); 534 it = properties.find(kFlimflamServiceDeviceProperty);
469 if (it != properties.end()) { 535 if (it != properties.end()) {
470 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); 536 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
471 OnDeviceUpdate(value.reader().get_path()); 537 OnDeviceUpdate(value.reader().get_path());
472 } else { 538 } else {
473 DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property"; 539 DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property";
474 } 540 }
475 it = properties.find(kFlimflamServiceStateProperty); 541 it = properties.find(kFlimflamServiceStateProperty);
476 if (it != properties.end()) { 542 if (it != properties.end()) {
477 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); 543 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
478 OnStateUpdate(value.reader().get_string()); 544 OnStateUpdate(value.reader().get_string());
479 } else { 545 } else {
480 DLOG(WARNING) << path_ << ": GetServiceProperties: no State property"; 546 DLOG(WARNING) << path_ << ": GetServiceProperties: no State property";
481 } 547 }
482 it = properties.find(kFlimflamServiceTypeProperty); 548 it = properties.find(kFlimflamServiceTypeProperty);
483 if (it != properties.end()) { 549 if (it != properties.end()) {
484 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); 550 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
485 OnTypeUpdate(value.reader().get_string()); 551 OnTypeUpdate(value.reader().get_string());
486 } else { 552 } else {
487 DLOG(WARNING) << path_ << ": GetServiceProperties: no Type property"; 553 DLOG(WARNING) << path_ << ": GetServiceProperties: no Type property";
488 } 554 }
489 // don't expect to find Cellular.* properties if we're not a cellular service 555 // don't expect to find Cellular.* properties if we're not a cellular service
490 if (type_ != kTypeCellular) { 556 if (type_ != kTypeCellular) {
491 return; 557 return true;
492 } 558 }
493 it = properties.find(kFlimflamServiceUsageUrlProperty); 559 it = properties.find(kFlimflamServiceUsageUrlProperty);
494 if (it != properties.end()) { 560 if (it != properties.end()) {
495 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); 561 const DBus::Variant& value = static_cast<DBus::Variant>(it->second);
496 OnUsageUrlUpdate(value.reader().get_string()); 562 OnUsageUrlUpdate(value.reader().get_string());
497 } else { 563 } else {
498 DLOG(WARNING) << path_ 564 DLOG(WARNING) << path_
499 << ": GetServiceProperties: no Cellular.UsageUrl property"; 565 << ": GetServiceProperties: no Cellular.UsageUrl property";
500 } 566 }
567 return true;
501 } 568 }
502 569
503 void Service::DeleteDataPlans(DataPlanList *data_plans) { 570 void Service::DeleteDataPlans(DataPlanList *data_plans) {
504 DCHECK(data_plans != NULL); 571 DCHECK(data_plans != NULL);
505 while (!data_plans->empty()) { 572 while (!data_plans->empty()) {
506 DataPlan *plan = *data_plans->begin(); 573 DataPlan *plan = *data_plans->begin();
507 DCHECK(plan != NULL); 574 DCHECK(plan != NULL);
508 DLOG(INFO) << path_ << ": DeleteDataPlans: deleting plan: " 575 DLOG(INFO) << path_ << ": DeleteDataPlans: deleting plan: "
509 << plan->GetName(); 576 << plan->GetName();
510 delete plan; 577 delete plan;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 624 }
558 625
559 gboolean Service::UpdateTimeoutCallback() { 626 gboolean Service::UpdateTimeoutCallback() {
560 DLOG(INFO) << path_ << ": UpdateTimeoutCallback"; 627 DLOG(INFO) << path_ << ": UpdateTimeoutCallback";
561 RequestUsageUpdate(); 628 RequestUsageUpdate();
562 return TRUE; 629 return TRUE;
563 } 630 }
564 631
565 // static 632 // static
566 gboolean Service::StaticUpdateTimeoutCallback(gpointer data) { 633 gboolean Service::StaticUpdateTimeoutCallback(gpointer data) {
567 CHECK_NOTNULL(data); 634 Service *service = reinterpret_cast<Service*>(data);
568 return reinterpret_cast<Service*>(data)->UpdateTimeoutCallback(); 635 CHECK_NOTNULL(service);
636 return service->UpdateTimeoutCallback();
569 } 637 }
570 638
571 bool Service::CreateUpdateTimer() { 639 bool Service::CreateUpdateTimer() {
572 DCHECK(provider_ != NULL); 640 DCHECK(provider_ != NULL);
573 DCHECK(policy_ != NULL); 641 DCHECK(policy_ != NULL);
574 guint idle_seconds = policy_->GetUpdateTimerIdleSecs(data_plans_); 642 guint idle_seconds = policy_->GetUpdateTimerIdleSecs(data_plans_);
575 DLOG(INFO) << path_ << ": CreateUpdateTimer: idle_seconds = " << idle_seconds; 643 DLOG(INFO) << path_ << ": CreateUpdateTimer: idle_seconds = " << idle_seconds;
576 if (update_timeout_source_ != NULL) { 644 if (update_timeout_source_ != NULL) {
577 DLOG(WARNING) << path_ << ": CreateUpdateTimer: timer already running"; 645 DLOG(WARNING) << path_ << ": CreateUpdateTimer: timer already running";
578 return false; 646 return false;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 void Service::ReconsiderSendingUsageRequests() { 781 void Service::ReconsiderSendingUsageRequests() {
714 DLOG(INFO) << path_ << ": ReconsiderSendingUsageRequests"; 782 DLOG(INFO) << path_ << ": ReconsiderSendingUsageRequests";
715 if (!IsSendingUsageRequests() && ShouldSendUsageRequests()) { 783 if (!IsSendingUsageRequests() && ShouldSendUsageRequests()) {
716 StartSendingUsageRequests(); 784 StartSendingUsageRequests();
717 } else if (IsSendingUsageRequests() && !ShouldSendUsageRequests()) { 785 } else if (IsSendingUsageRequests() && !ShouldSendUsageRequests()) {
718 StopSendingUsageRequests(); 786 StopSendingUsageRequests();
719 } 787 }
720 } 788 }
721 789
722 } // namespace cashew 790 } // namespace cashew
OLDNEW
« no previous file with comments | « src/service.h ('k') | src/service_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698