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 #ifndef SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_ 18 #define SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_ 19 20 #include <string> 21 22 #include <base/callback.h> 23 #include <base/macros.h> 24 #include <base/memory/weak_ptr.h> 25 #include <brillo/dbus/dbus_object.h> 26 #include <brillo/dbus/exported_object_manager.h> 27 #include <gtest/gtest_prod.h> // for FRIEND_TEST 28 29 #include "shill/callbacks.h" 30 #include "shill/error.h" 31 #include "shill/property_store.h" 32 33 namespace shill { 34 35 template<typename... Types> 36 using DBusMethodResponsePtr = 37 std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<Types...>>; 38 39 // Superclass for all DBus-backed Adaptor objects 40 class ChromeosDBusAdaptor : public base::SupportsWeakPtr<ChromeosDBusAdaptor> { 41 public: 42 static const char kNullPath[]; 43 44 ChromeosDBusAdaptor( 45 const scoped_refptr<dbus::Bus>& bus, 46 const std::string& object_path); 47 ~ChromeosDBusAdaptor(); 48 dbus_path()49 const dbus::ObjectPath& dbus_path() const { return dbus_path_; } 50 51 protected: 52 FRIEND_TEST(ChromeosDBusAdaptorTest, SanitizePathElement); 53 54 // Callback to wrap around DBus method response. 55 ResultCallback GetMethodReplyCallback(DBusMethodResponsePtr<> response); 56 57 // It would be nice if these two methods could be templated. Unfortunately, 58 // attempts to do so will trigger some fairly esoteric warnings from the 59 // base library. 60 ResultStringCallback GetStringMethodReplyCallback( 61 DBusMethodResponsePtr<std::string> response); 62 ResultBoolCallback GetBoolMethodReplyCallback( 63 DBusMethodResponsePtr<bool> response); 64 65 // Adaptors call this method just before returning. If |error| 66 // indicates that the operation has completed, with no asynchronously 67 // delivered result expected, then a DBus method reply is immediately 68 // sent to the client that initiated the method invocation. Otherwise, 69 // the operation is ongoing, and the result will be sent to the client 70 // when the operation completes at some later time. 71 // 72 // Adaptors should always construct an Error initialized to the value 73 // Error::kOperationInitiated. A pointer to this Error is passed down 74 // through the call stack. Any layer that determines that the operation 75 // has completed, either because of a failure that prevents carrying it 76 // out, or because it was possible to complete it without sending a request 77 // to an external server, should call error.Reset() to indicate success, 78 // or to some error type to reflect the kind of failure that occurred. 79 // Otherwise, they should leave the Error alone. 80 // 81 // The general structure of an adaptor method is 82 // 83 // void XXXXDBusAdaptor::SomeMethod(<args...>, DBusMethodResponsePtr<> resp) { 84 // Error e(Error::kOperationInitiated); 85 // ResultCallback callback = GetMethodReplyCallback(resp); 86 // xxxx_->SomeMethod(<args...>, &e, callback); 87 // ReturnResultOrDefer(callback, e); 88 // } 89 // 90 void ReturnResultOrDefer(const ResultCallback& callback, const Error& error); 91 dbus_object()92 brillo::dbus_utils::DBusObject* dbus_object() const { 93 return dbus_object_.get(); 94 } 95 96 // Set the property with |name| through |store|. Returns true if and 97 // only if the property was changed. Updates |error| if a) an error 98 // was encountered, and b) |error| is non-NULL. Otherwise, |error| is 99 // unchanged. 100 static bool SetProperty(PropertyStore* store, 101 const std::string& name, 102 const brillo::Any& value, 103 brillo::ErrorPtr* error); 104 static bool GetProperties(const PropertyStore& store, 105 brillo::VariantDictionary* out_properties, 106 brillo::ErrorPtr* error); 107 // Look for a property with |name| in |store|. If found, reset the 108 // property to its "factory" value. If the property can not be 109 // found, or if it can not be cleared (e.g., because it is 110 // read-only), set |error| accordingly. 111 // 112 // Returns true if the property was found and cleared; returns false 113 // otherwise. 114 static bool ClearProperty(PropertyStore* store, 115 const std::string& name, 116 brillo::ErrorPtr* error); 117 118 // Returns an object path fragment that conforms to D-Bus specifications. 119 static std::string SanitizePathElement(const std::string& object_path); 120 121 private: 122 void MethodReplyCallback(DBusMethodResponsePtr<> response, 123 const Error& error); 124 125 void StringMethodReplyCallback(DBusMethodResponsePtr<std::string> response, 126 const Error& error, 127 const std::string& returned); 128 void BoolMethodReplyCallback(DBusMethodResponsePtr<bool> response, 129 const Error& error, 130 bool returned); 131 template<typename T> 132 void TypedMethodReplyCallback(DBusMethodResponsePtr<T> response, 133 const Error& error, 134 const T& returned); 135 136 dbus::ObjectPath dbus_path_; 137 std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_; 138 139 DISALLOW_COPY_AND_ASSIGN(ChromeosDBusAdaptor); 140 }; 141 142 } // namespace shill 143 144 #endif // SHILL_DBUS_CHROMEOS_DBUS_ADAPTOR_H_ 145