Merge "binding: media: free sqlite3 prepared query statement" into dab
[apps/mediaplayer.git] / binding / mediaplayer-api.c
1 /* 
2  *   Copyright 2017 Konsulko Group
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 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <json-c/json.h>
23 #include <afb/afb-binding.h>
24
25 #include "mediaplayer-manager.h"
26
27 const struct afb_binding_interface *afbitf;
28
29 static struct afb_event media_added_event;
30 static struct afb_event media_removed_event;
31
32 /*
33  * @brief Subscribe for an event
34  *
35  * @param struct afb_req : an afb request structure
36  *
37  */
38 static void subscribe(struct afb_req request)
39 {
40         const char *value = afb_req_value(request, "value");
41         if(value) {
42                 if(!strcasecmp(value, "media_added")) {
43                         afb_req_subscribe(request, media_added_event);
44                 } else if(!strcasecmp(value, "media_removed")) {
45                         afb_req_subscribe(request, media_removed_event);
46                 } else {
47                         afb_req_fail(request, "failed", "Invalid event");
48                         return;
49                 }
50         }
51         afb_req_success(request, NULL, NULL);
52 }
53
54 /*
55  * @brief Unsubscribe for an event
56  *
57  * @param struct afb_req : an afb request structure
58  *
59  */
60 static void unsubscribe(struct afb_req request)
61 {
62         const char *value = afb_req_value(request, "value");
63         if(value) {
64                 if(!strcasecmp(value, "media_added")) {
65                         afb_req_unsubscribe(request, media_added_event);
66                 } else if(!strcasecmp(value, "media_removed")) {
67                         afb_req_unsubscribe(request, media_removed_event);
68                 } else {
69                         afb_req_fail(request, "failed", "Invalid event");
70                         return;
71                 }
72         }
73         afb_req_success(request, NULL, NULL);
74 }
75
76 static json_object *new_json_object_from_device(GList *list)
77 {
78     json_object *jarray = json_object_new_array();
79     json_object *jresp = json_object_new_object();
80     json_object *jstring = NULL;
81     GList *l;
82
83     for (l = list; l; l = l->next)
84     {
85         jstring = json_object_new_string(l->data);
86         json_object_array_add(jarray, jstring);
87     }
88
89     if (jstring == NULL) {
90         json_object_put(jarray);
91         json_object_put(jresp);
92         return NULL;
93     }
94
95     json_object_object_add(jresp, "Media", jarray);
96
97     // TODO: Add media path
98     jstring = json_object_new_string("");
99     json_object_object_add(jresp, "Path", jstring);
100
101     return jresp;
102 }
103
104 static void media_results_get (struct afb_req request)
105 {
106     GList *list;
107     json_object *jresp = NULL;
108
109     ListLock();
110     list = media_lightmediascanner_scan();
111     if (list == NULL) {
112         afb_req_fail(request, "failed", "media scan error");
113         ListUnlock();
114         return;
115     }
116
117     jresp = new_json_object_from_device(list);
118     g_list_free(list);
119     ListUnlock();
120
121     if (jresp == NULL) {
122         afb_req_fail(request, "failed", "media parsing error");
123         return;
124     }
125
126     afb_req_success(request, jresp, "Media Results Displayed");
127 }
128
129 static void media_broadcast_device_added (GList *list)
130 {
131     json_object *jresp = new_json_object_from_device(list);
132
133     if (jresp != NULL) {
134         afb_event_push(media_added_event, jresp);
135     }
136 }
137
138 static void media_broadcast_device_removed (const char *obj_path)
139 {
140     json_object *jresp = json_object_new_object();
141     json_object *jstring = json_object_new_string(obj_path);
142
143     json_object_object_add(jresp, "Path", jstring);
144
145     afb_event_push(media_removed_event, jresp);
146 }
147
148 static const struct afb_verb_desc_v1 binding_verbs[] = {
149     { "media_result",   AFB_SESSION_CHECK, media_results_get,   "Media scan result" },
150     { "subscribe",      AFB_SESSION_CHECK, subscribe,           "Subscribe for an event" },
151     { "unsubscribe",    AFB_SESSION_CHECK, unsubscribe,         "Unsubscribe for an event" },
152     { NULL }
153 };
154
155 static const struct afb_binding binding_description = {
156     .type = AFB_BINDING_VERSION_1,
157     .v1 = {
158         .prefix = "media-manager",
159         .info = "mediaplayer API",
160         .verbs = binding_verbs,
161     }
162 };
163
164 const struct afb_binding
165 *afbBindingV1Register(const struct afb_binding_interface *itf)
166 {
167     afbitf = itf;
168
169     Binding_RegisterCallback_t API_Callback;
170     API_Callback.binding_device_added = media_broadcast_device_added;
171     API_Callback.binding_device_removed = media_broadcast_device_removed;
172     BindingAPIRegister(&API_Callback);
173
174     MediaPlayerManagerInit();
175
176     return &binding_description;
177 }
178
179 int afbBindingV1ServiceInit(struct afb_service service)
180 {
181     media_added_event = afb_daemon_make_event(afbitf->daemon, "media_added");
182     media_removed_event = afb_daemon_make_event(afbitf->daemon, "media_removed");
183
184     return 0;
185 }