Apply consistent log messages.
[platform/core/system/system-popup.git] / src / usb / usbotg-mobile.c
1 /*
2  *  system-popup
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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 "popup-common.h"
21 #include <appsvc.h>
22 #include <app_control.h>
23
24
25 #define MYFILES_APPNAME "org.tizen.myfile"
26 #define GALLERY_APPNAME "org.tizen.gallery"
27
28 #define USB_MOUNT_ROOT_PATH     "/opt/storage"
29 #define USB_MOUNT_PATH          "_DEVICE_PATH_"
30
31 #define BUF_MAX 128
32
33 #define DEVICED_PATH                    "/Org/Tizen/System/DeviceD"
34 #define DEVICED_IFACE                   "org.tizen.system.deviced"
35 #define DEVICED_PATH_USBHOST    DEVICED_PATH"/Usbhost"
36 #define DEVICED_IFACE_USBHOST   DEVICED_IFACE".Usbhost"
37 #define SIGNAL_NAME_UNMOUNT             "unmount_storage"
38
39 static char added_path[BUF_MAX];
40 static char removed_path[BUF_MAX];
41
42 enum ext_app {
43         EXT_MYFILES,
44         EXT_GALLERY,
45 };
46
47 static const struct popup_ops storage_mounted_ops;
48 static const struct popup_ops unmount_storage_ops;
49 static const struct popup_ops camera_added_ops;
50 static const struct popup_ops storage_mount_failed_ops;
51 static const struct popup_ops storage_removed_unsafe_ops;
52
53 static void remove_otg_popup(const struct popup_ops *ops, char *path)
54 {
55         int len;
56         char *popup_path = NULL;
57
58         if (ops == &storage_mounted_ops)
59                 popup_path = added_path;
60         else if (ops == &unmount_storage_ops)
61                 popup_path = removed_path;
62         else
63                 popup_path = NULL;
64
65         if (popup_path) {
66                 if (!path)
67                         return;
68                 len = strlen(popup_path);
69                 if (len != strlen(path))
70                         return;
71                 if (strncmp(popup_path, path, len))
72                         return;
73         }
74
75         unload_simple_popup(ops);
76 }
77
78 static void set_myfiles_param(bundle *b)
79 {
80         if (!b)
81                 return;
82
83         if (strlen(added_path) > 0)
84                 appsvc_add_data(b, "path", added_path);
85         else
86                 appsvc_add_data(b, "path", USB_MOUNT_ROOT_PATH);
87         appsvc_set_pkgname(b, MYFILES_APPNAME);
88 }
89
90 static void set_gallery_param(bundle *b)
91 {
92         if (!b)
93                 return;
94         appsvc_add_data(b, "album-id", "GALLERY_ALBUM_PTP_ID");
95         appsvc_set_pkgname(b, GALLERY_APPNAME);
96 }
97
98 static struct ext_app_type {
99         int type;
100         void (*set_param)(bundle *b);
101 } app_type[] = {
102         { EXT_MYFILES   , set_myfiles_param     },
103         { EXT_GALLERY   , set_gallery_param     },
104 };
105
106 static void launch_app(int type)
107 {
108         app_control_h app_control;
109
110         int ret = -1, i, type_len;
111
112         type_len = ARRAY_SIZE(app_type);
113         for (i = 0 ; i < ARRAY_SIZE(app_type) ; i++) {
114                 if (type == app_type[i].type)
115                         break;
116         }
117         if (i == type_len) {
118                 _E("Invalid type(%d).", type);
119                 return;
120         }
121
122         ret = app_control_create(&app_control);
123         if (ret != APP_CONTROL_ERROR_NONE)
124                 return;
125
126         if (type == 0)
127                 ret = app_control_set_app_id(app_control, MYFILES_APPNAME);
128         else if (type == 1)
129                 ret = app_control_set_app_id(app_control, GALLERY_APPNAME);
130         else {
131                 _E("No matched type(%d).", type);
132                 goto out;
133         }
134
135         if (ret != APP_CONTROL_ERROR_NONE) {
136                 _E("Failed to set app id.");
137                 goto out;
138         }
139
140         ret = app_control_send_launch_request(app_control, NULL, NULL);
141         if (ret != APP_CONTROL_ERROR_NONE)
142                 _E("Fail to send launch request.");
143
144 out:
145         if (app_control) {
146                 (void)app_control_destroy(app_control);
147                 app_control = NULL;
148         }
149 }
150
151 static void storage_browse(const struct popup_ops *ops)
152 {
153         unload_simple_popup(ops);
154         launch_app(EXT_MYFILES);
155         terminate_if_no_popup();
156 }
157
158 static void camera_browse(const struct popup_ops *ops)
159 {
160         unload_simple_popup(ops);
161         launch_app(EXT_GALLERY);
162         terminate_if_no_popup();
163 }
164
165 static void storage_unmount(const struct popup_ops *ops)
166 {
167         char *param[1];
168         int ret;
169
170         unload_simple_popup(ops);
171
172         param[0] = removed_path;
173
174         ret = broadcast_dbus_signal(DEVICED_PATH_USBHOST,
175                         DEVICED_IFACE_USBHOST,
176                         SIGNAL_NAME_UNMOUNT, "s", param);
177         if (ret < 0)
178                 _E("Failed to broadcast_dbus_signal().");
179
180         memset(removed_path, 0, sizeof(removed_path));
181
182         terminate_if_no_popup();
183 }
184
185 static int storage_mounted_launch(bundle *b, const struct popup_ops *ops)
186 {
187         char *path;
188
189         if (!ops)
190                 return -1;
191
192         path = (char *)bundle_get_val(b, USB_MOUNT_PATH);
193         if (!path) {
194                 _E("Failed to get mount path.");
195                 return -2;
196         }
197
198         _I("USB storage mount path(%s).", path);
199         snprintf(added_path, sizeof(added_path), "%s", path);
200         return 0;
201 }
202
203 static int unmount_storage_launch(bundle *b, const struct popup_ops *ops)
204 {
205         char *path;
206
207         if (!ops)
208                 return -1;
209
210         path = (char *)bundle_get_val(b, USB_MOUNT_PATH);
211         if (!path) {
212                 _E("Failed to get mount path.");
213                 return -2;
214         }
215
216         remove_otg_popup(&storage_mounted_ops, path);
217
218         snprintf(removed_path, sizeof(removed_path), "%s", path);
219         return 0;
220 }
221
222 static int storage_unmounted(bundle *b, const struct popup_ops *ops)
223 {
224         char *path;
225
226         if (!b || !ops)
227                 return -EINVAL;
228
229         path = (char *)bundle_get_val(b, USB_MOUNT_PATH);
230         if (!path) {
231                 _E("Failed to get mount path.");
232                 return -ENOENT;
233         }
234
235         remove_otg_popup(&storage_mounted_ops, path);
236         remove_otg_popup(&unmount_storage_ops, path);
237
238         terminate_if_no_popup();
239         return 0;
240 }
241
242 static int camera_removed(bundle *b, const struct popup_ops *ops)
243 {
244         remove_otg_popup(&camera_added_ops, NULL);
245         terminate_if_no_popup();
246         return 0;
247 }
248
249 static const struct popup_ops storage_mounted_ops = {
250         .name                   = "usbotg_storage_mounted",
251         .pattern                = FEEDBACK_PATTERN_LOWBATT,
252         .show                   = load_simple_popup,
253         .title                  = "IDS_ST_BODY_USB_STORAGE_ABB",
254         .content                = "IDS_USB_BODY_BROWSE_STORAGE_CONNECTED_VIA_USB_Q",
255         .left_text              = "IDS_COM_SK_CANCEL",
256         .right_text             = "IDS_BT_SK_BROWSE",
257         .right                  = storage_browse,
258         .pre                    = storage_mounted_launch,
259 };
260
261 static const struct popup_ops storage_unmounted_ops = {
262         .name                   = "usbotg_storage_unmounted",
263         .show                   = storage_unmounted,
264 };
265
266 static const struct popup_ops unmount_storage_ops = {
267         .name                   = "usbotg_unmount_storage",
268         .show                   = load_simple_popup,
269         .title                  = "IDS_ST_BODY_USB_STORAGE_ABB",
270         .content                = "IDS_COM_POP_UNMOUNT_USB_MASS_STORAGE_BEFORE_REMOVING_TO_AVOID_DATA_LOSS",
271         .left_text              = "IDS_COM_SK_CANCEL",
272         .right_text             = "IDS_USB_BUTTON_UNMOUNT",
273         .right                  = storage_unmount,
274         .pre                    = unmount_storage_launch,
275 };
276
277 static const struct popup_ops camera_added_ops = {
278         .name                   = "usbotg_camera_added",
279         .pattern                = FEEDBACK_PATTERN_LOWBATT,
280         .show                   = load_simple_popup,
281         .title                  = "IDS_CAM_HEADER_CAMERA_M_APPLICATION",
282         .content                = "IDS_USB_BODY_BROWSE_CAMERA_CONNECTED_VIA_USB_Q",
283         .left_text              = "IDS_COM_SK_CANCEL",
284         .right_text             = "IDS_BT_SK_BROWSE",
285         .right                  = camera_browse,
286 };
287
288 static const struct popup_ops camera_removed_ops = {
289         .name                   = "usbotg_camera_removed",
290         .show                   = camera_removed,
291 };
292
293 static const struct popup_ops storage_mount_failed_ops = {
294         .name                   = "usbotg_storage_mount_failed",
295         .pattern                = FEEDBACK_PATTERN_LOWBATT,
296         .show                   = load_simple_popup,
297         .title                  = "IDS_COM_HEADER_ATTENTION",
298         .content                = "IDS_COM_BODY_USB_STORAGE_BLANK_OR_HAS_UNSUPPORTED_FILE_SYSTEM",
299         .left_text              = "IDS_COM_SK_OK",
300 };
301
302 static const struct popup_ops storage_removed_unsafe_ops = {
303         .name                   = "usbotg_storage_removed_unsafe",
304         .show                   = load_simple_popup,
305         .title                  = "IDS_COM_HEADER_ATTENTION",
306         .content                = "IDS_COM_POP_USB_MASS_STORAGE_UNEXPECTEDLY_REMOVED",
307         .left_text              = "IDS_COM_SK_OK",
308 };
309
310
311 /* Constructor to register mount_failed button */
312 static __attribute__ ((constructor)) void usbotg_register_popup(void)
313 {
314         register_popup(&storage_mounted_ops);
315         register_popup(&storage_unmounted_ops);
316         register_popup(&unmount_storage_ops);
317         register_popup(&camera_added_ops);
318         register_popup(&camera_removed_ops);
319         register_popup(&storage_mount_failed_ops);
320         register_popup(&storage_removed_unsafe_ops);
321 }