Reorganize source directory: concrete state class files are moved to 'state' subdirectory 88/141088/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 28 Jul 2017 06:20:02 +0000 (15:20 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Fri, 28 Jul 2017 06:20:02 +0000 (15:20 +0900)
Change-Id: I09853d9be3aec9ef2f14d3c93cf7d66fa0bf2324
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
22 files changed:
src/server/ActionState.cpp [deleted file]
src/server/ActionState.h [deleted file]
src/server/ClosingState.cpp [deleted file]
src/server/ClosingState.h [deleted file]
src/server/OnDemandJobRunner.cpp
src/server/PeriodicJobRunner.cpp
src/server/ReqVerificationState.cpp [deleted file]
src/server/ReqVerificationState.h [deleted file]
src/server/TimerStandbyState.cpp [deleted file]
src/server/TimerStandbyState.h [deleted file]
src/server/TriggerStandbyState.cpp [deleted file]
src/server/TriggerStandbyState.h [deleted file]
src/server/state/ActionState.cpp [new file with mode: 0644]
src/server/state/ActionState.h [new file with mode: 0644]
src/server/state/ClosingState.cpp [new file with mode: 0644]
src/server/state/ClosingState.h [new file with mode: 0644]
src/server/state/ReqVerificationState.cpp [new file with mode: 0644]
src/server/state/ReqVerificationState.h [new file with mode: 0644]
src/server/state/TimerStandbyState.cpp [new file with mode: 0644]
src/server/state/TimerStandbyState.h [new file with mode: 0644]
src/server/state/TriggerStandbyState.cpp [new file with mode: 0644]
src/server/state/TriggerStandbyState.h [new file with mode: 0644]

diff --git a/src/server/ActionState.cpp b/src/server/ActionState.cpp
deleted file mode 100644 (file)
index ea6dee7..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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 <aul_svc.h>
-#include <notification.h>
-#include <notification_internal.h>
-#include <vconf.h>
-#include <Conf.h>
-#include <JobSchedulerTypesPrivate.h>
-#include <JobAction.h>
-#include "IPC.h"
-#include "ActionState.h"
-#include "ClosingState.h"
-
-#define SYSTEM_UID     0
-
-using namespace ctx;
-
-ActionState::ActionState(JobState* prevState, bool timeout) :
-       JobState(prevState),
-       __timeout(timeout),
-       __stopped(false),
-       __gSrcId(0),
-       __client(NULL)
-{
-       _ENTER;
-}
-
-ActionState::~ActionState()
-{
-       _EXIT;
-
-       if (__gSrcId != 0)
-               g_source_remove(__gSrcId);
-}
-
-bool ActionState::execute()
-{
-       auto type = getJobInfo()->getAction()->getType();
-
-       if (type == JobAction::Type::DBUS_METHOD) {
-               __callDBusMethod();
-
-       } else if (type == JobAction::Type::APP_CONTROL) {
-               __sendAppControl();
-
-       } else if (type == JobAction::Type::NOTIFICATION) {
-               __postNotification();
-
-       } else {
-               return false;
-       }
-
-       __gSrcId = g_timeout_add(CTX_ACTION_STOP_MARGIN, __stop, this);
-       return true;
-}
-
-void ActionState::setClient(IClient* client)
-{
-       __client = client;
-       IF_FAIL_VOID(__client);
-
-       std::string jobInfo = getJobInfo()->serialize();
-
-       __client->publish(SIGNAL_START_JOB, g_variant_new("(sb)", jobInfo.c_str(), __timeout));
-
-       if (__stopped)
-               __client->publish(SIGNAL_STOP_JOB, g_variant_new("(s)", jobInfo.c_str()));
-}
-
-void ActionState::jobFinished()
-{
-       transit(new ClosingState(this));
-}
-
-void ActionState::__callDBusMethod()
-{
-       JobDBusCall* action = static_cast<JobDBusCall*>(getJobInfo()->getAction());
-       bool success = false;
-
-       _D("Call %s.%s", action->getInterface().c_str(), action->getMethodName().c_str());
-       success = IPC::dbusCall(action->getBusName(), action->getObjectPath(),
-                       action->getInterface(), action->getMethodName(), action->getParameters());
-
-       IF_FAIL_VOID_TAG(success, _E, "DBus call failed");
-}
-
-static void __aul_svc_result_cb(bundle* b, int requestCode, aul_svc_result_val result, void* data)
-{
-       _D("App-control sent: %d", result);
-}
-
-void ActionState::__sendAppControl()
-{
-       IF_FAIL_VOID_TAG(getUid() != SYSTEM_UID, _W, "Not a user session");
-
-       _D("Send app-control to %u", static_cast<unsigned>(getUid()));
-
-       bundle* bn = static_cast<JobAppControl*>(getJobInfo()->getAction())->getAppControl();
-       IF_FAIL_VOID_TAG(bn, _E, "App-control not found");
-
-       int pid = aul_svc_run_service_for_uid(bn, 0, __aul_svc_result_cb, NULL, getUid());
-       IF_FAIL_VOID_TAG(pid >= 0, _E, "Sending app-control failed");
-}
-
-static notification_h __create_notification(const std::string& title,
-               const std::string& content, const std::string& iconPath, bundle* appCtrlBundle)
-{
-       notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
-
-       if (!title.empty()) {
-               notification_set_text(notification,
-                               NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-       }
-
-       if (!content.empty()) {
-               notification_set_text(notification,
-                               NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-       }
-
-       if (!iconPath.empty()) {
-               notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, iconPath.c_str());
-       }
-
-       if (appCtrlBundle) {
-               notification_set_execute_option(notification,
-                               NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, appCtrlBundle);
-       } else {
-               notification_set_property(notification, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
-       }
-
-       int sound = 0;
-       vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound);
-       if (sound) {
-               notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
-       }
-
-       int vibration = 0;
-       vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration);
-       if (vibration) {
-               notification_set_vibration(notification,
-                               NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
-       }
-
-       return notification;
-}
-
-void ActionState::__postNotification()
-{
-       IF_FAIL_VOID_TAG(getUid() != SYSTEM_UID, _W, "Not a user session");
-
-       JobNotification* action = static_cast<JobNotification*>(getJobInfo()->getAction());
-
-       notification_h notification = __create_notification(action->getTitle(),
-                       action->getContent(), action->getIconPath(), action->getAppControl());
-       IF_FAIL_VOID_TAG(notification, _E, "Notification construction failed");
-
-       int error = notification_post_for_uid(notification, getUid());
-       notification_free(notification);
-
-       IF_FAIL_VOID_TAG(error == NOTIFICATION_ERROR_NONE, _E, "Posting notification failed");
-}
-
-void ActionState::__stop()
-{
-       __stopped = true;
-
-       if (__client) {
-               std::string jobInfo = getJobInfo()->serialize();
-               __client->publish(SIGNAL_STOP_JOB, g_variant_new("(s)", jobInfo.c_str()));
-       }
-
-       __gSrcId = g_timeout_add(CTX_ACTION_EXIT_MARGIN, __exit, this);
-}
-
-void ActionState::__exit()
-{
-       __gSrcId = 0;
-       transit(new ClosingState(this));
-}
-
-gboolean ActionState::__stop(gpointer data)
-{
-       static_cast<ActionState*>(data)->__stop();
-       return G_SOURCE_REMOVE;
-}
-
-gboolean ActionState::__exit(gpointer data)
-{
-       static_cast<ActionState*>(data)->__exit();
-       return G_SOURCE_REMOVE;
-}
diff --git a/src/server/ActionState.h b/src/server/ActionState.h
deleted file mode 100644 (file)
index 30b9a33..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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_ACTION_STATE_H__
-#define __CONTEXT_JOB_SCHEDULER_ACTION_STATE_H__
-
-#include <WakeLock.h>
-#include "JobState.h"
-
-namespace ctx {
-
-       class ActionState : public JobState {
-       public:
-               ActionState(JobState* prevState, bool timeout);
-               ~ActionState();
-
-               bool execute();
-
-               void setClient(IClient* client);
-               void jobFinished();
-
-       private:
-               void __callDBusMethod();
-               void __sendAppControl();
-               void __postNotification();
-
-               void __stop();
-               void __exit();
-
-               static gboolean __stop(gpointer data);
-               static gboolean __exit(gpointer data);
-
-               bool __timeout;
-               bool __stopped;
-               guint __gSrcId;
-               IClient* __client;
-
-               WakeLock __wakeLock;
-       };
-
-}
-
-#endif /* __CONTEXT_JOB_SCHEDULER_ACTION_STATE_H__ */
diff --git a/src/server/ClosingState.cpp b/src/server/ClosingState.cpp
deleted file mode 100644 (file)
index f189cb8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 "JobRunner.h"
-#include "ClosingState.h"
-
-using namespace ctx;
-
-ClosingState::ClosingState(JobState* prevState) :
-       JobState(prevState)
-{
-       _ENTER;
-}
-
-ClosingState::~ClosingState()
-{
-       _EXIT;
-}
-
-bool ClosingState::execute()
-{
-       g_idle_add(__exit, this);
-       return true;
-}
-
-void ClosingState::__exit()
-{
-       if (getJobInfo()->isOneTime()) {
-               getJobRunner()->terminate();
-       } else {
-               getJobRunner()->restart();
-       }
-}
-
-gboolean ClosingState::__exit(gpointer data)
-{
-       static_cast<ClosingState*>(data)->__exit();
-       return G_SOURCE_REMOVE;
-}
diff --git a/src/server/ClosingState.h b/src/server/ClosingState.h
deleted file mode 100644 (file)
index bf701b9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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_CLOSING_STATE_H__
-#define __CONTEXT_JOB_SCHEDULER_CLOSING_STATE_H__
-
-#include <WakeLock.h>
-#include "JobState.h"
-
-namespace ctx {
-
-       class ClosingState : public JobState {
-       public:
-               ClosingState(JobState* prevState);
-               ~ClosingState();
-
-               bool execute();
-
-       private:
-               void __exit();
-
-               static gboolean __exit(gpointer data);
-
-               WakeLock __wakeLock;
-       };
-
-}
-
-#endif /* __CONTEXT_JOB_SCHEDULER_CLOSING_STATE_H__ */
index 9d266e443cb808c3ba6e0a987d3cbcfd100b63e3..053e866c5e748562ef9bab8f277680f10d77095c 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include "JobManager.h"
-#include "TriggerStandbyState.h"
+#include "state/TriggerStandbyState.h"
 #include "OnDemandJobRunner.h"
 
 using namespace ctx;
index bc6a77e2452d95e67c9016264b487869d29fc5d6..e88a5310e865cf776f2b06e7f90913418383beca 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "SchedTimer.h"
 #include "JobManager.h"
-#include "TimerStandbyState.h"
+#include "state/TimerStandbyState.h"
 #include "PeriodicJobRunner.h"
 
 using namespace ctx;
diff --git a/src/server/ReqVerificationState.cpp b/src/server/ReqVerificationState.cpp
deleted file mode 100644 (file)
index 707d0df..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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 <algorithm>
-#include <JobContext.h>
-#include "ContextManager.h"
-#include "ContextPublisher.h"
-#include "JobRunner.h"
-#include "ActionState.h"
-#include "ReqVerificationState.h"
-
-#define MIN_TIMEOUT    20u
-
-using namespace ctx;
-
-ReqVerificationState::ReqVerificationState(JobState* prevState) :
-       JobState(prevState),
-       __startSrcId(0),
-       __timeoutSrcId(0)
-{
-       _ENTER;
-}
-
-ReqVerificationState::~ReqVerificationState()
-{
-       _EXIT;
-       __unsubscribe();
-}
-
-bool ReqVerificationState::execute()
-{
-       if (!__subscribe())
-               return false;
-
-       return true;
-}
-
-void ReqVerificationState::contextDataReady(ContextPublisher* pubs, void* userData)
-{
-       for (auto it = __reqInfos.begin(); it != __reqInfos.end(); ++it) {
-               if ((*it).pubs != pubs)
-                       continue;
-
-               if (!(*((*it).req) <= pubs->getData()))
-                       continue;
-
-               pubs->removeObserver(this);
-               __reqInfos.erase(it);
-       }
-
-       if (__inspectAll())
-               transit(new ActionState(this, false));
-}
-
-bool ReqVerificationState::__subscribe()
-{
-       auto& reqs = getJobInfo()->getRequirements();
-
-       for (auto& req : reqs) {
-               ContextPublisher* pubs = ContextManager::getPublisher(req->getUri(), getUid());
-               IF_FAIL_RETURN(pubs, false);
-
-               pubs->addObserver(this, req);
-               __reqInfos.emplace_back(req, pubs);
-       }
-
-       unsigned int timeout = std::max(getJobInfo()->getRequirementTimeout(), MIN_TIMEOUT);
-
-       __startSrcId = g_idle_add(__onStart, this);
-       __timeoutSrcId = g_timeout_add(timeout, __onTimeout, this);
-
-       return true;
-}
-
-void ReqVerificationState::__unsubscribe()
-{
-       if (__startSrcId != 0) {
-               g_source_remove(__startSrcId);
-               __startSrcId = 0;
-       }
-
-       if (__timeoutSrcId != 0) {
-               g_source_remove(__timeoutSrcId);
-               __timeoutSrcId = 0;
-       }
-
-       for (auto& info : __reqInfos) {
-               info.pubs->removeObserver(this);
-       }
-
-       __reqInfos.clear();
-}
-
-void ReqVerificationState::__readLatest()
-{
-       __reqInfos.remove_if(
-                       [this](const ReqInfo& info)->bool {
-                               if (!info.pubs->isReady())
-                                       return false;
-                               if (!(*(info.req) <= info.pubs->getData()))
-                                       return false;
-                               info.pubs->removeObserver(this);
-                               return true;
-                       });
-}
-
-bool ReqVerificationState::__inspectAll()
-{
-       if (getJobInfo()->isDisjunction()) {
-               bool satisfied = __inspectDisjunction();
-               if (satisfied)
-                       __unsubscribe();
-               return satisfied;
-       }
-
-       return __reqInfos.empty();
-}
-
-bool ReqVerificationState::__inspectMandatory()
-{
-       if (getJobInfo()->isDisjunction())
-               return __inspectDisjunction();
-
-       for (auto& info : __reqInfos) {
-               if (!info.req->isOptional())
-                       return false;
-       }
-
-       return true;
-}
-
-bool ReqVerificationState::__inspectDisjunction()
-{
-       unsigned int all = getJobInfo()->getRequirements().size();
-       unsigned int remaining = __reqInfos.size();
-       return remaining < all;
-}
-
-void ReqVerificationState::__onStart()
-{
-       __startSrcId = 0;
-
-       __readLatest();
-
-       if (__inspectAll())
-               transit(new ActionState(this, false));
-}
-
-void ReqVerificationState::__onTimeout()
-{
-       __timeoutSrcId = 0;
-
-       if (__inspectMandatory()) {
-               __unsubscribe();
-               transit(new ActionState(this, true));
-               return;
-       }
-
-       _I("Not all mandatory requirements are satisfied");
-       __unsubscribe();
-       getJobRunner()->restart();
-}
-
-gboolean ReqVerificationState::__onStart(gpointer data)
-{
-       static_cast<ReqVerificationState*>(data)->__onStart();
-       return G_SOURCE_REMOVE;
-}
-
-gboolean ReqVerificationState::__onTimeout(gpointer data)
-{
-       static_cast<ReqVerificationState*>(data)->__onTimeout();
-       return G_SOURCE_REMOVE;
-}
-
-ReqVerificationState::ReqInfo::ReqInfo(JobRequirement* r, ContextPublisher* p) :
-       req(r),
-       pubs(p)
-{
-}
diff --git a/src/server/ReqVerificationState.h b/src/server/ReqVerificationState.h
deleted file mode 100644 (file)
index 008ae1a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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_REQ_VERIFICATION_STATE_H__
-#define __CONTEXT_JOB_SCHEDULER_REQ_VERIFICATION_STATE_H__
-
-#include <list>
-#include <WakeLock.h>
-#include "IContextObserver.h"
-#include "JobState.h"
-
-namespace ctx {
-
-       class ReqVerificationState : public JobState, public IContextObserver {
-       public:
-               ReqVerificationState(JobState* prevState);
-               ~ReqVerificationState();
-
-               bool execute();
-               void contextDataReady(ContextPublisher* pubs, void* userData);
-
-       private:
-               bool __subscribe();
-               void __unsubscribe();
-               void __readLatest();
-
-               bool __inspectAll();
-               bool __inspectMandatory();
-
-               void __onStart();
-               void __onTimeout();
-
-               static gboolean __onStart(gpointer data);
-               static gboolean __onTimeout(gpointer data);
-
-               /* Legacy support */
-               bool __inspectDisjunction();
-
-               struct ReqInfo {
-                       JobRequirement* req;
-                       ContextPublisher* pubs;
-                       ReqInfo(JobRequirement* r, ContextPublisher* p);
-               };
-
-               std::list<ReqInfo> __reqInfos;
-
-               guint __startSrcId;
-               guint __timeoutSrcId;
-
-               WakeLock __wakeLock;
-       };
-
-}
-
-#endif /* __CONTEXT_JOB_SCHEDULER_REQ_VERIFICATION_STATE_H__ */
diff --git a/src/server/TimerStandbyState.cpp b/src/server/TimerStandbyState.cpp
deleted file mode 100644 (file)
index ae3df63..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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 <Conf.h>
-#include "PeriodicJobRunner.h"
-#include "ReqVerificationState.h"
-#include "TimerStandbyState.h"
-
-#define SEC_PER_MIN    60
-
-using namespace ctx;
-
-unsigned int TimerStandbyState::__timerStandbyStateCnt = 0;
-
-TimerStandbyState::TimerStandbyState(JobRunner* runner) :
-       JobState(runner)
-{
-       _ENTER;
-       ++__timerStandbyStateCnt;
-}
-
-TimerStandbyState::~TimerStandbyState()
-{
-       _EXIT;
-       --__timerStandbyStateCnt;
-       SchedTimer::remove(this);
-}
-
-bool TimerStandbyState::execute()
-{
-       return __setTimer();
-}
-
-void TimerStandbyState::onSchedTimerExpired()
-{
-       transit(new ReqVerificationState(this));
-}
-
-unsigned int TimerStandbyState::getCount()
-{
-       return __timerStandbyStateCnt;
-}
-
-bool TimerStandbyState::__setTimer()
-{
-       PeriodicJobRunner* runner = static_cast<PeriodicJobRunner*>(getJobRunner());
-       time_t interval = static_cast<time_t>(static_cast<PeriodicJobInfo*>(getJobInfo())->getInterval()) * SEC_PER_MIN;
-
-       time_t lastTime = [&]()->time_t {
-               if (runner->getLastTime() != 0)
-                       return runner->getLastTime();
-
-               time_t now = time(NULL);
-               time_t anchor = static_cast<PeriodicJobInfo*>(getJobInfo())->getAnchor();
-
-               anchor = anchor % interval;
-               return static_cast<time_t>((now - anchor) / interval) * interval + anchor;
-       }();
-
-       time_t nextTime = lastTime + interval;
-       unsigned int margin = static_cast<double>(interval) * CTX_PERIOD_MARGIN;
-
-       runner->setLastTime(nextTime);
-
-       _I("Set a timer at %ld with %us margin", static_cast<long>(nextTime), margin);
-       return SchedTimer::set(this, nextTime, margin);
-}
diff --git a/src/server/TimerStandbyState.h b/src/server/TimerStandbyState.h
deleted file mode 100644 (file)
index 1ddd056..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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_TIMER_STANDBY_STATE_H__
-#define __CONTEXT_JOB_SCHEDULER_TIMER_STANDBY_STATE_H__
-
-#include <WakeLock.h>
-#include "SchedTimer.h"
-#include "JobState.h"
-
-namespace ctx {
-
-       class TimerStandbyState : public JobState, public ISchedTimerListener {
-       public:
-               TimerStandbyState(JobRunner* runner);
-               ~TimerStandbyState();
-
-               bool execute();
-
-               void onSchedTimerExpired();
-
-               static unsigned int getCount();
-
-       private:
-               bool __setTimer();
-
-               static unsigned int __timerStandbyStateCnt;
-       };
-
-}
-
-#endif /* __CONTEXT_JOB_SCHEDULER_TIMER_STANDBY_STATE_H__ */
diff --git a/src/server/TriggerStandbyState.cpp b/src/server/TriggerStandbyState.cpp
deleted file mode 100644 (file)
index 5191998..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 <JobContext.h>
-#include "ContextManager.h"
-#include "ContextPublisher.h"
-#include "ReqVerificationState.h"
-#include "TriggerStandbyState.h"
-
-using namespace ctx;
-
-TriggerStandbyState::TriggerStandbyState(JobRunner* runner) :
-       JobState(runner)
-{
-       _ENTER;
-}
-
-TriggerStandbyState::~TriggerStandbyState()
-{
-       _EXIT;
-       __unsubscribe();
-}
-
-bool TriggerStandbyState::execute()
-{
-       return __subscribe();
-}
-
-void TriggerStandbyState::contextDataReady(ContextPublisher* pubs, void* userData)
-{
-       JobTrigger* trigger = static_cast<JobTrigger*>(userData);
-
-       if (*trigger <= pubs->getData()) {
-               __unsubscribe();
-               transit(new ReqVerificationState(this));
-       }
-}
-
-bool TriggerStandbyState::__subscribe()
-{
-       auto& triggers = static_cast<OnDemandJobInfo*>(getJobInfo())->getTriggers();
-
-       for (auto& trg : triggers) {
-               ContextPublisher* pubs = ContextManager::getPublisher(trg->getUri(), getUid());
-               IF_FAIL_RETURN(pubs, false);
-
-               pubs->addObserver(this, trg);
-               __publishers.push_back(pubs);
-       }
-
-       return true;
-}
-
-void TriggerStandbyState::__unsubscribe()
-{
-       for (auto& pubs : __publishers) {
-               pubs->removeObserver(this);
-       }
-
-       __publishers.clear();
-}
diff --git a/src/server/TriggerStandbyState.h b/src/server/TriggerStandbyState.h
deleted file mode 100644 (file)
index 9e5e34b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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_TRIGGER_STANDBY_STATE_H__
-#define __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__
-
-#include <vector>
-#include <WakeLock.h>
-#include "IContextObserver.h"
-#include "JobState.h"
-
-namespace ctx {
-
-       class ContextPublisher;
-
-       class TriggerStandbyState : public JobState, public IContextObserver {
-       public:
-               TriggerStandbyState(JobRunner* runner);
-               ~TriggerStandbyState();
-
-               bool execute();
-               void contextDataReady(ContextPublisher* pubs, void* userData);
-
-       private:
-               bool __subscribe();
-               void __unsubscribe();
-
-               std::vector<ContextPublisher*> __publishers;
-       };
-
-}
-
-#endif /* __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__ */
diff --git a/src/server/state/ActionState.cpp b/src/server/state/ActionState.cpp
new file mode 100644 (file)
index 0000000..91dd240
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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 <aul_svc.h>
+#include <notification.h>
+#include <notification_internal.h>
+#include <vconf.h>
+#include <Conf.h>
+#include <JobSchedulerTypesPrivate.h>
+#include <JobAction.h>
+#include "../IPC.h"
+#include "ActionState.h"
+#include "ClosingState.h"
+
+#define SYSTEM_UID     0
+
+using namespace ctx;
+
+ActionState::ActionState(JobState* prevState, bool timeout) :
+       JobState(prevState),
+       __timeout(timeout),
+       __stopped(false),
+       __gSrcId(0),
+       __client(NULL)
+{
+       _ENTER;
+}
+
+ActionState::~ActionState()
+{
+       _EXIT;
+
+       if (__gSrcId != 0)
+               g_source_remove(__gSrcId);
+}
+
+bool ActionState::execute()
+{
+       auto type = getJobInfo()->getAction()->getType();
+
+       if (type == JobAction::Type::DBUS_METHOD) {
+               __callDBusMethod();
+
+       } else if (type == JobAction::Type::APP_CONTROL) {
+               __sendAppControl();
+
+       } else if (type == JobAction::Type::NOTIFICATION) {
+               __postNotification();
+
+       } else {
+               return false;
+       }
+
+       __gSrcId = g_timeout_add(CTX_ACTION_STOP_MARGIN, __stop, this);
+       return true;
+}
+
+void ActionState::setClient(IClient* client)
+{
+       __client = client;
+       IF_FAIL_VOID(__client);
+
+       std::string jobInfo = getJobInfo()->serialize();
+
+       __client->publish(SIGNAL_START_JOB, g_variant_new("(sb)", jobInfo.c_str(), __timeout));
+
+       if (__stopped)
+               __client->publish(SIGNAL_STOP_JOB, g_variant_new("(s)", jobInfo.c_str()));
+}
+
+void ActionState::jobFinished()
+{
+       transit(new ClosingState(this));
+}
+
+void ActionState::__callDBusMethod()
+{
+       JobDBusCall* action = static_cast<JobDBusCall*>(getJobInfo()->getAction());
+       bool success = false;
+
+       _D("Call %s.%s", action->getInterface().c_str(), action->getMethodName().c_str());
+       success = IPC::dbusCall(action->getBusName(), action->getObjectPath(),
+                       action->getInterface(), action->getMethodName(), action->getParameters());
+
+       IF_FAIL_VOID_TAG(success, _E, "DBus call failed");
+}
+
+static void __aul_svc_result_cb(bundle* b, int requestCode, aul_svc_result_val result, void* data)
+{
+       _D("App-control sent: %d", result);
+}
+
+void ActionState::__sendAppControl()
+{
+       IF_FAIL_VOID_TAG(getUid() != SYSTEM_UID, _W, "Not a user session");
+
+       _D("Send app-control to %u", static_cast<unsigned>(getUid()));
+
+       bundle* bn = static_cast<JobAppControl*>(getJobInfo()->getAction())->getAppControl();
+       IF_FAIL_VOID_TAG(bn, _E, "App-control not found");
+
+       int pid = aul_svc_run_service_for_uid(bn, 0, __aul_svc_result_cb, NULL, getUid());
+       IF_FAIL_VOID_TAG(pid >= 0, _E, "Sending app-control failed");
+}
+
+static notification_h __create_notification(const std::string& title,
+               const std::string& content, const std::string& iconPath, bundle* appCtrlBundle)
+{
+       notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
+
+       if (!title.empty()) {
+               notification_set_text(notification,
+                               NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+       }
+
+       if (!content.empty()) {
+               notification_set_text(notification,
+                               NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+       }
+
+       if (!iconPath.empty()) {
+               notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, iconPath.c_str());
+       }
+
+       if (appCtrlBundle) {
+               notification_set_execute_option(notification,
+                               NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, appCtrlBundle);
+       } else {
+               notification_set_property(notification, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
+       }
+
+       int sound = 0;
+       vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound);
+       if (sound) {
+               notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
+       }
+
+       int vibration = 0;
+       vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration);
+       if (vibration) {
+               notification_set_vibration(notification,
+                               NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
+       }
+
+       return notification;
+}
+
+void ActionState::__postNotification()
+{
+       IF_FAIL_VOID_TAG(getUid() != SYSTEM_UID, _W, "Not a user session");
+
+       JobNotification* action = static_cast<JobNotification*>(getJobInfo()->getAction());
+
+       notification_h notification = __create_notification(action->getTitle(),
+                       action->getContent(), action->getIconPath(), action->getAppControl());
+       IF_FAIL_VOID_TAG(notification, _E, "Notification construction failed");
+
+       int error = notification_post_for_uid(notification, getUid());
+       notification_free(notification);
+
+       IF_FAIL_VOID_TAG(error == NOTIFICATION_ERROR_NONE, _E, "Posting notification failed");
+}
+
+void ActionState::__stop()
+{
+       __stopped = true;
+
+       if (__client) {
+               std::string jobInfo = getJobInfo()->serialize();
+               __client->publish(SIGNAL_STOP_JOB, g_variant_new("(s)", jobInfo.c_str()));
+       }
+
+       __gSrcId = g_timeout_add(CTX_ACTION_EXIT_MARGIN, __exit, this);
+}
+
+void ActionState::__exit()
+{
+       __gSrcId = 0;
+       transit(new ClosingState(this));
+}
+
+gboolean ActionState::__stop(gpointer data)
+{
+       static_cast<ActionState*>(data)->__stop();
+       return G_SOURCE_REMOVE;
+}
+
+gboolean ActionState::__exit(gpointer data)
+{
+       static_cast<ActionState*>(data)->__exit();
+       return G_SOURCE_REMOVE;
+}
diff --git a/src/server/state/ActionState.h b/src/server/state/ActionState.h
new file mode 100644 (file)
index 0000000..b8cda88
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_ACTION_STATE_H__
+#define __CONTEXT_JOB_SCHEDULER_ACTION_STATE_H__
+
+#include <WakeLock.h>
+#include "../JobState.h"
+
+namespace ctx {
+
+       class ActionState : public JobState {
+       public:
+               ActionState(JobState* prevState, bool timeout);
+               ~ActionState();
+
+               bool execute();
+
+               void setClient(IClient* client);
+               void jobFinished();
+
+       private:
+               void __callDBusMethod();
+               void __sendAppControl();
+               void __postNotification();
+
+               void __stop();
+               void __exit();
+
+               static gboolean __stop(gpointer data);
+               static gboolean __exit(gpointer data);
+
+               bool __timeout;
+               bool __stopped;
+               guint __gSrcId;
+               IClient* __client;
+
+               WakeLock __wakeLock;
+       };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_ACTION_STATE_H__ */
diff --git a/src/server/state/ClosingState.cpp b/src/server/state/ClosingState.cpp
new file mode 100644 (file)
index 0000000..1df6094
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 "../JobRunner.h"
+#include "ClosingState.h"
+
+using namespace ctx;
+
+ClosingState::ClosingState(JobState* prevState) :
+       JobState(prevState)
+{
+       _ENTER;
+}
+
+ClosingState::~ClosingState()
+{
+       _EXIT;
+}
+
+bool ClosingState::execute()
+{
+       g_idle_add(__exit, this);
+       return true;
+}
+
+void ClosingState::__exit()
+{
+       if (getJobInfo()->isOneTime()) {
+               getJobRunner()->terminate();
+       } else {
+               getJobRunner()->restart();
+       }
+}
+
+gboolean ClosingState::__exit(gpointer data)
+{
+       static_cast<ClosingState*>(data)->__exit();
+       return G_SOURCE_REMOVE;
+}
diff --git a/src/server/state/ClosingState.h b/src/server/state/ClosingState.h
new file mode 100644 (file)
index 0000000..57bf6ea
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_CLOSING_STATE_H__
+#define __CONTEXT_JOB_SCHEDULER_CLOSING_STATE_H__
+
+#include <WakeLock.h>
+#include "../JobState.h"
+
+namespace ctx {
+
+       class ClosingState : public JobState {
+       public:
+               ClosingState(JobState* prevState);
+               ~ClosingState();
+
+               bool execute();
+
+       private:
+               void __exit();
+
+               static gboolean __exit(gpointer data);
+
+               WakeLock __wakeLock;
+       };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_CLOSING_STATE_H__ */
diff --git a/src/server/state/ReqVerificationState.cpp b/src/server/state/ReqVerificationState.cpp
new file mode 100644 (file)
index 0000000..a739015
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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 <algorithm>
+#include <JobContext.h>
+#include "../ContextManager.h"
+#include "../ContextPublisher.h"
+#include "../JobRunner.h"
+#include "ActionState.h"
+#include "ReqVerificationState.h"
+
+#define MIN_TIMEOUT    20u
+
+using namespace ctx;
+
+ReqVerificationState::ReqVerificationState(JobState* prevState) :
+       JobState(prevState),
+       __startSrcId(0),
+       __timeoutSrcId(0)
+{
+       _ENTER;
+}
+
+ReqVerificationState::~ReqVerificationState()
+{
+       _EXIT;
+       __unsubscribe();
+}
+
+bool ReqVerificationState::execute()
+{
+       if (!__subscribe())
+               return false;
+
+       return true;
+}
+
+void ReqVerificationState::contextDataReady(ContextPublisher* pubs, void* userData)
+{
+       for (auto it = __reqInfos.begin(); it != __reqInfos.end(); ++it) {
+               if ((*it).pubs != pubs)
+                       continue;
+
+               if (!(*((*it).req) <= pubs->getData()))
+                       continue;
+
+               pubs->removeObserver(this);
+               __reqInfos.erase(it);
+       }
+
+       if (__inspectAll())
+               transit(new ActionState(this, false));
+}
+
+bool ReqVerificationState::__subscribe()
+{
+       auto& reqs = getJobInfo()->getRequirements();
+
+       for (auto& req : reqs) {
+               ContextPublisher* pubs = ContextManager::getPublisher(req->getUri(), getUid());
+               IF_FAIL_RETURN(pubs, false);
+
+               pubs->addObserver(this, req);
+               __reqInfos.emplace_back(req, pubs);
+       }
+
+       unsigned int timeout = std::max(getJobInfo()->getRequirementTimeout(), MIN_TIMEOUT);
+
+       __startSrcId = g_idle_add(__onStart, this);
+       __timeoutSrcId = g_timeout_add(timeout, __onTimeout, this);
+
+       return true;
+}
+
+void ReqVerificationState::__unsubscribe()
+{
+       if (__startSrcId != 0) {
+               g_source_remove(__startSrcId);
+               __startSrcId = 0;
+       }
+
+       if (__timeoutSrcId != 0) {
+               g_source_remove(__timeoutSrcId);
+               __timeoutSrcId = 0;
+       }
+
+       for (auto& info : __reqInfos) {
+               info.pubs->removeObserver(this);
+       }
+
+       __reqInfos.clear();
+}
+
+void ReqVerificationState::__readLatest()
+{
+       __reqInfos.remove_if(
+                       [this](const ReqInfo& info)->bool {
+                               if (!info.pubs->isReady())
+                                       return false;
+                               if (!(*(info.req) <= info.pubs->getData()))
+                                       return false;
+                               info.pubs->removeObserver(this);
+                               return true;
+                       });
+}
+
+bool ReqVerificationState::__inspectAll()
+{
+       if (getJobInfo()->isDisjunction()) {
+               bool satisfied = __inspectDisjunction();
+               if (satisfied)
+                       __unsubscribe();
+               return satisfied;
+       }
+
+       return __reqInfos.empty();
+}
+
+bool ReqVerificationState::__inspectMandatory()
+{
+       if (getJobInfo()->isDisjunction())
+               return __inspectDisjunction();
+
+       for (auto& info : __reqInfos) {
+               if (!info.req->isOptional())
+                       return false;
+       }
+
+       return true;
+}
+
+bool ReqVerificationState::__inspectDisjunction()
+{
+       unsigned int all = getJobInfo()->getRequirements().size();
+       unsigned int remaining = __reqInfos.size();
+       return remaining < all;
+}
+
+void ReqVerificationState::__onStart()
+{
+       __startSrcId = 0;
+
+       __readLatest();
+
+       if (__inspectAll())
+               transit(new ActionState(this, false));
+}
+
+void ReqVerificationState::__onTimeout()
+{
+       __timeoutSrcId = 0;
+
+       if (__inspectMandatory()) {
+               __unsubscribe();
+               transit(new ActionState(this, true));
+               return;
+       }
+
+       _I("Not all mandatory requirements are satisfied");
+       __unsubscribe();
+       getJobRunner()->restart();
+}
+
+gboolean ReqVerificationState::__onStart(gpointer data)
+{
+       static_cast<ReqVerificationState*>(data)->__onStart();
+       return G_SOURCE_REMOVE;
+}
+
+gboolean ReqVerificationState::__onTimeout(gpointer data)
+{
+       static_cast<ReqVerificationState*>(data)->__onTimeout();
+       return G_SOURCE_REMOVE;
+}
+
+ReqVerificationState::ReqInfo::ReqInfo(JobRequirement* r, ContextPublisher* p) :
+       req(r),
+       pubs(p)
+{
+}
diff --git a/src/server/state/ReqVerificationState.h b/src/server/state/ReqVerificationState.h
new file mode 100644 (file)
index 0000000..51ff77f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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_REQ_VERIFICATION_STATE_H__
+#define __CONTEXT_JOB_SCHEDULER_REQ_VERIFICATION_STATE_H__
+
+#include <list>
+#include <WakeLock.h>
+#include "../IContextObserver.h"
+#include "../JobState.h"
+
+namespace ctx {
+
+       class ReqVerificationState : public JobState, public IContextObserver {
+       public:
+               ReqVerificationState(JobState* prevState);
+               ~ReqVerificationState();
+
+               bool execute();
+               void contextDataReady(ContextPublisher* pubs, void* userData);
+
+       private:
+               bool __subscribe();
+               void __unsubscribe();
+               void __readLatest();
+
+               bool __inspectAll();
+               bool __inspectMandatory();
+
+               void __onStart();
+               void __onTimeout();
+
+               static gboolean __onStart(gpointer data);
+               static gboolean __onTimeout(gpointer data);
+
+               /* Legacy support */
+               bool __inspectDisjunction();
+
+               struct ReqInfo {
+                       JobRequirement* req;
+                       ContextPublisher* pubs;
+                       ReqInfo(JobRequirement* r, ContextPublisher* p);
+               };
+
+               std::list<ReqInfo> __reqInfos;
+
+               guint __startSrcId;
+               guint __timeoutSrcId;
+
+               WakeLock __wakeLock;
+       };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_REQ_VERIFICATION_STATE_H__ */
diff --git a/src/server/state/TimerStandbyState.cpp b/src/server/state/TimerStandbyState.cpp
new file mode 100644 (file)
index 0000000..c8b1852
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 <Conf.h>
+#include "../PeriodicJobRunner.h"
+#include "ReqVerificationState.h"
+#include "TimerStandbyState.h"
+
+#define SEC_PER_MIN    60
+
+using namespace ctx;
+
+unsigned int TimerStandbyState::__timerStandbyStateCnt = 0;
+
+TimerStandbyState::TimerStandbyState(JobRunner* runner) :
+       JobState(runner)
+{
+       _ENTER;
+       ++__timerStandbyStateCnt;
+}
+
+TimerStandbyState::~TimerStandbyState()
+{
+       _EXIT;
+       --__timerStandbyStateCnt;
+       SchedTimer::remove(this);
+}
+
+bool TimerStandbyState::execute()
+{
+       return __setTimer();
+}
+
+void TimerStandbyState::onSchedTimerExpired()
+{
+       transit(new ReqVerificationState(this));
+}
+
+unsigned int TimerStandbyState::getCount()
+{
+       return __timerStandbyStateCnt;
+}
+
+bool TimerStandbyState::__setTimer()
+{
+       PeriodicJobRunner* runner = static_cast<PeriodicJobRunner*>(getJobRunner());
+       time_t interval = static_cast<time_t>(static_cast<PeriodicJobInfo*>(getJobInfo())->getInterval()) * SEC_PER_MIN;
+
+       time_t lastTime = [&]()->time_t {
+               if (runner->getLastTime() != 0)
+                       return runner->getLastTime();
+
+               time_t now = time(NULL);
+               time_t anchor = static_cast<PeriodicJobInfo*>(getJobInfo())->getAnchor();
+
+               anchor = anchor % interval;
+               return static_cast<time_t>((now - anchor) / interval) * interval + anchor;
+       }();
+
+       time_t nextTime = lastTime + interval;
+       unsigned int margin = static_cast<double>(interval) * CTX_PERIOD_MARGIN;
+
+       runner->setLastTime(nextTime);
+
+       _I("Set a timer at %ld with %us margin", static_cast<long>(nextTime), margin);
+       return SchedTimer::set(this, nextTime, margin);
+}
diff --git a/src/server/state/TimerStandbyState.h b/src/server/state/TimerStandbyState.h
new file mode 100644 (file)
index 0000000..6043a1a
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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_TIMER_STANDBY_STATE_H__
+#define __CONTEXT_JOB_SCHEDULER_TIMER_STANDBY_STATE_H__
+
+#include <WakeLock.h>
+#include "../SchedTimer.h"
+#include "../JobState.h"
+
+namespace ctx {
+
+       class TimerStandbyState : public JobState, public ISchedTimerListener {
+       public:
+               TimerStandbyState(JobRunner* runner);
+               ~TimerStandbyState();
+
+               bool execute();
+
+               void onSchedTimerExpired();
+
+               static unsigned int getCount();
+
+       private:
+               bool __setTimer();
+
+               static unsigned int __timerStandbyStateCnt;
+       };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_TIMER_STANDBY_STATE_H__ */
diff --git a/src/server/state/TriggerStandbyState.cpp b/src/server/state/TriggerStandbyState.cpp
new file mode 100644 (file)
index 0000000..2083ba9
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 <JobContext.h>
+#include "../ContextManager.h"
+#include "../ContextPublisher.h"
+#include "ReqVerificationState.h"
+#include "TriggerStandbyState.h"
+
+using namespace ctx;
+
+TriggerStandbyState::TriggerStandbyState(JobRunner* runner) :
+       JobState(runner)
+{
+       _ENTER;
+}
+
+TriggerStandbyState::~TriggerStandbyState()
+{
+       _EXIT;
+       __unsubscribe();
+}
+
+bool TriggerStandbyState::execute()
+{
+       return __subscribe();
+}
+
+void TriggerStandbyState::contextDataReady(ContextPublisher* pubs, void* userData)
+{
+       JobTrigger* trigger = static_cast<JobTrigger*>(userData);
+
+       if (*trigger <= pubs->getData()) {
+               __unsubscribe();
+               transit(new ReqVerificationState(this));
+       }
+}
+
+bool TriggerStandbyState::__subscribe()
+{
+       auto& triggers = static_cast<OnDemandJobInfo*>(getJobInfo())->getTriggers();
+
+       for (auto& trg : triggers) {
+               ContextPublisher* pubs = ContextManager::getPublisher(trg->getUri(), getUid());
+               IF_FAIL_RETURN(pubs, false);
+
+               pubs->addObserver(this, trg);
+               __publishers.push_back(pubs);
+       }
+
+       return true;
+}
+
+void TriggerStandbyState::__unsubscribe()
+{
+       for (auto& pubs : __publishers) {
+               pubs->removeObserver(this);
+       }
+
+       __publishers.clear();
+}
diff --git a/src/server/state/TriggerStandbyState.h b/src/server/state/TriggerStandbyState.h
new file mode 100644 (file)
index 0000000..85f6906
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_TRIGGER_STANDBY_STATE_H__
+#define __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__
+
+#include <vector>
+#include <WakeLock.h>
+#include "../IContextObserver.h"
+#include "../JobState.h"
+
+namespace ctx {
+
+       class ContextPublisher;
+
+       class TriggerStandbyState : public JobState, public IContextObserver {
+       public:
+               TriggerStandbyState(JobRunner* runner);
+               ~TriggerStandbyState();
+
+               bool execute();
+               void contextDataReady(ContextPublisher* pubs, void* userData);
+
+       private:
+               bool __subscribe();
+               void __unsubscribe();
+
+               std::vector<ContextPublisher*> __publishers;
+       };
+
+}
+
+#endif /* __CONTEXT_JOB_SCHEDULER_TRIGGER_STANDBY_STATE_H__ */