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
35 struct _channel_history {
41 * The Storage structure to used by tv related functions and events.
44 /**< The handle to use tv service live api. */
45 TvServiceLive live_svc;
46 /**< The handle to use tv service epg api. */
49 /**< Stores service id if tune to locked channel was succeeded. */
50 int viewing_locked_channel;
51 /**< Stores previous service id. */
52 struct _channel_history history;
54 /**< The function pointer to pass tv signal event */
55 void (*signal_cb)(void *data, int is_signal);
56 /**< An Additional data to passed to tv signal event */
60 static struct _tv_info g_tv_info;
63 * Gets the tv_channel_info with supplied TvServiceChannel.
65 * Abstracts tv service data structure.
67 * @param channel The channel data defined by tv service
68 * @return Channel information, or NULL if fails
70 static struct tv_channel_info *_tv_channel_get_info(TvServiceChannel *channel)
72 struct tv_channel_info *channel_info = NULL;
75 _ERR("failed to get channel");
79 channel_info = calloc(1, sizeof(*channel_info));
81 _ERR("failed to calloc channel info");
85 channel_info->service_id = channel->service_id;
86 channel_info->channel_major = channel->major;
87 channel_info->channel_minor = channel->minor;
88 channel_info->channel_type = channel->channel_type;
89 channel_info->locked = channel->locked;
90 channel_info->digital = channel->digital;
91 channel_info->favorite = channel->favorite;
92 channel_info->remembered = channel->remembered;
93 strncpy(channel_info->channel_name, channel->program_name,
96 if (channel->service_id == g_tv_info.viewing_locked_channel)
97 channel_info->tune_locked = EINA_TRUE;
103 * Clones the tv_channel_info.
105 * @param channel_info tv_channel_info pointer to be cloned
106 * @return Channel information, or NULL if fails
108 const struct tv_channel_info *tv_channel_clone_info(
109 const struct tv_channel_info *channel_info)
111 struct tv_channel_info *new_channel_info = NULL;
114 _ERR("failed to get channel info");
118 new_channel_info = calloc(1, sizeof(*channel_info));
119 if (!new_channel_info) {
120 _ERR("failed to calloc channel info");
124 memcpy(new_channel_info, channel_info, sizeof(*new_channel_info));
126 return new_channel_info;
130 * Frees the tv_channel_info.
132 * @param channel_info tv_channel_info pointer to be freed
134 void tv_channel_del_info(const struct tv_channel_info *channel_info)
137 _ERR("failed to get channel info");
141 free((void *)channel_info);
145 * Gets current channel's TvServiceChannel data from tv service.
147 * @param channel The pointer to store TvServiceChannel
148 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
150 static int _tv_get_channel(TvServiceChannel *channel)
155 if (!g_tv_info.live_svc) {
156 _ERR("failed to get live service");
160 r = tv_service_live_get_service_id(g_tv_info.live_svc, &svc_id);
162 _ERR("failed to get service id");
166 r = tv_service_get_channel(svc_id, channel);
168 _ERR("failed to get channel");
176 * Returns current channel's info.
178 * tv_channel_get_info retrieves current channel's information
181 * @return Returns current channel info, or NULL if fails
183 const struct tv_channel_info *tv_channel_get_info(void)
185 const struct tv_channel_info *channel_info;
186 TvServiceChannel channel;
189 r = _tv_get_channel(&channel);
191 _ERR("failed to get channel");
195 channel_info = _tv_channel_get_info(&channel);
201 * Returns tv_program_info with supplied TvServiceEpgEventData.
203 * Abstracts tv service data structure.
205 * @param prog TvServiceEpgEventData passed from tv service
206 * @return Returns tv_program_info, or NULL if fails
208 static struct tv_program_info *_tv_get_program_info(TvServiceEpgEventData *prog)
210 struct tv_program_info *prog_info;
212 prog_info = calloc(1, sizeof(*prog_info));
214 _ERR("failed to calloc program info");
218 prog_info->service_id = prog->service_id;
219 prog_info->start_time = prog->start_time;
220 prog_info->end_time = prog->start_time + prog->length_in_seconds;
221 prog_info->duration = prog->length_in_seconds;
222 prog_info->current_time = prog->current_time;
223 strncpy(prog_info->prog_title, (char *)prog->title_text,
224 sizeof(prog_info->prog_title) - 1);
225 strncpy(prog_info->prog_description, (char *)prog->extended_text,
226 sizeof(prog_info->prog_description) - 1);
232 * Gets current channel's service id from tv service.
234 * @param service_id The pointer to store service id
235 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
237 int tv_get_current_service_id(int *service_id)
241 if (!g_tv_info.live_svc) {
242 _ERR("failed to get live service");
246 r = tv_service_live_get_service_id(g_tv_info.live_svc, service_id);
247 if (r != TVS_ERROR_OK) {
248 _ERR("failed to get current service info");
258 * @param epg_list Eina_List to be freed
260 static void _tv_epg_del_list(Eina_List *epg_list)
262 struct tv_program_info *data;
264 EINA_LIST_FREE(epg_list, data)
269 * Callback function to get EPG program list from tv service.
271 * _tv_epg_event_cb is called from tv service when banner
272 * have requested to get program data.
273 * If this function is called, then derives program list from epg_list
274 * and calls banner's callback function which included in user_data.
276 * @param type Event type
277 * @param epg_list EPG program list
278 * @param user_data tv_program_request to handle request
280 static void _tv_epg_event_cb(tvs_epg_event_e type, GList *epg_list,
284 Eina_List *list = NULL;
285 TvServiceEpgEventData *epg_data;
286 struct tv_program_info *prog_info;
287 struct tv_program_request *request;
290 _ERR("failed to get user_data");
294 for (i = 0; i < g_list_length(epg_list); i++) {
295 epg_data = (TvServiceEpgEventData *)
296 g_list_nth_data(epg_list, i);
301 prog_info = _tv_get_program_info(epg_data);
303 list = eina_list_append(list, prog_info);
306 request = (struct tv_program_request *) user_data;
307 if (request->tv_program_cb)
308 request->tv_program_cb(list, request->user_data);
311 _tv_epg_del_list(list);
317 * Send a request to tv service to get a current program with supplied service_id.
319 * Beware that service_id should be current tuned channel.
320 * If not, calling this function may cause unexpected behavior.
321 * And note that get a EPG program is asynchronous operation.
322 * So tv_program_request should be supplied to get a result from tv service.
324 * @param service_id The channel id to get current program
325 * @param request The structure for return program data which contains function pointer
326 * and additional data for banner
327 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
329 int tv_epg_get_program(int service_id, struct tv_program_request *request)
333 if (!g_tv_info.epg_svc) {
334 _ERR("failed to get epg service");
339 _ERR("failed to get tv_program_request");
343 r = tv_service_epg_get_current_program(g_tv_info.epg_svc, service_id,
344 (TvServiceEpgCallback) _tv_epg_event_cb, request);
345 if (r != TVS_ERROR_OK) {
346 _ERR("failed to get epg get current program : %d", service_id);
354 * Gets a cached current program with supplied service_id from tv service.
356 * Note that this function is vaild only when tv service having a cached data
358 * To have a cached data, the channel ever been tuned before calling
361 * @param service_id The channel id to get current program
362 * @param request The structure for return program data which contains
363 * function pointer and additional data for banner
364 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
366 int tv_epg_get_cache_program(int service_id, struct tv_program_request *request)
368 Eina_List *list = NULL;
369 TvServiceEpgEventData epg_data;
370 struct tv_program_info *prog_info;
374 if (!g_tv_info.epg_svc) {
375 _ERR("failed to get epg service");
380 _ERR("failed to get tv_program_request");
384 r = tv_service_epg_get_cache_current_program(
385 g_tv_info.epg_svc, service_id, &epg_data);
386 if (r != TVS_ERROR_OK) {
387 _ERR("failed to get epg get cached current program : %d",
392 prog_info = _tv_get_program_info(&epg_data);
394 list = eina_list_append(list, prog_info);
396 if (request->tv_program_cb)
397 request->tv_program_cb(list, request->user_data);
400 _tv_epg_del_list(list);
408 * Sends a request to tv service to get programs with supplied service_id.
410 * Beware that service_id should be current tuned channel.
411 * If not, calling this function may cause unexpected behavior.
412 * And note that get a EPG program is asynchronous operation.
413 * So tv_program_request should be supplied to get a result from tv service.
415 * @param service_id The channel id to get current program
416 * @param request The structure for return program data which contains function pointer and additional data for banner
417 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
419 int tv_epg_get_program_list(int service_id,
420 struct tv_program_request *request)
424 if (!g_tv_info.epg_svc) {
425 _ERR("failed to get epg service");
430 _ERR("failed to get tv_program_request");
434 r = tv_service_epg_get_program_list(g_tv_info.epg_svc, service_id,
435 TVS_EPG_CURRENT_TIME, EPG_PROGRAM_OFFSET,
436 (TvServiceEpgCallback) _tv_epg_event_cb, request);
437 if (r != TVS_ERROR_OK) {
438 _ERR("failed to get epg get current program");
446 * Frees the TvServiceFilterNode.
448 * @param data TvServiceFilterNode pointer to be freed
450 static void _tv_channel_free_filter(gpointer data)
452 TvServiceFilterNode *filter_node;
457 filter_node = (TvServiceFilterNode *) data;
459 g_value_unset(filter_node->value);
460 g_free(filter_node->value);
465 * Gets a available channel list.
467 * Note that deleted channels and service channels are excluded by default.
469 * @return Available channel list, or NULL if fails
471 Eina_List *tv_channel_get_list()
473 GList *tvs_list = NULL;
474 Eina_List *channel_list = NULL;
475 TvServiceChannel *tvs_data = NULL;
476 const struct tv_channel_info *channel_info;
479 r = tv_service_get_channel_list(
480 TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG,
481 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list);
482 if (r != TVS_ERROR_OK) {
483 _ERR("failed to get channel list");
487 for (i = 0; i < g_list_length(tvs_list); i++) {
488 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
490 channel_info = _tv_channel_get_info(tvs_data);
492 channel_list = eina_list_append(channel_list,
497 tv_service_free_channel_list(tvs_list);
503 * Gets a favorite channel list.
505 * @return Favorite channel list, or NULL if fails
507 Eina_List *tv_channel_get_favorite_list()
509 GList *tvs_list = NULL;
510 Eina_List *channel_list = NULL;
511 TvServiceChannel *tvs_data = NULL;
512 const struct tv_channel_info *channel_info;
515 r = tv_service_get_channel_list(
516 TV_SERVICE_CHANNEL_MODE_FAVORITE,
517 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list);
518 if (r != TVS_ERROR_OK) {
519 _ERR("failed to get channel list");
523 for (i = 0; i < g_list_length(tvs_list); i++) {
524 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
526 channel_info = _tv_channel_get_info(tvs_data);
528 channel_list = eina_list_append(channel_list,
533 tv_service_free_channel_list(tvs_list);
538 TvServiceFilterNode *_tv_channel_get_filter(
539 TvServiceChannelDataAttr attribute, int type, void *data)
541 TvServiceFilterNode *filter;
544 filter = g_malloc0(sizeof(*filter));
548 filter->attribute = attribute;
550 value = g_malloc0(sizeof(GValue));
558 g_value_init(value, G_TYPE_STRING);
559 g_value_set_string(value, data);
561 filter->match_type = CHANNEL_FILTER_MATCH_CONTAIN;
564 g_value_init(value, G_TYPE_INT);
565 g_value_set_int(value, (gint) data);
567 filter->match_type = CHANNEL_FILTER_MATCH_EQUAL;
570 filter->value = value;
576 * Search channels that are starts with supplied major and minor number.
578 * Note that deleted channels and service channels are excluded by default.
580 * @param major Major channel number to search
581 * @param minor Minor channel number to search
582 * @return Found channel list, or NULL if fails
584 Eina_List *tv_channel_search_by_number(long major, long minor)
586 char buf[CHANNEL_FILTER_STRING_MAX_LEN];
587 GList *tvs_list = NULL, *filter = NULL;
588 TvServiceFilterNode *filter_node;
589 TvServiceChannel *tvs_data;
590 Eina_List *channel_list = NULL;
591 const struct tv_channel_info *channel_info;
594 if (major > 0 && major < MAJOR_MAX) {
595 snprintf(buf, CHANNEL_FILTER_STRING_MAX_LEN, "%ld", major);
597 filter_node = _tv_channel_get_filter(
598 TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER,
601 filter = g_list_append(filter, (gpointer)filter_node);
604 if (minor > 0 && minor < MINOR_MAX) {
605 snprintf(buf, CHANNEL_FILTER_STRING_MAX_LEN, "%ld", minor);
607 filter_node = _tv_channel_get_filter(
608 TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER,
611 filter = g_list_append(filter, (gpointer)filter_node);
615 _ERR("failed to get filter");
619 r = tv_service_get_channel_list_ex(
620 TV_SERVICE_CHANNEL_MODE_ALL_DIGITAL_ANALOG,
621 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list, filter, 0);
622 if (r != TVS_ERROR_OK) {
623 _ERR("failed to get channel list");
627 for (i = 0; i < g_list_length(tvs_list); i++) {
628 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
632 channel_info = _tv_channel_get_info(tvs_data);
634 channel_list = eina_list_append(channel_list,
639 tv_service_free_channel_list(tvs_list);
641 g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
648 * Frees the tv_channel_info.
650 * @param channel_list channel_list pointer to be freed
652 void tv_channel_del_list(Eina_List *channel_list)
654 struct tv_channel_info *data;
656 EINA_LIST_FREE(channel_list, data)
660 static void _tv_channel_add_history(int service_id)
664 g_tv_info.history.service_id[g_tv_info.history.idx++ % 2]
667 snprintf(buf, sizeof(buf), "%d", service_id);
668 app_contents_recent_add(CONTENTS_CHANNEL, buf);
671 static int _tv_channel_get_history(void)
675 service_id = g_tv_info.history.service_id[g_tv_info.history.idx % 2];
681 * Tunes to specific channel with service id.
683 * @param service_id The channel id
684 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
686 int tv_channel_tune_with_service_id(int service_id)
690 if (!g_tv_info.live_svc) {
691 _ERR("failed to get live service");
695 r = tv_service_live_tune(g_tv_info.live_svc, service_id);
696 if (r != TVS_ERROR_OK) {
697 _ERR("failed to set service");
701 _tv_channel_add_history(service_id);
703 g_tv_info.viewing_locked_channel = -1;
709 * Tunes to last viewed channel.
711 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
713 int tv_channel_tune(void)
718 if (!g_tv_info.live_svc) {
719 _ERR("failed to get live service");
723 r = tv_service_live_get_last_channel(&service_id);
724 if (r < 0 || service_id < 1) {
725 _ERR("failed to get current service id");
726 service_id = DEFAULT_SERVICE;
729 r = tv_service_live_tune(g_tv_info.live_svc, service_id);
730 if (r != TVS_ERROR_OK) {
731 _ERR("failed to set service");
735 _tv_channel_add_history(service_id);
737 g_tv_info.viewing_locked_channel = -1;
743 * Tunes to previously viewed channel.
745 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
747 int tv_channel_tune_prev_channel(void)
752 if (!g_tv_info.live_svc) {
753 _ERR("failed to get live service");
757 service_id = _tv_channel_get_history();
758 if (service_id < 1) {
759 _ERR("no previous channel");
763 r = tv_service_live_tune(g_tv_info.live_svc, service_id);
764 if (r != TVS_ERROR_OK) {
765 _ERR("failed to set service");
769 _tv_channel_add_history(service_id);
771 g_tv_info.viewing_locked_channel = -1;
777 * Tunes to specific channel with major and minor.
779 * @param service_id The channel id
780 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
782 int tv_channel_direct_tune(long major, long minor)
784 GList *tvs_list = NULL, *filter = NULL;
785 TvServiceFilterNode *filter_node;
786 TvServiceChannel *tvs_data;
789 if (!g_tv_info.live_svc) {
790 _ERR("failed to get live service");
794 if (major > 0 && major < MAJOR_MAX) {
795 filter_node = _tv_channel_get_filter(
796 TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER,
797 G_TYPE_INT, (void *) major);
799 filter = g_list_append(filter, (gpointer)filter_node);
802 if (minor > 0 && minor < MINOR_MAX) {
803 filter_node = _tv_channel_get_filter(
804 TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER,
805 G_TYPE_INT, (void *) minor);
807 filter = g_list_append(filter, (gpointer)filter_node);
811 _ERR("failed to get filter");
815 r = tv_service_get_channel_list_ex(
816 TV_SERVICE_CHANNEL_MODE_ALL_DIGITAL_ANALOG,
817 TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list, filter, 0);
818 if (r != TVS_ERROR_OK)
821 tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, 0);
823 r = tv_channel_tune_with_service_id(tvs_data->service_id);
825 _ERR("failed to get tvs_data");
829 if (r == TVS_ERROR_OK)
830 g_tv_info.viewing_locked_channel = -1;
832 tv_service_free_channel_list(tvs_list);
835 g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
842 * Tunes to locked channel.
844 * @param service_id The channel id
845 * @param password 4 digit password
846 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
848 int tv_channel_tune_locked_channel(int service_id, char *password)
852 if (!g_tv_info.live_svc) {
853 _ERR("failed to get live service");
857 r = tv_service_live_tune_locked_channel(g_tv_info.live_svc,
858 service_id, password);
859 if (r != TVS_ERROR_OK) {
860 _ERR("failed to set service");
864 _tv_channel_add_history(service_id);
866 g_tv_info.viewing_locked_channel = service_id;
872 * Sets the channel's favorite status.
874 * @param service_id The channel id
875 * @param flag The value to be set
876 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
878 int tv_channel_set_favorite(int service_id, Eina_Bool flag)
883 r = tv_service_add_favorite_channel(service_id);
885 _ERR("failed to add favorite channel");
889 r = tv_service_delete_favorite_channel(service_id);
891 _ERR("failed to delete favorite channel");
902 * If channel is added, the channel will be included at
903 * tv_channel_next, tv_channel_prev and tv_channel_get_list.
905 * @param service_id The channel id
906 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
908 int tv_channel_add_channel(int service_id)
912 r = tv_service_add_channel(service_id);
914 _ERR("failed to add channel");
922 * Deletes the channel.
924 * If channel is deleted, the channel will be omitted at
925 * tv_channel_next, tv_channel_prev and tv_channel_get_list.
927 * @param service_id The channel id
928 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
930 int tv_channel_del_channel(int service_id)
934 r = tv_service_delete_channel(service_id);
936 _ERR("failed to delete channel");
946 * @param service_id The channel id
947 * @param password 4 digits password
948 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
950 int tv_channel_lock_channel(int service_id, char *password)
954 r = tv_service_lock_channel(service_id, password);
956 _ERR("failed to lock channel");
964 * Unlocks the channel.
966 * @param service_id The channel id
967 * @param password 4 digits password
968 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
970 int tv_channel_unlock_channel(int service_id, char *password)
974 r = tv_service_unlock_channel(service_id, password);
976 _ERR("failed to unlock channel");
984 * Callback function for receives tv service events.
986 * @param event Event type
987 * @param user_data Not in use
988 * @param data Event specific detailed data
990 void _tv_service_event_cb(TvServiceLiveEvent event,
991 gpointer user_data, const gpointer data)
993 gboolean *lock_status;
996 case TV_SERVICE_LIVE_EVENT_TUNER_LOCK:
998 _ERR("failed to get data");
1002 lock_status = (gboolean *) data;
1003 if (g_tv_info.signal_cb)
1004 g_tv_info.signal_cb(g_tv_info.signal_cb_data,
1007 case TV_SERVICE_LIVE_EVENT_AUTO_DESTROY:
1008 g_tv_info.live_svc = NULL;
1010 case TV_SERVICE_LIVE_EVENT_RESOLUTION:
1011 case TV_SERVICE_LIVE_EVENT_BEGIN:
1012 case TV_SERVICE_LIVE_EVENT_CHANNEL_LOCK:
1013 case TV_SERVICE_LIVE_EVENT_CHANNEL_UNLOCK:
1019 * Sets tv signal callback function.
1021 * @param cb The function pointer to get callback
1022 * @param data An Additional data to passed to callback
1024 void tv_signal_cb_set(void (*cb)(void *data, int is_signal), void *data)
1026 g_tv_info.signal_cb = cb;
1027 g_tv_info.signal_cb_data = data;
1031 * Destory the tv service handles.
1033 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1035 int tv_destroy(void)
1039 if (g_tv_info.live_svc)
1040 g_tv_info.live_svc = NULL;
1042 r = tv_service_channel_info_destroy();
1044 _ERR("failed to destroy channel info service");
1046 if (g_tv_info.epg_svc) {
1047 r = tv_service_epg_destroy(g_tv_info.epg_svc);
1049 _ERR("failed to destroy epg service");
1050 g_tv_info.epg_svc = NULL;
1057 * Create the tv service handles.
1059 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1065 r = tv_service_live_create(&g_tv_info.live_svc);
1066 if (r != TVS_ERROR_OK) {
1067 _ERR("failed to create live service");
1071 r = tv_service_live_register_callback(g_tv_info.live_svc,
1072 _tv_service_event_cb, NULL);
1073 if (r != TVS_ERROR_OK) {
1074 _ERR("failed to register live callback");
1078 r = tv_service_channel_info_create();
1079 if (r != TVS_ERROR_OK) {
1080 _ERR("failed to create channel info service");
1085 r = tv_service_epg_create(&g_tv_info.epg_svc);
1086 if (r != TVS_ERROR_OK) {
1087 _ERR("failed to create epg service");
1092 memset(&g_tv_info.history, 0, sizeof(g_tv_info.history));
1101 * Pause the tv service handles.
1103 * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
1109 if (g_tv_info.live_svc) {
1110 r = tv_service_live_tune_pause(g_tv_info.live_svc);
1111 if (r != TVS_ERROR_OK)
1112 _ERR("failed to pause live service");
1119 * Resume the tv service handles.
1121 * Live service could be destroyed by tv service while app is pausing.
1122 * If live service is destroyed, then _tv_service_event_cb sets
1123 * g_tv_info.live_svc to NULL.
1124 * So if g_tv_info.live_svc is NULL, then recreates live service and returns 1.
1125 * Therefore, if tv_resume returns 1, then app needs to be set overlay and tune.
1126 * Or returns 0, then app just needs to set overlay.
1128 * @return 0 if successful; 1 if live service was destroyed; otherwise negative value is returned
1134 if (!g_tv_info.live_svc) {
1135 r = tv_service_live_create(&g_tv_info.live_svc);
1136 if (r != TVS_ERROR_OK) {
1137 _ERR("failed to create live service");
1141 r = tv_service_live_register_callback(g_tv_info.live_svc,
1142 _tv_service_event_cb, NULL);
1143 if (r != TVS_ERROR_OK) {
1144 _ERR("failed to register live callback");
1151 r = tv_service_live_tune_resume(g_tv_info.live_svc);
1152 if (r != TVS_ERROR_OK) {
1153 _ERR("failed to create live service");
1157 r = tv_service_live_register_callback(g_tv_info.live_svc,
1158 _tv_service_event_cb, NULL);
1159 if (r != TVS_ERROR_OK) {
1160 _ERR("failed to register live callback");