| Index: chromeos/dbus/shill_service_client.cc
|
| diff --git a/chromeos/dbus/shill_service_client.cc b/chromeos/dbus/shill_service_client.cc
|
| index 8e0ede00f565ea2ecb7d795702c48a3891816029..ae66387e34c338ae9d948540f5cafb367302f2b3 100644
|
| --- a/chromeos/dbus/shill_service_client.cc
|
| +++ b/chromeos/dbus/shill_service_client.cc
|
| @@ -40,12 +40,81 @@ void OnGetPropertiesError(
|
| callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
|
| }
|
|
|
| +// ShillClientHelper callback wrappers.
|
| +// For each one of the different callback types in ShillClientHelper, we define
|
| +// a wrapper that attachs a clousure to the given callback. This allows it to
|
| +// call a second callback (the clousure) after the first callback is called.
|
| +// This is used to get a notification in the ShillServiceClient when a
|
| +// MethodCall returns.
|
| +
|
| +// * Wrapper for DictionaryValueCallback.
|
| +void RunDictionaryValueCallback(
|
| + const base::Closure& closure,
|
| + const ShillClientHelper::DictionaryValueCallback& callback,
|
| + DBusMethodCallStatus call_status,
|
| + const DictionaryValue& argument) {
|
| + callback.Run(call_status, argument);
|
| + closure.Run();
|
| +}
|
| +
|
| +ShillClientHelper::DictionaryValueCallback
|
| + AttachClosureToDictionaryValueCallback(
|
| + const ShillClientHelper::DictionaryValueCallback& callback,
|
| + const base::Closure& closure) {
|
| + return base::Bind(&RunDictionaryValueCallback, closure, callback);
|
| +}
|
| +
|
| +// * Wrapper for ListValueCallback
|
| +void RunListValueCallback(
|
| + const base::Closure& closure,
|
| + const ShillClientHelper::ListValueCallback& callback,
|
| + const ListValue& argument) {
|
| + callback.Run(argument);
|
| + closure.Run();
|
| +}
|
| +
|
| +ShillClientHelper::ListValueCallback AttachClosureToListValueCallback(
|
| + const ShillClientHelper::ListValueCallback& callback,
|
| + const base::Closure& closure) {
|
| + return base::Bind(&RunListValueCallback, closure, callback);
|
| +}
|
| +
|
| +// * Wrapper for ErrorCallback
|
| +void RunErrorCallback(
|
| + const base::Closure& closure,
|
| + const ShillClientHelper::ErrorCallback& callback,
|
| + const std::string& error_name,
|
| + const std::string& error_message) {
|
| + callback.Run(error_name, error_message);
|
| + closure.Run();
|
| +}
|
| +
|
| +ShillClientHelper::ErrorCallback AttachClosureToErrorCallback(
|
| + const ShillClientHelper::ErrorCallback& callback,
|
| + const base::Closure& closure) {
|
| + return base::Bind(&RunErrorCallback, closure, callback);
|
| +}
|
| +
|
| +// * Wrapper for Closure
|
| +void RunClosure(const base::Closure& closure,
|
| + const base::Closure& callback) {
|
| + callback.Run();
|
| + closure.Run();
|
| +}
|
| +
|
| +base::Closure AttachClosureToClosure(
|
| + const base::Closure& callback,
|
| + const base::Closure& closure) {
|
| + return base::Bind(&RunClosure, closure, callback);
|
| +}
|
| +
|
| // The ShillServiceClient implementation.
|
| class ShillServiceClientImpl : public ShillServiceClient {
|
| public:
|
| explicit ShillServiceClientImpl(dbus::Bus* bus)
|
| : bus_(bus),
|
| - helpers_deleter_(&helpers_) {
|
| + helpers_deleter_(&helpers_),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
|
| }
|
|
|
| /////////////////////////////////////
|
| @@ -60,6 +129,7 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| const dbus::ObjectPath& service_path,
|
| ShillPropertyChangedObserver* observer) OVERRIDE {
|
| GetHelper(service_path)->RemovePropertyChangedObserver(observer);
|
| + OnHelperStatusUpdate(service_path);
|
| }
|
|
|
| virtual void GetProperties(const dbus::ObjectPath& service_path,
|
| @@ -68,8 +138,14 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| flimflam::kGetPropertiesFunction);
|
| GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback(
|
| &method_call,
|
| - base::Bind(callback, DBUS_METHOD_CALL_SUCCESS),
|
| - base::Bind(&OnGetPropertiesError, service_path, callback));
|
| + base::Bind(
|
| + AttachClosureToDictionaryValueCallback(callback,
|
| + base::Bind(&ShillServiceClientImpl::OnHelperStatusUpdate,
|
| + weak_ptr_factory_.GetWeakPtr(), service_path)),
|
| + DBUS_METHOD_CALL_SUCCESS),
|
| + AttachClosureToErrorCallback(
|
| + base::Bind(&OnGetPropertiesError, service_path, callback),
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void SetProperty(const dbus::ObjectPath& service_path,
|
| @@ -82,9 +158,12 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| dbus::MessageWriter writer(&method_call);
|
| writer.AppendString(name);
|
| ShillClientHelper::AppendValueDataAsVariant(&writer, value);
|
| - GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
|
| - callback,
|
| - error_callback);
|
| + GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void ClearProperty(const dbus::ObjectPath& service_path,
|
| @@ -95,9 +174,12 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| flimflam::kClearPropertyFunction);
|
| dbus::MessageWriter writer(&method_call);
|
| writer.AppendString(name);
|
| - GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
|
| - callback,
|
| - error_callback);
|
| + GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
|
|
| @@ -111,8 +193,10 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| writer.AppendArrayOfStrings(names);
|
| GetHelper(service_path)->CallListValueMethodWithErrorCallback(
|
| &method_call,
|
| - callback,
|
| - error_callback);
|
| + AttachClosureToListValueCallback(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void Connect(const dbus::ObjectPath& service_path,
|
| @@ -121,7 +205,11 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
|
| flimflam::kConnectFunction);
|
| GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| - &method_call, callback, error_callback);
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void Disconnect(const dbus::ObjectPath& service_path,
|
| @@ -129,9 +217,12 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
|
| flimflam::kDisconnectFunction);
|
| - GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
|
| - callback,
|
| - error_callback);
|
| + GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void Remove(const dbus::ObjectPath& service_path,
|
| @@ -139,9 +230,12 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| const ErrorCallback& error_callback) OVERRIDE {
|
| dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
|
| flimflam::kRemoveServiceFunction);
|
| - GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
|
| - callback,
|
| - error_callback);
|
| + GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual void ActivateCellularModem(
|
| @@ -153,9 +247,12 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| flimflam::kActivateCellularModemFunction);
|
| dbus::MessageWriter writer(&method_call);
|
| writer.AppendString(carrier);
|
| - GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
|
| - callback,
|
| - error_callback);
|
| + GetHelper(service_path)->CallVoidMethodWithErrorCallback(
|
| + &method_call,
|
| + AttachClosureToClosure(callback,
|
| + HelperStatusUpdateCallback(service_path)),
|
| + AttachClosureToErrorCallback(error_callback,
|
| + HelperStatusUpdateCallback(service_path)));
|
| }
|
|
|
| virtual bool CallActivateCellularModemAndBlock(
|
| @@ -165,7 +262,9 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| flimflam::kActivateCellularModemFunction);
|
| dbus::MessageWriter writer(&method_call);
|
| writer.AppendString(carrier);
|
| - return GetHelper(service_path)->CallVoidMethodAndBlock(&method_call);
|
| + bool result = GetHelper(service_path)->CallVoidMethodAndBlock(&method_call);
|
| + OnHelperStatusUpdate(service_path);
|
| + return result;
|
| }
|
|
|
| virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE {
|
| @@ -190,10 +289,39 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| return helper;
|
| }
|
|
|
| + // Returns a Closure that calls OnHelperStatusUpdate with the given
|
| + // |service_path| argument.
|
| + base::Closure HelperStatusUpdateCallback(
|
| + const dbus::ObjectPath& service_path) {
|
| + return base::Bind(&ShillServiceClientImpl::OnHelperStatusUpdate,
|
| + weak_ptr_factory_.GetWeakPtr(), service_path);
|
| + }
|
| +
|
| + // This function is called every time the IsObserved or the IsWaitingResponse
|
| + // helper's properties may have changed. If both are false, the cached helper
|
| + // can be safely removed.
|
| + void OnHelperStatusUpdate(const dbus::ObjectPath& service_path) {
|
| + HelperMap::iterator it = helpers_.find(service_path.value());
|
| + if (it == helpers_.end())
|
| + return;
|
| +
|
| + ShillClientHelper* const helper = it->second;
|
| + if (!helper->IsObserved() && !helper->IsWaitingResponse()) {
|
| + helpers_.erase(it);
|
| + delete helper;
|
| + bus_->RemoveObjectProxy(flimflam::kFlimflamServiceName, service_path,
|
| + base::Bind(&base::DoNothing));
|
| + }
|
| + }
|
| +
|
| dbus::Bus* bus_;
|
| HelperMap helpers_;
|
| STLValueDeleter<HelperMap> helpers_deleter_;
|
|
|
| + // Note: This should remain the last member so it'll be destroyed and
|
| + // invalidate its weak pointers before any other members are destroyed.
|
| + base::WeakPtrFactory<ShillServiceClientImpl> weak_ptr_factory_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl);
|
| };
|
|
|
| @@ -201,7 +329,8 @@ class ShillServiceClientImpl : public ShillServiceClient {
|
| class ShillServiceClientStubImpl : public ShillServiceClient,
|
| public ShillServiceClient::TestInterface {
|
| public:
|
| - ShillServiceClientStubImpl() : weak_ptr_factory_(this) {
|
| + ShillServiceClientStubImpl() :
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
|
| SetDefaultProperties();
|
| }
|
|
|
|
|