Merge "Tunneled Video Playback support" into lmp-dev
diff --git a/adb/adb.c b/adb/adb.c
index 2c7793d..10a1e0d 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -1670,11 +1670,6 @@
         /* we don't even need to send a reply */
         return 0;
     }
-#endif // ADB_HOST
-
-    int ret = handle_forward_request(service, ttype, serial, reply_fd);
-    if (ret >= 0)
-      return ret - 1;
 
     if(!strncmp(service,"get-state",strlen("get-state"))) {
         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
@@ -1682,6 +1677,11 @@
         send_msg_with_okay(reply_fd, state, strlen(state));
         return 0;
     }
+#endif // ADB_HOST
+
+    int ret = handle_forward_request(service, ttype, serial, reply_fd);
+    if (ret >= 0)
+      return ret - 1;
     return -1;
 }
 
diff --git a/adb/commandline.c b/adb/commandline.c
index e1ff856..b268ca5 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -675,7 +675,12 @@
     }
 }
 
-/** Duplicate and escape given argument. */
+static int should_escape(const char c)
+{
+    return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
+}
+
+/* Duplicate and escape given argument. */
 static char *escape_arg(const char *s)
 {
     const char *ts;
@@ -686,7 +691,7 @@
     alloc_len = 0;
     for (ts = s; *ts != '\0'; ts++) {
         alloc_len++;
-        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
+        if (should_escape(*ts)) {
             alloc_len++;
         }
     }
@@ -704,7 +709,7 @@
     dest = ret;
 
     for (ts = s; *ts != '\0'; ts++) {
-        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
+        if (should_escape(*ts)) {
             *dest++ = '\\';
         }
         *dest++ = *ts;
@@ -1741,9 +1746,10 @@
     return 1;
 }
 
+#define MAX_ARGV_LENGTH 16
 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
 {
-    char *argv[16];
+    char *argv[MAX_ARGV_LENGTH];
     int argc;
     va_list ap;
 
@@ -1760,7 +1766,9 @@
     }
 
     argv[argc++] = cmd;
-    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
+    while(argc < MAX_ARGV_LENGTH &&
+        (argv[argc] = va_arg(ap, char*)) != 0) argc++;
+    assert(argc < MAX_ARGV_LENGTH);
     va_end(ap);
 
 #if 0
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index c717f09..4ed23a8 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -41,7 +41,10 @@
 
 class BacktraceMap {
 public:
-  static BacktraceMap* Create(pid_t pid);
+  // If uncached is true, then parse the current process map as of the call.
+  // Passing a map created with uncached set to true to Backtrace::Create()
+  // is unsupported.
+  static BacktraceMap* Create(pid_t pid, bool uncached = false);
 
   virtual ~BacktraceMap();
 
diff --git a/include/system/audio.h b/include/system/audio.h
index 719a7c4..1c70240 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -110,7 +110,8 @@
     AUDIO_FLAG_AUDIBILITY_ENFORCED = 0x1,
     AUDIO_FLAG_SECURE              = 0x2,
     AUDIO_FLAG_SCO                 = 0x4,
-    AUDIO_FLAG_BEACON              = 0x8
+    AUDIO_FLAG_BEACON              = 0x8,
+    AUDIO_FLAG_HW_AV_SYNC          = 0x10
 };
 
 /* Do not change these values without updating their counterparts
@@ -696,7 +697,8 @@
     AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8, // use deep audio buffers
     AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10,  // offload playback of compressed
                                                 // streams to hardware codec
-    AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20 // use non-blocking write
+    AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20, // use non-blocking write
+    AUDIO_OUTPUT_FLAG_HW_AV_SYNC = 0x40 // output uses a hardware A/V synchronization source
 } audio_output_flags_t;
 
 /* The audio input flags are analogous to audio output flags.
@@ -997,6 +999,13 @@
 };
 
 
+
+/* a HW synchronization source returned by the audio HAL */
+typedef uint32_t audio_hw_sync_t;
+
+/* an invalid HW synchronization source indicating an error */
+#define AUDIO_HW_SYNC_INVALID 0
+
 static inline bool audio_is_output_device(audio_devices_t device)
 {
     if (((device & AUDIO_DEVICE_BIT_IN) == 0) &&
diff --git a/include/system/sound_trigger.h b/include/system/sound_trigger.h
index dcca34d..773e4f7 100644
--- a/include/system/sound_trigger.h
+++ b/include/system/sound_trigger.h
@@ -26,11 +26,16 @@
 #define SOUND_TRIGGER_MAX_USERS 10      /* max number of concurrent users */
 #define SOUND_TRIGGER_MAX_PHRASES 10    /* max number of concurrent phrases */
 
+typedef enum {
+    SOUND_TRIGGER_STATE_NO_INIT = -1,   /* The sound trigger service is not initialized */
+    SOUND_TRIGGER_STATE_ENABLED = 0,    /* The sound trigger service is enabled */
+    SOUND_TRIGGER_STATE_DISABLED = 1    /* The sound trigger service is disabled */
+} sound_trigger_service_state_t;
+
 #define RECOGNITION_MODE_VOICE_TRIGGER 0x1       /* simple voice trigger */
 #define RECOGNITION_MODE_USER_IDENTIFICATION 0x2 /* trigger only if one user in model identified */
 #define RECOGNITION_MODE_USER_AUTHENTICATION 0x4 /* trigger only if one user in mode
                                                     authenticated */
-
 #define RECOGNITION_STATUS_SUCCESS 0
 #define RECOGNITION_STATUS_ABORT 1
 #define RECOGNITION_STATUS_FAILURE 2
@@ -42,7 +47,6 @@
     SOUND_MODEL_TYPE_KEYPHRASE = 0    /* use for key phrase sound models */
 } sound_trigger_sound_model_type_t;
 
-
 typedef struct sound_trigger_uuid_s {
     unsigned int   timeLow;
     unsigned short timeMid;
@@ -73,6 +77,7 @@
                                                    capture_transition is true*/
     bool                 concurrent_capture;    /* supports capture by other use cases while
                                                    detection is active */
+    bool                 trigger_in_event;      /* returns the trigger capture in event */
     unsigned int         power_consumption_mw;  /* Rated power consumption when detection is active
                                                    with TDB silence/sound/speech ratio */
 };
@@ -144,9 +149,14 @@
                                                            for capture. A negative value is possible
                                                            (e.g. if key phrase is also available for
                                                            capture */
-    int                              capture_preamble_ms;  /* duration in ms of audio captured
+    int                              capture_preamble_ms; /* duration in ms of audio captured
                                                             before the start of the trigger.
                                                             0 if none. */
+    bool                             trigger_in_data; /* the opaque data is the capture of
+                                                            the trigger sound */
+    audio_config_t                   audio_config;        /* audio format of either the trigger in
+                                                             event data or to use for capture of the
+                                                             rest of the utterance */
     unsigned int                     data_size;         /* size of opaque event data */
     unsigned int                     data_offset;       /* offset of opaque data start from start of
                                                           this struct (e.g sizeof struct
@@ -169,16 +179,13 @@
 struct sound_trigger_phrase_recognition_extra {
     unsigned int id;                /* keyphrase ID */
     unsigned int recognition_modes; /* recognition modes used for this keyphrase */
+    unsigned int confidence_level;  /* confidence level for mode RECOGNITION_MODE_VOICE_TRIGGER */
     unsigned int num_levels;        /* number of user confidence levels */
     struct sound_trigger_confidence_level levels[SOUND_TRIGGER_MAX_USERS];
 };
 
 struct sound_trigger_phrase_recognition_event {
     struct sound_trigger_recognition_event common;
-    bool                                   key_phrase_in_capture; /* true if the key phrase is
-                                                                     present in audio data available
-                                                                     for capture after recognition
-                                                                     event is fired */
     unsigned int                           num_phrases;
     struct sound_trigger_phrase_recognition_extra phrase_extras[SOUND_TRIGGER_MAX_PHRASES];
 };
@@ -204,10 +211,11 @@
  * Event sent via load sound model callback
  */
 struct sound_trigger_model_event {
-    int             status;         /* sound model status e.g. SOUND_MODEL_STATUS_UPDATED */
-    unsigned int    data_size;      /* size of event data if any. Size of updated sound model if
+    int                  status;      /* sound model status e.g. SOUND_MODEL_STATUS_UPDATED */
+    sound_model_handle_t model;       /* loaded sound model that triggered the event */
+    unsigned int         data_size;   /* size of event data if any. Size of updated sound model if
                                        status is SOUND_MODEL_STATUS_UPDATED */
-    unsigned int    data_offset;    /* offset of data start from start of this struct
+    unsigned int         data_offset; /* offset of data start from start of this struct
                                        (e.g sizeof struct sound_trigger_model_event) */
 };
 
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index 0056f4b..f38e484 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -137,7 +137,7 @@
 #if defined(__APPLE__)
 // Corkscrew and libunwind don't compile on the mac, so create a generic
 // map object.
-BacktraceMap* BacktraceMap::Create(pid_t pid) {
+BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
   BacktraceMap* map = new BacktraceMap(pid);
   if (!map->Build()) {
     delete map;
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 4f9831b..387d768 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -130,9 +130,13 @@
 //-------------------------------------------------------------------------
 // BacktraceMap create function.
 //-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::Create(pid_t pid) {
+BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
   BacktraceMap* map;
-  if (pid == getpid()) {
+
+  if (uncached) {
+    // Force use of the base class to parse the maps when this call is made.
+    map = new BacktraceMap(pid);
+  } else if (pid == getpid()) {
     map = new UnwindMapLocal();
   } else {
     map = new UnwindMap(pid);
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index e7e3ec2..c6dc174 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -33,7 +33,6 @@
         , mRelease(false)
         , mError(false)
         , threadRunning(false)
-        , threadTriggered(true)
         , mReader(reader)
         , mLogMask(logMask)
         , mPid(pid)
@@ -45,7 +44,9 @@
         , mStart(start)
         , mNonBlock(nonBlock)
         , mEnd(CLOCK_MONOTONIC)
-{ }
+{
+        pthread_cond_init(&threadTriggeredCondition, NULL);
+}
 
 void LogTimeEntry::startReader_Locked(void) {
     pthread_attr_t attr;
@@ -74,7 +75,6 @@
 
     lock();
 
-    me->threadRunning = false;
     if (me->mNonBlock) {
         me->error_Locked();
     }
@@ -103,6 +103,7 @@
         client->decRef();
     }
 
+    me->threadRunning = false;
     me->decRef_Locked();
 
     unlock();
@@ -119,6 +120,7 @@
     if (!client) {
         me->error();
         pthread_exit(NULL);
+        // NOTREACH
     }
 
     LogBuffer &logbuf = me->mReader.logbuf();
@@ -127,12 +129,7 @@
 
     lock();
 
-    me->threadTriggered = true;
-
-    while(me->threadTriggered && !me->isError_Locked()) {
-
-        me->threadTriggered = false;
-
+    while (me->threadRunning && !me->isError_Locked()) {
         log_time start = me->mStart;
 
         unlock();
@@ -142,24 +139,24 @@
         }
         start = logbuf.flushTo(client, start, privileged, FilterSecondPass, me);
 
+        lock();
+
         if (start == LogBufferElement::FLUSH_ERROR) {
-            me->error();
+            me->error_Locked();
         }
 
-        if (me->mNonBlock) {
-            lock();
+        if (me->mNonBlock || !me->threadRunning || me->isError_Locked()) {
             break;
         }
 
-        sched_yield();
-
-        lock();
+        pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
     }
 
     unlock();
 
     pthread_exit(NULL);
 
+    // NOTREACH
     pthread_cleanup_pop(true);
 
     return NULL;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index beaf646..0bfa7a2 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -31,7 +31,7 @@
     bool mRelease;
     bool mError;
     bool threadRunning;
-    bool threadTriggered;
+    pthread_cond_t threadTriggeredCondition;
     pthread_t mThread;
     LogReader &mReader;
     static void *threadStart(void *me);
@@ -63,12 +63,16 @@
     bool runningReader_Locked(void) const {
         return threadRunning || mRelease || mError || mNonBlock;
     }
-    void triggerReader_Locked(void) { threadTriggered = true; }
+    void triggerReader_Locked(void) {
+        pthread_cond_signal(&threadTriggeredCondition);
+    }
+
     void triggerSkip_Locked(unsigned int skip) { skipAhead = skip; }
 
     // Called after LogTimeEntry removed from list, lock implicitly held
     void release_Locked(void) {
         mRelease = true;
+        pthread_cond_signal(&threadTriggeredCondition);
         if (mRefCount || threadRunning) {
             return;
         }
@@ -78,7 +82,7 @@
 
     // Called to mark socket in jeopardy
     void error_Locked(void) { mError = true; }
-    void error(void) { lock(); mError = true; unlock(); }
+    void error(void) { lock(); error_Locked(); unlock(); }
 
     bool isError_Locked(void) const { return mRelease || mError; }