2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <app_debug.h>
22 #include <app_contents.h>
24 #include <tv_service_proxy.h>
25 #include <tv_service_proxy_epg.h>
28 #include <glib-object.h>
33 #define DEFAULT_SERVICE 1
36 * The Storage structure to used by tv related functions and events.
39 /**< The handle to use tv service live api. */
40 TvServiceLive live_svc;
41 /**< The handle to use tv service epg api. */
44 /**< Stores service id if tune to locked channel was succeeded. */
45 int viewing_locked_channel;
47 /**< The function pointer to pass tv signal event */
48 void (*signal_cb)(void *data, int is_signal);
49 /**< An Additional data to passed to tv signal event */
53 static struct _tv_info g_tv_info;
56 * Gets the tv_channel_info with supplied TvServiceChannel.
58 * Abstracts tv service data structure.
60 * @param channel The channel data defined by tv service
61 * @return Channel information, or NULL if fails
63 static struct tv_channel_info *_tv_channel_get_info(TvServiceChannel *channel)
65 struct tv_channel_info *channel_info = NULL;
68 _ERR("failed to get channel");
72 channel_info = calloc(1, sizeof(*channel_info));
74 _ERR("failed to calloc channel info");
78 channel_info->service_id = channel->service_id;
79 channel_info->channel_major = channel->major;
80 channel_info->channel_minor = channel->minor;
81 channel_info->channel_type = channel->channel_type;
82 channel_info->locked = channel->locked;
83 channel_info->digital = channel->digital;
84 channel_info->favorite = channel->favorite;
85 channel_info->remembered = channel->remembered;
86 strncpy(channel_info->channel_name, channel->program_name,
89 if (channel->service_id == g_tv_info.viewing_locked_channel)
90 channel_info->tune_locked = EINA_TRUE;
96 * Clones the tv_channel_info.
98 * @param channel_info tv_channel_info pointer to be cloned
99 * @return Channel information, or NULL if fails
101 const struct tv_channel_info *tv_channel_clone_info(
102 const struct tv_channel_info *channel_info)
104 struct tv_channel_info *new_channel_info = NULL;
107 _ERR("failed to get channel info");
111 new_channel_info = calloc(1, sizeof(*channel_info));
112 if (!new_channel_info) {
113 _ERR("failed to calloc channel info");
117 memcpy(new_channel_info, channel_info, sizeof(*new_channel_info));
119 return new_channel_info;
123 * Frees the tv_channel_info.
125 * @param channel_info tv_channel_info pointer to be freed
127 void tv_channel_del_info(const struct tv_channel_info *channel_info)
130 _ERR("failed to get channel info");
134 free((void *)channel_info);
138 * Gets current channel's TvServiceChannel data from tv service.
140 * @param channel The pointer to store TvServiceChannel
141 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
143 static int _tv_get_channel(TvServiceChannel *channel)
148 if (!g_tv_info.live_svc) {
149 _ERR("failed to get live service");
153 r = tv_service_live_get_service_id(g_tv_info.live_svc, &svc_id);
155 _ERR("failed to get service id");
159 r = tv_service_get_channel(svc_id, channel);
161 _ERR("failed to get channel");
169 * Returns current channel's info.
171 * tv_channel_get_info retrieves current channel's information
174 * @return Returns current channel info, or NULL if fails
176 const struct tv_channel_info *tv_channel_get_info(void)
178 const struct tv_channel_info *channel_info;
179 TvServiceChannel channel;
182 r = _tv_get_channel(&channel);
184 _ERR("failed to get channel");
188 channel_info = _tv_channel_get_info(&channel);
194 * Returns tv_program_info with supplied TvServiceEpgEventData.
196 * Abstracts tv service data structure.
198 * @param prog TvServiceEpgEventData passed from tv service
199 * @return Returns tv_program_info, or NULL if fails
201 static struct tv_program_info *_tv_get_program_info(TvServiceEpgEventData *prog)
203 struct tv_program_info *prog_info;
205 prog_info = calloc(1, sizeof(*prog_info));
207 _ERR("failed to calloc program info");
211 prog_info->service_id = prog->service_id;
212 prog_info->start_time = prog->start_time;
213 prog_info->end_time = prog->start_time + prog->length_in_seconds;
214 prog_info->duration = prog->length_in_seconds;
215 prog_info->current_time = prog->current_time;
216 strncpy(prog_info->prog_title, (char *)prog->title_text,
217 sizeof(prog_info->prog_title) - 1);
218 strncpy(prog_info->prog_description, (char *)prog->extended_text,
219 sizeof(prog_info->prog_description) - 1);
225 * Gets current channel's service id from tv service.
227 * @param service_id The pointer to store service id
228 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
230 int tv_get_current_service_id(int *service_id)
234 if (!g_tv_info.live_svc) {
235 _ERR("failed to get live service");
239 r = tv_service_live_get_service_id(g_tv_info.live_svc, service_id);
240 if (r != TVS_ERROR_OK) {
241 _ERR("failed to get current service info");
251 * @param epg_list Eina_List to be freed
253 static void _tv_epg_del_list(Eina_List *epg_list)
255 struct tv_program_info *data;
257 EINA_LIST_FREE(epg_list, data)
262 * Callback function to get EPG program list from tv service.
264 * _tv_epg_event_cb is called from tv service when banner
265 * have requested to get program data.
266 * If this function is called, then derives program list from epg_list
267 * and calls banner's callback function which included in user_data.
269 * @param type Event type
270 * @param epg_list EPG program list
271 * @param user_data tv_program_request to handle request
273 static void _tv_epg_event_cb(tvs_epg_event_e type, GList *epg_list,
277 Eina_List *list = NULL;
278 TvServiceEpgEventData *epg_data;
279 struct tv_program_info *prog_info;
280 struct tv_program_request *request;
283 _ERR("failed to get user_data");
287 for (i = 0; i < g_list_length(epg_list); i++) {
288 epg_data = (TvServiceEpgEventData *)
289 g_list_nth_data(epg_list, i);
294 prog_info = _tv_get_program_info(epg_data);
296 list = eina_list_append(list, prog_info);
299 request = (struct tv_program_request *) user_data;
300 if (request->tv_program_cb)
301 request->tv_program_cb(list, request->user_data);
304 _tv_epg_del_list(list);
310 * Send a request to tv service to get a current program with supplied service_id.
312 * Beware that service_id should be current tuned channel.
313 * If not, calling this function may cause unexpected behavior.
314 * And note that get a EPG program is asynchronous operation.
315 * So tv_program_request should be supplied to get a result from tv service.
317 * @param service_id The channel id to get current program
318 * @param request The structure for return program data which contains function pointer
319 * and additional data for banner
320 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
322 int tv_epg_get_program(int service_id, struct tv_program_request *request)
326 if (!g_tv_info.epg_svc) {
327 _ERR("failed to get epg service");
332 _ERR("failed to get tv_program_request");
336 r = tv_service_epg_get_current_program(g_tv_info.epg_svc, service_id,
337 (TvServiceEpgCallback) _tv_epg_event_cb, request);
338 if (r != TVS_ERROR_OK) {
339 _ERR("failed to get epg get current program : %d", service_id);
348 * Gets a cached current program with supplied service_id from tv service.
350 * Note that this function is vaild only when tv service having a cached data
352 * To have a cached data, the channel ever been tuned before calling
355 * @param service_id The channel id to get current program
356 * @param request The structure for return program data which contains
357 * function pointer and additional data for banner
358 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
360 int tv_epg_get_cache_program(int service_id, struct tv_program_request *request)
362 Eina_List *list = NULL;
363 TvServiceEpgEventData epg_data;
364 struct tv_program_info *prog_info;
368 if (!g_tv_info.epg_svc) {
369 _ERR("failed to get epg service");
374 _ERR("failed to get tv_program_request");
378 r = tv_service_epg_get_cache_current_program(
379 g_tv_info.epg_svc, service_id, &epg_data);
380 if (r != TVS_ERROR_OK) {
381 _ERR("failed to get epg get cached current program : %d",
386 prog_info = _tv_get_program_info(&epg_data);
388 list = eina_list_append(list, prog_info);
390 if (request->tv_program_cb)
391 request->tv_program_cb(list, request->user_data);
394 _tv_epg_del_list(list);
402 * Sends a request to tv service to get programs with supplied service_id.
404 * Beware that service_id should be current tuned channel.
405 * If not, calling this function may cause unexpected behavior.
406 * And note that get a EPG program is asynchronous operation.
407 * So tv_program_request should be supplied to get a result from tv service.
409 * @param service_id The channel id to get current program
410 * @param request The structure for return program data which contains function pointer and additional data for banner
411 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
413 int tv_epg_get_program_list(int service_id,
414 struct tv_program_request *request)
418 if (!g_tv_info.epg_svc) {
419 _ERR("failed to get epg service");
424 _ERR("failed to get tv_program_request");
428 r = tv_service_epg_get_program_list(g_tv_info.epg_svc, service_id,
429 TVS_EPG_CURRENT_TIME, EPG_PROGRAM_OFFSET,
430 (TvServiceEpgCallback) _tv_epg_event_cb, request);
431 if (r != TVS_ERROR_OK) {
432 _ERR("failed to get epg get current program");
440 * Frees the TvServiceFilterNode.
442 * @param data TvServiceFilterNode pointer to be freed
444 static void _tv_channel_free_filter(gpointer data)
446 TvServiceFilterNode *filter_node;
451 filter_node = (TvServiceFilterNode *) data;
453 g_value_unset(filter_node->value);
454 g_free(filter_node->value);
459 * Gets a available channel list.
461 * Note that deleted channels and service channels are excluded by default.
463 * @return Available channel list, or NULL if fails
465 Eina_List *tv_channel_get_list()
467 GList *tvs_list = NULL;
468 Eina_List *channel_list = NULL;
469 TvServiceChannel *tvs_data = NULL;
470 const struct tv_channel_info *channel_info;
473 r = tv_service_get_channel_list(
474 TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG,
475 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list);
476 if (r != TVS_ERROR_OK) {
477 _ERR("failed to get channel list");
481 for (i = 0; i < g_list_length(tvs_list); i++) {
482 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
484 channel_info = _tv_channel_get_info(tvs_data);
486 channel_list = eina_list_append(channel_list,
496 * Gets a favorite channel list.
498 * @return Favorite channel list, or NULL if fails
500 Eina_List *tv_channel_get_favorite_list()
502 GList *tvs_list = NULL;
503 Eina_List *channel_list = NULL;
504 TvServiceChannel *tvs_data = NULL;
505 const struct tv_channel_info *channel_info;
508 r = tv_service_get_channel_list(
509 TV_SERVICE_CHANNEL_MODE_FAVORITE,
510 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list);
511 if (r != TVS_ERROR_OK) {
512 _ERR("failed to get channel list");
516 for (i = 0; i < g_list_length(tvs_list); i++) {
517 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
519 channel_info = _tv_channel_get_info(tvs_data);
521 channel_list = eina_list_append(channel_list,
530 TvServiceFilterNode *_tv_channel_get_filter(
531 TvServiceChannelDataAttr attribute, int type, void *data)
533 TvServiceFilterNode *filter;
536 filter = g_malloc0(sizeof(*filter));
540 filter->attribute = attribute;
542 value = g_malloc0(sizeof(GValue));
550 g_value_init(value, G_TYPE_STRING);
551 g_value_set_string(value, data);
553 filter->match_type = CHANNEL_FILTER_MATCH_CONTAIN;
556 g_value_init(value, G_TYPE_INT);
557 g_value_set_int(value, (gint) data);
559 filter->match_type = CHANNEL_FILTER_MATCH_EQUAL;
562 filter->value = value;
568 * Search channels that are starts with supplied major and minor number.
570 * Note that deleted channels and service channels are excluded by default.
572 * @param major Major channel number to search
573 * @param minor Minor channel number to search
574 * @return Found channel list, or NULL if fails
576 Eina_List *tv_channel_search_by_number(long major, long minor)
578 char buf[CHANNEL_FILTER_STRING_MAX_LEN];
579 GList *tvs_list = NULL, *filter = NULL;
580 TvServiceFilterNode *filter_node;
581 TvServiceChannel *tvs_data;
582 Eina_List *channel_list = NULL;
583 const struct tv_channel_info *channel_info;
586 if (major > 0 && major < MAJOR_MAX) {
587 snprintf(buf, CHANNEL_FILTER_STRING_MAX_LEN, "%ld", major);
589 filter_node = _tv_channel_get_filter(
590 TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER,
593 filter = g_list_append(filter, (gpointer)filter_node);
596 if (minor > 0 && minor < MINOR_MAX) {
597 snprintf(buf, CHANNEL_FILTER_STRING_MAX_LEN, "%ld", minor);
599 filter_node = _tv_channel_get_filter(
600 TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER,
603 filter = g_list_append(filter, (gpointer)filter_node);
607 _ERR("failed to get filter");
611 r = tv_service_get_channel_list_ex(
612 TV_SERVICE_CHANNEL_MODE_ALL_DIGITAL_ANALOG,
613 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list, filter, 0);
614 if (r != TVS_ERROR_OK) {
615 _ERR("failed to get channel list");
619 for (i = 0; i < g_list_length(tvs_list); i++) {
620 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
624 channel_info = _tv_channel_get_info(tvs_data);
626 channel_list = eina_list_append(channel_list,
633 g_list_free(tvs_list);
635 g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
642 * Frees the tv_channel_info.
644 * @param channel_list channel_list pointer to be freed
646 void tv_channel_del_list(Eina_List *channel_list)
648 struct tv_channel_info *data;
650 EINA_LIST_FREE(channel_list, data)
654 void _tv_channel_add_history(int service_id)
658 snprintf(buf, sizeof(buf), "%d", service_id);
659 app_contents_recent_add(CONTENTS_CHANNEL, buf);
663 * Tunes to specific channel with service id.
665 * @param service_id The channel id
666 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
668 int tv_channel_tune_with_service_id(int service_id)
672 if (!g_tv_info.live_svc) {
673 _ERR("failed to get live service");
677 r = tv_service_live_tune(g_tv_info.live_svc, service_id);
678 if (r != TVS_ERROR_OK) {
679 _ERR("failed to set service");
683 _tv_channel_add_history(service_id);
685 g_tv_info.viewing_locked_channel = -1;
691 * Tunes to last viewed channel.
693 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
695 int tv_channel_tune(void)
700 if (!g_tv_info.live_svc) {
701 _ERR("failed to get live service");
705 r = tv_service_live_get_last_channel(&service_id);
706 if (r < 0 || service_id < 1) {
707 _ERR("failed to get current service id");
708 service_id = DEFAULT_SERVICE;
711 r = tv_service_live_tune(g_tv_info.live_svc, service_id);
712 if (r != TVS_ERROR_OK) {
713 _ERR("failed to set service");
717 _tv_channel_add_history(service_id);
719 g_tv_info.viewing_locked_channel = -1;
725 * Tunes to specific channel with major and minor.
727 * @param service_id The channel id
728 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
730 int tv_channel_direct_tune(long major, long minor)
732 GList *tvs_list = NULL, *filter = NULL;
733 TvServiceFilterNode *filter_node;
734 TvServiceChannel *tvs_data;
737 if (major > 0 && major < MAJOR_MAX) {
738 filter_node = _tv_channel_get_filter(
739 TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER,
740 G_TYPE_INT, (void *) major);
742 filter = g_list_append(filter, (gpointer)filter_node);
745 if (minor > 0 && minor < MINOR_MAX) {
746 filter_node = _tv_channel_get_filter(
747 TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER,
748 G_TYPE_INT, (void *) minor);
750 filter = g_list_append(filter, (gpointer)filter_node);
754 _ERR("failed to get filter");
758 r = tv_service_get_channel_list_ex(
759 TV_SERVICE_CHANNEL_MODE_ALL_DIGITAL_ANALOG,
760 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list, filter, 0);
761 if (r != TVS_ERROR_OK)
764 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, 0);
766 r = tv_channel_tune_with_service_id(tvs_data->service_id);
768 _ERR("failed to get tvs_data");
772 if (r == TVS_ERROR_OK)
773 g_tv_info.viewing_locked_channel = -1;
775 g_list_foreach(tvs_list, (GFunc) g_free, NULL);
776 g_list_free(tvs_list);
779 g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
786 * Tunes to locked channel.
788 * @param service_id The channel id
789 * @param password 4 digit password
790 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
792 int tv_channel_tune_locked_channel(int service_id, char *password)
796 if (!g_tv_info.live_svc) {
797 _ERR("failed to get live service");
801 r = tv_service_live_tune_locked_channel(g_tv_info.live_svc,
802 service_id, password);
803 if (r != TVS_ERROR_OK) {
804 _ERR("failed to set service");
808 _tv_channel_add_history(service_id);
810 g_tv_info.viewing_locked_channel = service_id;
816 * Tunes to next channel.
818 * Note that deleted channels and service channels will skipped.
820 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
822 int tv_channel_next(void)
824 TvServiceAntenna antenna_type;
827 if (!g_tv_info.live_svc) {
828 _ERR("failed to get live service");
832 r = tv_service_live_get_antenna_type(g_tv_info.live_svc, &antenna_type);
834 _ERR("failed to get antenna type");
838 r = tv_service_live_tune_up(g_tv_info.live_svc,
839 TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG, antenna_type);
841 _ERR("failed to tune up");
845 g_tv_info.viewing_locked_channel = -1;
847 r = tv_service_live_get_service_id(g_tv_info.live_svc, &service_id);
849 _ERR("failed to get service id");
853 _tv_channel_add_history(service_id);
859 * Tunes to previous channel.
861 * Note that deleted channels and service channels will skipped.
863 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
865 int tv_channel_prev(void)
867 TvServiceAntenna antenna_type;
870 if (!g_tv_info.live_svc) {
871 _ERR("failed to get live service");
875 r = tv_service_live_get_antenna_type(g_tv_info.live_svc, &antenna_type);
877 _ERR("failed to get antenna type");
881 r = tv_service_live_tune_down(g_tv_info.live_svc,
882 TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG, antenna_type);
884 _ERR("failed to tune down");
888 g_tv_info.viewing_locked_channel = -1;
890 r = tv_service_live_get_service_id(g_tv_info.live_svc, &service_id);
892 _ERR("failed to get service id");
896 _tv_channel_add_history(service_id);
902 * Sets the channel's favorite status.
904 * @param service_id The channel id
905 * @param flag The value to be set
906 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
908 int tv_channel_set_favorite(int service_id, Eina_Bool flag)
913 r = tv_service_add_favorite_channel(service_id);
915 _ERR("failed to add favorite channel");
919 r = tv_service_delete_favorite_channel(service_id);
921 _ERR("failed to delete favorite channel");
932 * If channel is added, the channel will be included at
933 * tv_channel_next, tv_channel_prev and tv_channel_get_list.
935 * @param service_id The channel id
936 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
938 int tv_channel_add_channel(int service_id)
942 r = tv_service_add_channel(service_id);
944 _ERR("failed to add channel");
952 * Deletes the channel.
954 * If channel is deleted, the channel will be omitted at
955 * tv_channel_next, tv_channel_prev and tv_channel_get_list.
957 * @param service_id The channel id
958 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
960 int tv_channel_del_channel(int service_id)
964 r = tv_service_delete_channel(service_id);
966 _ERR("failed to delete channel");
976 * @param service_id The channel id
977 * @param password 4 digits password
978 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
980 int tv_channel_lock_channel(int service_id, char *password)
984 r = tv_service_lock_channel(service_id, password);
986 _ERR("failed to lock channel");
994 * Unlocks the channel.
996 * @param service_id The channel id
997 * @param password 4 digits password
998 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1000 int tv_channel_unlock_channel(int service_id, char *password)
1004 r = tv_service_unlock_channel(service_id, password);
1006 _ERR("failed to unlock channel");
1014 * Callback function for receives tv service events.
1016 * @param event Event type
1017 * @param user_data Not in use
1018 * @param data Event specific detailed data
1020 void _tv_service_event_cb(TvServiceLiveEvent event,
1021 gpointer user_data, const gpointer data)
1023 gboolean *lock_status;
1026 case TV_SERVICE_LIVE_EVENT_TUNER_LOCK:
1028 _ERR("failed to get data");
1032 lock_status = (gboolean *) data;
1033 if (g_tv_info.signal_cb)
1034 g_tv_info.signal_cb(g_tv_info.signal_cb_data,
1037 case TV_SERVICE_LIVE_EVENT_AUTO_DESTROY:
1038 g_tv_info.live_svc = NULL;
1040 case TV_SERVICE_LIVE_EVENT_RESOLUTION:
1041 case TV_SERVICE_LIVE_EVENT_BEGIN:
1042 case TV_SERVICE_LIVE_EVENT_CHANNEL_LOCK:
1043 case TV_SERVICE_LIVE_EVENT_CHANNEL_UNLOCK:
1049 * Sets tv signal callback function.
1051 * @param cb The function pointer to get callback
1052 * @param data An Additional data to passed to callback
1054 void tv_signal_cb_set(void (*cb)(void *data, int is_signal), void *data)
1056 g_tv_info.signal_cb = cb;
1057 g_tv_info.signal_cb_data = data;
1061 * Destory the tv service handles.
1063 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1065 int tv_destroy(void)
1069 if (g_tv_info.live_svc)
1070 g_tv_info.live_svc = NULL;
1072 r = tv_service_channel_info_destroy();
1074 _ERR("failed to destroy channel info service");
1076 if (g_tv_info.epg_svc) {
1077 r = tv_service_epg_destroy(g_tv_info.epg_svc);
1079 _ERR("failed to destroy epg service");
1080 g_tv_info.epg_svc = NULL;
1087 * Create the tv service handles.
1089 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1095 r = tv_service_live_create(&g_tv_info.live_svc);
1096 if (r != TVS_ERROR_OK) {
1097 _ERR("failed to create live service");
1101 r = tv_service_live_register_callback(g_tv_info.live_svc,
1102 _tv_service_event_cb, NULL);
1103 if (r != TVS_ERROR_OK) {
1104 _ERR("failed to register live callback");
1108 r = tv_service_channel_info_create();
1109 if (r != TVS_ERROR_OK) {
1110 _ERR("failed to create channel info service");
1114 r = tv_service_epg_create(&g_tv_info.epg_svc);
1115 if (r != TVS_ERROR_OK) {
1116 _ERR("failed to create epg service");
1127 * Pause the tv service handles.
1129 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1135 if (g_tv_info.live_svc) {
1136 r = tv_service_live_tune_pause(g_tv_info.live_svc);
1137 if (r != TVS_ERROR_OK)
1138 _ERR("failed to pause live service");
1145 * Resume the tv service handles.
1147 * Live service could be destroyed by tv service while app is pausing.
1148 * If live service is destroyed, then _tv_service_event_cb sets
1149 * g_tv_info.live_svc to NULL.
1150 * So if g_tv_info.live_svc is NULL, then recreates live service and returns 1.
1151 * Therefore, if tv_resume returns 1, then app needs to be set overlay and tune.
1152 * Or returns 0, then app just needs to set overlay.
1154 * @return 0 if successful; 1 if live service was destroyed; otherwise negative value is returned
1160 if (!g_tv_info.live_svc) {
1161 r = tv_service_live_create(&g_tv_info.live_svc);
1162 if (r != TVS_ERROR_OK) {
1163 _ERR("failed to create live service");
1170 r = tv_service_live_tune_resume(g_tv_info.live_svc);
1171 if (r != TVS_ERROR_OK) {
1172 _ERR("failed to create live service");
1176 r = tv_service_live_register_callback(g_tv_info.live_svc,
1177 _tv_service_event_cb, NULL);
1178 if (r != TVS_ERROR_OK) {
1179 _ERR("failed to register live callback");