1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef DBUS_TEST_SERVICE_H_ 6 #define DBUS_TEST_SERVICE_H_ 7 8 #include "base/compiler_specific.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/threading/thread.h" 11 #include "base/synchronization/waitable_event.h" 12 #include "dbus/bus.h" 13 #include "dbus/exported_object.h" 14 15 namespace base { 16 class SequencedTaskRunner; 17 } 18 19 namespace dbus { 20 21 class MethodCall; 22 class MessageWriter; 23 class Response; 24 25 // The test service is used for end-to-end tests. The service runs in a 26 // separate thread, so it does not interfere the test code that runs in 27 // the main thread. 28 // 29 // The test service exports an object with methods such as Echo() and 30 // SlowEcho(). The object has ability to send "Test" signal. 31 class TestService : public base::Thread { 32 public: 33 // Options for the test service. 34 struct Options { 35 Options(); 36 ~Options(); 37 38 // NULL by default (i.e. don't use the D-Bus thread). 39 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner; 40 41 // Flags governing parameters of service ownership request. 42 Bus::ServiceOwnershipOptions request_ownership_options; 43 }; 44 45 // The number of methods we'll export. 46 static const int kNumMethodsToExport; 47 48 explicit TestService(const Options& options); 49 virtual ~TestService(); 50 51 // Starts the service in a separate thread. 52 // Returns true if the thread is started successfully. 53 bool StartService(); 54 55 // Waits until the service is started (i.e. all methods are exported). 56 // Returns true on success. 57 bool WaitUntilServiceIsStarted() WARN_UNUSED_RESULT; 58 59 // Shuts down the service and blocks until it's done. 60 void ShutdownAndBlock(); 61 62 // Returns true if the bus has the D-Bus thread. 63 bool HasDBusThread(); 64 65 // Sends "Test" signal with the given message from the exported object. 66 void SendTestSignal(const std::string& message); 67 68 // Sends "Test" signal with the given message from the root object ("/"). 69 // This function emulates dbus-send's behavior. 70 void SendTestSignalFromRoot(const std::string& message); 71 72 // Request the ownership of a well-known name "TestService". 73 // |callback| will be called with the result when an ownership request is 74 // completed. 75 void RequestOwnership(base::Callback<void(bool)> callback); 76 77 // Release the ownership of the well-known name "TestService". 78 // |callback| will be called when the ownership has been released. 79 void ReleaseOwnership(base::Closure callback); 80 81 // Returns whether this instance has the name ownership or not. 82 bool has_ownership() const { return has_ownership_; } 83 84 private: 85 // Helper function for SendTestSignal(). 86 void SendTestSignalInternal(const std::string& message); 87 88 // Helper function for SendTestSignalFromRoot. 89 void SendTestSignalFromRootInternal(const std::string& message); 90 91 // Helper function for ShutdownAndBlock(). 92 void ShutdownAndBlockInternal(); 93 94 // Called when an ownership request is completed. 95 // |callback| is the callback to be called with the result. |service_name| is 96 // the requested well-known bus name. |callback| and |service_name| are bound 97 // when the service requests the ownership. |success| is the result of the 98 // completed request, and is propagated to |callback|. 99 void OnOwnership(base::Callback<void(bool)> callback, 100 const std::string& service_name, 101 bool success); 102 103 // Called when a method is exported. 104 void OnExported(const std::string& interface_name, 105 const std::string& method_name, 106 bool success); 107 108 // base::Thread override. 109 virtual void Run(base::MessageLoop* message_loop) OVERRIDE; 110 111 // 112 // Exported methods. 113 // 114 115 // Echos the text message received from the method call. 116 void Echo(MethodCall* method_call, 117 dbus::ExportedObject::ResponseSender response_sender); 118 119 // Echos the text message received from the method call, but sleeps for 120 // TestTimeouts::tiny_timeout_ms() before returning the response. 121 void SlowEcho(MethodCall* method_call, 122 dbus::ExportedObject::ResponseSender response_sender); 123 124 // Echos the text message received from the method call, but sends its 125 // response asynchronously after this callback has returned. 126 void AsyncEcho(MethodCall* method_call, 127 dbus::ExportedObject::ResponseSender response_sender); 128 129 // Returns NULL, instead of a valid Response. 130 void BrokenMethod(MethodCall* method_call, 131 dbus::ExportedObject::ResponseSender response_sender); 132 133 // Returns a set of property values for testing. 134 void GetAllProperties(MethodCall* method_call, 135 dbus::ExportedObject::ResponseSender response_sender); 136 137 // Returns a new value of 20 for the Version property when called. 138 void GetProperty(MethodCall* method_call, 139 dbus::ExportedObject::ResponseSender response_sender); 140 141 // Allows the name property to be changed, errors otherwise. 142 void SetProperty(MethodCall* method_call, 143 dbus::ExportedObject::ResponseSender response_sender); 144 145 // Performs an action for testing. 146 void PerformAction(MethodCall* method_call, 147 dbus::ExportedObject::ResponseSender response_sender); 148 149 // Object Manager: returns the set of objects and properties. 150 void GetManagedObjects(MethodCall* method_call, 151 dbus::ExportedObject::ResponseSender response_sender); 152 153 // Add a properties dictionary to a message writer. 154 void AddPropertiesToWriter(MessageWriter* writer); 155 156 // Add a new object to the manager. 157 void AddObject(const dbus::ObjectPath& object_path); 158 void AddObjectInternal(const dbus::ObjectPath& object_path); 159 160 // Remove an object from the manager. 161 void RemoveObject(const dbus::ObjectPath& object_path); 162 void RemoveObjectInternal(const dbus::ObjectPath& object_path); 163 164 // Sends a property changed signal for the name property. 165 void SendPropertyChangedSignal(const std::string& name); 166 167 // Helper function for SendPropertyChangedSignal(). 168 void SendPropertyChangedSignalInternal(const std::string& name); 169 170 // Helper function for RequestOwnership(). 171 void RequestOwnershipInternal(base::Callback<void(bool)> callback); 172 173 // Helper function for ReleaseOwnership(). 174 void ReleaseOwnershipInternal(base::Closure callback); 175 176 // Configures the test service to send a PropertiesChanged signal for the 177 // "Name" property immediately after a call to GetManagedObjects. 178 void SetSendImmediatePropertiesChanged(); 179 180 // Sends the response on completion of the performed action. 181 void PerformActionResponse( 182 MethodCall* method_call, 183 dbus::ExportedObject::ResponseSender response_sender); 184 185 // Re-requests ownership of the well-known name after releasing it. 186 void OwnershipReleased( 187 MethodCall* method_call, 188 dbus::ExportedObject::ResponseSender response_sender); 189 190 // Sends the action response after regaining the well-known name. 191 void OwnershipRegained( 192 MethodCall* method_call, 193 dbus::ExportedObject::ResponseSender response_sender, 194 bool success); 195 196 // Options to use when requesting service ownership. 197 Bus::ServiceOwnershipOptions request_ownership_options_; 198 199 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_; 200 base::WaitableEvent on_name_obtained_; 201 // The number of methods actually exported. 202 int num_exported_methods_; 203 204 // True if a PropertiesChanged signal for the "Name" property should be sent 205 // immediately following a call to GetManagedObjects. 206 bool send_immediate_properties_changed_; 207 208 // True iff this instance has successfully acquired the name ownership. 209 bool has_ownership_; 210 211 scoped_refptr<Bus> bus_; 212 ExportedObject* exported_object_; 213 ExportedObject* exported_object_manager_; 214 }; 215 216 } // namespace dbus 217 218 #endif // DBUS_TEST_SERVICE_H_ 219