*/
typedef bool (*ctx_sched_foreach_job_cb)(ctx_sched_h scheduler, ctx_sched_job_h job, void* user_data);
+/**
+ * @brief Called when a job has been executed.
+ * @details In addition to the action assigned to the job, for convenience,
+ * the application is able to set this callback function.
+ * @remarks @c job should be destroyed using ctx_sched_job_destroy().
+ * @param[in] scheduler TBD
+ * @param[in] job TBD
+ * @param[in] timeout @c true if only the mandatory requirements are satisfied; @c false otherwise.
+ * @param[in] user_data TBD
+ */
+typedef void (*ctx_sched_start_job_cb)(ctx_sched_h scheduler, ctx_sched_job_h job, bool timeout, void* user_data);
+
/**
* @brief Called when a job needs to be stopped.
* @details In some reason, the device may no longer allow executions of scheduled jobs.
int ctx_sched_add_job(ctx_sched_h scheduler, ctx_sched_job_h job, int* job_id);
/**
- * @brief Starts a job
+ * @brief Starts a job.
* @param[in] scheduler TBD
* @param[in] job_id TBD
* @return @c 0 on success, otherwise a negative error value
int ctx_sched_start_job(ctx_sched_h scheduler, int job_id);
/**
- * @brief Stops a job
+ * @brief Stops a job.
* @param[in] scheduler TBD
* @param[in] job_id TBD
* @return @c 0 on success, otherwise a negative error value
int ctx_sched_stop_job(ctx_sched_h scheduler, int job_id);
/**
- * @brief Unregisters a job
+ * @brief Unregisters a job.
* @param[in] scheduler TBD
* @param[in] job_id TBD
* @return @c 0 on success, otherwise a negative error value
*/
int ctx_sched_remove_job(ctx_sched_h scheduler, int job_id);
+/**
+ * @brief Notifies that a job is finished.
+ * @details If a job has been launched, the system is kept awake for a while.
+ * It is highly recommended to notifies that the job is done,
+ * the system thus knows that it does not need to be kept awake.
+ * @param[in] scheduler TBD
+ * @param[in] job_id TBD
+ * @return @c 0 on success, otherwise a negative error value
+ */
+int ctx_sched_job_finished(ctx_sched_h scheduler, int job_id);
+
/**
* @brief Gets a job information handle.
/**
- * @brief Sets the callback function to be called when a job needs to be stopped.
+ * @brief Sets the callback functions to be called when a job is started or about to be stopped.
* @param[in] scheduler TBD
- * @param[in] callback TBD
+ * @param[in] start_cb TBD
+ * @param[in] stop_cb TBD
* @param[in] user_data TBD
* @return @c 0 on success, otherwise a negative error value
*/
-int ctx_sched_set_stop_job_cb(ctx_sched_h scheduler, ctx_sched_stop_job_cb callback, void* user_data);
+int ctx_sched_set_job_cb(ctx_sched_h scheduler, ctx_sched_start_job_cb start_cb, ctx_sched_stop_job_cb stop_cb, void* user_data);
/**
return E_SUPPORT;
}
+EXPORT_API int ctx_sched_job_finished(ctx_sched_h scheduler, int job_id)
+{
+ return E_SUPPORT;
+}
+
EXPORT_API int ctx_sched_get_job(ctx_sched_h scheduler, int job_id, ctx_sched_job_h* job)
{
return E_SUPPORT;
return E_SUPPORT;
}
-EXPORT_API int ctx_sched_set_stop_job_cb(ctx_sched_h scheduler, ctx_sched_stop_job_cb callback, void* user_data)
+EXPORT_API int ctx_sched_set_job_cb(ctx_sched_h scheduler, ctx_sched_start_job_cb start_cb, ctx_sched_stop_job_cb stop_cb, void* user_data)
{
return E_SUPPORT;
}
JobManagerProxy::JobManagerProxy() :
__serviceProxy(CTX_JOB_SCHEDULER),
+ __startJobCb(NULL),
__stopJobCb(NULL),
__userData(NULL),
- __subscriptionId(0)
+ __subscribing(false)
{
}
JobManagerProxy::~JobManagerProxy()
{
- if (__subscriptionId != 0)
- __serviceProxy.unsubscribe(__subscriptionId);
}
int JobManagerProxy::addJob(JobInfo* jobInfo)
return err;
}
+int JobManagerProxy::jobFinished(int jobId)
+{
+ int err = __serviceProxy.call(METHOD_JOB_FINISHED, g_variant_new("(i)", jobId));
+ PRINT_ERR(err);
+ return err;
+}
+
JobInfo* JobManagerProxy::getJob(int jobId)
{
GVariant* result = NULL;
return jobInfos;
}
-void JobManagerProxy::setStopJobCb(void (*stopJobCb)(JobInfo*, void*), void* userData)
+void JobManagerProxy::setJobCb(void (*startJobCb)(JobInfo*, bool, void*), void (*stopJobCb)(JobInfo*, void*), void* userData)
{
+ __startJobCb = startJobCb;
__stopJobCb = stopJobCb;
__userData = userData;
- if (__subscriptionId == 0)
- __subscriptionId = __serviceProxy.subscribe(SIGNAL_STOP_JOB, this);
+ if (!__subscribing) {
+ __serviceProxy.subscribe(SIGNAL_START_JOB, this);
+ __serviceProxy.subscribe(SIGNAL_STOP_JOB, this);
+ __subscribing = true;
+ }
}
void JobManagerProxy::onSignal(const std::string& signalName, GVariant* param)
{
- const char* jobStr = NULL;
- g_variant_get(param, "(&s)", jobStr);
-
- JobInfo* jobInfo = JobInfo::deserialize(jobStr);
- IF_FAIL_VOID_TAG(jobInfo, _E, "Deserialization failed");
-
- __stopJobCb(jobInfo, __userData);
+ if (signalName == SIGNAL_START_JOB)
+ __onStartJob(param);
+ else if (signalName == SIGNAL_STOP_JOB)
+ __onStopJob(param);
}
bool JobManagerProxy::isAvailableTrigger(const std::string& uri)
_E("Error: %s", CTX_ERROR_STR(err));
throw err;
}
+
+void JobManagerProxy::__onStartJob(GVariant* param)
+{
+ const char* jobStr = NULL;
+ gboolean timeout = FALSE;
+
+ g_variant_get(param, "(&sb)", jobStr, &timeout);
+
+ JobInfo* jobInfo = JobInfo::deserialize(jobStr);
+ IF_FAIL_VOID_TAG(jobInfo, _E, "Deserialization failed");
+
+ __startJobCb(jobInfo, (timeout == TRUE), __userData);
+}
+
+void JobManagerProxy::__onStopJob(GVariant* param)
+{
+ const char* jobStr = NULL;
+ g_variant_get(param, "(&s)", jobStr);
+
+ JobInfo* jobInfo = JobInfo::deserialize(jobStr);
+ IF_FAIL_VOID_TAG(jobInfo, _E, "Deserialization failed");
+
+ __stopJobCb(jobInfo, __userData);
+}
int startJob(int jobId);
int stopJob(int jobId);
+ int jobFinished(int jobId);
+
JobInfo* getJob(int jobId);
std::vector<JobInfo*> getAllJob();
- void setStopJobCb(void (*stopJobCb)(JobInfo*, void*), void* userData);
+ void setJobCb(void (*startJobCb)(JobInfo*, bool, void*), void (*stopJobCb)(JobInfo*, void*), void* userData);
void onSignal(const std::string& signalName, GVariant* param);
private:
bool __isAvailable(int type, const std::string& uri);
+ void __onStartJob(GVariant* param);
+ void __onStopJob(GVariant* param);
ServiceProxy __serviceProxy;
+ void (*__startJobCb)(JobInfo*, bool, void*);
void (*__stopJobCb)(JobInfo*, void*);
void* __userData;
- unsigned int __subscriptionId;
+ bool __subscribing;
};
}
typedef struct _ctx_sched_s {
JobManagerProxy jobManager;
+ ctx_sched_start_job_cb startJobCb;
ctx_sched_stop_job_cb stopJobCb;
void* userData;
_ctx_sched_s() :
- stopJobCb(NULL), userData(NULL) {}
+ startJobCb(NULL), stopJobCb(NULL), userData(NULL) {}
} ctx_sched_s;
return scheduler->jobManager.removeJob(job_id);
}
+EXPORT_API int ctx_sched_job_finished(ctx_sched_h scheduler, int job_id)
+{
+ IF_FAIL_RETURN(scheduler && job_id > 0, E_PARAM);
+
+ return scheduler->jobManager.jobFinished(job_id);
+}
+
EXPORT_API int ctx_sched_get_job(ctx_sched_h scheduler, int job_id, ctx_sched_job_h* job)
{
IF_FAIL_RETURN(scheduler && job_id > 0 && job, E_PARAM);
return E_NONE;
}
+static void __startJob(JobInfo* jobInfo, bool timeout, void* userData)
+{
+ ctx_sched_s* scheduler = static_cast<ctx_sched_s*>(userData);
+ ctx_sched_job_s* job = new(std::nothrow) ctx_sched_job_s();
+
+ if (!job) {
+ _E_ALLOC;
+ delete jobInfo;
+ return;
+ }
+
+ job->jobInfo = jobInfo;
+ scheduler->startJobCb(scheduler, job, timeout, scheduler->userData);
+}
+
static void __stopJob(JobInfo* jobInfo, void* userData)
{
ctx_sched_s* scheduler = static_cast<ctx_sched_s*>(userData);
scheduler->stopJobCb(scheduler, job, scheduler->userData);
}
-EXPORT_API int ctx_sched_set_stop_job_cb(ctx_sched_h scheduler, ctx_sched_stop_job_cb callback, void* user_data)
+EXPORT_API int ctx_sched_set_job_cb(ctx_sched_h scheduler, ctx_sched_start_job_cb start_cb, ctx_sched_stop_job_cb stop_cb, void* user_data)
{
- IF_FAIL_RETURN(scheduler && callback, E_PARAM);
+ IF_FAIL_RETURN(scheduler && start_cb && stop_cb, E_PARAM);
- scheduler->stopJobCb = callback;
+ scheduler->startJobCb = start_cb;
+ scheduler->stopJobCb = stop_cb;
scheduler->userData = user_data;
- scheduler->jobManager.setStopJobCb(__stopJob, scheduler);
+ scheduler->jobManager.setJobCb(__startJob, __stopJob, scheduler);
return E_NONE;
}
int JobManager::removeJob(int jobId, IClient* owner)
{
- JobRunner* runner = __getRunner(owner->getName(), jobId);
- IF_FAIL_RETURN_TAG(runner, E_PARAM, _W, "Not found");
+ JobRunner* jobRunner = __getRunner(owner->getName(), jobId);
+ IF_FAIL_RETURN_TAG(jobRunner, E_PARAM, _W, "Not found");
- if (runner->isPersistent())
+ if (jobRunner->isPersistent())
__jobInfoDatabase.remove(jobId);
- __removeRunner(runner);
+ __removeRunner(jobRunner);
+
+ return E_NONE;
+}
+
+int JobManager::jobFinished(int jobId, IClient* owner)
+{
+ JobRunner* jobRunner = __getRunner(owner->getName(), jobId);
+ IF_FAIL_RETURN_TAG(jobRunner, E_PARAM, _W, "Not found");
+
+ jobRunner->jobFinished();
return E_NONE;
}
int startJob(int jobId, IClient* owner);
int stopJob(int jobId, IClient* owner);
int removeJob(int jobId, IClient* owner);
+ int jobFinished(int jobId, IClient* owner);
void removeRunner(JobRunner* runner);
JobInfo* getJobInfo(int jobId, IClient* owner);
} else if (methodCall->getMethodName() == METHOD_REMOVE_JOB) {
__removeJob(*methodCall);
+ } else if (methodCall->getMethodName() == METHOD_JOB_FINISHED) {
+ __jobFinished(*methodCall);
+
} else if (methodCall->getMethodName() == METHOD_GET_JOB) {
__getJob(*methodCall);
methodCall.reply(E_NONE);
}
+void MethodCallHandler::__jobFinished(IMethodCall& methodCall)
+{
+ int jobId = 0;
+ g_variant_get(methodCall.getParam(), "(i)", &jobId);
+
+ _I("Job-%d finished", jobId);
+
+ int err = __getJobManager().jobFinished(jobId, __caller);
+ IF_FAIL_THROW(IS_SUCCESS(err), err);
+
+ methodCall.reply(E_NONE);
+}
+
void MethodCallHandler::__getJob(IMethodCall& methodCall)
{
int jobId = 0;
void __startJob(IMethodCall& methodCall);
void __stopJob(IMethodCall& methodCall);
void __removeJob(IMethodCall& methodCall);
+ void __jobFinished(IMethodCall& methodCall);
void __getJob(IMethodCall& methodCall);
void __getAllJob(IMethodCall& methodCall);
"<method name='" METHOD_REMOVE_JOB "'>" \
" <arg type='i' name='jobId' direction='in'/>" \
"</method>" \
+ "<method name='" METHOD_JOB_FINISHED "'>" \
+ " <arg type='i' name='jobId' direction='in'/>" \
+ "</method>" \
"<method name='" METHOD_GET_JOB "'>" \
" <arg type='i' name='jobId' direction='in'/>" \
" <arg type='s' name='job' direction='out'/>" \
"<method name='" METHOD_IS_SUPPORTED"'>" \
" <arg type='i' name='type' direction='in'/>" \
" <arg type='s' name='uri' direction='in'/>" \
- "</method>" \
- "<signal name='" SIGNAL_STOP_JOB "'>" \
- " <arg type='s' name='job' direction='out'/>" \
- "</signal>"
+ "</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 SIGNAL_START_JOB "JobStarted"
#define SIGNAL_STOP_JOB "JobToBeStopped"
#ifdef PRINT_ERR