+++ /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 <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;
-}
+++ /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_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__ */
+++ /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 "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;
-}
+++ /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_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__ */
*/
#include "JobManager.h"
-#include "TriggerStandbyState.h"
+#include "state/TriggerStandbyState.h"
#include "OnDemandJobRunner.h"
using namespace ctx;
#include "SchedTimer.h"
#include "JobManager.h"
-#include "TimerStandbyState.h"
+#include "state/TimerStandbyState.h"
#include "PeriodicJobRunner.h"
using namespace ctx;
+++ /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 <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)
-{
-}
+++ /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_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__ */
+++ /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 <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);
-}
+++ /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_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__ */
+++ /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 <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();
-}
+++ /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_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__ */
--- /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 <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;
+}
--- /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_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__ */
--- /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 "../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;
+}
--- /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_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__ */
--- /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 <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)
+{
+}
--- /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_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__ */
--- /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 <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);
+}
--- /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_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__ */
--- /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 <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();
+}
--- /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_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__ */