27d852c59b4ce30c0b32357faea5f9a5c8ee667e
[platform/core/appfw/aul-1.git] / src / aul_watchdog.cc
1 /*
2  * Copyright (c) 2018 - 2022 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "include/aul_watchdog.h"
18
19 #include <glib.h>
20
21 #include "app_request.h"
22 #include "aul_api.h"
23 #include "aul_util.h"
24 #include "include/aul.h"
25 #include "include/aul_error.h"
26 #include "aul/common/exception.hh"
27
28 using namespace aul;
29
30 namespace {
31 using namespace aul::internal;
32
33 class WatchdogContext {
34  public:
35   WatchdogContext() = default;
36
37   ~WatchdogContext() {
38     Stop();
39
40     if (enabled_) {
41       try {
42         Disable();
43       } catch (const Exception& e) {
44         _E("Exception occurs. error(%d)", e.GetErrorCode());
45       }
46     }
47   }
48
49   void Enable() {
50     if (enabled_) {
51       _W("Already enabled");
52       return;
53     }
54
55     int ret = AppRequest(WATCHDOG_ENABLE, getuid())
56         .SendCmdOnly(AUL_SOCK_NOREPLY);
57     if (ret < 0)
58       THROW(aul_error_convert(ret));
59
60     enabled_ = true;
61     _D("Enabled");
62   }
63
64   void Disable() {
65     if (!enabled_)
66       THROW(AUL_R_ERROR);
67
68     int ret = AppRequest(WATCHDOG_DISABLE, getuid())
69         .SendCmdOnly(AUL_SOCK_NOREPLY);
70     if (ret < 0)
71       THROW(aul_error_convert(ret));
72
73     enabled_ = false;
74     _D("Disabled");
75   }
76
77   void Kick() {
78     if (!enabled_)
79       THROW(AUL_R_ERROR);
80
81     int ret = AppRequest(WATCHDOG_KICK, getuid())
82         .SendCmdOnly(AUL_SOCK_NOREPLY);
83     if (ret < 0)
84       THROW(aul_error_convert(ret));
85
86     Stop();
87     Start(interval_);
88     _D("Kicked");
89   }
90
91   void Start(unsigned int interval) {
92     _D("Interval: %u", interval);
93     if (interval == 0) {
94       _E("Invalid parameter");
95       return;
96     }
97
98     if (timer_ != 0) {
99       _E("Already started");
100       return;
101     }
102
103     enabled_ = true;
104     interval_ = interval;
105     timer_ = g_timeout_add(interval,
106         [](gpointer user_data) -> gboolean {
107           auto* handle = static_cast<WatchdogContext*>(user_data);
108           try {
109             handle->Ping();
110           } catch (const Exception& e) {
111             _E("Exception occurs. error(%d)", e.GetErrorCode());
112           }
113
114           return G_SOURCE_CONTINUE;
115         }, this);
116   }
117
118   void Stop() {
119     if (timer_ == 0)
120       return;
121
122     g_source_remove(timer_);
123     timer_ = 0;
124   }
125
126   bool IsEnabled() const {
127     return enabled_;
128   }
129
130  private:
131   void Ping() {
132     int ret = AppRequest(WATCHDOG_PING, getuid())
133         .SendCmdOnly(AUL_SOCK_NOREPLY);
134     if (ret < 0)
135       THROW(aul_error_convert(ret));
136
137     _D("Ping");
138   }
139
140  private:
141   bool enabled_ = false;
142   unsigned int interval_ = 0;
143   guint timer_ = 0;
144 };
145
146 WatchdogContext context;
147
148 }  // namespace
149
150 extern "C" API int aul_watchdog_enable(void) {
151   try {
152     context.Enable();
153   } catch (const Exception& e) {
154     _E("Exception occurs. error(%d)", e.GetErrorCode());
155     return e.GetErrorCode();
156   }
157
158   return AUL_R_OK;
159 }
160
161 extern "C" API int aul_watchdog_disable(void) {
162   try {
163     context.Disable();
164   } catch (const Exception& e) {
165     if (context.IsEnabled())
166       _E("Exception occurs. error(%d)", e.GetErrorCode());
167
168     return e.GetErrorCode();
169   }
170
171   return AUL_R_OK;
172 }
173
174 extern "C" API int aul_watchdog_kick(void) {
175   try {
176     context.Kick();
177   } catch (const Exception& e) {
178     _E("Exception occurs. error(%d)", e.GetErrorCode());
179     return e.GetErrorCode();
180   }
181
182   return AUL_R_OK;
183 }
184
185 extern "C" void aul_watchdog_start(unsigned int interval) {
186   context.Start(interval);
187 }
188
189 extern "C" void aul_watchdog_stop(void) {
190   context.Stop();
191 }