Initialize Tizen 2.3
[framework/system/deviced.git] / src / core / predefine.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <unistd.h>
21 #include <time.h>
22 #include <limits.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <vconf.h>
26
27 #include <sys/reboot.h>
28 #include <sys/time.h>
29 #include <mntent.h>
30 #include <sys/mount.h>
31 #include "dd-deviced.h"
32 #include "log.h"
33 #include "launch.h"
34 #include "queue.h"
35 #include "device-handler.h"
36 #include "device-node.h"
37 #include "predefine.h"
38 #include "proc/proc-handler.h"
39 #include "data.h"
40 #include "common.h"
41 #include "display/poll.h"
42 #include "display/setting.h"
43 #include "devices.h"
44 #include "battery/battery.h"
45 #include "edbus-handler.h"
46
47 #define VCONFKEY_SYSMAN_FACTORY_MODE                    "memory/sysman/factory_mode"
48
49 #define PREDEFINE_SO_DIR                PREFIX"/lib/ss_predefine/"
50 #define PREDEF_CALL                     "call"
51 #define PREDEF_FACTORY_MODE             "factorymode"
52
53 #define CALL_EXEC_PATH                  PREFIX"/bin/call"
54
55 #define LOWBAT_EXEC_PATH                PREFIX"/bin/lowbatt-popup"
56
57 #define HDMI_NOTI_EXEC_PATH             PREFIX"/bin/hdmi_connection_noti"
58
59
60 static int bFactoryMode = 0;
61
62 int predefine_get_pid(const char *execpath)
63 {
64         DIR *dp;
65         struct dirent *dentry;
66         int pid = -1, fd;
67         int ret;
68         char buf[PATH_MAX];
69         char buf2[PATH_MAX];
70
71         dp = opendir("/proc");
72         if (!dp) {
73                 _E("FAIL: open /proc");
74                 return -1;
75         }
76
77         while ((dentry = readdir(dp)) != NULL) {
78                 if (!isdigit(dentry->d_name[0]))
79                         continue;
80
81                 pid = atoi(dentry->d_name);
82
83                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
84                 fd = open(buf, O_RDONLY);
85                 if (fd < 0)
86                         continue;
87                 ret = read(fd, buf2, PATH_MAX);
88                 close(fd);
89
90                 if (ret < 0 || ret >=PATH_MAX)
91                         continue;
92
93                 buf2[ret] = '\0';
94
95                 if (!strcmp(buf2, execpath)) {
96                         closedir(dp);
97                         return pid;
98                 }
99         }
100
101         errno = ESRCH;
102         closedir(dp);
103         return -1;
104 }
105
106 #ifdef NOUSE
107 int call_predefine_action(int argc, char **argv)
108 {
109         char argstr[128];
110         int pid;
111
112         if (argc < 2)
113                 return -1;
114
115         snprintf(argstr, sizeof(argstr), "-t MT -n %s -i %s", argv[0], argv[1]);
116         pid = launch_if_noexist(CALL_EXEC_PATH, argstr);
117         if (pid < 0) {
118                 _E("call predefine action failed");
119                 return -1;
120         }
121         return pid;
122 }
123 #endif
124
125 void predefine_pm_change_state(unsigned int s_bits)
126 {
127         if (is_factory_mode() == 1)
128                 _D("skip LCD control for factory mode");
129         else
130                 pm_change_internal(getpid(), s_bits);
131 }
132
133 int is_factory_mode(void)
134 {
135         return bFactoryMode;
136 }
137 int set_factory_mode(int bOn)
138 {
139         int ret = -1;
140         if ( bOn==1 || bOn==0 ) {
141                 bFactoryMode = bOn;
142                 /* For USB-server to refer the value */
143                 ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, bOn);
144                 if(ret != 0) {
145                         _E("FAIL: vconf_set_int()");
146                 }
147         }
148         return bFactoryMode;
149 }
150
151 int factory_mode_action(int argc, char **argv)
152 {
153         int bOn;
154         if (argc != 1 || argv[0] == NULL) {
155                 _E("Factory Mode Set predefine action failed");
156                 return -1;
157         }
158         bOn = atoi(argv[0]);
159         bOn = set_factory_mode(bOn);
160         return 0;
161
162 }
163
164 static void action_entry_load_from_sodir()
165 {
166         DIR *dp;
167         struct dirent *dentry;
168         struct sysnoti *msg;
169         char *ext;
170         char tmp[128];
171
172         dp = opendir(PREDEFINE_SO_DIR);
173         if (!dp) {
174                 _E("fail open %s", PREDEFINE_SO_DIR);
175                 return;
176         }
177
178         msg = malloc(sizeof(struct sysnoti));
179         if (msg == NULL) {
180                 _E("Malloc failed");
181                 closedir(dp);
182                 return;
183         }
184
185         msg->pid = getpid();
186
187         while ((dentry = readdir(dp)) != NULL) {
188                 if ((ext = strstr(dentry->d_name, ".so")) == NULL)
189                         continue;
190
191                 snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
192                          dentry->d_name);
193                 msg->path = tmp;
194                 *ext = 0;
195                 msg->type = &(dentry->d_name[3]);
196                 register_msg(msg);
197         }
198         free(msg);
199
200         closedir(dp);
201 }
202
203 static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
204 {
205         DBusError err;
206         DBusMessageIter iter;
207         DBusMessage *reply;
208         pid_t pid;
209         int ret;
210         int argc;
211         char *type_str;
212         char *argv;
213
214         dbus_error_init(&err);
215
216         if (!dbus_message_get_args(msg, &err,
217                     DBUS_TYPE_STRING, &type_str,
218                     DBUS_TYPE_INT32, &argc,
219                     DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
220                 _E("there is no message");
221                 ret = -EINVAL;
222                 goto out;
223         }
224
225         if (argc < 0) {
226                 _E("message is invalid!");
227                 ret = -EINVAL;
228                 goto out;
229         }
230
231         pid = get_edbus_sender_pid(msg);
232         if (kill(pid, 0) == -1) {
233                 _E("%d process does not exist, dbus ignored!", pid);
234                 ret = -ESRCH;
235                 goto out;
236         }
237
238         ret = set_factory_mode(atoi(argv));
239 out:
240         reply = dbus_message_new_method_return(msg);
241         dbus_message_iter_init_append(reply, &iter);
242         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
243
244         return reply;
245 }
246
247 static const struct edbus_method edbus_methods[] = {
248         { PREDEF_FACTORY_MODE, "sis", "i", dbus_factory_mode },
249 };
250
251 static void predefine_init(void *data)
252 {
253         /* telephony initialize */
254         int ret;
255
256         ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
257         if (ret < 0)
258                 _E("fail to init edbus method(%d)", ret);
259 #ifdef NOUSE
260         register_action(PREDEF_CALL, call_predefine_action, NULL, NULL);
261 #endif
262         register_action(PREDEF_FACTORY_MODE, factory_mode_action, NULL, NULL);
263
264         action_entry_load_from_sodir();
265 }
266
267 static const struct device_ops predefine_device_ops = {
268         .priority = DEVICE_PRIORITY_NORMAL,
269         .name     = "predefine",
270         .init     = predefine_init,
271 };
272
273 DEVICE_OPS_REGISTER(&predefine_device_ops)