Merge changes from topic "remove-dep"

* changes:
  Remove libmedia and libstagefright dependency from extractors
  Clean move of files to keep the git history
  Sort shared libs in Android.bp for extractors
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index eba6d1a..bced72a 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1721,6 +1721,9 @@
                     // ratio. Use compression ratio of 1.
                     max_size = width * height * 3 / 2;
                 }
+                // HACK: allow 10% overhead
+                // TODO: read sample size from traf atom for fragmented MPEG4.
+                max_size += max_size / 10;
                 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size);
             }
 
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
index 37b010d..4120f7f 100644
--- a/media/libaaudio/tests/Android.mk
+++ b/media/libaaudio/tests/Android.mk
@@ -80,3 +80,13 @@
 LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
 LOCAL_MODULE := test_n_streams
 include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := \
+    $(call include-path-for, audio-utils) \
+    frameworks/av/media/libaaudio/include \
+    frameworks/av/media/libaaudio/src
+LOCAL_SRC_FILES:= test_bad_disconnect.cpp
+LOCAL_SHARED_LIBRARIES := libaaudio libbinder libcutils libutils
+LOCAL_MODULE := test_bad_disconnect
+include $(BUILD_NATIVE_TEST)
diff --git a/media/libaaudio/tests/test_bad_disconnect.cpp b/media/libaaudio/tests/test_bad_disconnect.cpp
new file mode 100644
index 0000000..aa00ec9
--- /dev/null
+++ b/media/libaaudio/tests/test_bad_disconnect.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Handle a DISCONNECT by only opening and starting a new stream
+ * without stopping and closing the old one.
+ * This caused the new stream to use the old disconnected device.
+ */
+
+#include <stdio.h>
+#include <thread>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+
+#define DEFAULT_TIMEOUT_NANOS  ((int64_t)1000000000)
+
+static void s_myErrorCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        aaudio_result_t error);
+
+struct AudioEngine {
+    AAudioStreamBuilder *builder = nullptr;
+    AAudioStream *stream = nullptr;
+    std::thread *thread = nullptr;
+    int64_t framesRead = 0;
+};
+
+AudioEngine s_AudioEngine;
+
+// Callback function that fills the audio output buffer.
+static aaudio_data_callback_result_t s_myDataCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        void *audioData,
+        int32_t numFrames
+) {
+    stream;
+    (void) userData;
+    (void) audioData;
+    (void) numFrames;
+    s_AudioEngine.framesRead = AAudioStream_getFramesRead(stream);
+    return AAUDIO_CALLBACK_RESULT_CONTINUE;
+}
+
+static aaudio_result_t s_StartAudio() {
+    int32_t framesPerBurst = 0;
+    int32_t deviceId = 0;
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    aaudio_result_t result = AAudio_createStreamBuilder(&s_AudioEngine.builder);
+    if (result != AAUDIO_OK) {
+        printf("AAudio_createStreamBuilder returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    // Request stream properties.
+    AAudioStreamBuilder_setFormat(s_AudioEngine.builder, AAUDIO_FORMAT_PCM_FLOAT);
+    AAudioStreamBuilder_setPerformanceMode(s_AudioEngine.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+    AAudioStreamBuilder_setDataCallback(s_AudioEngine.builder, s_myDataCallbackProc, nullptr);
+    AAudioStreamBuilder_setErrorCallback(s_AudioEngine.builder, s_myErrorCallbackProc, nullptr);
+
+    // Create an AAudioStream using the Builder.
+    result = AAudioStreamBuilder_openStream(s_AudioEngine.builder, &s_AudioEngine.stream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStreamBuilder_openStream returned %s",
+               AAudio_convertResultToText(result));
+        return result;
+    }
+
+    result = AAudioStream_requestStart(s_AudioEngine.stream);
+    if (result != AAUDIO_OK) {
+        printf("AAudioStream_requestStart returned %s",
+               AAudio_convertResultToText(result));
+    }
+
+    // Check to see what kind of stream we actually got.
+    deviceId = AAudioStream_getDeviceId(s_AudioEngine.stream);
+    framesPerBurst = AAudioStream_getFramesPerBurst(s_AudioEngine.stream);
+
+    printf("-------- started: deviceId = %3d, framesPerBurst = %3d\n", deviceId, framesPerBurst);
+
+    return result;
+}
+
+static aaudio_result_t s_StopAudio() {
+    aaudio_result_t result = AAUDIO_OK;
+    if (s_AudioEngine.stream != nullptr) {
+        result = AAudioStream_requestStop(s_AudioEngine.stream);
+        if (result != AAUDIO_OK) {
+            printf("AAudioStream_requestStop returned %s\n",
+                   AAudio_convertResultToText(result));
+        }
+        result = AAudioStream_close(s_AudioEngine.stream);
+        if (result != AAUDIO_OK) {
+            printf("AAudioStream_close returned %s\n",
+                   AAudio_convertResultToText(result));
+        }
+        s_AudioEngine.stream = nullptr;
+        AAudioStreamBuilder_delete(s_AudioEngine.builder);
+        s_AudioEngine.builder = nullptr;
+    }
+    return result;
+}
+
+static void s_StartThreadProc() {
+    // A good app would call s_StopAudio here! This test simulates a bad app.
+    s_StartAudio();
+    s_AudioEngine.thread = nullptr;
+}
+
+static void s_myErrorCallbackProc(
+        AAudioStream *stream __unused,
+        void *userData __unused,
+        aaudio_result_t error) {
+    if (error == AAUDIO_ERROR_DISCONNECTED) {
+        // Handle stream restart on a separate thread
+        if (s_AudioEngine.thread == nullptr) {
+            s_AudioEngine.thread = new std::thread(s_StartThreadProc);
+        }
+    }
+}
+
+int main(int argc, char **argv) {
+    (void) argc;
+    (void *)argv;
+
+    aaudio_result_t result = AAUDIO_OK;
+
+    // Make printf print immediately so that debug info is not stuck
+    // in a buffer if we hang or crash.
+    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+    printf("Test Bad Disconnect V1.0\n");
+    printf("\n=========== Please PLUG and UNPLUG headphones! ==============\n\n");
+    printf("You should see the deviceID change on each plug event.\n");
+    printf("Headphones will generally get a new deviceId each time.\n");
+    printf("Speakers will have the same deviceId each time.\n");
+    printf("The framesRead should reset on each plug event then increase over time.\n");
+    printf("\n");
+
+    result = s_StartAudio();
+
+    if (result == AAUDIO_OK) {
+        for (int i = 20; i > 0; i--) {
+            sleep(1);
+            printf("playing silence #%d, framesRead = %d\n", i, (int) s_AudioEngine.framesRead);
+        }
+    }
+
+    s_StopAudio();
+
+    printf("result = %d = %s\n", result, AAudio_convertResultToText(result));
+}
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index f106aae..91e2246 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -64,4 +64,7 @@
     $(call include-path-for, audio-effects)
 
 LOCAL_HEADER_LIBRARIES += libhardware_headers
+
+LOCAL_SANITIZE := integer_overflow
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index de2c6db..cc7f688 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -110,6 +110,7 @@
       mAnchorTimeMediaUs(-1),
       mAnchorNumFramesWritten(-1),
       mVideoLateByUs(0ll),
+      mNextVideoTimeMediaUs(-1),
       mHasAudio(false),
       mHasVideo(false),
       mNotifyCompleteAudio(false),
@@ -301,6 +302,7 @@
 
         mMediaClock->clearAnchor();
         mVideoLateByUs = 0;
+        mNextVideoTimeMediaUs = -1;
         mSyncQueues = false;
     }
 
@@ -1277,9 +1279,10 @@
             mAnchorTimeMediaUs = mediaTimeUs;
         }
     }
+    mNextVideoTimeMediaUs = mediaTimeUs + 100000;
     if (!mHasAudio) {
         // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
+        mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
     }
 
     if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
@@ -1411,6 +1414,13 @@
         // Video might outlive audio. Clear anchor to enable video only case.
         mAnchorTimeMediaUs = -1;
         mHasAudio = false;
+        if (mNextVideoTimeMediaUs >= 0) {
+            int64_t mediaUs = 0;
+            mMediaClock->getMediaTime(ALooper::GetNowUs(), &mediaUs);
+            if (mNextVideoTimeMediaUs > mediaUs) {
+                mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
+            }
+        }
     }
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 567f8f1..a047975 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -177,6 +177,7 @@
     int64_t mAnchorTimeMediaUs;
     int64_t mAnchorNumFramesWritten;
     int64_t mVideoLateByUs;
+    int64_t mNextVideoTimeMediaUs;
     bool mHasAudio;
     bool mHasVideo;
 
diff --git a/media/libstagefright/codec2/include/C2Param.h b/media/libstagefright/codec2/include/C2Param.h
index 7d0155a..0fb9881a 100644
--- a/media/libstagefright/codec2/include/C2Param.h
+++ b/media/libstagefright/codec2/include/C2Param.h
@@ -933,6 +933,7 @@
     enum : uint32_t { baseIndex = kParamIndex##name | C2Param::BaseIndex::_kFlexibleFlag }; \
     DEFINE_C2STRUCT_NO_BASE(name)
 
+#ifdef __C2_GENERATE_GLOBAL_VARS__
 /// \ingroup internal
 /// Describe a structure of a templated structure.
 #define DESCRIBE_TEMPLATED_C2STRUCT(strukt, list) \
@@ -943,6 +944,12 @@
 /// Describe the fields of a structure using an initializer list.
 #define DESCRIBE_C2STRUCT(name, list) \
     const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = list;
+#else
+/// \if 0
+#define DESCRIBE_TEMPLATED_C2STRUCT(strukt, list)
+#define DESCRIBE_C2STRUCT(name, list)
+/// \endif
+#endif
 
 /**
  * Describe a field of a structure.
@@ -1022,6 +1029,7 @@
  *  ~~~~~~~~~~~~~
  *
  */
+#ifdef __C2_GENERATE_GLOBAL_VARS__
 #define C2FIELD(member, name) \
   C2FieldDescriptor(&((_type*)(nullptr))->member, name),
 
@@ -1032,7 +1040,7 @@
 /// Define a structure with matching baseIndex and start describing its fields.
 /// This must be at the end of the structure definition.
 #define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
-    DEFINE_C2STRUCT(name) }  C2_PACK; \
+    DEFINE_C2STRUCT(name) } C2_PACK; \
     const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
 
 /// Define a flexible structure with matching baseIndex and start describing its fields.
@@ -1040,6 +1048,24 @@
 #define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
     DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; \
     const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::fieldList = {
+#else
+/// \if 0
+/* Alternate declaration of field definitions in case no field list is to be generated.
+   TRICKY: use namespace declaration to handle closing bracket that is normally after
+   these macros. */
+#define C2FIELD(member, name)
+/// \deprecated
+#define C2SOLE_FIELD(member, name)
+/// Define a structure with matching baseIndex and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
+    DEFINE_C2STRUCT(name) }  C2_PACK; namespace ignored {
+/// Define a flexible structure with matching baseIndex and start describing its fields.
+/// This must be at the end of the structure definition.
+#define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
+    DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; namespace ignored {
+/// \endif
+#endif
 
 /**
  * Parameter reflector class.
@@ -1164,6 +1190,15 @@
         }
     }
 
+    template<typename T>
+    C2FieldSupportedValues(bool flags, const std::vector<T>& list)
+        : type(flags ? FLAGS : VALUES),
+          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
+        for(T value : list) {
+            values.emplace_back(value);
+        }
+    }
+
     template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)0))>
     C2FieldSupportedValues(bool flags, const T*)
         : type(flags ? FLAGS : VALUES),
diff --git a/media/libstagefright/codec2/tests/C2Param_test.cpp b/media/libstagefright/codec2/tests/C2Param_test.cpp
index 9165aad..9a2ead6 100644
--- a/media/libstagefright/codec2/tests/C2Param_test.cpp
+++ b/media/libstagefright/codec2/tests/C2Param_test.cpp
@@ -19,6 +19,7 @@
 
 #include <gtest/gtest.h>
 
+#define __C2_GENERATE_GLOBAL_VARS__
 #include <util/C2ParamUtils.h>
 #include <C2ParamDef.h>
 
@@ -2405,9 +2406,9 @@
 template<typename T>
 void dumpFSV(const C2FieldSupportedValues &sv, T*t) {
     using namespace std;
-    cout << (std::is_enum<T>::value ? (std::is_signed<typename std::underlying_type<T>::type>::value ? "i" : "u")
+    cout << (std::is_enum<T>::value ? (std::is_signed<typename lax_underlying_type<T>::type>::value ? "i" : "u")
              : std::is_integral<T>::value ? std::is_signed<T>::value ? "i" : "u" : "f")
-        << (8 * sizeof(T));
+         << (8 * sizeof(T));
     if (sv.type == sv.RANGE) {
         cout << ".range(" << get(sv.range.min, t);
         if (get(sv.range.step, t) != std::is_integral<T>::value) {
@@ -2552,6 +2553,22 @@
     }
 }
 
+TEST_F(C2ParamTest, FieldSupportedValuesTest) {
+    typedef C2GlobalParam<C2Info, C2Uint32Value, 0> Uint32TestInfo;
+    Uint32TestInfo t;
+    std::vector<C2FieldSupportedValues> values;
+    values.push_back(C2FieldSupportedValues(0, 10, 1));  // min, max, step
+    values.push_back(C2FieldSupportedValues(1, 64, 2, 1));  // min, max, nom, den
+    values.push_back(C2FieldSupportedValues(false, {1, 2, 3}));  // flags, std::initializer_list
+    uint32_t val[] = {1, 3, 5, 7};
+    std::vector<uint32_t> v(std::begin(val), std::end(val));
+    values.push_back(C2FieldSupportedValues(false, v));  // flags, std::vector
+
+    for (const C2FieldSupportedValues &sv : values) {
+        dumpFSV(sv, &t.mValue);
+    }
+}
+
 C2ENUM(Enum1, uint32_t,
     Enum1Value1,
     Enum1Value2,
diff --git a/media/libstagefright/codec2/vndk/Android.bp b/media/libstagefright/codec2/vndk/Android.bp
index 916a6a9..66f31cb 100644
--- a/media/libstagefright/codec2/vndk/Android.bp
+++ b/media/libstagefright/codec2/vndk/Android.bp
@@ -1,7 +1,10 @@
 cc_library_static {
     name: "libstagefright_codec2_vndk",
 
-    srcs: ["C2Buffer.cpp"],
+    srcs: [
+        "C2Buffer.cpp",
+        "C2Config.cpp",
+    ],
 
     include_dirs: [
         "frameworks/av/media/libstagefright/codec2/include",
diff --git a/media/libstagefright/codec2/vndk/C2Config.cpp b/media/libstagefright/codec2/vndk/C2Config.cpp
new file mode 100644
index 0000000..6acf524
--- /dev/null
+++ b/media/libstagefright/codec2/vndk/C2Config.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "C2Config"
+
+/**
+ * Define and initialize global config field descriptors in this cpp file
+ */
+#define __C2_GENERATE_GLOBAL_VARS__
+#include <C2Config.h>
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 3095bc9..f917675 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -60,6 +60,7 @@
     result << "    Reference Count:      " << mOpenCount << "\n";
     result << "    Requested Device Id:  " << mRequestedDeviceId << "\n";
     result << "    Device Id:            " << getDeviceId() << "\n";
+    result << "    Connected:            " << mConnected.load() << "\n";
     result << "    Registered Streams:" << "\n";
     result << AAudioServiceStreamShared::dumpHeader() << "\n";
     for (const auto stream : mRegisteredStreams) {
@@ -74,7 +75,9 @@
 
 void AAudioServiceEndpoint::disconnectRegisteredStreams() {
     std::lock_guard<std::mutex> lock(mLockStreams);
+    mConnected.store(false);
     for (const auto stream : mRegisteredStreams) {
+        ALOGD("disconnectRegisteredStreams() stop and disconnect %p", stream.get());
         stream->stop();
         stream->disconnect();
     }
@@ -96,6 +99,9 @@
 }
 
 bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configuration) {
+    if (!mConnected.load()) {
+        return false; // Only use an endpoint if it is connected to a device.
+    }
     if (configuration.getDirection() != getDirection()) {
         return false;
     }
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 2ef6234..6312c51 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -97,6 +97,10 @@
         mOpenCount = count;
     }
 
+    bool isConnected() const {
+        return mConnected;
+    }
+
 protected:
     void                     disconnectRegisteredStreams();
 
@@ -111,6 +115,8 @@
     int32_t                  mOpenCount = 0;
     int32_t                  mRequestedDeviceId = 0;
 
+    std::atomic<bool>        mConnected{true};
+
 };
 
 } /* namespace aaudio */
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index cd40066..820ed28 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -91,7 +91,12 @@
 static void *aaudio_endpoint_thread_proc(void *context) {
     AAudioServiceEndpointShared *endpoint = (AAudioServiceEndpointShared *) context;
     if (endpoint != NULL) {
-        return endpoint->callbackLoop();
+        void *result = endpoint->callbackLoop();
+        // Close now so that the HW resource is freed and we can open a new device.
+        if (!endpoint->isConnected()) {
+            endpoint->close();
+        }
+        return result;
     } else {
         return NULL;
     }