Home | History | Annotate | Download | only in dbus
      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 
     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 
     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