Add an API function ctx_sched_job_finished() and a callback ctx_sched_start_job_cb 15/138815/6
authorMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 14 Jul 2017 02:01:05 +0000 (11:01 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 14 Jul 2017 10:13:09 +0000 (10:13 +0000)
Change-Id: Ia6e6ebec8b1d3ed6d3d56bd17d1251331ff10ca3
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
include/job_scheduler_internal.h
src/client-dummy/job_scheduler.cpp
src/client/JobManagerProxy.cpp
src/client/JobManagerProxy.h
src/client/job_scheduler.cpp
src/server/JobManager.cpp
src/server/JobManager.h
src/server/MethodCallHandler.cpp
src/server/MethodCallHandler.h
src/shared/JobSchedulerTypesPrivate.h

index f2416b2744eb45ae9bcf53082b5c3cc1a53dcb0d..32b6c051935110d498a3c369e321736c2e18b004 100644 (file)
@@ -57,6 +57,18 @@ typedef struct _ctx_sched_job_context_s* ctx_sched_job_context_h;
  */
 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.
@@ -121,7 +133,7 @@ int ctx_sched_cancel_all(ctx_sched_h scheduler);
 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
@@ -129,7 +141,7 @@ int ctx_sched_add_job(ctx_sched_h scheduler, ctx_sched_job_h job, int* job_id);
 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
@@ -137,13 +149,24 @@ int ctx_sched_start_job(ctx_sched_h scheduler, int job_id);
 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.
@@ -165,13 +188,14 @@ int ctx_sched_foreach_job(ctx_sched_h scheduler, ctx_sched_foreach_job_cb callba
 
 
 /**
- * @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);
 
 
 /**
index 40f6a3b21a2dc6714bf0cd2f5cf6369bfa0f315a..e2a583b8647ebf4f1f42a9352311c0c0500800bd 100644 (file)
@@ -74,6 +74,11 @@ EXPORT_API int ctx_sched_remove_job(ctx_sched_h scheduler, int job_id)
        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;
@@ -84,7 +89,7 @@ EXPORT_API int ctx_sched_foreach_job(ctx_sched_h scheduler, ctx_sched_foreach_jo
        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;
 }
index 584fdf0236357b8dbf01ebc4f5b229c173dff1db..4aab5a3452375a903f89d70f47ecf15b49beeb1b 100644 (file)
@@ -22,16 +22,15 @@ using namespace ctx;
 
 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)
@@ -73,6 +72,13 @@ int JobManagerProxy::removeJob(int jobId)
        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;
@@ -135,24 +141,25 @@ std::vector<JobInfo*> JobManagerProxy::getAllJob()
        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)
@@ -179,3 +186,27 @@ bool JobManagerProxy::__isAvailable(int type, 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);
+}
index 7b0397f1891d7e2f07d1842a76e44f860e84258e..5c9d34a2575453d36828ea61ac6df520aa46d8fc 100644 (file)
@@ -36,10 +36,12 @@ namespace ctx {
                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);
 
@@ -48,11 +50,14 @@ namespace ctx {
 
        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;
        };
 
 }
index d349debad15a3736056208d149cf8eaa49ea0b3e..967323ade6956d3c57701e8eb273d87fa438fac0 100644 (file)
@@ -30,11 +30,12 @@ using namespace ctx;
 
 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;
 
 
@@ -156,6 +157,13 @@ EXPORT_API int ctx_sched_remove_job(ctx_sched_h scheduler, int job_id)
        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);
@@ -207,6 +215,21 @@ EXPORT_API int ctx_sched_foreach_job(ctx_sched_h scheduler, ctx_sched_foreach_jo
        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);
@@ -222,13 +245,14 @@ static void __stopJob(JobInfo* jobInfo, void* 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;
 }
index afeadcd990e78b85f881df689d00a4f6096e489d..416747949aeb9a487337e835833339189e643923 100644 (file)
@@ -187,13 +187,23 @@ int JobManager::stopJob(int jobId, IClient* owner)
 
 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;
 }
index 324b94cc5ab0939033de34d6928c33ebe6443bfa..2d983c70107a1b8f690223596ba84fa15301a529 100644 (file)
@@ -40,6 +40,7 @@ namespace ctx {
                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);
index a45c6893091f9d0c1729f05f9bc5834aff8ebab0..77f3dd29c34ed2fef2e3b3173588e51d8bab4136 100644 (file)
@@ -49,6 +49,9 @@ void MethodCallHandler::onMethodCalled(IMethodCall* methodCall)
                } 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);
 
@@ -158,6 +161,19 @@ void MethodCallHandler::__removeJob(IMethodCall& 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;
index 6f759bf349e0afb9ec1cdaa570839a273f4ae325..0912058517b0883d60766fa05c3e7a49bf2df422 100644 (file)
@@ -41,6 +41,7 @@ namespace ctx {
                void __startJob(IMethodCall& methodCall);
                void __stopJob(IMethodCall& methodCall);
                void __removeJob(IMethodCall& methodCall);
+               void __jobFinished(IMethodCall& methodCall);
                void __getJob(IMethodCall& methodCall);
                void __getAllJob(IMethodCall& methodCall);
 
index 792456c0b87283f116e73e5734621549d00b91f6..abfb34bfdd0519c30db176aeb683d96d32737a9e 100644 (file)
@@ -35,6 +35,9 @@
        "<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