int ctx_sched_job_context_destroy(ctx_sched_job_context_h job_context);
-/**
- * @brief Declares a custom context that can be used as a trigger or a requirement by other applications.
- * @param[in] scheduler TBD
- * @param[in] uri TBD
- * @return @c 0 on success, otherwise a negative error value
- */
-int ctx_sched_declare_context(ctx_sched_h scheduler, const char* uri);
-
-/**
- * @brief Retracts a custom context declared by the current application.
- * @param[in] scheduler TBD
- * @param[in] uri TBD
- * @return @c 0 on success, otherwise a negative error value
- */
-int ctx_sched_undeclare_context(ctx_sched_h scheduler, const char* uri);
-
/**
* @brief Publishes a custom context data corresponding to a URI declared using ctx_sched_declare_context().
* @param[in] scheduler TBD
return E_SUPPORT;
}
-EXPORT_API int ctx_sched_declare_context(ctx_sched_h scheduler, const char* uri)
-{
- return E_SUPPORT;
-}
-
-EXPORT_API int ctx_sched_undeclare_context(ctx_sched_h scheduler, const char* uri)
-{
- return E_SUPPORT;
-}
-
EXPORT_API int ctx_sched_publish_context_json(ctx_sched_h scheduler, const char* uri, const char* json_payload)
{
return E_SUPPORT;
return __isAvailable(static_cast<int>(JobContext::Type::REQUIREMENT), uri);
}
+int JobManagerProxy::publishContext(const std::string& uri, const std::string& payload)
+{
+ return __serviceProxy.call(METHOD_PUBLISH_CONTEXT, g_variant_new("(ss)", uri.c_str(), payload.c_str()));
+}
+
bool JobManagerProxy::__isAvailable(int type, const std::string& uri)
{
GVariant* param = g_variant_new("(is)", type, uri.c_str());
bool isAvailableTrigger(const std::string& uri);
bool isAvailableRequirement(const std::string& uri);
+ int publishContext(const std::string& uri, const std::string& payload);
+
private:
bool __isAvailable(int type, const std::string& uri);
void __onStartJob(GVariant* param);
return E_NONE;
}
-EXPORT_API int ctx_sched_declare_context(ctx_sched_h scheduler, const char* uri)
-{
- IF_FAIL_RETURN(scheduler && uri, E_PARAM);
- //TODO
- return E_SUPPORT;
-}
-
-EXPORT_API int ctx_sched_undeclare_context(ctx_sched_h scheduler, const char* uri)
-{
- IF_FAIL_RETURN(scheduler && uri, E_PARAM);
- //TODO
- return E_SUPPORT;
-}
-
EXPORT_API int ctx_sched_publish_context_json(ctx_sched_h scheduler, const char* uri, const char* json_payload)
{
IF_FAIL_RETURN(scheduler && uri && json_payload, E_PARAM);
- //TODO
- return E_SUPPORT;
+
+ return scheduler->jobManager.publishContext(uri, json_payload);
}
EXPORT_API int ctx_sched_job_set_disjunction(ctx_sched_job_h job, bool disjunction)
return __instance->__getPublisher(uri.c_str(), uid);
}
+bool ContextManager::isCustomUri(const std::string& uri)
+{
+ return ContextPublisher::isCustomUri(uri);
+}
+
ContextPublisher* ContextManager::__getPublisher(const char* uri, uid_t uid)
{
ContextPublisher* pubs = NULL;
- if ((pubs = __find(uri, SYSTEM_UID)))
+ if ((pubs = __find(uri, uid)))
return pubs;
- if ((pubs = __find(uri, uid)))
+ if ((pubs = __find(uri, SYSTEM_UID)))
return pubs;
try {
static void init();
static void release();
static ContextPublisher* getPublisher(const std::string& uri, uid_t uid);
+ static bool isCustomUri(const std::string& uri);
private:
ContextManager();
*/
#include <vector>
+#include <regex>
#include <ContextTypes.h>
#include <SharedUtil.h>
#include "IContextObserver.h"
#include "ContextPublisher.h"
+#include "publisher/CustomPublisher.h"
+
+#define CUSTOM_URI_REGEX R"~(^http:\/\/[\w-\.]+\/context\/custom\/[\w-\._]+$)~"
using namespace ctx;
ContextPublisher* ContextPublisher::build(const char* uri, uid_t uid)
{
+ // Pre-defined publishers
for (auto& it : __creators) {
if (STR_EQ(it.first, uri)) {
return (it.second)(uid);
}
}
- throw E_SUPPORT;
+ // Custom publishers
+ IF_FAIL_THROW(isCustomUri(uri), E_SUPPORT);
+ return new CustomPublisher(uri, uid);
+}
+
+bool ContextPublisher::isCustomUri(const std::string& uri)
+{
+ static std::regex customUriRegex(CUSTOM_URI_REGEX, std::regex::optimize);
+ return std::regex_match(uri, customUriRegex);
}
ContextPublisher::~ContextPublisher()
return true;
}
+bool ContextPublisher::isWritable() const
+{
+ // Pre-defined context items are not allowed to be written by clients.
+ return false;
+}
+
bool ContextPublisher::isUserContext() const
{
// Most context items are system-level data.
return __data;
}
+void ContextPublisher::putData(const Json::Value& data)
+{
+ // Pre-defined publishers do not support this.
+}
+
void ContextPublisher::notifyObservers()
{
_D("%s notifies", getUri());
virtual const char* getUri() const = 0;
virtual const char* getPrivilege() const;
+ // If not readable, it cannot be used as a requirement
virtual bool isReadable() const;
+ virtual bool isWritable() const;
virtual bool isUserContext() const;
virtual bool isReady();
virtual const Json::Value& getData();
+ virtual void putData(const Json::Value& data);
static void registerPublisher(const char* uri, ContextPublisher* (*creator)(uid_t));
static ContextPublisher* build(const char* uri, uid_t uid);
+ static bool isCustomUri(const std::string& uri);
+
protected:
void notifyObservers();
bool JobManager::isSupported(JobContext::Type type, const std::string& uri, IClient* client)
{
+ if (ContextManager::isCustomUri(uri))
+ return true;
+
ContextPublisher* pubs = ContextManager::getPublisher(uri, client->getUid());
IF_FAIL_RETURN(pubs, false);
bool JobManager::__isPermitted(const std::string& uri, IClient* client)
{
+ if (ContextManager::isCustomUri(uri))
+ return true;
+
ContextPublisher* pubs = ContextManager::getPublisher(uri, client->getUid());
IF_FAIL_RETURN(pubs, false);
IF_FAIL_RETURN(client->hasPrivilege(pubs->getPrivilege()), false);
+
return true;
}
*/
#include <algorithm>
+#include <json/json.h>
#include <JobSchedulerTypesPrivate.h>
#include <JobSchedulerService.h>
#include "JobManager.h"
+#include "ContextManager.h"
+#include "ContextPublisher.h"
#include "MethodCallHandler.h"
using namespace ctx;
} else if (methodCall->getMethodName() == METHOD_ENABLE_CB) {
__enableLifecycleCallbacks(*methodCall);
+
+ } else if (methodCall->getMethodName() == METHOD_PUBLISH_CONTEXT) {
+ __publishContext(*methodCall);
}
} catch (const int error) {
_W("Catch: %s", CTX_ERROR_STR(error));
methodCall.reply(E_NONE);
}
+
+void MethodCallHandler::__publishContext(IMethodCall& methodCall)
+{
+ const char* uri = NULL;
+ const char* payload = NULL;
+ Json::Value data;
+
+ g_variant_get(methodCall.getParam(), "(&s&s)", &uri, &payload);
+ IF_FAIL_THROW(uri && payload, E_PARAM);
+
+ try {
+ Json::Reader reader;
+ reader.parse(payload, data);
+ } catch (const Json::Exception& e) {
+ _E("Exception: %s", e.what());
+ throw E_PARAM;
+ }
+
+ ContextPublisher* pubs = ContextManager::getPublisher(uri, __caller->getUid());
+ IF_FAIL_THROW(pubs, E_PARAM);
+ IF_FAIL_THROW(pubs->isWritable(), E_PARAM);
+
+ methodCall.reply(E_NONE);
+
+ pubs->putData(data);
+}
void __getJob(IMethodCall& methodCall);
void __getAllJob(IMethodCall& methodCall);
void __enableLifecycleCallbacks(IMethodCall& methodCall);
+ void __publishContext(IMethodCall& methodCall);
IClient* __caller;
bool __callbackEnabled;
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <ContextTypes.h>
+#include <JobSchedulerTypesPrivate.h>
+#include <job_scheduler_types_internal.h>
+#include "CustomPublisher.h"
+#include "../IContextObserver.h"
+
+using namespace ctx;
+
+CustomPublisher::CustomPublisher(const std::string& uri, uid_t uid) :
+ __uri(uri),
+ __uid(uid)
+{
+ _D("Created '%s' (%u)", __uri.c_str(), static_cast<unsigned>(__uid));
+}
+
+CustomPublisher::~CustomPublisher()
+{
+ _D("Destroyed '%s' (%u)", __uri.c_str(), static_cast<unsigned>(__uid));
+}
+
+const char* CustomPublisher::getUri() const
+{
+ return __uri.c_str();
+}
+
+bool CustomPublisher::isWritable() const
+{
+ return true;
+}
+
+bool CustomPublisher::isUserContext() const
+{
+ return true;
+}
+
+void CustomPublisher::putData(const Json::Value& data)
+{
+ _D("Publish '%s' (%u)", __uri.c_str(), static_cast<unsigned>(__uid));
+ __data = data;
+ notifyObservers();
+}
+
+void CustomPublisher::read()
+{
+ // CustomPublisher works passively.
+}
+
+void CustomPublisher::subscribe()
+{
+ // CustomPublisher works passively.
+}
+
+void CustomPublisher::unsubscribe()
+{
+ // CustomPublisher works passively.
+}
+
+void CustomPublisher::clearData()
+{
+ // CustomPublisher cannot read data from its source.
+ // The cached should not be removed.
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 __CONTEXT_JOB_SCHEDULER_CUSTOM_PUBLISHER_H__
+#define __CONTEXT_JOB_SCHEDULER_CUSTOM_PUBLISHER_H__
+
+#include <string>
+#include "../ContextPublisher.h"
+
+namespace ctx {
+
+ class CustomPublisher : public ContextPublisher {
+ public:
+ CustomPublisher(const std::string& uri, uid_t uid);
+ ~CustomPublisher();
+
+ const char* getUri() const;
+
+ bool isWritable() const;
+ bool isUserContext() const;
+
+ void putData(const Json::Value& data);
+
+ protected:
+ void read();
+ void subscribe();
+ void unsubscribe();
+ void clearData();
+
+ private:
+ std::string __uri;
+ uid_t __uid;
+ };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_CUSTOM_PUBLISHER_H__ */
"<method name='" METHOD_GET_ALL_JOB "'>" \
" <arg type='as' name='jobs' direction='out'/>" \
"</method>" \
- "<method name='" METHOD_IS_SUPPORTED"'>" \
+ "<method name='" METHOD_IS_SUPPORTED "'>" \
" <arg type='i' name='type' direction='in'/>" \
" <arg type='s' name='uri' direction='in'/>" \
"</method>" \
- "<method name='" METHOD_ENABLE_CB"'>" \
+ "<method name='" METHOD_ENABLE_CB "'/>" \
+ "<method name='" METHOD_PUBLISH_CONTEXT "'>" \
+ " <arg type='s' name='uri' direction='in'/>" \
+ " <arg type='s' name='payload' direction='in'/>" \
"</method>"
-#define METHOD_ADD_JOB "AddJob"
-#define METHOD_START_JOB "StartJob"
-#define METHOD_STOP_JOB "StopJob"
-#define METHOD_REMOVE_JOB "RemoveJob"
-#define METHOD_JOB_FINISHED "JobFinished"
-#define METHOD_GET_JOB "GetJob"
-#define METHOD_GET_ALL_JOB "GetAllJob"
-#define METHOD_IS_SUPPORTED "IsSupported"
-#define METHOD_ENABLE_CB "EnableCb"
+#define METHOD_ADD_JOB "AddJob"
+#define METHOD_START_JOB "StartJob"
+#define METHOD_STOP_JOB "StopJob"
+#define METHOD_REMOVE_JOB "RemoveJob"
+#define METHOD_JOB_FINISHED "JobFinished"
+#define METHOD_GET_JOB "GetJob"
+#define METHOD_GET_ALL_JOB "GetAllJob"
+#define METHOD_IS_SUPPORTED "IsSupported"
+#define METHOD_ENABLE_CB "EnableCb"
+#define METHOD_PUBLISH_CONTEXT "PublishContext"
-#define SIGNAL_START_JOB "JobStarted"
-#define SIGNAL_STOP_JOB "JobToBeStopped"
+#define SIGNAL_START_JOB "JobStarted"
+#define SIGNAL_STOP_JOB "JobToBeStopped"
#define URI(x) CTX_SCHED_URI_##x
#define NAME(x) CTX_SCHED_ATTR_NAME_##x