Merge "contexthub: Handle service death" into oc-dev
diff --git a/audio/2.0/vts/Android.mk b/audio/2.0/vts/Android.mk
new file mode 100644
index 0000000..7a16792
--- /dev/null
+++ b/audio/2.0/vts/Android.mk
@@ -0,0 +1,3 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/audio/2.0/vts/functional/Android.bp b/audio/2.0/vts/functional/Android.bp
deleted file mode 100644
index f5ab76f..0000000
--- a/audio/2.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// 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.
-//
-
-cc_test {
-    name: "VtsHalAudioV2_0TargetTest",
-    defaults: ["hidl_defaults"],
-    srcs: ["AudioPrimaryHidlHalTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libhidlbase",
-        "libhidltransport",
-        "libutils",
-        "libcutils",
-        "android.hardware.audio@2.0",
-        "android.hardware.audio.common@2.0",
-    ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-}
diff --git a/audio/2.0/vts/functional/Android.mk b/audio/2.0/vts/functional/Android.mk
new file mode 100644
index 0000000..db08dde
--- /dev/null
+++ b/audio/2.0/vts/functional/Android.mk
@@ -0,0 +1,42 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_CLANG := true
+LOCAL_MODULE := VtsHalAudioV2_0TargetTest
+LOCAL_CPPFLAGS := -O0 -g -Wall -Wextra -Werror
+LOCAL_SRC_FILES := \
+    AudioPrimaryHidlHalTest.cpp \
+    ValidateAudioConfiguration.cpp \
+    utility/ValidateXml.cpp
+
+LOCAL_C_INCLUDES := external/libxml2/include
+
+LOCAL_STATIC_LIBRARIES := VtsHalHidlTargetTestBase
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    liblog \
+    libhidlbase \
+    libhidltransport \
+    libutils \
+    libcutils \
+    libxml2 \
+    libicuuc \
+    android.hardware.audio@2.0 \
+    android.hardware.audio.common@2.0 \
+
+include $(BUILD_NATIVE_TEST)
diff --git a/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp
new file mode 100644
index 0000000..01324c8
--- /dev/null
+++ b/audio/2.0/vts/functional/ValidateAudioConfiguration.cpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+#include "utility/ValidateXml.h"
+
+TEST(CheckConfig, audioPolicyConfigurationValidation) {
+    ASSERT_VALID_XML("/vendor/etc/audio_policy_configuration.xml",
+                     "/data/local/tmp/audio_policy_configuration.xsd");
+}
diff --git a/audio/2.0/vts/functional/utility/ValidateXml.cpp b/audio/2.0/vts/functional/utility/ValidateXml.cpp
new file mode 100644
index 0000000..ff08d2d
--- /dev/null
+++ b/audio/2.0/vts/functional/utility/ValidateXml.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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_TAG "ValidateAudioConfig"
+#include <utils/Log.h>
+
+#define LIBXML_SCHEMAS_ENABLED
+#include <libxml/xmlschemastypes.h>
+#define LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+
+#include <memory>
+#include <string>
+
+#include "ValidateXml.h"
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace test {
+
+/** Map libxml2 structures to their corresponding deleters. */
+template <class T>
+constexpr void (*xmlDeleter)(T* t);
+template <>
+constexpr auto xmlDeleter<xmlSchema> = xmlSchemaFree;
+template <>
+constexpr auto xmlDeleter<xmlDoc> = xmlFreeDoc;
+template <>
+constexpr auto xmlDeleter<xmlSchemaParserCtxt> = xmlSchemaFreeParserCtxt;
+template <>
+constexpr auto xmlDeleter<xmlSchemaValidCtxt> = xmlSchemaFreeValidCtxt;
+
+/** @return a unique_ptr with the correct deleter for the libxml2 object. */
+template <class T>
+constexpr auto make_xmlUnique(T* t) {
+    // Wrap deleter in lambda to enable empty base optimization
+    auto deleter = [](T* t) { xmlDeleter<T>(t); };
+    return std::unique_ptr<T, decltype(deleter)>{t, deleter};
+}
+
+/** Class that handles libxml2 initialization and cleanup. NOT THREAD SAFE*/
+struct Libxml2Global {
+    Libxml2Global() {
+        xmlLineNumbersDefault(1);  // Better error message
+        xmlSetGenericErrorFunc(this, errorCb);
+    }
+    ~Libxml2Global() {
+        // TODO: check if all those cleanup are needed
+        xmlSetGenericErrorFunc(nullptr, nullptr);
+        xmlSchemaCleanupTypes();
+        xmlCleanupParser();
+        xmlCleanupThreads();
+    }
+
+    const std::string& getErrors() { return errors; }
+
+   private:
+    static void errorCb(void* ctxt, const char* msg, ...) {
+        auto* self = static_cast<Libxml2Global*>(ctxt);
+        va_list args;
+        va_start(args, msg);
+
+        char* formatedMsg;
+        if (vasprintf(&formatedMsg, msg, args) >= 0) {
+            LOG_PRI(ANDROID_LOG_ERROR, LOG_TAG, "%s", formatedMsg);
+            self->errors += "Error: ";
+            self->errors += formatedMsg;
+        }
+        free(formatedMsg);
+
+        va_end(args);
+    }
+    std::string errors;
+};
+
+::testing::AssertionResult validateXml(const char* xmlFilePathExpr,
+                                       const char* xsdFilePathExpr,
+                                       const char* xmlFilePath,
+                                       const char* xsdFilePath) {
+    Libxml2Global libxml2;
+
+    auto context = [&]() {
+        return std::string() + "    While validating: " + xmlFilePathExpr +
+               "\n          Which is: " + xmlFilePath +
+               "\nAgainst the schema: " + xsdFilePathExpr +
+               "\n          Which is: " + xsdFilePath + "Libxml2 errors\n" +
+               libxml2.getErrors();
+    };
+
+    auto schemaParserCtxt = make_xmlUnique(xmlSchemaNewParserCtxt(xsdFilePath));
+    auto schema = make_xmlUnique(xmlSchemaParse(schemaParserCtxt.get()));
+    if (schema == nullptr) {
+        return ::testing::AssertionFailure() << "Failed to parse schema (xsd)\n"
+                                             << context();
+    }
+
+    auto doc = make_xmlUnique(xmlReadFile(xmlFilePath, nullptr, 0));
+    if (doc == nullptr) {
+        return ::testing::AssertionFailure() << "Failed to parse xml\n"
+                                             << context();
+    }
+
+    if (xmlXIncludeProcess(doc.get()) == -1) {
+        return ::testing::AssertionFailure()
+               << "Failed to resolve xincludes in xml\n"
+               << context();
+    }
+
+    auto schemaCtxt = make_xmlUnique(xmlSchemaNewValidCtxt(schema.get()));
+    int ret = xmlSchemaValidateDoc(schemaCtxt.get(), doc.get());
+    if (ret > 0) {
+        return ::testing::AssertionFailure()
+               << "xml is not valid according to the xsd.\n"
+               << context();
+    }
+    if (ret < 0) {
+        return ::testing::AssertionFailure() << "Internal or API error\n"
+                                             << context();
+    }
+
+    return ::testing::AssertionSuccess();
+}
+
+}  // namespace test
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
diff --git a/audio/2.0/vts/functional/utility/ValidateXml.h b/audio/2.0/vts/functional/utility/ValidateXml.h
new file mode 100644
index 0000000..619dd40
--- /dev/null
+++ b/audio/2.0/vts/functional/utility/ValidateXml.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
+#define ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace test {
+
+/** Validate the provided XmlFile with the provided xsdFile.
+ * Intended to use with ASSERT_PRED_FORMAT2 as such:
+ *   ASSERT_PRED_FORMAT2(validateXml, pathToXml, pathToXsd);
+ * See ASSERT_VALID_XML for a helper macro.
+ */
+::testing::AssertionResult validateXml(const char* xmlFilePathExpr,
+                                       const char* xsdFilePathExpr,
+                                       const char* xmlFilePath,
+                                       const char* xsdPathName);
+
+/** Helper gtest ASSERT to test xml validity against an xsd. */
+#define ASSERT_VALID_XML(xmlFilePath, xsdFilePath)                     \
+    ASSERT_PRED_FORMAT2(::android::hardware::audio::test::validateXml, \
+                        xmlFilePath, xsdFilePath)
+
+}  // namespace test
+}  // namespace audio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIO_TEST_VALIDATEXML
diff --git a/audio/Android.bp b/audio/Android.bp
index c3c2be1..abb2bbb 100644
--- a/audio/Android.bp
+++ b/audio/Android.bp
@@ -1,7 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "2.0",
-    "2.0/vts/functional",
     "common/2.0",
     "common/2.0/default",
     "effect/2.0",
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index 4c76c45..0d86099 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -34,7 +34,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 
     // Test with sending random string
@@ -48,7 +49,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 }
 
@@ -83,7 +85,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 }
 
@@ -101,12 +104,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
-                    radioRsp->rspInfo.error == RadioError::SYSTEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::NO_MEMORY ||
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 }
 
@@ -123,7 +124,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::NONE);
     }
 }
 
@@ -144,7 +146,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 
     // Test with sending random string
@@ -158,6 +161,7 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+        ASSERT_TRUE(CheckGeneralError() ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
index 1aa9d6c..b957c6e 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
@@ -65,10 +65,11 @@
             radioRsp->rspInfo.error == RadioError::NO_MEMORY ||
             radioRsp->rspInfo.error == RadioError::INTERNAL_ERR ||
             radioRsp->rspInfo.error == RadioError::SYSTEM_ERR ||
-            radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+            radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED ||
+            radioRsp->rspInfo.error == RadioError::CANCELLED);
 }
 
 bool RadioHidlTest::CheckOEMError() {
     return (radioRsp->rspInfo.error >= RadioError::OEM_ERROR_1 &&
             radioRsp->rspInfo.error <= RadioError::OEM_ERROR_25);
-}
\ No newline at end of file
+}