// // Copyright (C) 2015 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_ #define SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_ #include <string> #include <base/callback.h> #include <base/macros.h> #include <base/memory/weak_ptr.h> #include <brillo/dbus/dbus_object.h> #include <brillo/dbus/exported_object_manager.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST #include "shill/callbacks.h" #include "shill/error.h" #include "shill/property_store.h" namespace shill { template<typename... Types> using DBusMethodResponsePtr = std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<Types...>>; // Superclass for all DBus-backed Adaptor objects class ChromeosDBusAdaptor : public base::SupportsWeakPtr<ChromeosDBusAdaptor> { public: static const char kNullPath[]; ChromeosDBusAdaptor( const scoped_refptr<dbus::Bus>& bus, const std::string& object_path); ~ChromeosDBusAdaptor(); const dbus::ObjectPath& dbus_path() const { return dbus_path_; } protected: FRIEND_TEST(ChromeosDBusAdaptorTest, SanitizePathElement); // Callback to wrap around DBus method response. ResultCallback GetMethodReplyCallback(DBusMethodResponsePtr<> response); // It would be nice if these two methods could be templated. Unfortunately, // attempts to do so will trigger some fairly esoteric warnings from the // base library. ResultStringCallback GetStringMethodReplyCallback( DBusMethodResponsePtr<std::string> response); ResultBoolCallback GetBoolMethodReplyCallback( DBusMethodResponsePtr<bool> response); // Adaptors call this method just before returning. If |error| // indicates that the operation has completed, with no asynchronously // delivered result expected, then a DBus method reply is immediately // sent to the client that initiated the method invocation. Otherwise, // the operation is ongoing, and the result will be sent to the client // when the operation completes at some later time. // // Adaptors should always construct an Error initialized to the value // Error::kOperationInitiated. A pointer to this Error is passed down // through the call stack. Any layer that determines that the operation // has completed, either because of a failure that prevents carrying it // out, or because it was possible to complete it without sending a request // to an external server, should call error.Reset() to indicate success, // or to some error type to reflect the kind of failure that occurred. // Otherwise, they should leave the Error alone. // // The general structure of an adaptor method is // // void XXXXDBusAdaptor::SomeMethod(<args...>, DBusMethodResponsePtr<> resp) { // Error e(Error::kOperationInitiated); // ResultCallback callback = GetMethodReplyCallback(resp); // xxxx_->SomeMethod(<args...>, &e, callback); // ReturnResultOrDefer(callback, e); // } // void ReturnResultOrDefer(const ResultCallback& callback, const Error& error); brillo::dbus_utils::DBusObject* dbus_object() const { return dbus_object_.get(); } // Set the property with |name| through |store|. Returns true if and // only if the property was changed. Updates |error| if a) an error // was encountered, and b) |error| is non-NULL. Otherwise, |error| is // unchanged. static bool SetProperty(PropertyStore* store, const std::string& name, const brillo::Any& value, brillo::ErrorPtr* error); static bool GetProperties(const PropertyStore& store, brillo::VariantDictionary* out_properties, brillo::ErrorPtr* error); // Look for a property with |name| in |store|. If found, reset the // property to its "factory" value. If the property can not be // found, or if it can not be cleared (e.g., because it is // read-only), set |error| accordingly. // // Returns true if the property was found and cleared; returns false // otherwise. static bool ClearProperty(PropertyStore* store, const std::string& name, brillo::ErrorPtr* error); // Returns an object path fragment that conforms to D-Bus specifications. static std::string SanitizePathElement(const std::string& object_path); private: void MethodReplyCallback(DBusMethodResponsePtr<> response, const Error& error); void StringMethodReplyCallback(DBusMethodResponsePtr<std::string> response, const Error& error, const std::string& returned); void BoolMethodReplyCallback(DBusMethodResponsePtr<bool> response, const Error& error, bool returned); template<typename T> void TypedMethodReplyCallback(DBusMethodResponsePtr<T> response, const Error& error, const T& returned); dbus::ObjectPath dbus_path_; std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_; DISALLOW_COPY_AND_ASSIGN(ChromeosDBusAdaptor); }; } // namespace shill #endif // SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_