dispatcher = std::thread([this] { mainloop.run(); });
}
-int Client::subscribe(const std::string& name)
+int Client::subscribe(const std::string& provider, const std::string& name)
{
- Message request = connection->createMessage(Message::MethodCall, "Server::subscribeNotification");
+ Message request = connection->createMessage(Message::MethodCall, provider);
request.packParameters(name);
connection->send(request);
void connect();
void disconnect();
- int subscribe(const std::string& name);
+ int subscribe(const std::string& provider, const std::string& name);
template<typename... Args>
- void subscribe(const std::string& name,
- const typename MethodHandler<void, Args...>::type& handler);
+ int subscribe(const std::string& provider, const std::string& name,
+ const typename MethodHandler<void, Args...>::type& handler);
template<typename Type, typename... Args>
Type methodCall(const std::string& method, Args&&... args);
};
template<typename... Args>
-void Client::subscribe(const std::string& name,
+int Client::subscribe(const std::string& provider, const std::string& name,
const typename MethodHandler<void, Args...>::type& handler)
{
auto callback = [handler, this](int fd, runtime::Mainloop::Event event) {
}
};
- int fd = subscribe(name);
+ int fd = subscribe(provider, name);
if (fd > 0) {
mainloop.addEventSource(fd, EPOLLIN | EPOLLHUP | EPOLLRDHUP, callback);
+ return 0;
}
+
+ return -1;
}
template<typename Type, typename... Args>
void Service::notify(const std::string& name, Args&&... args)
{
Notification& slot = notificationRegistry[name];
- slot.notify(std::forward<Args>(args)...);
+ slot.notify(name, std::forward<Args>(args)...);
}
} // namespace rmi
#endif //__RMI_SERVICE_H__
-
delete &GetDevicePolicyClient(handle);
}
+
+DPM_API int dpm_add_policy_change_listener(dpm_client_h handle, const char* name, dpm_policy_change_cb handler, void* user_data)
+{
+ assert(handle);
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle);
+ client.subscribePolicyChange(name, handler, user_data);
+
+ return 0;
+}
+
+DPM_API void dpm_remove_policy_change_listener(dpm_client_h handle, const char* name, int id)
+{
+ assert(handle);
+}
* @{
*/
+ /**
+ * @brief Called when a policy has changed
+ */
+ typedef void (*dpm_policy_change_cb)(const char* name, int state, void *user_data);
+
/**
* @brief The Device Policy Client handle
* @details The Device Policy Client Handle is an abstraction of the
DPM_API void dpm_destroy_client(dpm_client_h handle);
/**
+ * @brief Adds policy change notification listener to the Device Policy Manager
+ * @details This API can be used to subscribe policy change notification.
+ * The handler will be asynchronously called when policy is changed on runtime.
+ * @since_tizen 3.0
+ * @param[in] handle Device Policy Client Handle
+ * @param[in] name Policy name to subscribe
+ * @param[in] callback handler to be invoked
+ * @param[in] user_data User specified data passed to the listener
+ * @return Listener identifier on success, otherwise negative value
+ * @retval #DPM_ERROR_INVALID_PARAMETER Invalid policy name
+ * @retval #DPM_ERROR_PERMISSION_DENIED The application does not have
+ * the privilege to subscribe the policy change notification
+ * @pre The handle must be created by dpm_create_client()
+ * @see dpm_create_client()
+ * @see dpm_remove_policy_change_listener()
+ */
+DPM_API int dpm_add_policy_change_listener(dpm_client_h handle, const char* name, dpm_policy_change_cb listener, void* user_data);
+
+/**
+ * @brief Removes policy change notification listener from the Device Policy Manager
+ * @details This API must be called if interaction with the Device
+ * Policy Manager is no longer required.
+ * @since_tizen 3.0
+ * @param[in] handle Device Policy Client Handle
+ * @param[in] name Policy policy name to subscribe
+ * @param[in] callback handler to be invoked
+ * @param[in] user_data User specified data passed to the listener
+ * @return None
+ * @pre The handle must be created by dpm_create_client()
+ * @see dpm_create_client()
+ * @see dpm_add_policy_change_listener()
+ */
+DPM_API void dpm_remove_policy_change_listener(dpm_client_h handle, const char* name, int id);
+/**
* @}
*/
namespace {
+const std::string POLICY_NOTIFICATION_PROVIDER = "Server::subscribeNotification";
const std::string POLICY_MANAGER_ADDRESS = "/tmp/.device-policy-manager";
} // namespace
{
client.reset();
}
+
+int DevicePolicyClient::subscribePolicyChange(const std::string& name,
+ const PolicyChangeListener& listener,
+ void* data)
+{
+ auto listenerDispatcher = [listener, data](const std::string& policy, int value) {
+ listener(policy.c_str(), value, data);
+ };
+
+ return client->subscribe<std::string, int>(POLICY_NOTIFICATION_PROVIDER,
+ name, listenerDispatcher);
+}
+
+void DevicePolicyClient::unsubscribePolicyChange(const std::string& name, int subscriberId)
+{
+}
+
+int DevicePolicyClient::connectSignal(const std::string& name,
+ const PolicySignalHandler& handler, void* data)
+{
+ auto signalDispatcher = [handler, data](const std::string& signal) {
+ handler(signal.c_str(), data);
+ };
+
+ return client->subscribe<std::string>(POLICY_NOTIFICATION_PROVIDER, name, signalDispatcher);
+}
+
+void DevicePolicyClient::disconnectSignal(const std::string& name, int signalId)
+{
+}
#include <string>
#include <memory>
+#include <functional>
#include "rmi/client.h"
+typedef std::function<void(const char*, int, void*)> PolicyChangeListener;
+typedef std::function<void(const char*, void*)> PolicySignalHandler;
+
class DevicePolicyClient {
public:
typedef std::unique_ptr<rmi::Client> PolicyControlContext;
int connect(const std::string& address) noexcept;
void disconnect() noexcept;
+ int subscribePolicyChange(const std::string& name, const PolicyChangeListener& listener, void* data);
+ void unsubscribePolicyChange(const std::string& name, int subscriberId);
+
+ int connectSignal(const std::string& name, const PolicySignalHandler& handler, void* data);
+ void disconnectSignal(const std::string& name, int signalId);
+
template<typename Policy, typename... Args>
Policy createPolicyInterface(Args&&... args) noexcept
{
Server::Server()
{
service.reset(new rmi::Service(POLICY_MANAGER_ADDRESS));
+
+ service->registerParametricMethod(this, (FileDescriptor)(Server::subscribeNotification)(std::string));
}
Server::~Server()
service->stop();
}
+FileDescriptor Server::subscribeNotification(const std::string& name)
+{
+ return FileDescriptor(service->subscribeNotification(name), true);
+}
+
Server& Server::instance()
{
static Server _instance_;
#include "client-manager.h"
+#include "file-descriptor.h"
#include "rmi/service.h"
class Server {
return *service;
}
+ FileDescriptor subscribeNotification(const std::string& name);
+
static Server& instance();
private:
#include <utility>
#include "data-type.h"
+#include "file-descriptor.h"
#include "rmi/service.h"
#include "rmi/client.h"
#include "audit/logger.h"
service->registerMethod(this, (String)(TestServer::method2)(String, String));
service->registerMethod(this, (String)(TestServer::method3)(String, String, String));
service->registerMethod(this, (String)(TestServer::method4)(String, String, String, String));
+
+ service->registerMethod(this, (FileDescriptor)(TestServer::signalProvider)(std::string));
+ service->registerMethod(this, (FileDescriptor)(TestServer::policyNotificationProvider)(std::string));
+
+ service->registerNonparametricMethod(this, (int)(TestServer::sendSignal)());
+ service->registerNonparametricMethod(this, (int)(TestServer::sendPolicyChangeNotification)());
+
+ service->createNotification("TestPolicyChanged");
+ service->createNotification("TestSignal");
}
void run()
return String("Method4 result");
}
+ int sendPolicyChangeNotification()
+ {
+ service->notify("TestPolicyChanged", 1234);
+ return 0;
+ }
+
+ int sendSignal()
+ {
+ service->notify("TestSignal");
+ return 0;
+ }
+
+ FileDescriptor signalProvider(const std::string& name)
+ {
+ return service->subscribeNotification(name);
+ }
+
+ FileDescriptor policyNotificationProvider(const std::string& name)
+ {
+ return service->subscribeNotification(name);
+ }
+
private:
std::unique_ptr<rmi::Service> service;
};
void connect()
{
+ auto policyChangedListener = [](const std::string& name, int value) {
+ std::cout << "Policy Changed: " << name << " : " << value << std::endl;
+ };
+
+ auto policySignalListener = [](const std::string& name) {
+ std::cout << "Signal Triggered" << std::endl;
+ };
+
client.reset(new rmi::Client(IPC_TEST_ADDRESS));
client->connect();
+
+ client->subscribe<std::string, int>("TestServer::policyNotificationProvider",
+ "TestPolicyChanged", policyChangedListener);
+ client->subscribe<std::string>("TestServer::signalProvider",
+ "TestSignal", policySignalListener);
}
void disconnect()
return client->methodCall<String>("TestServer::method4", arg1, arg2, arg3, arg4);
}
+ void requestSignal()
+ {
+ signalTriggered = false;
+ client->methodCall<int>("TestServer::sendSignal");
+ while (!signalTriggered) {
+ ::sleep(1);
+ }
+ }
+
+ void requestPolicyChangeNotification()
+ {
+ policyChangeNotificationTriggered = false;
+ client->methodCall<int>("TestServer::sendPolicyChangeNotification");
+ while (!policyChangeNotificationTriggered) {
+ sleep(1);
+ }
+ }
+
String invalidMethod(String& arg)
{
return client->methodCall<String>("TestServer::invalidMethod", arg);
}
private:
+ volatile bool signalTriggered;
+ volatile bool policyChangeNotificationTriggered;
std::unique_ptr<rmi::Client> client;
};
{
addTest(IpcTestSuite::connectionTest);
addTest(IpcTestSuite::remoteMethodCallTest);
+ addTest(IpcTestSuite::notificationTest);
}
void setup()
}
}
+ void notificationTest()
+ {
+ try {
+ TestClient client;
+ client.connect();
+
+ client.requestSignal();
+ client.requestPolicyChangeNotification();
+
+ client.disconnect();
+ } catch (runtime::Exception& e) {
+ ERROR(e.what());
+ }
+ }
+
void remoteMethodCallTest()
{
try {
String result3 = client.method3(param1, param2, param3);
String result4 = client.method4(param1, param2, param3, param4);
+ client.requestSignal();
+ client.requestPolicyChangeNotification();
+
+ sleep(5);
+
client.disconnect();
} catch (runtime::Exception& e) {
ERROR(e.what());