Merge "libaudiohal: Dynamically load appropriate HIDL shim library"
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index bdff29a..a2930a6 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -63,6 +63,7 @@
     ],
 
     header_libs: [
+        "libbinder_headers",
         "libsystem_headers",
         "libcodec2_internal", // private
     ],
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index c620bad..c747190 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -125,6 +125,9 @@
         if (!mClient) {
             mClient = Codec2Client::_CreateFromIndex(mIndex);
         }
+        CHECK(mClient) << "Failed to create Codec2Client to service \""
+                       << GetServiceNames()[mIndex] << "\". (Index = "
+                       << mIndex << ").";
         return mClient;
     }
 
@@ -832,6 +835,7 @@
 
 c2_status_t Codec2Client::ForAllServices(
         const std::string &key,
+        size_t numberOfAttempts,
         std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
             predicate) {
     c2_status_t status = C2_NO_INIT;  // no IComponentStores present
@@ -860,23 +864,31 @@
 
     for (size_t index : indices) {
         Cache& cache = Cache::List()[index];
-        std::shared_ptr<Codec2Client> client{cache.getClient()};
-        if (client) {
+        for (size_t tries = numberOfAttempts; tries > 0; --tries) {
+            std::shared_ptr<Codec2Client> client{cache.getClient()};
             status = predicate(client);
             if (status == C2_OK) {
                 std::scoped_lock lock{key2IndexMutex};
                 key2Index[key] = index; // update last known client index
                 return C2_OK;
+            } else if (status == C2_TRANSACTION_FAILED) {
+                LOG(WARNING) << "\"" << key << "\" failed for service \""
+                             << client->getName()
+                             << "\" due to transaction failure. "
+                             << "(Service may have crashed.)"
+                             << (tries > 1 ? " Retrying..." : "");
+                cache.invalidate();
+                continue;
             }
-        }
-        if (wasMapped) {
-            LOG(INFO) << "Could not find \"" << key << "\""
-                         " in the last instance. Retrying...";
-            wasMapped = false;
-            cache.invalidate();
+            if (wasMapped) {
+                LOG(INFO) << "\"" << key << "\" became invalid in service \""
+                          << client->getName() << "\". Retrying...";
+                wasMapped = false;
+            }
+            break;
         }
     }
-    return status;  // return the last status from a valid client
+    return status; // return the last status from a valid client
 }
 
 std::shared_ptr<Codec2Client::Component>
@@ -885,35 +897,37 @@
         const std::shared_ptr<Listener>& listener,
         std::shared_ptr<Codec2Client>* owner,
         size_t numberOfAttempts) {
-    while (true) {
-        std::shared_ptr<Component> component;
-        c2_status_t status = ForAllServices(
-                componentName,
-                [owner, &component, componentName, &listener](
-                        const std::shared_ptr<Codec2Client> &client)
-                            -> c2_status_t {
-                    c2_status_t status = client->createComponent(componentName,
-                                                                 listener,
-                                                                 &component);
-                    if (status == C2_OK) {
-                        if (owner) {
-                            *owner = client;
-                        }
-                    } else if (status != C2_NOT_FOUND) {
-                        LOG(DEBUG) << "IComponentStore("
-                                       << client->getServiceName()
-                                   << ")::createComponent(\"" << componentName
-                                   << "\") returned status = "
-                                   << status << ".";
+    std::string key{"create:"};
+    key.append(componentName);
+    std::shared_ptr<Component> component;
+    c2_status_t status = ForAllServices(
+            key,
+            numberOfAttempts,
+            [owner, &component, componentName, &listener](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createComponent(componentName,
+                                                             listener,
+                                                             &component);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
                     }
-                    return status;
-                });
-        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
-            --numberOfAttempts;
-            continue;
-        }
-        return component;
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createComponent(\"" << componentName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Failed to create component \"" << componentName
+                   << "\" from all known services. "
+                      "Last returned status = " << status << ".";
     }
+    return component;
 }
 
 std::shared_ptr<Codec2Client::Interface>
@@ -921,34 +935,36 @@
         const char* interfaceName,
         std::shared_ptr<Codec2Client>* owner,
         size_t numberOfAttempts) {
-    while (true) {
-        std::shared_ptr<Interface> interface;
-        c2_status_t status = ForAllServices(
-                interfaceName,
-                [owner, &interface, interfaceName](
-                        const std::shared_ptr<Codec2Client> &client)
-                            -> c2_status_t {
-                    c2_status_t status = client->createInterface(interfaceName,
-                                                                 &interface);
-                    if (status == C2_OK) {
-                        if (owner) {
-                            *owner = client;
-                        }
-                    } else if (status != C2_NOT_FOUND) {
-                        LOG(DEBUG) << "IComponentStore("
-                                       << client->getServiceName()
-                                   << ")::createInterface(\"" << interfaceName
-                                   << "\") returned status = "
-                                   << status << ".";
+    std::string key{"create:"};
+    key.append(interfaceName);
+    std::shared_ptr<Interface> interface;
+    c2_status_t status = ForAllServices(
+            key,
+            numberOfAttempts,
+            [owner, &interface, interfaceName](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createInterface(interfaceName,
+                                                             &interface);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
                     }
-                    return status;
-                });
-        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
-            --numberOfAttempts;
-            continue;
-        }
-        return interface;
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createInterface(\"" << interfaceName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Failed to create interface \"" << interfaceName
+                   << "\" from all known services. "
+                      "Last returned status = " << status << ".";
     }
+    return interface;
 }
 
 std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index 848901d..c37407f 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -208,11 +208,25 @@
 protected:
     sp<Base> mBase;
 
-    // Finds the first store where the predicate returns OK, and returns the last
-    // predicate result. Uses key to remember the last store found, and if cached,
-    // it tries that store before trying all stores (one retry).
+    // Finds the first store where the predicate returns C2_OK and returns the
+    // last predicate result. The predicate will be tried on all stores. The
+    // function will return C2_OK the first time the predicate returns C2_OK,
+    // or it will return the value from the last time that predicate is tried.
+    // (The latter case corresponds to a failure on every store.) The order of
+    // the stores to try is the same as the return value of GetServiceNames().
+    //
+    // key is used to remember the last store with which the predicate last
+    // succeeded. If the last successful store is cached, it will be tried
+    // first before all the stores are tried. Note that the last successful
+    // store will be tried twice---first before all the stores, and another time
+    // with all the stores.
+    //
+    // If an attempt to evaluate the predicate results in a transaction failure,
+    // repeated attempts will be made until the predicate returns without a
+    // transaction failure or numberOfAttempts attempts have been made.
     static c2_status_t ForAllServices(
             const std::string& key,
+            size_t numberOfAttempts,
             std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)>
                 predicate);
 
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 6fbad0a..52cc7ad 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -71,8 +71,6 @@
         "libutils",
     ],
 
-    tidy: false, // b/146435095, clang-tidy segmentation fault
-
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/media/extractors/tests/AndroidTest.xml b/media/extractors/tests/AndroidTest.xml
new file mode 100644
index 0000000..6bb2c8a
--- /dev/null
+++ b/media/extractors/tests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for extractor unit tests">
+    <option name="test-suite-tag" value="ExtractorUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ExtractorUnitTest->/data/local/tmp/ExtractorUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip?unzip=true"
+            value="/data/local/tmp/ExtractorUnitTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ExtractorUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/ExtractorUnitTestRes/" />
+    </test>
+</configuration>
diff --git a/media/extractors/tests/README.md b/media/extractors/tests/README.md
index 6e02d3e..69538b6 100644
--- a/media/extractors/tests/README.md
+++ b/media/extractors/tests/README.md
@@ -22,8 +22,8 @@
 adb push ${OUT}/data/nativetest/ExtractorUnitTest/ExtractorUnitTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/1Z9nCIRB6pGLvb5mPkF8BURa5Nc6cY9pY). Push these files into device for testing.
-Download extractor folder and push all the files in this folder to /data/local/tmp/ on the device.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip). Download, unzip and push these files into device for testing.
+
 ```
 adb push extractor /data/local/tmp/
 ```
@@ -32,3 +32,8 @@
 ```
 adb shell /data/local/tmp/ExtractorUnitTest -P /data/local/tmp/extractor/
 ```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ExtractorUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/codecs/on2/enc/Android.bp b/media/libstagefright/codecs/on2/enc/Android.bp
index cd69e0d..705e554 100644
--- a/media/libstagefright/codecs/on2/enc/Android.bp
+++ b/media/libstagefright/codecs/on2/enc/Android.bp
@@ -21,4 +21,5 @@
     },
 
     shared_libs: ["libvpx"],
+    header_libs: ["libbase_headers"],
 }
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index b95f054..effbb4e 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -34,10 +34,6 @@
         "media_plugin_headers",
     ],
 
-    export_shared_lib_headers: [
-        "libbinder",
-    ],
-
     cflags: [
         "-Wno-multichar",
         "-Werror",
diff --git a/media/libstagefright/tests/writer/AndroidTest.xml b/media/libstagefright/tests/writer/AndroidTest.xml
new file mode 100644
index 0000000..d831555
--- /dev/null
+++ b/media/libstagefright/tests/writer/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Test module config for writer tests">
+    <option name="test-suite-tag" value="writerTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="writerTest->/data/local/tmp/writerTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/Writer.zip?unzip=true"
+            value="/data/local/tmp/writerTestRes/" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="writerTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/writerTestRes/" />
+    </test>
+</configuration>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
index 1179d6c..1890661 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
+++ b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
@@ -14,6 +14,12 @@
      limitations under the License.
 -->
 <configuration description="Runs Media Benchmark Tests">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/tests/benchmark/MediaBenchmark.zip?unzip=true"
+            value="/data/local/tmp/MediaBenchmark/res/" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
         <option name="cleanup-apks" value="false" />
         <option name="test-file-name" value="MediaBenchmarkTest.apk" />