Merge "Changes to LPTD_CFG and transmit gain" into lmp-mr1-dev
diff --git a/BoardConfig.mk b/BoardConfig.mk
index 17fe2f4..0bc3a04 100644
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -59,10 +59,9 @@
 BOARD_USES_GENERIC_INVENSENSE := false
 
 # RenderScript
-# OVERRIDE_RS_DRIVER := libnvRSDriver.so
+OVERRIDE_RS_DRIVER := libnvRSDriver.so
 BOARD_OVERRIDE_RS_CPU_VARIANT_32 := cortex-a15
 BOARD_OVERRIDE_RS_CPU_VARIANT_64 := cortex-a57
-# DISABLE_RS_64_BIT_DRIVER := true
 
 # Bluetooth
 BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := device/htc/flounder/bluetooth
diff --git a/audio/hal/audio_hw.c b/audio/hal/audio_hw.c
index 8b7fc20..2557619 100644
--- a/audio/hal/audio_hw.c
+++ b/audio/hal/audio_hw.c
@@ -47,6 +47,8 @@
 
 #include "sound/compress_params.h"
 
+#define MIXER_CTL_COMPRESS_PLAYBACK_VOLUME "Compress Playback Volume"
+
 /* TODO: the following PCM device profiles could be read from a config file */
 struct pcm_device_profile pcm_device_playback_hs = {
     .config = {
@@ -2108,8 +2110,6 @@
 /* must be called iwth out->lock locked */
 static void stop_compressed_output_l(struct stream_out *out)
 {
-    out->offload_state = OFFLOAD_STATE_IDLE;
-    out->playback_started = 0;
     out->send_new_metadata = 1;
     if (out->compr != NULL) {
         compress_stop(out->compr);
@@ -2124,9 +2124,6 @@
     struct stream_out *out = (struct stream_out *) context;
     struct listnode *item;
 
-    out->offload_state = OFFLOAD_STATE_IDLE;
-    out->playback_started = 0;
-
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
     set_sched_policy(0, SP_FOREGROUND);
     prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
@@ -2221,7 +2218,6 @@
 static int destroy_offload_callback_thread(struct stream_out *out)
 {
     pthread_mutex_lock(&out->lock);
-    stop_compressed_output_l(out);
     send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
 
     pthread_mutex_unlock(&out->lock);
@@ -2350,43 +2346,29 @@
     return ret;
 }
 
-static int stop_output_stream(struct stream_out *out)
+static int disable_output_path_l(struct stream_out *out)
 {
-    int i, ret = 0;
-    struct audio_usecase *uc_info;
     struct audio_device *adev = out->dev;
+    struct audio_usecase *uc_info;
 
-    ALOGV("%s: enter: usecase(%d: %s)", __func__,
-          out->usecase, use_case_table[out->usecase]);
     uc_info = get_usecase_from_id(adev, out->usecase);
     if (uc_info == NULL) {
         ALOGE("%s: Could not find the usecase (%d) in the list",
-              __func__, out->usecase);
+             __func__, out->usecase);
         return -EINVAL;
     }
-
-    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
-            adev->offload_fx_stop_output != NULL)
-        adev->offload_fx_stop_output(out->handle);
-
     disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
-
     uc_release_pcm_devices(uc_info);
     list_remove(&uc_info->adev_list_node);
     free(uc_info);
 
-    ALOGV("%s: exit: status(%d)", __func__, ret);
-    return ret;
+    return 0;
 }
 
-int start_output_stream(struct stream_out *out)
+static void enable_output_path_l(struct stream_out *out)
 {
-    int ret = 0;
-    struct audio_usecase *uc_info;
     struct audio_device *adev = out->dev;
-
-    ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
-          __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
+    struct audio_usecase *uc_info;
 
     uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
     uc_info->id = out->usecase;
@@ -2400,6 +2382,42 @@
     list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
 
     select_devices(adev, out->usecase);
+}
+
+static int stop_output_stream(struct stream_out *out)
+{
+    int ret = 0;
+    struct audio_device *adev = out->dev;
+    bool do_disable = true;
+
+    ALOGV("%s: enter: usecase(%d: %s)", __func__,
+          out->usecase, use_case_table[out->usecase]);
+
+    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
+            adev->offload_fx_stop_output != NULL) {
+        adev->offload_fx_stop_output(out->handle);
+
+        if (out->offload_state == OFFLOAD_STATE_PAUSED ||
+                out->offload_state == OFFLOAD_STATE_PAUSED_FLUSHED)
+            do_disable = false;
+        out->offload_state = OFFLOAD_STATE_IDLE;
+    }
+    if (do_disable)
+        ret = disable_output_path_l(out);
+
+    ALOGV("%s: exit: status(%d)", __func__, ret);
+    return ret;
+}
+
+int start_output_stream(struct stream_out *out)
+{
+    int ret = 0;
+    struct audio_device *adev = out->dev;
+
+    ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
+          __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
+
+    enable_output_path_l(out);
 
     if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
         out->compr = NULL;
@@ -2842,15 +2860,37 @@
                           float right)
 {
     struct stream_out *out = (struct stream_out *)stream;
-    int volume[2];
+    struct audio_device *adev = out->dev;
+    int offload_volume[2];//For stereo
 
     if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
         /* only take left channel into account: the API is for stereo anyway */
         out->muted = (left == 0.0f);
         return 0;
     } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
-        (void)right;
-        /* TODO */
+        struct mixer_ctl *ctl;
+        struct mixer *mixer = NULL;
+
+        offload_volume[0] = (int)(left * COMPRESS_PLAYBACK_VOLUME_MAX);
+        offload_volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX);
+
+        mixer = mixer_open(MIXER_CARD);
+        if (!mixer) {
+            ALOGE("%s unable to open the mixer for card %d, aborting.",
+                    __func__, MIXER_CARD);
+            return -EINVAL;
+        }
+        ctl = mixer_get_ctl_by_name(mixer, MIXER_CTL_COMPRESS_PLAYBACK_VOLUME);
+        if (!ctl) {
+            ALOGE("%s: Could not get ctl for mixer cmd - %s",
+                  __func__, MIXER_CTL_COMPRESS_PLAYBACK_VOLUME);
+            mixer_close(mixer);
+            return -EINVAL;
+        }
+        ALOGD("out_set_volume set offload volume (%f, %f)", left, right);
+        mixer_ctl_set_array(ctl, offload_volume,
+                            sizeof(offload_volume)/sizeof(offload_volume[0]));
+        mixer_close(mixer);
         return 0;
     }
 
@@ -2938,6 +2978,14 @@
 
     if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
         ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
+
+        if (out->offload_state == OFFLOAD_STATE_PAUSED_FLUSHED) {
+            ALOGV("start offload write from pause state");
+            pthread_mutex_lock(&adev->lock);
+            enable_output_path_l(out);
+            pthread_mutex_unlock(&adev->lock);
+        }
+
         if (out->send_new_metadata) {
             ALOGVV("send new gapless metadata");
             compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
@@ -2949,9 +2997,8 @@
         if (ret >= 0 && ret < (ssize_t)bytes) {
             send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
         }
-        if (!out->playback_started) {
+        if (out->offload_state != OFFLOAD_STATE_PLAYING) {
             compress_start(out->compr);
-            out->playback_started = 1;
             out->offload_state = OFFLOAD_STATE_PLAYING;
         }
         pthread_mutex_unlock(&out->lock);
@@ -3243,6 +3290,9 @@
         if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
             status = compress_pause(out->compr);
             out->offload_state = OFFLOAD_STATE_PAUSED;
+            pthread_mutex_lock(&out->dev->lock);
+            status = disable_output_path_l(out);
+            pthread_mutex_unlock(&out->dev->lock);
         }
         pthread_mutex_unlock(&out->lock);
     }
@@ -3258,6 +3308,9 @@
         status = 0;
         pthread_mutex_lock(&out->lock);
         if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
+            pthread_mutex_lock(&out->dev->lock);
+            enable_output_path_l(out);
+            pthread_mutex_unlock(&out->dev->lock);
             status = compress_resume(out->compr);
             out->offload_state = OFFLOAD_STATE_PLAYING;
         }
@@ -3288,7 +3341,15 @@
     ALOGV("%s", __func__);
     if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
         pthread_mutex_lock(&out->lock);
-        stop_compressed_output_l(out);
+        if (out->offload_state == OFFLOAD_STATE_PLAYING) {
+            ALOGE("out_flush() called in wrong state %d", out->offload_state);
+            pthread_mutex_unlock(&out->lock);
+            return -ENOSYS;
+        }
+        if (out->offload_state == OFFLOAD_STATE_PAUSED) {
+            stop_compressed_output_l(out);
+            out->offload_state = OFFLOAD_STATE_PAUSED_FLUSHED;
+        }
         pthread_mutex_unlock(&out->lock);
         return 0;
     }
@@ -3796,8 +3857,7 @@
                 get_snd_codec_id(config->offload_info.format);
         out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
         out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
-        out->compr_config.codec->sample_rate =
-                    compress_get_alsa_rate(config->offload_info.sample_rate);
+        out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
         out->compr_config.codec->bit_rate =
                     config->offload_info.bit_rate;
         out->compr_config.codec->ch_in =
@@ -3809,6 +3869,8 @@
 
         out->send_new_metadata = 1;
         create_offload_callback_thread(out);
+        out->offload_state = OFFLOAD_STATE_IDLE;
+
         ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
                 __func__, config->offload_info.version,
                 config->offload_info.bit_rate);
diff --git a/audio/hal/audio_hw.h b/audio/hal/audio_hw.h
index 63a0c1d..15ed4bd 100644
--- a/audio/hal/audio_hw.h
+++ b/audio/hal/audio_hw.h
@@ -173,7 +173,7 @@
 #define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
 /* ToDo: Check and update a proper value in msec */
 #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
-#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
+#define COMPRESS_PLAYBACK_VOLUME_MAX 0x10000 //NV suggested value
 
 #define DEEP_BUFFER_OUTPUT_SAMPLING_RATE 48000
 #define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 480
@@ -225,6 +225,7 @@
     OFFLOAD_STATE_IDLE,
     OFFLOAD_STATE_PLAYING,
     OFFLOAD_STATE_PAUSED,
+    OFFLOAD_STATE_PAUSED_FLUSHED,
 };
 
 typedef enum {
@@ -283,7 +284,6 @@
     audio_io_handle_t           handle;
 
     int                         non_blocking;
-    int                         playback_started;
     int                         offload_state;
     pthread_cond_t              offload_cond;
     pthread_t                   offload_thread;
diff --git a/device.mk b/device.mk
index 580dbc6..5302b93 100644
--- a/device.mk
+++ b/device.mk
@@ -23,7 +23,7 @@
 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)
 LOCAL_KERNEL := device/htc/flounder_svelte-kernel/Image.gz-dtb
-else 
+else
 LOCAL_KERNEL := device/htc/flounder-kernel/Image.gz-dtb
 endif # USE_SVELTE_KERNEL
 else
@@ -81,6 +81,8 @@
     frameworks/native/data/etc/android.hardware.camera.xml:system/etc/permissions/android.hardware.camera.xml \
     frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
     frameworks/native/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \
+    frameworks/native/data/etc/android.hardware.camera.manual_sensor.xml:system/etc/permissions/android.hardware.camera.manual_sensor.xml \
+    frameworks/native/data/etc/android.hardware.camera.burst_capture.xml:system/etc/permissions/android.hardware.camera.burst_capture.xml \
     frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \
     frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
     frameworks/native/data/etc/android.hardware.location.gps.xml:system/etc/permissions/android.hardware.location.gps.xml \
diff --git a/gps/qct/lib64/libloc_api_v02.so b/gps/qct/lib64/libloc_api_v02.so
index 7152529..853c600 100644
--- a/gps/qct/lib64/libloc_api_v02.so
+++ b/gps/qct/lib64/libloc_api_v02.so
Binary files differ
diff --git a/gps/qct/libloc_api_v02.so b/gps/qct/libloc_api_v02.so
index d7ceb09..c595413 100644
--- a/gps/qct/libloc_api_v02.so
+++ b/gps/qct/libloc_api_v02.so
Binary files differ
diff --git a/lte_only_overlay/packages/apps/Settings/res/drawable/regulatory_info.png b/lte_only_overlay/packages/apps/Settings/res/drawable/regulatory_info.png
index 05a35d1..e282685 100755
--- a/lte_only_overlay/packages/apps/Settings/res/drawable/regulatory_info.png
+++ b/lte_only_overlay/packages/apps/Settings/res/drawable/regulatory_info.png
Binary files differ
diff --git a/overlay/packages/apps/Settings/res/drawable/regulatory_info.png b/overlay/packages/apps/Settings/res/drawable/regulatory_info.png
index 1d54cb1..22782b2 100755
--- a/overlay/packages/apps/Settings/res/drawable/regulatory_info.png
+++ b/overlay/packages/apps/Settings/res/drawable/regulatory_info.png
Binary files differ