Hide background image
[profile/tv/apps/native/air_livetv.git] / src / tv.c
index abacbe9..cfd92dc 100644 (file)
--- a/src/tv.c
+++ b/src/tv.c
 #include <iconv.h>
 #include <math.h>
 #include <app_debug.h>
+#include <app_contents.h>
+
+#include <tv_service_proxy.h>
+#include <tv_service_proxy_epg.h>
 
 #include <glib.h>
 #include <glib-object.h>
 
 #include "define.h"
 #include "tv.h"
-#include "tv_service.h"
 
 #define DEFAULT_SERVICE 1
 
+struct _channel_history {
+       int service_id[2];
+       unsigned int idx;
+};
+
 /**
  * The Storage structure to used by tv related functions and events.
  */
@@ -40,6 +48,8 @@ struct _tv_info {
 
        /**< Stores service id if tune to locked channel was succeeded. */
        int viewing_locked_channel;
+       /**< Stores previous service id. */
+       struct _channel_history history;
 
        /**< The function pointer to pass tv signal event */
        void (*signal_cb)(void *data, int is_signal);
@@ -90,6 +100,33 @@ static struct tv_channel_info *_tv_channel_get_info(TvServiceChannel *channel)
 }
 
 /**
+ * Clones the tv_channel_info.
+ *
+ * @param channel_info tv_channel_info pointer to be cloned
+ * @return Channel information, or NULL if fails
+ */
+const struct tv_channel_info *tv_channel_clone_info(
+               const struct tv_channel_info *channel_info)
+{
+       struct tv_channel_info *new_channel_info = NULL;
+
+       if (!channel_info) {
+               _ERR("failed to get channel info");
+               return NULL;
+       }
+
+       new_channel_info = calloc(1, sizeof(*channel_info));
+       if (!new_channel_info) {
+               _ERR("failed to calloc channel info");
+               return NULL;
+       }
+
+       memcpy(new_channel_info, channel_info, sizeof(*new_channel_info));
+
+       return new_channel_info;
+}
+
+/**
  * Frees the tv_channel_info.
  *
  * @param channel_info tv_channel_info pointer to be freed
@@ -454,10 +491,47 @@ Eina_List *tv_channel_get_list()
                        if (channel_info)
                                channel_list = eina_list_append(channel_list,
                                                channel_info);
-                       free(tvs_data);
                }
        }
 
+       tv_service_free_channel_list(tvs_list);
+
+       return channel_list;
+}
+
+/**
+ * Gets a favorite channel list.
+ *
+ * @return Favorite channel list, or NULL if fails
+ */
+Eina_List *tv_channel_get_favorite_list()
+{
+       GList *tvs_list = NULL;
+       Eina_List *channel_list = NULL;
+       TvServiceChannel *tvs_data = NULL;
+       const struct tv_channel_info *channel_info;
+       int r, i;
+
+       r = tv_service_get_channel_list(
+                       TV_SERVICE_CHANNEL_MODE_FAVORITE,
+                       TV_SERVICE_ANTENNA_TYPE_ALL, &tvs_list);
+       if (r != TVS_ERROR_OK) {
+               _ERR("failed to get channel list");
+               return NULL;
+       }
+
+       for (i = 0; i < g_list_length(tvs_list); i++) {
+               tvs_data = (TvServiceChannel *) g_list_nth_data(tvs_list, i);
+               if (tvs_data) {
+                       channel_info = _tv_channel_get_info(tvs_data);
+                       if (channel_info)
+                               channel_list = eina_list_append(channel_list,
+                                               channel_info);
+               }
+       }
+
+       tv_service_free_channel_list(tvs_list);
+
        return channel_list;
 }
 
@@ -559,12 +633,10 @@ Eina_List *tv_channel_search_by_number(long major, long minor)
                if (channel_info)
                        channel_list = eina_list_append(channel_list,
                                        channel_info);
-               free(tvs_data);
        }
 
 free:
-       if (tvs_list)
-               g_list_free(tvs_list);
+       tv_service_free_channel_list(tvs_list);
 
        g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
        g_list_free(filter);
@@ -585,6 +657,26 @@ void tv_channel_del_list(Eina_List *channel_list)
                free(data);
 }
 
+static void _tv_channel_add_history(int service_id)
+{
+       char buf[128];
+
+       g_tv_info.history.service_id[g_tv_info.history.idx++ % 2]
+                       = service_id;
+
+       snprintf(buf, sizeof(buf), "%d", service_id);
+       app_contents_recent_add(CONTENTS_CHANNEL, buf);
+}
+
+static int _tv_channel_get_history(void)
+{
+       int service_id;
+
+       service_id = g_tv_info.history.service_id[g_tv_info.history.idx % 2];
+
+       return service_id;
+}
+
 /**
  * Tunes to specific channel with service id.
  *
@@ -606,6 +698,8 @@ int tv_channel_tune_with_service_id(int service_id)
                return -1;
        }
 
+       _tv_channel_add_history(service_id);
+
        g_tv_info.viewing_locked_channel = -1;
 
        return 0;
@@ -627,7 +721,7 @@ int tv_channel_tune(void)
        }
 
        r = tv_service_live_get_last_channel(&service_id);
-       if (r < 0) {
+       if (r < 0 || service_id < 1) {
                _ERR("failed to get current service id");
                service_id = DEFAULT_SERVICE;
        }
@@ -638,6 +732,42 @@ int tv_channel_tune(void)
                return -1;
        }
 
+       _tv_channel_add_history(service_id);
+
+       g_tv_info.viewing_locked_channel = -1;
+
+       return 0;
+}
+
+/**
+ * Tunes to previously viewed channel.
+ *
+ * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
+ */
+int tv_channel_tune_prev_channel(void)
+{
+       int service_id;
+       int r;
+
+       if (!g_tv_info.live_svc) {
+               _ERR("failed to get live service");
+               return -1;
+       }
+
+       service_id = _tv_channel_get_history();
+       if (service_id < 1) {
+               _ERR("no previous channel");
+               return -1;
+       }
+
+       r = tv_service_live_tune(g_tv_info.live_svc, service_id);
+       if (r != TVS_ERROR_OK) {
+               _ERR("failed to set service");
+               return -1;
+       }
+
+       _tv_channel_add_history(service_id);
+
        g_tv_info.viewing_locked_channel = -1;
 
        return 0;
@@ -656,6 +786,11 @@ int tv_channel_direct_tune(long major, long minor)
        TvServiceChannel *tvs_data;
        int r;
 
+       if (!g_tv_info.live_svc) {
+               _ERR("failed to get live service");
+               return -1;
+       }
+
        if (major > 0 && major < MAJOR_MAX) {
                filter_node = _tv_channel_get_filter(
                                TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER,
@@ -694,8 +829,7 @@ int tv_channel_direct_tune(long major, long minor)
        if (r == TVS_ERROR_OK)
                g_tv_info.viewing_locked_channel = -1;
 
-       g_list_foreach(tvs_list, (GFunc) g_free, NULL);
-       g_list_free(tvs_list);
+       tv_service_free_channel_list(tvs_list);
 
 free:
        g_list_foreach(filter, (GFunc) _tv_channel_free_filter, NULL);
@@ -727,77 +861,9 @@ int tv_channel_tune_locked_channel(int service_id, char *password)
                return -1;
        }
 
-       g_tv_info.viewing_locked_channel = service_id;
-
-       return 0;
-}
-
-/**
- * Tunes to next channel.
- *
- * Note that deleted channels and service channels will skipped.
- *
- * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
- */
-int tv_channel_next(void)
-{
-       TvServiceAntenna antenna_type;
-       int r;
-
-       if (!g_tv_info.live_svc) {
-               _ERR("failed to get live service");
-               return -1;
-       }
-
-       r = tv_service_live_get_antenna_type(g_tv_info.live_svc, &antenna_type);
-       if (r < 0) {
-               _ERR("failed to get antenna type");
-               return -1;
-       }
-
-       r = tv_service_live_tune_up(g_tv_info.live_svc,
-                       TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG, antenna_type);
-       if (r < 0) {
-               _ERR("failed to tune up");
-               return -1;
-       }
-
-       g_tv_info.viewing_locked_channel = -1;
-
-       return 0;
-}
-
-/**
- * Tunes to previous channel.
- *
- * Note that deleted channels and service channels will skipped.
- *
- * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
- */
-int tv_channel_prev(void)
-{
-       TvServiceAntenna antenna_type;
-       int r;
-
-       if (!g_tv_info.live_svc) {
-               _ERR("failed to get live service");
-               return -1;
-       }
-
-       r = tv_service_live_get_antenna_type(g_tv_info.live_svc, &antenna_type);
-       if (r < 0) {
-               _ERR("failed to get antenna type");
-               return -1;
-       }
-
-       r = tv_service_live_tune_down(g_tv_info.live_svc,
-                       TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG, antenna_type);
-       if (r < 0) {
-               _ERR("failed to tune down");
-               return -1;
-       }
+       _tv_channel_add_history(service_id);
 
-       g_tv_info.viewing_locked_channel = -1;
+       g_tv_info.viewing_locked_channel = service_id;
 
        return 0;
 }
@@ -962,30 +1028,6 @@ void tv_signal_cb_set(void (*cb)(void *data, int is_signal), void *data)
 }
 
 /**
- * Sets window id for tv overlay.
- *
- * @param window_id The window id to overlay
- * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
- */
-int tv_overlay_set(void *window_id)
-{
-       int r;
-
-       if (!g_tv_info.live_svc) {
-               _ERR("failed to get live service");
-               return -1;
-       }
-
-       r = tv_service_live_set_window_overlay(g_tv_info.live_svc, window_id);
-       if (r < 0) {
-               _ERR("failed to set overlay");
-               return -1;
-       }
-
-       return 0;
-}
-
-/**
  * Destory the tv service handles.
  *
  * @return If the operation was sucessful 0 is returned; otherwise negative value is returned
@@ -994,12 +1036,8 @@ int tv_destroy(void)
 {
        int r;
 
-       if (g_tv_info.live_svc) {
-               r = tv_service_live_destroy(g_tv_info.live_svc);
-               if (r != TVS_ERROR_OK)
-                       _ERR("failed to destroy live service");
+       if (g_tv_info.live_svc)
                g_tv_info.live_svc = NULL;
-       }
 
        r = tv_service_channel_info_destroy();
        if (r < 0)
@@ -1043,11 +1081,15 @@ int tv_create(void)
                goto err;
        }
 
+       /*
        r = tv_service_epg_create(&g_tv_info.epg_svc);
        if (r != TVS_ERROR_OK) {
                _ERR("failed to create epg service");
                goto err;
        }
+       */
+
+       memset(&g_tv_info.history, 0, sizeof(g_tv_info.history));
 
        return 0;
 err:
@@ -1062,6 +1104,14 @@ err:
  */
 int tv_pause(void)
 {
+       int r;
+
+       if (g_tv_info.live_svc) {
+               r = tv_service_live_tune_pause(g_tv_info.live_svc);
+               if (r != TVS_ERROR_OK)
+                       _ERR("failed to pause live service");
+       }
+
        return 0;
 }
 
@@ -1081,10 +1131,24 @@ int tv_resume(void)
 {
        int r;
 
-       if (g_tv_info.live_svc)
-               return 0;
+       if (!g_tv_info.live_svc) {
+               r = tv_service_live_create(&g_tv_info.live_svc);
+               if (r != TVS_ERROR_OK) {
+                       _ERR("failed to create live service");
+                       goto err;
+               }
 
-       r = tv_service_live_create(&g_tv_info.live_svc);
+               r = tv_service_live_register_callback(g_tv_info.live_svc,
+                               _tv_service_event_cb, NULL);
+               if (r != TVS_ERROR_OK) {
+                       _ERR("failed to register live callback");
+                       goto err;
+               }
+
+               return 1;
+       }
+
+       r = tv_service_live_tune_resume(g_tv_info.live_svc);
        if (r != TVS_ERROR_OK) {
                _ERR("failed to create live service");
                goto err;
@@ -1097,7 +1161,7 @@ int tv_resume(void)
                goto err;
        }
 
-       return 1;
+       return 0;
 
 err:
        tv_destroy();