Merge "Add USB audio HAL to the build" into jb-dev
diff --git a/include/sec_lcd.h b/include/sec_lcd.h
index b5451b7..b829f0e 100755
--- a/include/sec_lcd.h
+++ b/include/sec_lcd.h
@@ -33,7 +33,7 @@
 
 #define FBIO_WAITFORVSYNC       _IO  ('F', 32)
 #define SECFB_WIN_POSITION      _IOW ('F', 203, struct secfb_user_window)
-
+#define S3CFB_SET_VSYNC_ACTIVE  _IOW ('F', 208, uint32_t)
 
 #define DEFAULT_LCD_WIDTH   (480)
 #define DEFAULT_LCD_HEIGHT  (800)
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index f484dfd..72c7b59 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -21,7 +21,7 @@
 include $(CLEAR_VARS)
 LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libGLESv1_CM libhardware
+LOCAL_SHARED_LIBRARIES := liblog libcutils libEGL libGLESv1_CM libhardware libhardware_legacy
 LOCAL_CFLAGS += -DLOG_TAG=\"hwcomposer\"
 
 LOCAL_C_INCLUDES := \
diff --git a/libhwcomposer/SecHWC.cpp b/libhwcomposer/SecHWC.cpp
index e63558b..14e4f9b 100644
--- a/libhwcomposer/SecHWC.cpp
+++ b/libhwcomposer/SecHWC.cpp
@@ -23,10 +23,12 @@
  *
  */
 
+#include <sys/resource.h>
 #include <cutils/log.h>
 #include <cutils/atomic.h>
 #include <EGL/egl.h>
 #include <GLES/gl.h>
+#include <hardware_legacy/uevent.h>
 #include "SecHWCUtils.h"
 
 static IMG_gralloc_module_public_t *gpsGrallocModule;
@@ -41,8 +43,8 @@
 hwc_module_t HAL_MODULE_INFO_SYM = {
     common: {
         tag: HARDWARE_MODULE_TAG,
-        version_major: 1,
-        version_minor: 0,
+        module_api_version: HWC_MODULE_API_VERSION_0_1,
+        hal_api_version: HARDWARE_HAL_API_VERSION,
         id: HWC_HARDWARE_MODULE_ID,
         name: "Samsung S5PC11X hwcomposer module",
         author: "SAMSUNG",
@@ -292,7 +294,6 @@
     struct sec_rect src_rect;
     struct sec_rect dst_rect;
 
-
     if (dpy == NULL && sur == NULL && list == NULL) {
         // release our resources, the screen is turning off
         // in our case, there is nothing to do.
@@ -424,6 +425,94 @@
     return 0;
 }
 
+static void hwc_registerProcs(struct hwc_composer_device* dev,
+        hwc_procs_t const* procs)
+{
+    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+    ctx->procs = const_cast<hwc_procs_t *>(procs);
+}
+
+static int hwc_query(struct hwc_composer_device* dev,
+        int what, int* value)
+{
+    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+
+    switch (what) {
+    case HWC_BACKGROUND_LAYER_SUPPORTED:
+        // we don't support the background layer yet
+        value[0] = 0;
+        break;
+    case HWC_VSYNC_PERIOD:
+        // vsync period in nanosecond
+        value[0] = 1000000000.0 / gpsGrallocModule->psFrameBufferDevice->base.fps;
+        break;
+    default:
+        // unsupported query
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int hwc_eventControl(struct hwc_composer_device* dev,
+        int event, int enabled)
+{
+    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
+
+    switch (event) {
+    case HWC_EVENT_VSYNC:
+        int val = !!enabled;
+        int err = ioctl(ctx->global_lcd_win.fd, S3CFB_SET_VSYNC_ACTIVE, &val);
+        if (err < 0)
+            return -errno;
+
+        return 0;
+    }
+
+    return -EINVAL;
+}
+
+void handle_vsync_uevent(hwc_context_t *ctx, const char *buff, int len)
+{
+    uint64_t timestamp = 0;
+    const char *s = buff;
+
+    if(!ctx->procs || !ctx->procs->vsync)
+       return;
+
+    s += strlen(s) + 1;
+
+    while(*s) {
+        if (!strncmp(s, "VSYNC=", strlen("VSYNC=")))
+            timestamp = strtoull(s + strlen("VSYNC="), NULL, 0);
+
+        s += strlen(s) + 1;
+        if (s - buff >= len)
+            break;
+    }
+
+    ctx->procs->vsync(ctx->procs, 0, timestamp);
+}
+
+static void *hwc_vsync_thread(void *data)
+{
+    hwc_context_t *ctx = (hwc_context_t *)(data);
+    char uevent_desc[4096];
+    memset(uevent_desc, 0, sizeof(uevent_desc));
+
+    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+    uevent_init();
+    while(true) {
+        int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
+
+        bool vsync = !strcmp(uevent_desc, "change@/devices/platform/s3cfb");
+        if(vsync)
+            handle_vsync_uevent(ctx, uevent_desc, len);
+    }
+
+    return NULL;
+}
+
 static int hwc_device_close(struct hw_device_t *dev)
 {
     struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
@@ -436,6 +525,11 @@
             ret = -1;
         }
 
+        if (window_close(&ctx->global_lcd_win) < 0) {
+            ALOGE("%s::window_close() fail", __func__);
+            ret = -1;
+        }
+
         for (i = 0; i < NUM_OF_WIN; i++) {
             if (window_close(&ctx->win[i]) < 0) {
                 ALOGE("%s::window_close() fail", __func__);
@@ -443,15 +537,22 @@
             }
         }
 
+        // TODO: stop vsync_thread
+
         free(ctx);
     }
     return ret;
 }
 
+static const struct hwc_methods hwc_methods = {
+    eventControl: hwc_eventControl
+};
+
 static int hwc_device_open(const struct hw_module_t* module, const char* name,
         struct hw_device_t** device)
 {
     int status = 0;
+    int err;
     struct hwc_win_info_t *win;
 
     if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
@@ -472,18 +573,21 @@
 
     /* initialize the procs */
     dev->device.common.tag = HARDWARE_DEVICE_TAG;
-    dev->device.common.version = 0;
+    dev->device.common.version = HWC_DEVICE_API_VERSION_0_3;
     dev->device.common.module = const_cast<hw_module_t*>(module);
     dev->device.common.close = hwc_device_close;
 
     dev->device.prepare = hwc_prepare;
     dev->device.set = hwc_set;
+    dev->device.registerProcs = hwc_registerProcs;
+    dev->device.query = hwc_query;
+    dev->device.methods = &hwc_methods;
 
     *device = &dev->device.common;
 
     /* initializing */
     memset(&(dev->fimc), 0, sizeof(s5p_fimc_t));
-	dev->fimc.dev_fd = -1;
+    dev->fimc.dev_fd = -1;
 
     /* open WIN0 & WIN1 here */
     for (int i = 0; i < NUM_OF_WIN; i++) {
@@ -494,10 +598,17 @@
         }
     }
 
+    /* open window 2, used to query global LCD info */
+    if (window_open(&dev->global_lcd_win, 2) < 0) {
+        ALOGE("%s:: Failed to open window 2 device ", __func__);
+        status = -EINVAL;
+        goto err;
+    }
+
     /* get default window config */
-    if (window_get_global_lcd_info(&dev->lcd_info) < 0) {
+    if (window_get_global_lcd_info(dev) < 0) {
         ALOGE("%s::window_get_global_lcd_info is failed : %s",
-				__func__, strerror(errno));
+                __func__, strerror(errno));
         status = -EINVAL;
         goto err;
     }
@@ -517,14 +628,14 @@
 
         if (window_set_pos(win) < 0) {
             ALOGE("%s::window_set_pos is failed : %s",
-					__func__, strerror(errno));
+                    __func__, strerror(errno));
             status = -EINVAL;
             goto err;
         }
 
         if (window_get_info(win) < 0) {
             ALOGE("%s::window_get_info is failed : %s",
-					__func__, strerror(errno));
+                    __func__, strerror(errno));
             status = -EINVAL;
             goto err;
         }
@@ -550,6 +661,13 @@
         goto err;
     }
 
+    err = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
+    if (err) {
+        ALOGE("%s::pthread_create() failed : %s", __func__, strerror(err));
+        status = -err;
+        goto err;
+    }
+
     ALOGD("%s:: success\n", __func__);
 
     return 0;
@@ -558,6 +676,9 @@
     if (destroyFimc(&dev->fimc) < 0)
         ALOGE("%s::destroyFimc() fail", __func__);
 
+    if (window_close(&dev->global_lcd_win) < 0)
+        ALOGE("%s::window_close() fail", __func__);
+
     for (int i = 0; i < NUM_OF_WIN; i++) {
         if (window_close(&dev->win[i]) < 0)
             ALOGE("%s::window_close() fail", __func__);
diff --git a/libhwcomposer/SecHWCUtils.cpp b/libhwcomposer/SecHWCUtils.cpp
index e933985..2b3f09f 100644
--- a/libhwcomposer/SecHWCUtils.cpp
+++ b/libhwcomposer/SecHWCUtils.cpp
@@ -166,40 +166,30 @@
     return 0;
 }
 
-int window_get_global_lcd_info(struct fb_var_screeninfo *lcd_info)
+int window_get_global_lcd_info(struct hwc_context_t *ctx)
 {
     struct hwc_win_info_t win;
     int ret = 0;
 
-    if (window_open(&win, 2)  < 0) {
-        ALOGE("%s:: Failed to open window 2 device ", __func__);
+    if (ioctl(ctx->global_lcd_win.fd, FBIOGET_VSCREENINFO, &ctx->lcd_info) < 0) {
+        ALOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
         return -1;
     }
 
-    if (ioctl(win.fd, FBIOGET_VSCREENINFO, lcd_info) < 0) {
-        ALOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
-        ret = -1;
-        goto fun_err;
+    if (ctx->lcd_info.xres == 0) {
+        ctx->lcd_info.xres = DEFAULT_LCD_WIDTH;
+        ctx->lcd_info.xres_virtual = DEFAULT_LCD_WIDTH;
     }
 
-    if (lcd_info->xres == 0) {
-        lcd_info->xres = DEFAULT_LCD_WIDTH;
-        lcd_info->xres_virtual = DEFAULT_LCD_WIDTH;
+    if (ctx->lcd_info.yres == 0) {
+        ctx->lcd_info.yres = DEFAULT_LCD_HEIGHT;
+        ctx->lcd_info.yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
     }
 
-    if (lcd_info->yres == 0) {
-        lcd_info->yres = DEFAULT_LCD_HEIGHT;
-        lcd_info->yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
-    }
+    if (ctx->lcd_info.bits_per_pixel == 0)
+        ctx->lcd_info.bits_per_pixel = DEFAULT_LCD_BPP;
 
-    if (lcd_info->bits_per_pixel == 0)
-        lcd_info->bits_per_pixel = DEFAULT_LCD_BPP;
-
-fun_err:
-    if (window_close(&win) < 0)
-        ALOGE("%s::window2 close fail", __func__);   
-
-    return ret;
+    return 0;
 }
 
 int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
diff --git a/libhwcomposer/SecHWCUtils.h b/libhwcomposer/SecHWCUtils.h
index 21d6598..d59c120 100644
--- a/libhwcomposer/SecHWCUtils.h
+++ b/libhwcomposer/SecHWCUtils.h
@@ -113,8 +113,11 @@
 
     /* our private state goes below here */
     struct hwc_win_info_t     win[NUM_OF_WIN];
+    struct hwc_win_info_t     global_lcd_win;
     struct fb_var_screeninfo  lcd_info;
     s5p_fimc_t                fimc;
+    hwc_procs_t               *procs;
+    pthread_t                 vsync_thread;
     unsigned int              num_of_fb_layer;
     unsigned int              num_of_hwc_layer;
     unsigned int              num_of_fb_layer_prev;
@@ -127,7 +130,7 @@
 int window_pan_display(struct hwc_win_info_t *win);
 int window_show(struct hwc_win_info_t *win);
 int window_hide(struct hwc_win_info_t *win);
-int window_get_global_lcd_info(struct fb_var_screeninfo *lcd_info);
+int window_get_global_lcd_info(struct hwc_context_t *ctx);
 
 int createFimc(s5p_fimc_t *fimc);
 int destroyFimc(s5p_fimc_t *fimc);
diff --git a/media_profiles.xml b/media_profiles.xml
index 7483267..5d9d364 100644
--- a/media_profiles.xml
+++ b/media_profiles.xml
@@ -56,7 +56,7 @@
 <!ATTLIST VideoEncoderCap minFrameRate CDATA #REQUIRED>
 <!ATTLIST VideoEncoderCap maxFrameRate CDATA #REQUIRED>
 <!ELEMENT AudioEncoderCap EMPTY>
-<!ATTLIST AudioEncoderCap name (amrnb|amrwb|aac|wma) #REQUIRED>
+<!ATTLIST AudioEncoderCap name (amrnb|amrwb|aac|aaceld|wma) #REQUIRED>
 <!ATTLIST AudioEncoderCap enabled (true|false) #REQUIRED>
 <!ATTLIST AudioEncoderCap minBitRate CDATA #REQUIRED>
 <!ATTLIST AudioEncoderCap maxBitRate CDATA #REQUIRED>
@@ -241,10 +241,15 @@
         minFrameRate="15" maxFrameRate="30" />
 
     <AudioEncoderCap name="aac" enabled="true"
-        minBitRate="8192" maxBitRate="96000"
+        minBitRate="8192" maxBitRate="128000"
         minSampleRate="8000" maxSampleRate="16000"
         minChannels="1" maxChannels="1" />
 
+    <AudioEncoderCap name="aaceld" enabled="true"
+        minBitRate="8000" maxBitRate="384000"
+        minSampleRate="8000" maxSampleRate="48000"
+        minChannels="1" maxChannels="1" />
+
     <AudioEncoderCap name="amrwb" enabled="true"
         minBitRate="6600" maxBitRate="23050"
         minSampleRate="16000" maxSampleRate="16000"