Merge "Make dvr tests a separate module" into rvc-dev
diff --git a/Android.bp b/Android.bp
index f64968f..9e1df13 100644
--- a/Android.bp
+++ b/Android.bp
@@ -21,7 +21,7 @@
 
     // Lists all dependencies that can *not* be expected on the device.
     static_libs: [
-        "VtsHalHidlTargetTestBase",
+        "VtsHalHidlTestUtils",
         "libhidl-gen-utils",
     ],
 
@@ -47,3 +47,15 @@
 
     require_root: true,
 }
+
+// TODO: Remove this after all vts tests under vendor/qcom are converted to
+// parameterized gtest.
+cc_defaults {
+    name: "Vts10HalTargetTestDefaults",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+    ],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+    ],
+}
diff --git a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h
index ee206f7..274a10b 100644
--- a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h
+++ b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h
@@ -51,8 +51,31 @@
  */
 template <bool atLeastOneRequired = true>
 ::testing::AssertionResult validateXmlMultipleLocations(
-    const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
-    const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath);
+        const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
+        const char* xmlFileName, const std::vector<std::string>& xmlFileLocations,
+        const char* xsdFilePath);
+template <bool atLeastOneRequired = true>
+::testing::AssertionResult validateXmlMultipleLocations(
+        const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
+        const char* xmlFileName, std::initializer_list<const char*> xmlFileLocations,
+        const char* xsdFilePath) {
+    return validateXmlMultipleLocations<atLeastOneRequired>(
+            xmlFileNameExpr, xmlFileLocationsExpr, xsdFilePathExpr, xmlFileName,
+            std::vector<std::string>(xmlFileLocations.begin(), xmlFileLocations.end()),
+            xsdFilePath);
+}
+template <bool atLeastOneRequired = true>
+::testing::AssertionResult validateXmlMultipleLocations(const char* xmlFileNameExpr,
+                                                        const char* xmlFileLocationsExpr,
+                                                        const char* xsdFilePathExpr,
+                                                        const char* xmlFileName,
+                                                        std::vector<const char*> xmlFileLocations,
+                                                        const char* xsdFilePath) {
+    return validateXmlMultipleLocations<atLeastOneRequired>(
+            xmlFileNameExpr, xmlFileLocationsExpr, xsdFilePathExpr, xmlFileName,
+            std::vector<std::string>(xmlFileLocations.begin(), xmlFileLocations.end()),
+            xsdFilePath);
+}
 
 /** ASSERT that all found XML are valid according to an xsd. */
 #define ASSERT_VALID_XML_MULTIPLE_LOCATIONS(xmlFileName, xmlFileLocations, xsdFilePath)         \
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index bdafa82..a866104 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -131,14 +131,15 @@
 
 template <bool atLeastOneRequired>
 ::testing::AssertionResult validateXmlMultipleLocations(
-    const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
-    const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath) {
+        const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
+        const char* xmlFileName, const std::vector<std::string>& xmlFileLocations,
+        const char* xsdFilePath) {
     using namespace std::string_literals;
 
     std::vector<std::string> errors;
     std::vector<std::string> foundFiles;
 
-    for (const char* location : xmlFileLocations) {
+    for (const auto& location : xmlFileLocations) {
         std::string xmlFilePath = location + "/"s + xmlFileName;
         if (access(xmlFilePath.c_str(), F_OK) != 0) {
             // If the file does not exist ignore this location and fallback on the next one
@@ -166,14 +167,12 @@
                                   : "\nWhere no file might exist.");
 }
 
-template ::testing::AssertionResult validateXmlMultipleLocations<true>(const char*, const char*,
-                                                                       const char*, const char*,
-                                                                       std::vector<const char*>,
-                                                                       const char*);
-template ::testing::AssertionResult validateXmlMultipleLocations<false>(const char*, const char*,
-                                                                        const char*, const char*,
-                                                                        std::vector<const char*>,
-                                                                        const char*);
+template ::testing::AssertionResult validateXmlMultipleLocations<true>(
+        const char*, const char*, const char*, const char*, const std::vector<std::string>&,
+        const char*);
+template ::testing::AssertionResult validateXmlMultipleLocations<false>(
+        const char*, const char*, const char*, const char*, const std::vector<std::string>&,
+        const char*);
 
 }  // namespace utility
 }  // namespace test
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index db52e60..729ee7a 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -33,7 +33,7 @@
     ],
     test_suites: [
         "general-tests",
-        "vts-core",
+        "vts",
     ],
 }
 
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 5d82e7b..d5af335 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -35,6 +35,7 @@
 #include <hwbinder/IPCThreadState.h>
 
 #include <android-base/logging.h>
+#include <system/audio_config.h>
 
 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
 #include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
@@ -135,7 +136,6 @@
 ////////////////////////// Audio policy configuration ////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-static const std::vector<const char*> kConfigLocations = {"/odm/etc", "/vendor/etc", "/system/etc"};
 static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
 
 // Stringify the argument.
@@ -154,8 +154,8 @@
     PolicyConfig()
         : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
                             defaultOutputDevice) {
-        for (const char* location : kConfigLocations) {
-            std::string path = std::string(location) + '/' + kConfigFileName;
+        for (const auto& location : android::audio_get_configuration_paths()) {
+            std::string path = location + '/' + kConfigFileName;
             if (access(path.c_str(), F_OK) == 0) {
                 mFilePath = path;
                 break;
@@ -188,7 +188,7 @@
     std::string getError() const {
         if (mFilePath.empty()) {
             return std::string{"Could not find "} + kConfigFileName +
-                   " file in: " + testing::PrintToString(kConfigLocations);
+                   " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
         } else {
             return "Invalid config file: " + mFilePath;
         }
@@ -304,7 +304,8 @@
                    "is valid according to the schema");
 
     const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
-    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName, kConfigLocations, xsd);
+    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName,
+                                            android::audio_get_configuration_paths(), xsd);
 }
 
 class AudioPolicyConfigTest : public AudioHidlTestWithDeviceParameter {
diff --git a/audio/effect/all-versions/vts/functional/ValidateAudioEffectsConfiguration.cpp b/audio/effect/all-versions/vts/functional/ValidateAudioEffectsConfiguration.cpp
index 9c0135b..f251634 100644
--- a/audio/effect/all-versions/vts/functional/ValidateAudioEffectsConfiguration.cpp
+++ b/audio/effect/all-versions/vts/functional/ValidateAudioEffectsConfiguration.cpp
@@ -18,6 +18,7 @@
 #include <iterator>
 
 #include <media/EffectsConfig.h>
+#include <system/audio_config.h>
 // clang-format off
 #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
 // clang-format on
@@ -41,13 +42,14 @@
         GTEST_SKIP() << "No Effects HAL version " STRINGIFY(CPP_VERSION) " on this device";
     }
 
-    std::vector<const char*> locations(std::begin(DEFAULT_LOCATIONS), std::end(DEFAULT_LOCATIONS));
     const char* xsd = "/data/local/tmp/audio_effects_conf_" STRINGIFY(CPP_VERSION) ".xsd";
 #if MAJOR_VERSION == 2
     // In V2, audio effect XML is not required. .conf is still allowed though deprecated
-    EXPECT_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations, xsd);
+    EXPECT_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, android::audio_get_configuration_paths(),
+                                        xsd);
 #elif MAJOR_VERSION >= 4
     // Starting with V4, audio effect XML is required
-    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations, xsd);
+    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, android::audio_get_configuration_paths(),
+                                            xsd);
 #endif
 }
diff --git a/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp b/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
index a0aaa6e..5741fa9 100644
--- a/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
+++ b/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
@@ -23,7 +23,8 @@
 #include <string>
 #include "utility/ValidateXml.h"
 
-static const std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"};
+#include <system/audio_config.h>
+
 static const std::string config = "audio_policy_engine_configuration.xml";
 static const std::string schema =
         std::string(XSD_DIR) + "/audio_policy_engine_configuration_V1_0.xsd";
@@ -42,7 +43,8 @@
     RecordProperty("description",
                    "Verify that the audio policy engine configuration file "
                    "is valid according to the schemas");
-    EXPECT_VALID_XML_MULTIPLE_LOCATIONS(config.c_str(), locations, schema.c_str());
+    EXPECT_VALID_XML_MULTIPLE_LOCATIONS(config.c_str(), android::audio_get_configuration_paths(),
+                                        schema.c_str());
 }
 
 /**
@@ -52,9 +54,11 @@
  */
 static bool deviceUsesConfigurableEngine() {
     return android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>(
-                   "", "", "", config.c_str(), locations, schema.c_str()) &&
+                   "", "", "", config.c_str(), android::audio_get_configuration_paths(),
+                   schema.c_str()) &&
            android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>(
-                   "", "", "", configurableConfig.c_str(), locations, configurableSchemas.c_str());
+                   "", "", "", configurableConfig.c_str(), android::audio_get_configuration_paths(),
+                   configurableSchemas.c_str());
 }
 
 TEST(ValidateConfiguration, audioPolicyEngineConfigurable) {
diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp
index a2643af..9c0f2c5 100644
--- a/automotive/can/1.0/default/CanController.cpp
+++ b/automotive/can/1.0/default/CanController.cpp
@@ -23,7 +23,7 @@
 #include <android-base/logging.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
 
-#include <filesystem>
+#include <automotive/filesystem>
 #include <fstream>
 #include <regex>
 
@@ -31,6 +31,7 @@
 
 using IfId = ICanController::BusConfig::InterfaceId;
 using IfIdDisc = ICanController::BusConfig::InterfaceId::hidl_discriminator;
+namespace fs = android::hardware::automotive::filesystem;
 
 namespace fsErrors {
 static const std::error_code ok;
@@ -42,10 +43,10 @@
 /* In the /sys/devices tree, there are files called "serial", which contain the serial numbers
  * for various devices. The exact location inside of this directory is dependent upon the
  * hardware we are running on, so we have to start from /sys/devices and work our way down. */
-static const std::filesystem::path kDevPath("/sys/devices/");
+static const fs::path kDevPath("/sys/devices/");
 static const std::regex kTtyRe("^tty[A-Z]+[0-9]+$");
-static constexpr auto kOpts = ~(std::filesystem::directory_options::follow_directory_symlink |
-                                std::filesystem::directory_options::skip_permission_denied);
+static constexpr auto kOpts = ~(fs::directory_options::follow_directory_symlink |
+                                fs::directory_options::skip_permission_denied);
 
 /**
  * A helper object to associate the interface name and type of a USB to CAN adapter.
@@ -72,16 +73,16 @@
  * \param serialPath - Absolute path to a "serial" file for a given device in /sys.
  * \return A populated UsbCanIface. On failure, nullopt is returned.
  */
-static std::optional<UsbCanIface> getIfaceName(std::filesystem::path serialPath) {
+static std::optional<UsbCanIface> getIfaceName(fs::path serialPath) {
     std::error_code fsStatus;
     // Since the path is to a file called "serial", we need to search its parent directory.
-    std::filesystem::recursive_directory_iterator fsItr(serialPath.parent_path(), kOpts, fsStatus);
+    fs::recursive_directory_iterator fsItr(serialPath.parent_path(), kOpts, fsStatus);
     if (fsStatus != fsErrors::ok) {
         LOG(ERROR) << "Failed to open " << serialPath.parent_path();
         return std::nullopt;
     }
 
-    for (; fsStatus == fsErrors::ok && fsItr != std::filesystem::recursive_directory_iterator();
+    for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
          fsItr.increment(fsStatus)) {
         /* We want either a directory called "net" or a directory that looks like tty<something>, so
          * skip files. */
@@ -95,7 +96,7 @@
         if (currentDir == "net") {
             /* This device is a SocketCAN device. The iface name is the only directory under
              * net/. Multiple directories under net/ is an error.*/
-            std::filesystem::directory_iterator netItr(fsItr->path(), kOpts, fsStatus);
+            fs::directory_iterator netItr(fsItr->path(), kOpts, fsStatus);
             if (fsStatus != fsErrors::ok) {
                 LOG(ERROR) << "Failed to open " << fsItr->path() << " to get net name!";
                 return std::nullopt;
@@ -111,7 +112,7 @@
                 LOG(ERROR) << "Failed to verify " << fsItr->path() << " has valid net name!";
                 return std::nullopt;
             }
-            if (netItr != std::filesystem::directory_iterator()) {
+            if (netItr != fs::directory_iterator()) {
                 // There should never be more than one name under net/
                 LOG(ERROR) << "Found more than one net name in " << fsItr->path() << "!";
                 return std::nullopt;
@@ -157,13 +158,13 @@
  */
 static std::optional<UsbCanIface> findUsbDevice(const hidl_vec<hidl_string>& configSerialnos) {
     std::error_code fsStatus;
-    std::filesystem::recursive_directory_iterator fsItr(kDevPath, kOpts, fsStatus);
+    fs::recursive_directory_iterator fsItr(kDevPath, kOpts, fsStatus);
     if (fsStatus != fsErrors::ok) {
         LOG(ERROR) << "Failed to open " << kDevPath;
         return std::nullopt;
     }
 
-    for (; fsStatus == fsErrors::ok && fsItr != std::filesystem::recursive_directory_iterator();
+    for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
          fsItr.increment(fsStatus)) {
         // We want to find a file called "serial", which is in a directory somewhere. Skip files.
         bool isDir = fsItr->is_directory(fsStatus);
@@ -174,7 +175,7 @@
         if (!isDir) continue;
 
         auto serialnoPath = fsItr->path() / "serial";
-        bool isReg = std::filesystem::is_regular_file(serialnoPath, fsStatus);
+        bool isReg = fs::is_regular_file(serialnoPath, fsStatus);
 
         /* Make sure we have permissions to this directory, ignore enoent, since the file
          * "serial" may not exist, which is ok. */
diff --git a/automotive/can/1.0/default/libc++fs/.clang-format b/automotive/can/1.0/default/libc++fs/.clang-format
new file mode 100644
index 0000000..dd59681
--- /dev/null
+++ b/automotive/can/1.0/default/libc++fs/.clang-format
@@ -0,0 +1,13 @@
+BasedOnStyle: LLVM
+
+---
+Language: Cpp
+Standard: Cpp03
+
+AlwaysBreakTemplateDeclarations: true
+PointerAlignment: Left
+
+# Disable formatting options which may break tests.
+SortIncludes: false
+ReflowComments: false
+---
diff --git a/automotive/can/1.0/default/libc++fs/Android.bp b/automotive/can/1.0/default/libc++fs/Android.bp
index 1fe324e..7ab1c28 100644
--- a/automotive/can/1.0/default/libc++fs/Android.bp
+++ b/automotive/can/1.0/default/libc++fs/Android.bp
@@ -19,7 +19,6 @@
 
 cc_defaults {
     name: "android.hardware.automotive@libc++fsdefaults",
-    host_supported: true,
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
     cflags: [
@@ -28,33 +27,12 @@
         "-Wno-unused-parameter",
     ],
     cppflags: [
-        "-std=c++14",
+        "-std=c++17",
         "-fexceptions",
         "-DLIBCXX_BUILDING_LIBCXXABI",
         "-D_LIBCPP_BUILDING_LIBRARY",
     ],
     rtti: true,
-    stl: "none",
-    target: {
-        linux_bionic: {
-            enabled: true,
-        },
-        windows: {
-            enabled: true,
-            cflags: [
-                "-D_LIBCPP_HAS_THREAD_API_WIN32",
-                "-D_LIBCXXABI_BUILDING_LIBRARY",
-                "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
-                "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
-                "-UWIN32_LEAN_AND_MEAN",
-            ],
-        },
-        windows_x86: {
-            cflags: [
-                "-fsjlj-exceptions",
-            ],
-        },
-    },
 }
 
 cc_library_static {
diff --git a/automotive/can/1.0/default/libc++fs/include b/automotive/can/1.0/default/libc++fs/include
deleted file mode 120000
index 346e659..0000000
--- a/automotive/can/1.0/default/libc++fs/include
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../../external/libcxx/include/
\ No newline at end of file
diff --git a/automotive/can/1.0/default/libc++fs/include/automotive/filesystem b/automotive/can/1.0/default/libc++fs/include/automotive/filesystem
new file mode 100644
index 0000000..660ad09
--- /dev/null
+++ b/automotive/can/1.0/default/libc++fs/include/automotive/filesystem
@@ -0,0 +1,2699 @@
+// -*- C++ -*-
+//===--------------------------- filesystem -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBAUTO_FILESYSTEM
+#define _LIBAUTO_FILESYSTEM
+/*
+    filesystem synopsis
+
+    namespace android::hardware::automotive { namespace filesystem {
+
+    class path;
+
+    void swap(path& lhs, path& rhs) noexcept;
+    size_t hash_value(const path& p) noexcept;
+
+    bool operator==(const path& lhs, const path& rhs) noexcept;
+    bool operator!=(const path& lhs, const path& rhs) noexcept;
+    bool operator< (const path& lhs, const path& rhs) noexcept;
+    bool operator<=(const path& lhs, const path& rhs) noexcept;
+    bool operator> (const path& lhs, const path& rhs) noexcept;
+    bool operator>=(const path& lhs, const path& rhs) noexcept;
+
+    path operator/ (const path& lhs, const path& rhs);
+
+    // fs.path.io operators are friends of path.
+    template <class charT, class traits>
+    friend basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const path& p);
+
+    template <class charT, class traits>
+    friend basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is, path& p);
+
+    template <class Source>
+      path u8path(const Source& source);
+    template <class InputIterator>
+      path u8path(InputIterator first, InputIterator last);
+
+    class filesystem_error;
+    class directory_entry;
+
+    class directory_iterator;
+
+    // enable directory_iterator range-based for statements
+    directory_iterator begin(directory_iterator iter) noexcept;
+    directory_iterator end(const directory_iterator&) noexcept;
+
+    class recursive_directory_iterator;
+
+    // enable recursive_directory_iterator range-based for statements
+    recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
+    recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
+
+    class file_status;
+
+    struct space_info
+    {
+      uintmax_t capacity;
+      uintmax_t free;
+      uintmax_t available;
+    };
+
+    enum class file_type;
+    enum class perms;
+    enum class perm_options;
+    enum class copy_options;
+    enum class directory_options;
+
+    typedef chrono::time_point<trivial-clock>  file_time_type;
+
+    // operational functions
+
+    path absolute(const path& p);
+    path absolute(const path& p, error_code &ec);
+
+    path canonical(const path& p);
+    path canonical(const path& p, error_code& ec);
+
+    void copy(const path& from, const path& to);
+    void copy(const path& from, const path& to, error_code& ec);
+    void copy(const path& from, const path& to, copy_options options);
+    void copy(const path& from, const path& to, copy_options options,
+                   error_code& ec);
+
+    bool copy_file(const path& from, const path& to);
+    bool copy_file(const path& from, const path& to, error_code& ec);
+    bool copy_file(const path& from, const path& to, copy_options option);
+    bool copy_file(const path& from, const path& to, copy_options option,
+                           error_code& ec);
+
+    void copy_symlink(const path& existing_symlink, const path& new_symlink);
+    void copy_symlink(const path& existing_symlink, const path& new_symlink,
+                              error_code& ec) noexcept;
+
+    bool create_directories(const path& p);
+    bool create_directories(const path& p, error_code& ec);
+
+    bool create_directory(const path& p);
+    bool create_directory(const path& p, error_code& ec) noexcept;
+
+    bool create_directory(const path& p, const path& attributes);
+    bool create_directory(const path& p, const path& attributes,
+                                  error_code& ec) noexcept;
+
+    void create_directory_symlink(const path& to, const path& new_symlink);
+    void create_directory_symlink(const path& to, const path& new_symlink,
+                                          error_code& ec) noexcept;
+
+    void create_hard_link(const path& to, const path& new_hard_link);
+    void create_hard_link(const path& to, const path& new_hard_link,
+                                  error_code& ec) noexcept;
+
+    void create_symlink(const path& to, const path& new_symlink);
+    void create_symlink(const path& to, const path& new_symlink,
+                                error_code& ec) noexcept;
+
+    path current_path();
+    path current_path(error_code& ec);
+    void current_path(const path& p);
+    void current_path(const path& p, error_code& ec) noexcept;
+
+    bool exists(file_status s) noexcept;
+    bool exists(const path& p);
+    bool exists(const path& p, error_code& ec) noexcept;
+
+    bool equivalent(const path& p1, const path& p2);
+    bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
+
+    uintmax_t    file_size(const path& p);
+    uintmax_t    file_size(const path& p, error_code& ec) noexcept;
+
+    uintmax_t    hard_link_count(const path& p);
+    uintmax_t    hard_link_count(const path& p, error_code& ec) noexcept;
+
+    bool is_block_file(file_status s) noexcept;
+    bool is_block_file(const path& p);
+    bool is_block_file(const path& p, error_code& ec) noexcept;
+
+    bool is_character_file(file_status s) noexcept;
+    bool is_character_file(const path& p);
+    bool is_character_file(const path& p, error_code& ec) noexcept;
+
+    bool is_directory(file_status s) noexcept;
+    bool is_directory(const path& p);
+    bool is_directory(const path& p, error_code& ec) noexcept;
+
+    bool is_empty(const path& p);
+    bool is_empty(const path& p, error_code& ec) noexcept;
+
+    bool is_fifo(file_status s) noexcept;
+    bool is_fifo(const path& p);
+    bool is_fifo(const path& p, error_code& ec) noexcept;
+
+    bool is_other(file_status s) noexcept;
+    bool is_other(const path& p);
+    bool is_other(const path& p, error_code& ec) noexcept;
+
+    bool is_regular_file(file_status s) noexcept;
+    bool is_regular_file(const path& p);
+    bool is_regular_file(const path& p, error_code& ec) noexcept;
+
+    bool is_socket(file_status s) noexcept;
+    bool is_socket(const path& p);
+    bool is_socket(const path& p, error_code& ec) noexcept;
+
+    bool is_symlink(file_status s) noexcept;
+    bool is_symlink(const path& p);
+    bool is_symlink(const path& p, error_code& ec) noexcept;
+
+    file_time_type  last_write_time(const path& p);
+    file_time_type  last_write_time(const path& p, error_code& ec) noexcept;
+    void last_write_time(const path& p, file_time_type new_time);
+    void last_write_time(const path& p, file_time_type new_time,
+                                 error_code& ec) noexcept;
+
+    void permissions(const path& p, perms prms,
+                     perm_options opts=perm_options::replace);
+    void permissions(const path& p, perms prms, error_code& ec) noexcept;
+    void permissions(const path& p, perms prms, perm_options opts,
+                     error_code& ec);
+
+    path proximate(const path& p, error_code& ec);
+    path proximate(const path& p, const path& base = current_path());
+    path proximate(const path& p, const path& base, error_code &ec);
+
+    path read_symlink(const path& p);
+    path read_symlink(const path& p, error_code& ec);
+
+    path relative(const path& p, error_code& ec);
+    path relative(const path& p, const path& base=current_path());
+    path relative(const path& p, const path& base, error_code& ec);
+
+    bool remove(const path& p);
+    bool remove(const path& p, error_code& ec) noexcept;
+
+    uintmax_t    remove_all(const path& p);
+    uintmax_t    remove_all(const path& p, error_code& ec);
+
+    void rename(const path& from, const path& to);
+    void rename(const path& from, const path& to, error_code& ec) noexcept;
+
+    void resize_file(const path& p, uintmax_t size);
+    void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;
+
+    space_info   space(const path& p);
+    space_info   space(const path& p, error_code& ec) noexcept;
+
+    file_status  status(const path& p);
+    file_status  status(const path& p, error_code& ec) noexcept;
+
+    bool status_known(file_status s) noexcept;
+
+    file_status  symlink_status(const path& p);
+    file_status  symlink_status(const path& p, error_code& ec) noexcept;
+
+    path temp_directory_path();
+    path temp_directory_path(error_code& ec);
+
+    path weakly_canonical(path const& p);
+    path weakly_canonical(path const& p, error_code& ec);
+
+
+} }  // namespace android::hardware::automotive::filesystem
+
+*/
+
+#include <__config>
+#include <cstddef>
+#include <cstdlib>
+#include <chrono>
+#include <iterator>
+#include <iosfwd>
+#include <locale>
+#include <memory>
+#include <stack>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <iomanip> // for quoted
+#include <string_view>
+#include <version>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#ifndef _LIBCPP_CXX03_LANG
+
+namespace android::hardware::automotive::filesystem {
+using namespace std;
+using namespace std::chrono;
+
+using std::basic_string;
+using std::enable_if;
+using std::error_code;
+using std::false_type;
+
+#ifndef _VSTD
+#define _LIBAUTO_UNDEF_VSTD
+#define _VSTD std
+#endif
+
+#ifdef _VSTD_FS
+#pragma push_macro("_VSTD_FS")
+#else
+#define _LIBAUTO_UNDEF_VSTD_FS
+#endif
+#define _VSTD_FS android::hardware::automotive::filesystem
+
+/* Begin copy of _FilesystemClock from include/chrono */
+struct _FilesystemClock {
+#if !defined(_LIBCPP_HAS_NO_INT128)
+  typedef __int128_t rep;
+  typedef nano period;
+#else
+  typedef long long rep;
+  typedef nano period;
+#endif
+
+  typedef chrono::duration<rep, period> duration;
+  typedef chrono::time_point<_FilesystemClock> time_point;
+
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
+
+  _LIBCPP_FUNC_VIS static time_point now() noexcept;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static time_t to_time_t(const time_point& __t) noexcept {
+      typedef chrono::duration<rep> __secs;
+      return time_t(
+          chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  static time_point from_time_t(time_t __t) noexcept {
+      typedef chrono::duration<rep> __secs;
+      return time_point(__secs(__t));
+  }
+};
+/* End copy of _FilesystemClock from include/chrono */
+
+typedef chrono::time_point<_FilesystemClock> file_time_type;
+
+struct _LIBCPP_TYPE_VIS space_info {
+  uintmax_t capacity;
+  uintmax_t free;
+  uintmax_t available;
+};
+
+enum class _LIBCPP_ENUM_VIS file_type : signed char {
+  none = 0,
+  not_found = -1,
+  regular = 1,
+  directory = 2,
+  symlink = 3,
+  block = 4,
+  character = 5,
+  fifo = 6,
+  socket = 7,
+  unknown = 8
+};
+
+enum class _LIBCPP_ENUM_VIS perms : unsigned {
+  none = 0,
+
+  owner_read = 0400,
+  owner_write = 0200,
+  owner_exec = 0100,
+  owner_all = 0700,
+
+  group_read = 040,
+  group_write = 020,
+  group_exec = 010,
+  group_all = 070,
+
+  others_read = 04,
+  others_write = 02,
+  others_exec = 01,
+  others_all = 07,
+
+  all = 0777,
+
+  set_uid = 04000,
+  set_gid = 02000,
+  sticky_bit = 01000,
+  mask = 07777,
+  unknown = 0xFFFF,
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perms operator&(perms _LHS, perms _RHS) {
+  return static_cast<perms>(static_cast<unsigned>(_LHS) &
+                            static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perms operator|(perms _LHS, perms _RHS) {
+  return static_cast<perms>(static_cast<unsigned>(_LHS) |
+                            static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perms operator^(perms _LHS, perms _RHS) {
+  return static_cast<perms>(static_cast<unsigned>(_LHS) ^
+                            static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perms operator~(perms _LHS) {
+  return static_cast<perms>(~static_cast<unsigned>(_LHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; }
+
+_LIBCPP_INLINE_VISIBILITY
+inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; }
+
+enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
+  replace = 1,
+  add = 2,
+  remove = 4,
+  nofollow = 8
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) {
+  return static_cast<perm_options>(static_cast<unsigned>(_LHS) &
+                                   static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) {
+  return static_cast<perm_options>(static_cast<unsigned>(_LHS) |
+                                   static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) {
+  return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^
+                                   static_cast<unsigned>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr perm_options operator~(perm_options _LHS) {
+  return static_cast<perm_options>(~static_cast<unsigned>(_LHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) {
+  return _LHS = _LHS & _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) {
+  return _LHS = _LHS | _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) {
+  return _LHS = _LHS ^ _RHS;
+}
+
+enum class _LIBCPP_ENUM_VIS copy_options : unsigned short {
+  none = 0,
+  skip_existing = 1,
+  overwrite_existing = 2,
+  update_existing = 4,
+  recursive = 8,
+  copy_symlinks = 16,
+  skip_symlinks = 32,
+  directories_only = 64,
+  create_symlinks = 128,
+  create_hard_links = 256,
+  __in_recursive_copy = 512,
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) {
+  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) &
+                                   static_cast<unsigned short>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) {
+  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) |
+                                   static_cast<unsigned short>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) {
+  return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^
+                                   static_cast<unsigned short>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr copy_options operator~(copy_options _LHS) {
+  return static_cast<copy_options>(~static_cast<unsigned short>(_LHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) {
+  return _LHS = _LHS & _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) {
+  return _LHS = _LHS | _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) {
+  return _LHS = _LHS ^ _RHS;
+}
+
+enum class _LIBCPP_ENUM_VIS directory_options : unsigned char {
+  none = 0,
+  follow_directory_symlink = 1,
+  skip_permission_denied = 2
+};
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr directory_options operator&(directory_options _LHS,
+                                             directory_options _RHS) {
+  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) &
+                                        static_cast<unsigned char>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr directory_options operator|(directory_options _LHS,
+                                             directory_options _RHS) {
+  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) |
+                                        static_cast<unsigned char>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr directory_options operator^(directory_options _LHS,
+                                             directory_options _RHS) {
+  return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^
+                                        static_cast<unsigned char>(_RHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline constexpr directory_options operator~(directory_options _LHS) {
+  return static_cast<directory_options>(~static_cast<unsigned char>(_LHS));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator&=(directory_options& _LHS,
+                                     directory_options _RHS) {
+  return _LHS = _LHS & _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator|=(directory_options& _LHS,
+                                     directory_options _RHS) {
+  return _LHS = _LHS | _RHS;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline directory_options& operator^=(directory_options& _LHS,
+                                     directory_options _RHS) {
+  return _LHS = _LHS ^ _RHS;
+}
+
+class _LIBCPP_TYPE_VIS file_status {
+public:
+  // constructors
+  _LIBCPP_INLINE_VISIBILITY
+  file_status() noexcept : file_status(file_type::none) {}
+  _LIBCPP_INLINE_VISIBILITY
+  explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept
+      : __ft_(__ft),
+        __prms_(__prms) {}
+
+  file_status(const file_status&) noexcept = default;
+  file_status(file_status&&) noexcept = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~file_status() {}
+
+  file_status& operator=(const file_status&) noexcept = default;
+  file_status& operator=(file_status&&) noexcept = default;
+
+  // observers
+  _LIBCPP_INLINE_VISIBILITY
+  file_type type() const noexcept { return __ft_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  perms permissions() const noexcept { return __prms_; }
+
+  // modifiers
+  _LIBCPP_INLINE_VISIBILITY
+  void type(file_type __ft) noexcept { __ft_ = __ft; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void permissions(perms __p) noexcept { __prms_ = __p; }
+
+private:
+  file_type __ft_;
+  perms __prms_;
+};
+
+class _LIBCPP_TYPE_VIS directory_entry;
+
+template <class _Tp>
+struct __can_convert_char {
+  static const bool value = false;
+};
+template <class _Tp>
+struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {};
+template <>
+struct __can_convert_char<char> {
+  static const bool value = true;
+  using __char_type = char;
+};
+template <>
+struct __can_convert_char<wchar_t> {
+  static const bool value = true;
+  using __char_type = wchar_t;
+};
+template <>
+struct __can_convert_char<char16_t> {
+  static const bool value = true;
+  using __char_type = char16_t;
+};
+template <>
+struct __can_convert_char<char32_t> {
+  static const bool value = true;
+  using __char_type = char32_t;
+};
+
+template <class _ECharT>
+typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
+__is_separator(_ECharT __e) {
+  return __e == _ECharT('/');
+}
+
+struct _NullSentinal {};
+
+template <class _Tp>
+using _Void = void;
+
+template <class _Tp, class = void>
+struct __is_pathable_string : public false_type {};
+
+template <class _ECharT, class _Traits, class _Alloc>
+struct __is_pathable_string<
+    basic_string<_ECharT, _Traits, _Alloc>,
+    _Void<typename __can_convert_char<_ECharT>::__char_type> >
+    : public __can_convert_char<_ECharT> {
+  using _Str = basic_string<_ECharT, _Traits, _Alloc>;
+  using _Base = __can_convert_char<_ECharT>;
+  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
+  static _ECharT const* __range_end(_Str const& __s) {
+    return __s.data() + __s.length();
+  }
+  static _ECharT __first_or_null(_Str const& __s) {
+    return __s.empty() ? _ECharT{} : __s[0];
+  }
+};
+
+template <class _ECharT, class _Traits>
+struct __is_pathable_string<
+    basic_string_view<_ECharT, _Traits>,
+    _Void<typename __can_convert_char<_ECharT>::__char_type> >
+    : public __can_convert_char<_ECharT> {
+  using _Str = basic_string_view<_ECharT, _Traits>;
+  using _Base = __can_convert_char<_ECharT>;
+  static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); }
+  static _ECharT const* __range_end(_Str const& __s) {
+    return __s.data() + __s.length();
+  }
+  static _ECharT __first_or_null(_Str const& __s) {
+    return __s.empty() ? _ECharT{} : __s[0];
+  }
+};
+
+template <class _Source, class _DS = typename decay<_Source>::type,
+          class _UnqualPtrType =
+              typename remove_const<typename remove_pointer<_DS>::type>::type,
+          bool _IsCharPtr = is_pointer<_DS>::value&&
+              __can_convert_char<_UnqualPtrType>::value>
+struct __is_pathable_char_array : false_type {};
+
+template <class _Source, class _ECharT, class _UPtr>
+struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true>
+    : __can_convert_char<typename remove_const<_ECharT>::type> {
+  using _Base = __can_convert_char<typename remove_const<_ECharT>::type>;
+
+  static _ECharT const* __range_begin(const _ECharT* __b) { return __b; }
+  static _ECharT const* __range_end(const _ECharT* __b) {
+    using _Iter = const _ECharT*;
+    const _ECharT __sentinal = _ECharT{};
+    _Iter __e = __b;
+    for (; *__e != __sentinal; ++__e)
+      ;
+    return __e;
+  }
+
+  static _ECharT __first_or_null(const _ECharT* __b) { return *__b; }
+};
+
+template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value,
+          class = void>
+struct __is_pathable_iter : false_type {};
+
+template <class _Iter>
+struct __is_pathable_iter<
+    _Iter, true,
+    _Void<typename __can_convert_char<
+        typename iterator_traits<_Iter>::value_type>::__char_type> >
+    : __can_convert_char<typename iterator_traits<_Iter>::value_type> {
+  using _ECharT = typename iterator_traits<_Iter>::value_type;
+  using _Base = __can_convert_char<_ECharT>;
+
+  static _Iter __range_begin(_Iter __b) { return __b; }
+  static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; }
+
+  static _ECharT __first_or_null(_Iter __b) { return *__b; }
+};
+
+template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value,
+          bool _IsCharIterT = __is_pathable_char_array<_Tp>::value,
+          bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value>
+struct __is_pathable : false_type {
+  static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false");
+};
+
+template <class _Tp>
+struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {};
+
+template <class _Tp>
+struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {
+};
+
+template <class _Tp>
+struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {};
+
+template <class _ECharT>
+struct _PathCVT {
+  static_assert(__can_convert_char<_ECharT>::value,
+                "Char type not convertible");
+
+  typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower;
+
+  static void __append_range(string& __dest, _ECharT const* __b,
+                             _ECharT const* __e) {
+    _Narrower()(back_inserter(__dest), __b, __e);
+  }
+
+  template <class _Iter>
+  static void __append_range(string& __dest, _Iter __b, _Iter __e) {
+    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
+    if (__b == __e)
+      return;
+    basic_string<_ECharT> __tmp(__b, __e);
+    _Narrower()(back_inserter(__dest), __tmp.data(),
+                __tmp.data() + __tmp.length());
+  }
+
+  template <class _Iter>
+  static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
+    static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload");
+    const _ECharT __sentinal = _ECharT{};
+    if (*__b == __sentinal)
+      return;
+    basic_string<_ECharT> __tmp;
+    for (; *__b != __sentinal; ++__b)
+      __tmp.push_back(*__b);
+    _Narrower()(back_inserter(__dest), __tmp.data(),
+                __tmp.data() + __tmp.length());
+  }
+
+  template <class _Source>
+  static void __append_source(string& __dest, _Source const& __s) {
+    using _Traits = __is_pathable<_Source>;
+    __append_range(__dest, _Traits::__range_begin(__s),
+                   _Traits::__range_end(__s));
+  }
+};
+
+template <>
+struct _PathCVT<char> {
+
+  template <class _Iter>
+  static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type
+  __append_range(string& __dest, _Iter __b, _Iter __e) {
+    for (; __b != __e; ++__b)
+      __dest.push_back(*__b);
+  }
+
+  template <class _Iter>
+  static typename enable_if<__is_forward_iterator<_Iter>::value>::type
+  __append_range(string& __dest, _Iter __b, _Iter __e) {
+    __dest.__append_forward_unsafe(__b, __e);
+  }
+
+  template <class _Iter>
+  static void __append_range(string& __dest, _Iter __b, _NullSentinal) {
+    const char __sentinal = char{};
+    for (; *__b != __sentinal; ++__b)
+      __dest.push_back(*__b);
+  }
+
+  template <class _Source>
+  static void __append_source(string& __dest, _Source const& __s) {
+    using _Traits = __is_pathable<_Source>;
+    __append_range(__dest, _Traits::__range_begin(__s),
+                   _Traits::__range_end(__s));
+  }
+};
+
+class _LIBCPP_TYPE_VIS path {
+  template <class _SourceOrIter, class _Tp = path&>
+  using _EnableIfPathable =
+      typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type;
+
+  template <class _Tp>
+  using _SourceChar = typename __is_pathable<_Tp>::__char_type;
+
+  template <class _Tp>
+  using _SourceCVT = _PathCVT<_SourceChar<_Tp> >;
+
+public:
+  typedef char value_type;
+  typedef basic_string<value_type> string_type;
+  typedef _VSTD::string_view __string_view;
+  static constexpr value_type preferred_separator = '/';
+
+  enum class _LIBCPP_ENUM_VIS format : unsigned char {
+    auto_format,
+    native_format,
+    generic_format
+  };
+
+  // constructors and destructor
+  _LIBCPP_INLINE_VISIBILITY path() noexcept {}
+  _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
+  _LIBCPP_INLINE_VISIBILITY path(path&& __p) noexcept
+      : __pn_(_VSTD::move(__p.__pn_)) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  path(string_type&& __s, format = format::auto_format) noexcept
+      : __pn_(_VSTD::move(__s)) {}
+
+  template <class _Source, class = _EnableIfPathable<_Source, void> >
+  path(const _Source& __src, format = format::auto_format) {
+    _SourceCVT<_Source>::__append_source(__pn_, __src);
+  }
+
+  template <class _InputIt>
+  path(_InputIt __first, _InputIt __last, format = format::auto_format) {
+    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+  }
+
+  // TODO Implement locale conversions.
+  template <class _Source, class = _EnableIfPathable<_Source, void> >
+  path(const _Source& __src, const locale& __loc, format = format::auto_format);
+  template <class _InputIt>
+  path(_InputIt __first, _InputIt _last, const locale& __loc,
+       format = format::auto_format);
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~path() = default;
+
+  // assignments
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator=(const path& __p) {
+    __pn_ = __p.__pn_;
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator=(path&& __p) noexcept {
+    __pn_ = _VSTD::move(__p.__pn_);
+    return *this;
+  }
+
+  template <class = void>
+  _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept {
+    __pn_ = _VSTD::move(__s);
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& assign(string_type&& __s) noexcept {
+    __pn_ = _VSTD::move(__s);
+    return *this;
+  }
+
+  template <class _Source>
+  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
+  operator=(const _Source& __src) {
+    return this->assign(__src);
+  }
+
+  template <class _Source>
+  _EnableIfPathable<_Source> assign(const _Source& __src) {
+    __pn_.clear();
+    _SourceCVT<_Source>::__append_source(__pn_, __src);
+    return *this;
+  }
+
+  template <class _InputIt>
+  path& assign(_InputIt __first, _InputIt __last) {
+    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+    __pn_.clear();
+    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+    return *this;
+  }
+
+private:
+  template <class _ECharT>
+  static bool __source_is_absolute(_ECharT __first_or_null) {
+    return __is_separator(__first_or_null);
+  }
+
+public:
+  // appends
+  path& operator/=(const path& __p) {
+    if (__p.is_absolute()) {
+      __pn_ = __p.__pn_;
+      return *this;
+    }
+    if (has_filename())
+      __pn_ += preferred_separator;
+    __pn_ += __p.native();
+    return *this;
+  }
+
+  // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
+  // is known at compile time to be "/' since the user almost certainly intended
+  // to append a separator instead of overwriting the path with "/"
+  template <class _Source>
+  _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source>
+  operator/=(const _Source& __src) {
+    return this->append(__src);
+  }
+
+  template <class _Source>
+  _EnableIfPathable<_Source> append(const _Source& __src) {
+    using _Traits = __is_pathable<_Source>;
+    using _CVT = _PathCVT<_SourceChar<_Source> >;
+    if (__source_is_absolute(_Traits::__first_or_null(__src)))
+      __pn_.clear();
+    else if (has_filename())
+      __pn_ += preferred_separator;
+    _CVT::__append_source(__pn_, __src);
+    return *this;
+  }
+
+  template <class _InputIt>
+  path& append(_InputIt __first, _InputIt __last) {
+    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+    static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
+    using _CVT = _PathCVT<_ItVal>;
+    if (__first != __last && __source_is_absolute(*__first))
+      __pn_.clear();
+    else if (has_filename())
+      __pn_ += preferred_separator;
+    _CVT::__append_range(__pn_, __first, __last);
+    return *this;
+  }
+
+  // concatenation
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator+=(const path& __x) {
+    __pn_ += __x.__pn_;
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator+=(const string_type& __x) {
+    __pn_ += __x;
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator+=(__string_view __x) {
+    __pn_ += __x;
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator+=(const value_type* __x) {
+    __pn_ += __x;
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& operator+=(value_type __x) {
+    __pn_ += __x;
+    return *this;
+  }
+
+  template <class _ECharT>
+  typename enable_if<__can_convert_char<_ECharT>::value, path&>::type
+  operator+=(_ECharT __x) {
+    basic_string<_ECharT> __tmp;
+    __tmp += __x;
+    _PathCVT<_ECharT>::__append_source(__pn_, __tmp);
+    return *this;
+  }
+
+  template <class _Source>
+  _EnableIfPathable<_Source> operator+=(const _Source& __x) {
+    return this->concat(__x);
+  }
+
+  template <class _Source>
+  _EnableIfPathable<_Source> concat(const _Source& __x) {
+    _SourceCVT<_Source>::__append_source(__pn_, __x);
+    return *this;
+  }
+
+  template <class _InputIt>
+  path& concat(_InputIt __first, _InputIt __last) {
+    typedef typename iterator_traits<_InputIt>::value_type _ItVal;
+    _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
+    return *this;
+  }
+
+  // modifiers
+  _LIBCPP_INLINE_VISIBILITY
+  void clear() noexcept { __pn_.clear(); }
+
+  path& make_preferred() { return *this; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  path& remove_filename() {
+    auto __fname = __filename();
+    if (!__fname.empty())
+      __pn_.erase(__fname.data() - __pn_.data());
+    return *this;
+  }
+
+  path& replace_filename(const path& __replacement) {
+    remove_filename();
+    return (*this /= __replacement);
+  }
+
+  path& replace_extension(const path& __replacement = path());
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); }
+
+  // private helper to allow reserving memory in the path
+  _LIBCPP_INLINE_VISIBILITY
+  void __reserve(size_t __s) { __pn_.reserve(__s); }
+
+  // native format observers
+  _LIBCPP_INLINE_VISIBILITY
+  const string_type& native() const noexcept { return __pn_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const value_type* c_str() const noexcept { return __pn_.c_str(); }
+
+  _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
+
+  template <class _ECharT, class _Traits = char_traits<_ECharT>,
+            class _Allocator = allocator<_ECharT> >
+  basic_string<_ECharT, _Traits, _Allocator>
+  string(const _Allocator& __a = _Allocator()) const {
+    using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>;
+    using _Str = basic_string<_ECharT, _Traits, _Allocator>;
+    _Str __s(__a);
+    __s.reserve(__pn_.size());
+    _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size());
+    return __s;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; }
+  _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const {
+    return string<wchar_t>();
+  }
+  _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; }
+  _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const {
+    return string<char16_t>();
+  }
+  _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const {
+    return string<char32_t>();
+  }
+
+  // generic format observers
+  template <class _ECharT, class _Traits = char_traits<_ECharT>,
+            class _Allocator = allocator<_ECharT> >
+  basic_string<_ECharT, _Traits, _Allocator>
+  generic_string(const _Allocator& __a = _Allocator()) const {
+    return string<_ECharT, _Traits, _Allocator>(__a);
+  }
+
+  std::string generic_string() const { return __pn_; }
+  std::wstring generic_wstring() const { return string<wchar_t>(); }
+  std::string generic_u8string() const { return __pn_; }
+  std::u16string generic_u16string() const { return string<char16_t>(); }
+  std::u32string generic_u32string() const { return string<char32_t>(); }
+
+private:
+  int __compare(__string_view) const;
+  __string_view __root_name() const;
+  __string_view __root_directory() const;
+  __string_view __root_path_raw() const;
+  __string_view __relative_path() const;
+  __string_view __parent_path() const;
+  __string_view __filename() const;
+  __string_view __stem() const;
+  __string_view __extension() const;
+
+public:
+  // compare
+  _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept {
+    return __compare(__p.__pn_);
+  }
+  _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const {
+    return __compare(__s);
+  }
+  _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const {
+    return __compare(__s);
+  }
+  _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const {
+    return __compare(__s);
+  }
+
+  // decomposition
+  _LIBCPP_INLINE_VISIBILITY path root_name() const {
+    return string_type(__root_name());
+  }
+  _LIBCPP_INLINE_VISIBILITY path root_directory() const {
+    return string_type(__root_directory());
+  }
+  _LIBCPP_INLINE_VISIBILITY path root_path() const {
+    return root_name().append(string_type(__root_directory()));
+  }
+  _LIBCPP_INLINE_VISIBILITY path relative_path() const {
+    return string_type(__relative_path());
+  }
+  _LIBCPP_INLINE_VISIBILITY path parent_path() const {
+    return string_type(__parent_path());
+  }
+  _LIBCPP_INLINE_VISIBILITY path filename() const {
+    return string_type(__filename());
+  }
+  _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); }
+  _LIBCPP_INLINE_VISIBILITY path extension() const {
+    return string_type(__extension());
+  }
+
+  // query
+  _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool
+  empty() const noexcept {
+    return __pn_.empty();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY bool has_root_name() const {
+    return !__root_name().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const {
+    return !__root_directory().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_root_path() const {
+    return !__root_path_raw().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const {
+    return !__relative_path().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const {
+    return !__parent_path().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_filename() const {
+    return !__filename().empty();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); }
+  _LIBCPP_INLINE_VISIBILITY bool has_extension() const {
+    return !__extension().empty();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY bool is_absolute() const {
+    return has_root_directory();
+  }
+  _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
+
+  // relative paths
+  path lexically_normal() const;
+  path lexically_relative(const path& __base) const;
+
+  _LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
+    path __result = this->lexically_relative(__base);
+    if (__result.native().empty())
+      return *this;
+    return __result;
+  }
+
+  // iterators
+  class _LIBCPP_TYPE_VIS iterator;
+  typedef iterator const_iterator;
+
+  iterator begin() const;
+  iterator end() const;
+
+  template <class _CharT, class _Traits>
+  _LIBCPP_INLINE_VISIBILITY friend
+      typename enable_if<is_same<_CharT, char>::value &&
+                             is_same<_Traits, char_traits<char> >::value,
+                         basic_ostream<_CharT, _Traits>&>::type
+      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+    __os << std::__quoted(__p.native());
+    return __os;
+  }
+
+  template <class _CharT, class _Traits>
+  _LIBCPP_INLINE_VISIBILITY friend
+      typename enable_if<!is_same<_CharT, char>::value ||
+                             !is_same<_Traits, char_traits<char> >::value,
+                         basic_ostream<_CharT, _Traits>&>::type
+      operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) {
+    __os << std::__quoted(__p.string<_CharT, _Traits>());
+    return __os;
+  }
+
+  template <class _CharT, class _Traits>
+  _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>&
+  operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) {
+    basic_string<_CharT, _Traits> __tmp;
+    __is >> __quoted(__tmp);
+    __p = __tmp;
+    return __is;
+  }
+
+  friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) == 0;
+  }
+  friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) != 0;
+  }
+  friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) < 0;
+  }
+  friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) <= 0;
+  }
+  friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) > 0;
+  }
+  friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
+    return __lhs.compare(__rhs) >= 0;
+  }
+
+  friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
+                                                  const path& __rhs) {
+    path __result(__lhs);
+    __result /= __rhs;
+    return __result;
+  }
+private:
+  inline _LIBCPP_INLINE_VISIBILITY path&
+  __assign_view(__string_view const& __s) noexcept {
+    __pn_ = string_type(__s);
+    return *this;
+  }
+  string_type __pn_;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
+  __lhs.swap(__rhs);
+}
+
+_LIBCPP_FUNC_VIS
+size_t hash_value(const path& __p) noexcept;
+
+template <class _Source>
+_LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_pathable<_Source>::value, path>::type
+    u8path(const _Source& __s) {
+  static_assert(
+      is_same<typename __is_pathable<_Source>::__char_type, char>::value,
+      "u8path(Source const&) requires Source have a character type of type "
+      "'char'");
+  return path(__s);
+}
+
+template <class _InputIt>
+_LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_pathable<_InputIt>::value, path>::type
+    u8path(_InputIt __f, _InputIt __l) {
+  static_assert(
+      is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
+      "u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
+  return path(__f, __l);
+}
+
+class _LIBCPP_TYPE_VIS path::iterator {
+public:
+  enum _ParserState : unsigned char {
+    _Singular,
+    _BeforeBegin,
+    _InRootName,
+    _InRootDir,
+    _InFilenames,
+    _InTrailingSep,
+    _AtEnd
+  };
+
+public:
+  typedef bidirectional_iterator_tag iterator_category;
+
+  typedef path value_type;
+  typedef std::ptrdiff_t difference_type;
+  typedef const path* pointer;
+  typedef const path& reference;
+
+  typedef void
+      __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator
+
+public:
+  _LIBCPP_INLINE_VISIBILITY
+  iterator()
+      : __stashed_elem_(), __path_ptr_(nullptr), __entry_(),
+        __state_(_Singular) {}
+
+  iterator(const iterator&) = default;
+  ~iterator() = default;
+
+  iterator& operator=(const iterator&) = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  reference operator*() const { return __stashed_elem_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  pointer operator->() const { return &__stashed_elem_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  iterator& operator++() {
+    _LIBCPP_ASSERT(__state_ != _Singular,
+                   "attempting to increment a singular iterator");
+    _LIBCPP_ASSERT(__state_ != _AtEnd,
+                   "attempting to increment the end iterator");
+    return __increment();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  iterator operator++(int) {
+    iterator __it(*this);
+    this->operator++();
+    return __it;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  iterator& operator--() {
+    _LIBCPP_ASSERT(__state_ != _Singular,
+                   "attempting to decrement a singular iterator");
+    _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(),
+                   "attempting to decrement the begin iterator");
+    return __decrement();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  iterator operator--(int) {
+    iterator __it(*this);
+    this->operator--();
+    return __it;
+  }
+
+private:
+  friend class path;
+
+  inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&,
+                                                          const iterator&);
+
+  iterator& __increment();
+  iterator& __decrement();
+
+  path __stashed_elem_;
+  const path* __path_ptr_;
+  path::__string_view __entry_;
+  _ParserState __state_;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs,
+                                                 const path::iterator& __rhs) {
+  return __lhs.__path_ptr_ == __rhs.__path_ptr_ &&
+         __lhs.__entry_.data() == __rhs.__entry_.data();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs,
+                                                 const path::iterator& __rhs) {
+  return !(__lhs == __rhs);
+}
+
+class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error {
+public:
+  _LIBCPP_INLINE_VISIBILITY
+  filesystem_error(const string& __what, error_code __ec)
+      : system_error(__ec, __what),
+        __storage_(make_shared<_Storage>(path(), path())) {
+    __create_what(0);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  filesystem_error(const string& __what, const path& __p1, error_code __ec)
+      : system_error(__ec, __what),
+        __storage_(make_shared<_Storage>(__p1, path())) {
+    __create_what(1);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  filesystem_error(const string& __what, const path& __p1, const path& __p2,
+                   error_code __ec)
+      : system_error(__ec, __what),
+        __storage_(make_shared<_Storage>(__p1, __p2)) {
+    __create_what(2);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const path& path1() const noexcept { return __storage_->__p1_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const path& path2() const noexcept { return __storage_->__p2_; }
+
+  ~filesystem_error() override; // key function
+
+  _LIBCPP_INLINE_VISIBILITY
+  const char* what() const noexcept override {
+    return __storage_->__what_.c_str();
+  }
+
+  _LIBCPP_FUNC_VIS
+  void __create_what(int __num_paths);
+
+private:
+  struct _Storage {
+    _LIBCPP_INLINE_VISIBILITY
+    _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {}
+
+    path __p1_;
+    path __p2_;
+    string __what_;
+  };
+  shared_ptr<_Storage> __storage_;
+};
+
+template <class... _Args>
+_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    void
+    __throw_filesystem_error(_Args&&... __args) {
+  throw filesystem_error(std::forward<_Args>(__args)...);
+}
+#else
+    void
+    __throw_filesystem_error(_Args&&...) {
+  _VSTD::abort();
+}
+#endif
+
+// operational functions
+
+_LIBCPP_FUNC_VIS
+path __absolute(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+path __canonical(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __copy(const path& __from, const path& __to, copy_options __opt,
+            error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __copy_file(const path& __from, const path& __to, copy_options __opt,
+                 error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __copy_symlink(const path& __existing_symlink, const path& __new_symlink,
+                    error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directories(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directory(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __create_directory(const path& p, const path& attributes,
+                        error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __create_directory_symlink(const path& __to, const path& __new_symlink,
+                                error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __create_hard_link(const path& __to, const path& __new_hard_link,
+                        error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __create_symlink(const path& __to, const path& __new_symlink,
+                      error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+path __current_path(error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __current_path(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __equivalent(const path&, const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __file_size(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __fs_is_empty(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+file_time_type __last_write_time(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __last_write_time(const path& p, file_time_type new_time,
+                       error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __permissions(const path&, perms, perm_options, error_code* = nullptr);
+_LIBCPP_FUNC_VIS
+path __read_symlink(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+bool __remove(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+uintmax_t __remove_all(const path& p, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __rename(const path& from, const path& to, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr);
+_LIBCPP_FUNC_VIS
+space_info __space(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+file_status __status(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+file_status __symlink_status(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+path __system_complete(const path&, error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+path __temp_directory_path(error_code* __ec = nullptr);
+_LIBCPP_FUNC_VIS
+path __weakly_canonical(path const& __p, error_code* __ec = nullptr);
+
+inline _LIBCPP_INLINE_VISIBILITY path current_path() {
+  return __current_path();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) {
+  return __current_path(&__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) {
+  __current_path(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p,
+                                                   error_code& __ec) noexcept {
+  __current_path(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) {
+  return __absolute(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p,
+                                               error_code& __ec) {
+  return __absolute(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) {
+  return __canonical(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p,
+                                                error_code& __ec) {
+  return __canonical(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from,
+                                           const path& __to) {
+  __copy(__from, __to, copy_options::none);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
+                                           error_code& __ec) {
+  __copy(__from, __to, copy_options::none, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
+                                           copy_options __opt) {
+  __copy(__from, __to, __opt);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to,
+                                           copy_options __opt,
+                                           error_code& __ec) {
+  __copy(__from, __to, __opt, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
+                                                const path& __to) {
+  return __copy_file(__from, __to, copy_options::none);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+copy_file(const path& __from, const path& __to, error_code& __ec) {
+  return __copy_file(__from, __to, copy_options::none, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+copy_file(const path& __from, const path& __to, copy_options __opt) {
+  return __copy_file(__from, __to, __opt);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from,
+                                                const path& __to,
+                                                copy_options __opt,
+                                                error_code& __ec) {
+  return __copy_file(__from, __to, __opt, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing,
+                                                   const path& __new) {
+  __copy_symlink(__existing, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept {
+  __copy_symlink(__ext, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) {
+  return __create_directories(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p,
+                                                         error_code& __ec) {
+  return __create_directories(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) {
+  return __create_directory(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+create_directory(const path& __p, error_code& __ec) noexcept {
+  return __create_directory(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p,
+                                                       const path& __attrs) {
+  return __create_directory(__p, __attrs);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+create_directory(const path& __p, const path& __attrs,
+                 error_code& __ec) noexcept {
+  return __create_directory(__p, __attrs, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+create_directory_symlink(const path& __to, const path& __new) {
+  __create_directory_symlink(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+create_directory_symlink(const path& __to, const path& __new,
+                         error_code& __ec) noexcept {
+  __create_directory_symlink(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to,
+                                                       const path& __new) {
+  __create_hard_link(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+create_hard_link(const path& __to, const path& __new,
+                 error_code& __ec) noexcept {
+  __create_hard_link(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to,
+                                                     const path& __new) {
+  __create_symlink(__to, __new);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept {
+  return __create_symlink(__to, __new, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept {
+  return __s.type() != file_type::none;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept {
+  return status_known(__s) && __s.type() != file_type::not_found;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) {
+  return exists(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p,
+                                             error_code& __ec) noexcept {
+  auto __s = __status(__p, &__ec);
+  if (status_known(__s))
+    __ec.clear();
+  return exists(__s);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1,
+                                                 const path& __p2) {
+  return __equivalent(__p1, __p2);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
+  return __equivalent(__p1, __p2, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) {
+  return __file_size(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t
+file_size(const path& __p, error_code& __ec) noexcept {
+  return __file_size(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) {
+  return __hard_link_count(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t
+hard_link_count(const path& __p, error_code& __ec) noexcept {
+  return __hard_link_count(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept {
+  return __s.type() == file_type::block;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) {
+  return is_block_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p,
+                                                    error_code& __ec) noexcept {
+  return is_block_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+is_character_file(file_status __s) noexcept {
+  return __s.type() == file_type::character;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) {
+  return is_character_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+is_character_file(const path& __p, error_code& __ec) noexcept {
+  return is_character_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept {
+  return __s.type() == file_type::directory;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) {
+  return is_directory(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p,
+                                                   error_code& __ec) noexcept {
+  return is_directory(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) {
+  return __fs_is_empty(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p,
+                                               error_code& __ec) {
+  return __fs_is_empty(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept {
+  return __s.type() == file_type::fifo;
+}
+inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) {
+  return is_fifo(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p,
+                                              error_code& __ec) noexcept {
+  return is_fifo(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+is_regular_file(file_status __s) noexcept {
+  return __s.type() == file_type::regular;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) {
+  return is_regular_file(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+is_regular_file(const path& __p, error_code& __ec) noexcept {
+  return is_regular_file(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept {
+  return __s.type() == file_type::socket;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) {
+  return is_socket(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p,
+                                                error_code& __ec) noexcept {
+  return is_socket(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept {
+  return __s.type() == file_type::symlink;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) {
+  return is_symlink(__symlink_status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p,
+                                                 error_code& __ec) noexcept {
+  return is_symlink(__symlink_status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept {
+  return exists(__s) && !is_regular_file(__s) && !is_directory(__s) &&
+         !is_symlink(__s);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) {
+  return is_other(__status(__p));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p,
+                                               error_code& __ec) noexcept {
+  return is_other(__status(__p, &__ec));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_time_type
+last_write_time(const path& __p) {
+  return __last_write_time(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_time_type
+last_write_time(const path& __p, error_code& __ec) noexcept {
+  return __last_write_time(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p,
+                                                      file_time_type __t) {
+  __last_write_time(__p, __t);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+last_write_time(const path& __p, file_time_type __t,
+                error_code& __ec) noexcept {
+  __last_write_time(__p, __t, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+permissions(const path& __p, perms __prms,
+            perm_options __opts = perm_options::replace) {
+  __permissions(__p, __prms, __opts);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
+                                                  error_code& __ec) noexcept {
+  __permissions(__p, __prms, perm_options::replace, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms,
+                                                  perm_options __opts,
+                                                  error_code& __ec) {
+  __permissions(__p, __prms, __opts, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
+                                                const path& __base,
+                                                error_code& __ec) {
+  path __tmp = __weakly_canonical(__p, &__ec);
+  if (__ec)
+    return {};
+  path __tmp_base = __weakly_canonical(__base, &__ec);
+  if (__ec)
+    return {};
+  return __tmp.lexically_proximate(__tmp_base);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p,
+                                                error_code& __ec) {
+  return proximate(__p, current_path(), __ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path
+proximate(const path& __p, const path& __base = current_path()) {
+  return __weakly_canonical(__p).lexically_proximate(
+      __weakly_canonical(__base));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) {
+  return __read_symlink(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p,
+                                                   error_code& __ec) {
+  return __read_symlink(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
+                                               const path& __base,
+                                               error_code& __ec) {
+  path __tmp = __weakly_canonical(__p, &__ec);
+  if (__ec)
+    return path();
+  path __tmpbase = __weakly_canonical(__base, &__ec);
+  if (__ec)
+    return path();
+  return __tmp.lexically_relative(__tmpbase);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p,
+                                               error_code& __ec) {
+  return relative(__p, current_path(), __ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path
+relative(const path& __p, const path& __base = current_path()) {
+  return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) {
+  return __remove(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p,
+                                             error_code& __ec) noexcept {
+  return __remove(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) {
+  return __remove_all(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p,
+                                                      error_code& __ec) {
+  return __remove_all(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from,
+                                             const path& __to) {
+  return __rename(__from, __to);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+rename(const path& __from, const path& __to, error_code& __ec) noexcept {
+  return __rename(__from, __to, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p,
+                                                  uintmax_t __ns) {
+  return __resize_file(__p, __ns);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void
+resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept {
+  return __resize_file(__p, __ns, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) {
+  return __space(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p,
+                                                  error_code& __ec) noexcept {
+  return __space(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) {
+  return __status(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p,
+                                                    error_code& __ec) noexcept {
+  return __status(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) {
+  return __symlink_status(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY file_status
+symlink_status(const path& __p, error_code& __ec) noexcept {
+  return __symlink_status(__p, &__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() {
+  return __temp_directory_path();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) {
+  return __temp_directory_path(&__ec);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) {
+  return __weakly_canonical(__p);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p,
+                                                       error_code& __ec) {
+  return __weakly_canonical(__p, &__ec);
+}
+
+class directory_iterator;
+class recursive_directory_iterator;
+class __dir_stream;
+
+class directory_entry {
+  typedef _VSTD_FS::path _Path;
+
+public:
+  // constructors and destructors
+  directory_entry() noexcept = default;
+  directory_entry(directory_entry const&) = default;
+  directory_entry(directory_entry&&) noexcept = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  explicit directory_entry(_Path const& __p) : __p_(__p) {
+    error_code __ec;
+    __refresh(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) {
+    __refresh(&__ec);
+  }
+
+  ~directory_entry() {}
+
+  directory_entry& operator=(directory_entry const&) = default;
+  directory_entry& operator=(directory_entry&&) noexcept = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  void assign(_Path const& __p) {
+    __p_ = __p;
+    error_code __ec;
+    __refresh(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void assign(_Path const& __p, error_code& __ec) {
+    __p_ = __p;
+    __refresh(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void replace_filename(_Path const& __p) {
+    __p_.replace_filename(__p);
+    error_code __ec;
+    __refresh(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void replace_filename(_Path const& __p, error_code& __ec) {
+    __p_ = __p_.parent_path() / __p;
+    __refresh(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void refresh() { __refresh(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  _Path const& path() const noexcept { return __p_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  operator const _Path&() const noexcept { return __p_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool exists(error_code& __ec) const noexcept {
+    return _VSTD_FS::exists(file_status{__get_ft(&__ec)});
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_block_file() const { return __get_ft() == file_type::block; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_block_file(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::block;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_character_file() const { return __get_ft() == file_type::character; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_character_file(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::character;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_directory() const { return __get_ft() == file_type::directory; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_directory(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::directory;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_fifo() const { return __get_ft() == file_type::fifo; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_fifo(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::fifo;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_other(error_code& __ec) const noexcept {
+    return _VSTD_FS::is_other(file_status{__get_ft(&__ec)});
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_regular_file() const { return __get_ft() == file_type::regular; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_regular_file(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::regular;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_socket() const { return __get_ft() == file_type::socket; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_socket(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::socket;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool is_symlink(error_code& __ec) const noexcept {
+    return __get_sym_ft(&__ec) == file_type::symlink;
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t file_size() const { return __get_size(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t file_size(error_code& __ec) const noexcept {
+    return __get_size(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t hard_link_count() const { return __get_nlink(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t hard_link_count(error_code& __ec) const noexcept {
+    return __get_nlink(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_time_type last_write_time() const { return __get_write_time(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_time_type last_write_time(error_code& __ec) const noexcept {
+    return __get_write_time(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status status() const { return __get_status(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status status(error_code& __ec) const noexcept {
+    return __get_status(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status symlink_status() const { return __get_symlink_status(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status symlink_status(error_code& __ec) const noexcept {
+    return __get_symlink_status(&__ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator<(directory_entry const& __rhs) const noexcept {
+    return __p_ < __rhs.__p_;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator==(directory_entry const& __rhs) const noexcept {
+    return __p_ == __rhs.__p_;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator!=(directory_entry const& __rhs) const noexcept {
+    return __p_ != __rhs.__p_;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator<=(directory_entry const& __rhs) const noexcept {
+    return __p_ <= __rhs.__p_;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator>(directory_entry const& __rhs) const noexcept {
+    return __p_ > __rhs.__p_;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool operator>=(directory_entry const& __rhs) const noexcept {
+    return __p_ >= __rhs.__p_;
+  }
+
+private:
+  friend class directory_iterator;
+  friend class recursive_directory_iterator;
+  friend class __dir_stream;
+
+  enum _CacheType : unsigned char {
+    _Empty,
+    _IterSymlink,
+    _IterNonSymlink,
+    _RefreshSymlink,
+    _RefreshSymlinkUnresolved,
+    _RefreshNonSymlink
+  };
+
+  struct __cached_data {
+    uintmax_t __size_;
+    uintmax_t __nlink_;
+    file_time_type __write_time_;
+    perms __sym_perms_;
+    perms __non_sym_perms_;
+    file_type __type_;
+    _CacheType __cache_type_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __cached_data() noexcept { __reset(); }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __reset() {
+      __cache_type_ = _Empty;
+      __type_ = file_type::none;
+      __sym_perms_ = __non_sym_perms_ = perms::unknown;
+      __size_ = __nlink_ = uintmax_t(-1);
+      __write_time_ = file_time_type::min();
+    }
+  };
+
+  _LIBCPP_INLINE_VISIBILITY
+  static __cached_data __create_iter_result(file_type __ft) {
+    __cached_data __data;
+    __data.__type_ = __ft;
+    __data.__cache_type_ = [&]() {
+      switch (__ft) {
+      case file_type::none:
+        return _Empty;
+      case file_type::symlink:
+        return _IterSymlink;
+      default:
+        return _IterNonSymlink;
+      }
+    }();
+    return __data;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
+    __p_ = std::move(__p);
+    __data_ = __dt;
+  }
+
+  _LIBCPP_FUNC_VIS
+  error_code __do_refresh() noexcept;
+
+  _LIBCPP_INLINE_VISIBILITY
+  static bool __is_dne_error(error_code const& __ec) {
+    if (!__ec)
+      return true;
+    switch (static_cast<errc>(__ec.value())) {
+    case errc::no_such_file_or_directory:
+    case errc::not_a_directory:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __handle_error(const char* __msg, error_code* __dest_ec,
+                      error_code const& __ec, bool __allow_dne = false) const {
+    if (__dest_ec) {
+      *__dest_ec = __ec;
+      return;
+    }
+    if (__ec && (!__allow_dne || !__is_dne_error(__ec)))
+      __throw_filesystem_error(__msg, __p_, __ec);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void __refresh(error_code* __ec = nullptr) {
+    __handle_error("in directory_entry::refresh", __ec, __do_refresh(),
+                   /*allow_dne*/ true);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_type __get_sym_ft(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+      return __symlink_status(__p_, __ec).type();
+    case _IterSymlink:
+    case _RefreshSymlink:
+    case _RefreshSymlinkUnresolved:
+      if (__ec)
+        __ec->clear();
+      return file_type::symlink;
+    case _IterNonSymlink:
+    case _RefreshNonSymlink:
+      file_status __st(__data_.__type_);
+      if (__ec && !_VSTD_FS::exists(__st))
+        *__ec = make_error_code(errc::no_such_file_or_directory);
+      else if (__ec)
+        __ec->clear();
+      return __data_.__type_;
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_type __get_ft(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterSymlink:
+    case _RefreshSymlinkUnresolved:
+      return __status(__p_, __ec).type();
+    case _IterNonSymlink:
+    case _RefreshNonSymlink:
+    case _RefreshSymlink: {
+      file_status __st(__data_.__type_);
+      if (__ec && !_VSTD_FS::exists(__st))
+        *__ec = make_error_code(errc::no_such_file_or_directory);
+      else if (__ec)
+        __ec->clear();
+      return __data_.__type_;
+    }
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status __get_status(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterNonSymlink:
+    case _IterSymlink:
+    case _RefreshSymlinkUnresolved:
+      return __status(__p_, __ec);
+    case _RefreshNonSymlink:
+    case _RefreshSymlink:
+      return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_status __get_symlink_status(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterNonSymlink:
+    case _IterSymlink:
+      return __symlink_status(__p_, __ec);
+    case _RefreshNonSymlink:
+      return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
+    case _RefreshSymlink:
+    case _RefreshSymlinkUnresolved:
+      return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t __get_size(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterNonSymlink:
+    case _IterSymlink:
+    case _RefreshSymlinkUnresolved:
+      return _VSTD_FS::__file_size(__p_, __ec);
+    case _RefreshSymlink:
+    case _RefreshNonSymlink: {
+      error_code __m_ec;
+      file_status __st(__get_ft(&__m_ec));
+      __handle_error("in directory_entry::file_size", __ec, __m_ec);
+      if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) {
+        errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory
+                                                       : errc::not_supported;
+        __handle_error("in directory_entry::file_size", __ec,
+                       make_error_code(__err_kind));
+      }
+      return __data_.__size_;
+    }
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  uintmax_t __get_nlink(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterNonSymlink:
+    case _IterSymlink:
+    case _RefreshSymlinkUnresolved:
+      return _VSTD_FS::__hard_link_count(__p_, __ec);
+    case _RefreshSymlink:
+    case _RefreshNonSymlink: {
+      error_code __m_ec;
+      (void)__get_ft(&__m_ec);
+      __handle_error("in directory_entry::hard_link_count", __ec, __m_ec);
+      return __data_.__nlink_;
+    }
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  file_time_type __get_write_time(error_code* __ec = nullptr) const {
+    switch (__data_.__cache_type_) {
+    case _Empty:
+    case _IterNonSymlink:
+    case _IterSymlink:
+    case _RefreshSymlinkUnresolved:
+      return _VSTD_FS::__last_write_time(__p_, __ec);
+    case _RefreshSymlink:
+    case _RefreshNonSymlink: {
+      error_code __m_ec;
+      file_status __st(__get_ft(&__m_ec));
+      __handle_error("in directory_entry::last_write_time", __ec, __m_ec);
+      if (_VSTD_FS::exists(__st) &&
+          __data_.__write_time_ == file_time_type::min())
+        __handle_error("in directory_entry::last_write_time", __ec,
+                       make_error_code(errc::value_too_large));
+      return __data_.__write_time_;
+    }
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+private:
+  _Path __p_;
+  __cached_data __data_;
+};
+
+class __dir_element_proxy {
+public:
+  inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() {
+    return _VSTD::move(__elem_);
+  }
+
+private:
+  friend class directory_iterator;
+  friend class recursive_directory_iterator;
+  explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {}
+  __dir_element_proxy(__dir_element_proxy&& __o)
+      : __elem_(_VSTD::move(__o.__elem_)) {}
+  directory_entry __elem_;
+};
+
+class directory_iterator {
+public:
+  typedef directory_entry value_type;
+  typedef ptrdiff_t difference_type;
+  typedef value_type const* pointer;
+  typedef value_type const& reference;
+  typedef input_iterator_tag iterator_category;
+
+public:
+  //ctor & dtor
+  directory_iterator() noexcept {}
+
+  explicit directory_iterator(const path& __p)
+      : directory_iterator(__p, nullptr) {}
+
+  directory_iterator(const path& __p, directory_options __opts)
+      : directory_iterator(__p, nullptr, __opts) {}
+
+  directory_iterator(const path& __p, error_code& __ec)
+      : directory_iterator(__p, &__ec) {}
+
+  directory_iterator(const path& __p, directory_options __opts,
+                     error_code& __ec)
+      : directory_iterator(__p, &__ec, __opts) {}
+
+  directory_iterator(const directory_iterator&) = default;
+  directory_iterator(directory_iterator&&) = default;
+  directory_iterator& operator=(const directory_iterator&) = default;
+
+  directory_iterator& operator=(directory_iterator&& __o) noexcept {
+    // non-default implementation provided to support self-move assign.
+    if (this != &__o) {
+      __imp_ = _VSTD::move(__o.__imp_);
+    }
+    return *this;
+  }
+
+  ~directory_iterator() = default;
+
+  const directory_entry& operator*() const {
+    _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced");
+    return __dereference();
+  }
+
+  const directory_entry* operator->() const { return &**this; }
+
+  directory_iterator& operator++() { return __increment(); }
+
+  __dir_element_proxy operator++(int) {
+    __dir_element_proxy __p(**this);
+    __increment();
+    return __p;
+  }
+
+  directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
+
+private:
+  inline _LIBCPP_INLINE_VISIBILITY friend bool
+  operator==(const directory_iterator& __lhs,
+             const directory_iterator& __rhs) noexcept;
+
+  // construct the dir_stream
+  _LIBCPP_FUNC_VIS
+  directory_iterator(const path&, error_code*,
+                     directory_options = directory_options::none);
+
+  _LIBCPP_FUNC_VIS
+  directory_iterator& __increment(error_code* __ec = nullptr);
+
+  _LIBCPP_FUNC_VIS
+  const directory_entry& __dereference() const;
+
+private:
+  shared_ptr<__dir_stream> __imp_;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+operator==(const directory_iterator& __lhs,
+           const directory_iterator& __rhs) noexcept {
+  return __lhs.__imp_ == __rhs.__imp_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+operator!=(const directory_iterator& __lhs,
+           const directory_iterator& __rhs) noexcept {
+  return !(__lhs == __rhs);
+}
+
+// enable directory_iterator range-based for statements
+inline _LIBCPP_INLINE_VISIBILITY directory_iterator
+begin(directory_iterator __iter) noexcept {
+  return __iter;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY directory_iterator
+end(const directory_iterator&) noexcept {
+  return directory_iterator();
+}
+
+class recursive_directory_iterator {
+public:
+  using value_type = directory_entry;
+  using difference_type = std::ptrdiff_t;
+  using pointer = directory_entry const*;
+  using reference = directory_entry const&;
+  using iterator_category = std::input_iterator_tag;
+
+public:
+  // constructors and destructor
+  _LIBCPP_INLINE_VISIBILITY
+  recursive_directory_iterator() noexcept : __rec_(false) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  explicit recursive_directory_iterator(
+      const path& __p, directory_options __xoptions = directory_options::none)
+      : recursive_directory_iterator(__p, __xoptions, nullptr) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  recursive_directory_iterator(const path& __p, directory_options __xoptions,
+                               error_code& __ec)
+      : recursive_directory_iterator(__p, __xoptions, &__ec) {}
+
+  _LIBCPP_INLINE_VISIBILITY
+  recursive_directory_iterator(const path& __p, error_code& __ec)
+      : recursive_directory_iterator(__p, directory_options::none, &__ec) {}
+
+  recursive_directory_iterator(const recursive_directory_iterator&) = default;
+  recursive_directory_iterator(recursive_directory_iterator&&) = default;
+
+  recursive_directory_iterator&
+  operator=(const recursive_directory_iterator&) = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  recursive_directory_iterator&
+  operator=(recursive_directory_iterator&& __o) noexcept {
+    // non-default implementation provided to support self-move assign.
+    if (this != &__o) {
+      __imp_ = _VSTD::move(__o.__imp_);
+      __rec_ = __o.__rec_;
+    }
+    return *this;
+  }
+
+  ~recursive_directory_iterator() = default;
+
+  _LIBCPP_INLINE_VISIBILITY
+  const directory_entry& operator*() const { return __dereference(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const directory_entry* operator->() const { return &__dereference(); }
+
+  recursive_directory_iterator& operator++() { return __increment(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  __dir_element_proxy operator++(int) {
+    __dir_element_proxy __p(**this);
+    __increment();
+    return __p;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  recursive_directory_iterator& increment(error_code& __ec) {
+    return __increment(&__ec);
+  }
+
+  _LIBCPP_FUNC_VIS directory_options options() const;
+  _LIBCPP_FUNC_VIS int depth() const;
+
+  _LIBCPP_INLINE_VISIBILITY
+  void pop() { __pop(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void pop(error_code& __ec) { __pop(&__ec); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  bool recursion_pending() const { return __rec_; }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void disable_recursion_pending() { __rec_ = false; }
+
+private:
+  recursive_directory_iterator(const path& __p, directory_options __opt,
+                               error_code* __ec);
+
+  _LIBCPP_FUNC_VIS
+  const directory_entry& __dereference() const;
+
+  _LIBCPP_FUNC_VIS
+  bool __try_recursion(error_code* __ec);
+
+  _LIBCPP_FUNC_VIS
+  void __advance(error_code* __ec = nullptr);
+
+  _LIBCPP_FUNC_VIS
+  recursive_directory_iterator& __increment(error_code* __ec = nullptr);
+
+  _LIBCPP_FUNC_VIS
+  void __pop(error_code* __ec = nullptr);
+
+  inline _LIBCPP_INLINE_VISIBILITY friend bool
+  operator==(const recursive_directory_iterator&,
+             const recursive_directory_iterator&) noexcept;
+
+  struct __shared_imp;
+  shared_ptr<__shared_imp> __imp_;
+  bool __rec_;
+}; // class recursive_directory_iterator
+
+inline _LIBCPP_INLINE_VISIBILITY bool
+operator==(const recursive_directory_iterator& __lhs,
+           const recursive_directory_iterator& __rhs) noexcept {
+  return __lhs.__imp_ == __rhs.__imp_;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline bool operator!=(const recursive_directory_iterator& __lhs,
+                       const recursive_directory_iterator& __rhs) noexcept {
+  return !(__lhs == __rhs);
+}
+// enable recursive_directory_iterator range-based for statements
+inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
+begin(recursive_directory_iterator __iter) noexcept {
+  return __iter;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
+end(const recursive_directory_iterator&) noexcept {
+  return recursive_directory_iterator();
+}
+
+}  // namespace android::hardware::automotive::filesystem
+#ifdef _LIBAUTO_UNDEF_VSTD
+#undef _VSTD
+#undef _LIBAUTO_UNDEF_VSTD
+#endif
+
+#ifndef _LIBAUTO_UNDEF_VSTD_FS
+#pragma pop_macro("_VSTD_FS")
+#else
+#undef _VSTD
+#undef _LIBAUTO_UNDEF_VSTD_FS
+#endif
+
+#endif // !_LIBCPP_CXX03_LANG
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBAUTO_FILESYSTEM
diff --git a/automotive/can/1.0/default/libc++fs/src b/automotive/can/1.0/default/libc++fs/src
deleted file mode 120000
index 7abb4ba..0000000
--- a/automotive/can/1.0/default/libc++fs/src
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../../external/libcxx/src/
\ No newline at end of file
diff --git a/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
new file mode 100644
index 0000000..624538b
--- /dev/null
+++ b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
@@ -0,0 +1,397 @@
+//===------------------ directory_iterator.cpp ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/* clang-format off */
+#include "automotive/filesystem"
+#include <__config>
+#if defined(_LIBCPP_WIN32API)
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#else
+#include <dirent.h>
+#endif
+#include <errno.h>
+
+#include "filesystem_common.h"
+
+namespace android::hardware::automotive::filesystem {
+
+namespace detail {
+namespace {
+
+#if !defined(_LIBCPP_WIN32API)
+template <class DirEntT, class = decltype(DirEntT::d_type)>
+static file_type get_file_type(DirEntT* ent, int) {
+  switch (ent->d_type) {
+  case DT_BLK:
+    return file_type::block;
+  case DT_CHR:
+    return file_type::character;
+  case DT_DIR:
+    return file_type::directory;
+  case DT_FIFO:
+    return file_type::fifo;
+  case DT_LNK:
+    return file_type::symlink;
+  case DT_REG:
+    return file_type::regular;
+  case DT_SOCK:
+    return file_type::socket;
+  // Unlike in lstat, hitting "unknown" here simply means that the underlying
+  // filesystem doesn't support d_type. Report is as 'none' so we correctly
+  // set the cache to empty.
+  case DT_UNKNOWN:
+    break;
+  }
+  return file_type::none;
+}
+
+template <class DirEntT>
+static file_type get_file_type(DirEntT* ent, long) {
+  return file_type::none;
+}
+
+static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
+                                                  error_code& ec) {
+  struct dirent* dir_entry_ptr = nullptr;
+  errno = 0; // zero errno in order to detect errors
+  ec.clear();
+  if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
+    if (errno)
+      ec = capture_errno();
+    return {};
+  } else {
+    return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
+  }
+}
+#else
+
+static file_type get_file_type(const WIN32_FIND_DATA& data) {
+  //auto attrs = data.dwFileAttributes;
+  // FIXME(EricWF)
+  return file_type::unknown;
+}
+static uintmax_t get_file_size(const WIN32_FIND_DATA& data) {
+  return (data.nFileSizeHight * (MAXDWORD + 1)) + data.nFileSizeLow;
+}
+static file_time_type get_write_time(const WIN32_FIND_DATA& data) {
+  ULARGE_INTEGER tmp;
+  FILETIME& time = data.ftLastWriteTime;
+  tmp.u.LowPart = time.dwLowDateTime;
+  tmp.u.HighPart = time.dwHighDateTime;
+  return file_time_type(file_time_type::duration(time.QuadPart));
+}
+
+#endif
+
+} // namespace
+} // namespace detail
+
+using detail::ErrorHandler;
+
+#if defined(_LIBCPP_WIN32API)
+class __dir_stream {
+public:
+  __dir_stream() = delete;
+  __dir_stream& operator=(const __dir_stream&) = delete;
+
+  __dir_stream(__dir_stream&& __ds) noexcept : __stream_(__ds.__stream_),
+                                               __root_(move(__ds.__root_)),
+                                               __entry_(move(__ds.__entry_)) {
+    __ds.__stream_ = INVALID_HANDLE_VALUE;
+  }
+
+  __dir_stream(const path& root, directory_options opts, error_code& ec)
+      : __stream_(INVALID_HANDLE_VALUE), __root_(root) {
+    __stream_ = ::FindFirstFileEx(root.c_str(), &__data_);
+    if (__stream_ == INVALID_HANDLE_VALUE) {
+      ec = error_code(::GetLastError(), generic_category());
+      const bool ignore_permission_denied =
+          bool(opts & directory_options::skip_permission_denied);
+      if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED)
+        ec.clear();
+      return;
+    }
+  }
+
+  ~__dir_stream() noexcept {
+    if (__stream_ == INVALID_HANDLE_VALUE)
+      return;
+    close();
+  }
+
+  bool good() const noexcept { return __stream_ != INVALID_HANDLE_VALUE; }
+
+  bool advance(error_code& ec) {
+    while (::FindNextFile(__stream_, &__data_)) {
+      if (!strcmp(__data_.cFileName, ".") || strcmp(__data_.cFileName, ".."))
+        continue;
+      // FIXME: Cache more of this
+      //directory_entry::__cached_data cdata;
+      //cdata.__type_ = get_file_type(__data_);
+      //cdata.__size_ = get_file_size(__data_);
+      //cdata.__write_time_ = get_write_time(__data_);
+      __entry_.__assign_iter_entry(
+          __root_ / __data_.cFileName,
+          directory_entry::__create_iter_result(get_file_type(__data)));
+      return true;
+    }
+    ec = error_code(::GetLastError(), generic_category());
+    close();
+    return false;
+  }
+
+private:
+  error_code close() noexcept {
+    error_code ec;
+    if (!::FindClose(__stream_))
+      ec = error_code(::GetLastError(), generic_category());
+    __stream_ = INVALID_HANDLE_VALUE;
+    return ec;
+  }
+
+  HANDLE __stream_{INVALID_HANDLE_VALUE};
+  WIN32_FIND_DATA __data_;
+
+public:
+  path __root_;
+  directory_entry __entry_;
+};
+#else
+class __dir_stream {
+public:
+  __dir_stream() = delete;
+  __dir_stream& operator=(const __dir_stream&) = delete;
+
+  __dir_stream(__dir_stream&& other) noexcept : __stream_(other.__stream_),
+                                                __root_(move(other.__root_)),
+                                                __entry_(move(other.__entry_)) {
+    other.__stream_ = nullptr;
+  }
+
+  __dir_stream(const path& root, directory_options opts, error_code& ec)
+      : __stream_(nullptr), __root_(root) {
+    if ((__stream_ = ::opendir(root.c_str())) == nullptr) {
+      ec = detail::capture_errno();
+      const bool allow_eacess =
+          bool(opts & directory_options::skip_permission_denied);
+      if (allow_eacess && ec.value() == EACCES)
+        ec.clear();
+      return;
+    }
+    advance(ec);
+  }
+
+  ~__dir_stream() noexcept {
+    if (__stream_)
+      close();
+  }
+
+  bool good() const noexcept { return __stream_ != nullptr; }
+
+  bool advance(error_code& ec) {
+    while (true) {
+      auto str_type_pair = detail::posix_readdir(__stream_, ec);
+      auto& str = str_type_pair.first;
+      if (str == "." || str == "..") {
+        continue;
+      } else if (ec || str.empty()) {
+        close();
+        return false;
+      } else {
+        __entry_.__assign_iter_entry(
+            __root_ / str,
+            directory_entry::__create_iter_result(str_type_pair.second));
+        return true;
+      }
+    }
+  }
+
+private:
+  error_code close() noexcept {
+    error_code m_ec;
+    if (::closedir(__stream_) == -1)
+      m_ec = detail::capture_errno();
+    __stream_ = nullptr;
+    return m_ec;
+  }
+
+  DIR* __stream_{nullptr};
+
+public:
+  path __root_;
+  directory_entry __entry_;
+};
+#endif
+
+// directory_iterator
+
+directory_iterator::directory_iterator(const path& p, error_code* ec,
+                                       directory_options opts) {
+  ErrorHandler<void> err("directory_iterator::directory_iterator(...)", ec, &p);
+
+  error_code m_ec;
+  __imp_ = make_shared<__dir_stream>(p, opts, m_ec);
+  if (ec)
+    *ec = m_ec;
+  if (!__imp_->good()) {
+    __imp_.reset();
+    if (m_ec)
+      err.report(m_ec);
+  }
+}
+
+directory_iterator& directory_iterator::__increment(error_code* ec) {
+  _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
+  ErrorHandler<void> err("directory_iterator::operator++()", ec);
+
+  error_code m_ec;
+  if (!__imp_->advance(m_ec)) {
+    path root = move(__imp_->__root_);
+    __imp_.reset();
+    if (m_ec)
+      err.report(m_ec, "at root \"%s\"", root);
+  }
+  return *this;
+}
+
+directory_entry const& directory_iterator::__dereference() const {
+  _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator");
+  return __imp_->__entry_;
+}
+
+// recursive_directory_iterator
+
+struct recursive_directory_iterator::__shared_imp {
+  stack<__dir_stream> __stack_;
+  directory_options __options_;
+};
+
+recursive_directory_iterator::recursive_directory_iterator(
+    const path& p, directory_options opt, error_code* ec)
+    : __imp_(nullptr), __rec_(true) {
+  ErrorHandler<void> err("recursive_directory_iterator", ec, &p);
+
+  error_code m_ec;
+  __dir_stream new_s(p, opt, m_ec);
+  if (m_ec)
+    err.report(m_ec);
+  if (m_ec || !new_s.good())
+    return;
+
+  __imp_ = make_shared<__shared_imp>();
+  __imp_->__options_ = opt;
+  __imp_->__stack_.push(move(new_s));
+}
+
+void recursive_directory_iterator::__pop(error_code* ec) {
+  _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
+  if (ec)
+    ec->clear();
+  __imp_->__stack_.pop();
+  if (__imp_->__stack_.size() == 0)
+    __imp_.reset();
+  else
+    __advance(ec);
+}
+
+directory_options recursive_directory_iterator::options() const {
+  return __imp_->__options_;
+}
+
+int recursive_directory_iterator::depth() const {
+  return __imp_->__stack_.size() - 1;
+}
+
+const directory_entry& recursive_directory_iterator::__dereference() const {
+  return __imp_->__stack_.top().__entry_;
+}
+
+recursive_directory_iterator&
+recursive_directory_iterator::__increment(error_code* ec) {
+  if (ec)
+    ec->clear();
+  if (recursion_pending()) {
+    if (__try_recursion(ec) || (ec && *ec))
+      return *this;
+  }
+  __rec_ = true;
+  __advance(ec);
+  return *this;
+}
+
+void recursive_directory_iterator::__advance(error_code* ec) {
+  ErrorHandler<void> err("recursive_directory_iterator::operator++()", ec);
+
+  const directory_iterator end_it;
+  auto& stack = __imp_->__stack_;
+  error_code m_ec;
+  while (stack.size() > 0) {
+    if (stack.top().advance(m_ec))
+      return;
+    if (m_ec)
+      break;
+    stack.pop();
+  }
+
+  if (m_ec) {
+    path root = move(stack.top().__root_);
+    __imp_.reset();
+    err.report(m_ec, "at root \"%s\"", root);
+  } else {
+    __imp_.reset();
+  }
+}
+
+bool recursive_directory_iterator::__try_recursion(error_code* ec) {
+  ErrorHandler<void> err("recursive_directory_iterator::operator++()", ec);
+
+  bool rec_sym = bool(options() & directory_options::follow_directory_symlink);
+
+  auto& curr_it = __imp_->__stack_.top();
+
+  bool skip_rec = false;
+  error_code m_ec;
+  if (!rec_sym) {
+    file_status st(curr_it.__entry_.__get_sym_ft(&m_ec));
+    if (m_ec && status_known(st))
+      m_ec.clear();
+    if (m_ec || is_symlink(st) || !is_directory(st))
+      skip_rec = true;
+  } else {
+    file_status st(curr_it.__entry_.__get_ft(&m_ec));
+    if (m_ec && status_known(st))
+      m_ec.clear();
+    if (m_ec || !is_directory(st))
+      skip_rec = true;
+  }
+
+  if (!skip_rec) {
+    __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec);
+    if (new_it.good()) {
+      __imp_->__stack_.push(move(new_it));
+      return true;
+    }
+  }
+  if (m_ec) {
+    const bool allow_eacess =
+        bool(__imp_->__options_ & directory_options::skip_permission_denied);
+    if (m_ec.value() == EACCES && allow_eacess) {
+      if (ec)
+        ec->clear();
+    } else {
+      path at_ent = move(curr_it.__entry_.__p_);
+      __imp_.reset();
+      err.report(m_ec, "attempting recursion into \"%s\"", at_ent);
+    }
+  }
+  return false;
+}
+
+}  // namespace android::hardware::automotive::filesystem
+/* clang-format on */
diff --git a/automotive/can/1.0/default/libc++fs/src/filesystem/filesystem_common.h b/automotive/can/1.0/default/libc++fs/src/filesystem/filesystem_common.h
new file mode 100644
index 0000000..4f44661
--- /dev/null
+++ b/automotive/can/1.0/default/libc++fs/src/filesystem/filesystem_common.h
@@ -0,0 +1,441 @@
+//===----------------------------------------------------------------------===////
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===////
+/* clang-format off */
+#ifndef AUTO_FILESYSTEM_COMMON_H
+#define AUTO_FILESYSTEM_COMMON_H
+
+#include "automotive/filesystem"
+#include <array>
+#include <chrono>
+#include <cstdlib>
+#include <climits>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/time.h> // for ::utimes as used in __last_write_time
+#include <fcntl.h>    /* values for fchmodat */
+
+#if !defined(__APPLE__)
+// We can use the presence of UTIME_OMIT to detect platforms that provide
+// utimensat.
+#if defined(UTIME_OMIT)
+#define _LIBCPP_USE_UTIMENSAT
+#endif
+#endif
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+namespace android::hardware::automotive::filesystem {
+using namespace std::chrono;
+
+using std::error_code;
+using std::is_floating_point;
+using std::micro;
+using std::nano;
+using std::ratio;
+
+namespace detail {
+namespace {
+
+static string format_string_imp(const char* msg, ...) {
+  // we might need a second shot at this, so pre-emptivly make a copy
+  struct GuardVAList {
+    va_list& target;
+    bool active = true;
+    GuardVAList(va_list& target) : target(target), active(true) {}
+    void clear() {
+      if (active)
+        va_end(target);
+      active = false;
+    }
+    ~GuardVAList() {
+      if (active)
+        va_end(target);
+    }
+  };
+  va_list args;
+  va_start(args, msg);
+  GuardVAList args_guard(args);
+
+  va_list args_cp;
+  va_copy(args_cp, args);
+  GuardVAList args_copy_guard(args_cp);
+
+  std::string result;
+
+  array<char, 256> local_buff;
+  size_t size_with_null = local_buff.size();
+  auto ret = ::vsnprintf(local_buff.data(), size_with_null, msg, args_cp);
+
+  args_copy_guard.clear();
+
+  // handle empty expansion
+  if (ret == 0)
+    return result;
+  if (static_cast<size_t>(ret) < size_with_null) {
+    result.assign(local_buff.data(), static_cast<size_t>(ret));
+    return result;
+  }
+
+  // we did not provide a long enough buffer on our first attempt. The
+  // return value is the number of bytes (excluding the null byte) that are
+  // needed for formatting.
+  size_with_null = static_cast<size_t>(ret) + 1;
+  result.__resize_default_init(size_with_null - 1);
+  ret = ::vsnprintf(&result[0], size_with_null, msg, args);
+  _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
+
+  return result;
+}
+
+const char* unwrap(string const& s) { return s.c_str(); }
+const char* unwrap(path const& p) { return p.native().c_str(); }
+template <class Arg>
+Arg const& unwrap(Arg const& a) {
+  static_assert(!is_class<Arg>::value, "cannot pass class here");
+  return a;
+}
+
+template <class... Args>
+string format_string(const char* fmt, Args const&... args) {
+  return format_string_imp(fmt, unwrap(args)...);
+}
+
+error_code capture_errno() {
+  _LIBCPP_ASSERT(errno, "Expected errno to be non-zero");
+  return error_code(errno, generic_category());
+}
+
+template <class T>
+T error_value();
+template <>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 void error_value<void>() {}
+template <>
+bool error_value<bool>() {
+  return false;
+}
+template <>
+uintmax_t error_value<uintmax_t>() {
+  return uintmax_t(-1);
+}
+template <>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 file_time_type error_value<file_time_type>() {
+  return file_time_type::min();
+}
+template <>
+path error_value<path>() {
+  return {};
+}
+
+template <class T>
+struct ErrorHandler {
+  const char* func_name;
+  error_code* ec = nullptr;
+  const path* p1 = nullptr;
+  const path* p2 = nullptr;
+
+  ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
+               const path* p2 = nullptr)
+      : func_name(fname), ec(ec), p1(p1), p2(p2) {
+    if (ec)
+      ec->clear();
+  }
+
+  T report(const error_code& m_ec) const {
+    if (ec) {
+      *ec = m_ec;
+      return error_value<T>();
+    }
+    string what = string("in ") + func_name;
+    switch (bool(p1) + bool(p2)) {
+    case 0:
+      __throw_filesystem_error(what, m_ec);
+    case 1:
+      __throw_filesystem_error(what, *p1, m_ec);
+    case 2:
+      __throw_filesystem_error(what, *p1, *p2, m_ec);
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  template <class... Args>
+  T report(const error_code& m_ec, const char* msg, Args const&... args) const {
+    if (ec) {
+      *ec = m_ec;
+      return error_value<T>();
+    }
+    string what =
+        string("in ") + func_name + ": " + format_string(msg, args...);
+    switch (bool(p1) + bool(p2)) {
+    case 0:
+      __throw_filesystem_error(what, m_ec);
+    case 1:
+      __throw_filesystem_error(what, *p1, m_ec);
+    case 2:
+      __throw_filesystem_error(what, *p1, *p2, m_ec);
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  T report(errc const& err) const { return report(make_error_code(err)); }
+
+  template <class... Args>
+  T report(errc const& err, const char* msg, Args const&... args) const {
+    return report(make_error_code(err), msg, args...);
+  }
+
+private:
+  ErrorHandler(ErrorHandler const&) = delete;
+  ErrorHandler& operator=(ErrorHandler const&) = delete;
+};
+
+using chrono::duration;
+using chrono::duration_cast;
+
+using TimeSpec = struct ::timespec;
+using StatT = struct ::stat;
+
+template <class FileTimeT, class TimeT,
+          bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
+struct time_util_base {
+  using rep = typename FileTimeT::rep;
+  using fs_duration = typename FileTimeT::duration;
+  using fs_seconds = duration<rep>;
+  using fs_nanoseconds = duration<rep, nano>;
+  using fs_microseconds = duration<rep, micro>;
+
+  static constexpr rep max_seconds =
+      duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
+
+  static constexpr rep max_nsec =
+      duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
+                                    fs_seconds(max_seconds))
+          .count();
+
+  static constexpr rep min_seconds =
+      duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
+
+  static constexpr rep min_nsec_timespec =
+      duration_cast<fs_nanoseconds>(
+          (FileTimeT::duration::min() - fs_seconds(min_seconds)) +
+          fs_seconds(1))
+          .count();
+
+private:
+#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
+  static constexpr fs_duration get_min_nsecs() {
+    return duration_cast<fs_duration>(
+        fs_nanoseconds(min_nsec_timespec) -
+        duration_cast<fs_nanoseconds>(fs_seconds(1)));
+  }
+  // Static assert that these values properly round trip.
+  static_assert(fs_seconds(min_seconds) + get_min_nsecs() ==
+                    FileTimeT::duration::min(),
+                "value doesn't roundtrip");
+
+  static constexpr bool check_range() {
+    // This kinda sucks, but it's what happens when we don't have __int128_t.
+    if (sizeof(TimeT) == sizeof(rep)) {
+      typedef duration<long long, ratio<3600 * 24 * 365> > Years;
+      return duration_cast<Years>(fs_seconds(max_seconds)) > Years(250) &&
+             duration_cast<Years>(fs_seconds(min_seconds)) < Years(-250);
+    }
+    return max_seconds >= numeric_limits<TimeT>::max() &&
+           min_seconds <= numeric_limits<TimeT>::min();
+  }
+  static_assert(check_range(), "the representable range is unacceptable small");
+#endif
+};
+
+template <class FileTimeT, class TimeT>
+struct time_util_base<FileTimeT, TimeT, true> {
+  using rep = typename FileTimeT::rep;
+  using fs_duration = typename FileTimeT::duration;
+  using fs_seconds = duration<rep>;
+  using fs_nanoseconds = duration<rep, nano>;
+  using fs_microseconds = duration<rep, micro>;
+
+  static const rep max_seconds;
+  static const rep max_nsec;
+  static const rep min_seconds;
+  static const rep min_nsec_timespec;
+};
+
+template <class FileTimeT, class TimeT>
+const typename FileTimeT::rep
+    time_util_base<FileTimeT, TimeT, true>::max_seconds =
+        duration_cast<fs_seconds>(FileTimeT::duration::max()).count();
+
+template <class FileTimeT, class TimeT>
+const typename FileTimeT::rep time_util_base<FileTimeT, TimeT, true>::max_nsec =
+    duration_cast<fs_nanoseconds>(FileTimeT::duration::max() -
+                                  fs_seconds(max_seconds))
+        .count();
+
+template <class FileTimeT, class TimeT>
+const typename FileTimeT::rep
+    time_util_base<FileTimeT, TimeT, true>::min_seconds =
+        duration_cast<fs_seconds>(FileTimeT::duration::min()).count();
+
+template <class FileTimeT, class TimeT>
+const typename FileTimeT::rep
+    time_util_base<FileTimeT, TimeT, true>::min_nsec_timespec =
+        duration_cast<fs_nanoseconds>((FileTimeT::duration::min() -
+                                       fs_seconds(min_seconds)) +
+                                      fs_seconds(1))
+            .count();
+
+template <class FileTimeT, class TimeT, class TimeSpecT>
+struct time_util : time_util_base<FileTimeT, TimeT> {
+  using Base = time_util_base<FileTimeT, TimeT>;
+  using Base::max_nsec;
+  using Base::max_seconds;
+  using Base::min_nsec_timespec;
+  using Base::min_seconds;
+
+  using typename Base::fs_duration;
+  using typename Base::fs_microseconds;
+  using typename Base::fs_nanoseconds;
+  using typename Base::fs_seconds;
+
+public:
+  template <class CType, class ChronoType>
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool checked_set(CType* out,
+                                                        ChronoType time) {
+    using Lim = numeric_limits<CType>;
+    if (time > Lim::max() || time < Lim::min())
+      return false;
+    *out = static_cast<CType>(time);
+    return true;
+  }
+
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool is_representable(TimeSpecT tm) {
+    if (tm.tv_sec >= 0) {
+      return tm.tv_sec < max_seconds ||
+             (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec);
+    } else if (tm.tv_sec == (min_seconds - 1)) {
+      return tm.tv_nsec >= min_nsec_timespec;
+    } else {
+      return tm.tv_sec >= min_seconds;
+    }
+  }
+
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool is_representable(FileTimeT tm) {
+    auto secs = duration_cast<fs_seconds>(tm.time_since_epoch());
+    auto nsecs = duration_cast<fs_nanoseconds>(tm.time_since_epoch() - secs);
+    if (nsecs.count() < 0) {
+      secs = secs + fs_seconds(1);
+      nsecs = nsecs + fs_seconds(1);
+    }
+    using TLim = numeric_limits<TimeT>;
+    if (secs.count() >= 0)
+      return secs.count() <= TLim::max();
+    return secs.count() >= TLim::min();
+  }
+
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 FileTimeT
+  convert_from_timespec(TimeSpecT tm) {
+    if (tm.tv_sec >= 0 || tm.tv_nsec == 0) {
+      return FileTimeT(fs_seconds(tm.tv_sec) +
+                       duration_cast<fs_duration>(fs_nanoseconds(tm.tv_nsec)));
+    } else { // tm.tv_sec < 0
+      auto adj_subsec = duration_cast<fs_duration>(fs_seconds(1) -
+                                                   fs_nanoseconds(tm.tv_nsec));
+      auto Dur = fs_seconds(tm.tv_sec + 1) - adj_subsec;
+      return FileTimeT(Dur);
+    }
+  }
+
+  template <class SubSecT>
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool
+  set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) {
+    auto dur = tp.time_since_epoch();
+    auto sec_dur = duration_cast<fs_seconds>(dur);
+    auto subsec_dur = duration_cast<fs_nanoseconds>(dur - sec_dur);
+    // The tv_nsec and tv_usec fields must not be negative so adjust accordingly
+    if (subsec_dur.count() < 0) {
+      if (sec_dur.count() > min_seconds) {
+        sec_dur = sec_dur - fs_seconds(1);
+        subsec_dur = subsec_dur + fs_seconds(1);
+      } else {
+        subsec_dur = fs_nanoseconds::zero();
+      }
+    }
+    return checked_set(sec_out, sec_dur.count()) &&
+           checked_set(subsec_out, subsec_dur.count());
+  }
+  static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool convert_to_timespec(TimeSpecT& dest,
+                                                                FileTimeT tp) {
+    if (!is_representable(tp))
+      return false;
+    return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp);
+  }
+};
+
+using fs_time = time_util<file_time_type, time_t, TimeSpec>;
+
+#if defined(__APPLE__)
+TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+#else
+TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
+TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
+#endif
+
+// allow the utimes implementation to compile even it we're not going
+// to use it.
+
+bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
+                  error_code& ec) {
+  using namespace chrono;
+  auto Convert = [](long nsec) {
+    using int_type = decltype(std::declval< ::timeval>().tv_usec);
+    auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
+    return static_cast<int_type>(dur);
+  };
+  struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)},
+                                     {TS[1].tv_sec, Convert(TS[1].tv_nsec)}};
+  if (::utimes(p.c_str(), ConvertedTS) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  return false;
+}
+
+#if defined(_LIBCPP_USE_UTIMENSAT)
+bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
+                     error_code& ec) {
+  if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  return false;
+}
+#endif
+
+bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+                    error_code& ec) {
+#if !defined(_LIBCPP_USE_UTIMENSAT)
+  return posix_utimes(p, TS, ec);
+#else
+  return posix_utimensat(p, TS, ec);
+#endif
+}
+
+} // namespace
+} // end namespace detail
+
+}  // namespace android::hardware::automotive::filesystem
+
+#endif // AUTO_FILESYSTEM_COMMON_H
+/* clang-format on */
diff --git a/automotive/can/1.0/default/libc++fs/src/filesystem/operations.cpp b/automotive/can/1.0/default/libc++fs/src/filesystem/operations.cpp
new file mode 100644
index 0000000..404c0bd
--- /dev/null
+++ b/automotive/can/1.0/default/libc++fs/src/filesystem/operations.cpp
@@ -0,0 +1,1773 @@
+//===--------------------- filesystem/ops.cpp -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/* clang-format off */
+#include "automotive/filesystem"
+#include <array>
+#include <iterator>
+#include <fstream>
+#include <random> /* for unique_path */
+#include <string_view>
+#include <type_traits>
+#include <vector>
+#include <cstdlib>
+#include <climits>
+
+#include "filesystem_common.h"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <time.h>
+#include <fcntl.h> /* values for fchmodat */
+
+#if defined(__linux__)
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+#include <sys/sendfile.h>
+#define _LIBCPP_USE_SENDFILE
+#endif
+#elif defined(__APPLE__) || __has_include(<copyfile.h>)
+#include <copyfile.h>
+#define _LIBCPP_USE_COPYFILE
+#endif
+
+#if !defined(__APPLE__)
+#define _LIBCPP_USE_CLOCK_GETTIME
+#endif
+
+#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
+#include <sys/time.h> // for gettimeofday and timeval
+#endif                // !defined(CLOCK_REALTIME)
+
+#if defined(_LIBCPP_COMPILER_GCC)
+#if _GNUC_VER < 500
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+#endif
+
+namespace android::hardware::automotive::filesystem {
+
+#ifdef _VSTD_FS
+#pragma push_macro("_VSTD_FS")
+#else
+#define _LIBAUTO_UNDEF_VSTD_FS
+#endif
+#define _VSTD_FS android::hardware::automotive::filesystem
+
+namespace {
+namespace parser {
+
+using string_view_t = path::__string_view;
+using string_view_pair = pair<string_view_t, string_view_t>;
+using PosPtr = path::value_type const*;
+
+struct PathParser {
+  enum ParserState : unsigned char {
+    // Zero is a special sentinel value used by default constructed iterators.
+    PS_BeforeBegin = path::iterator::_BeforeBegin,
+    PS_InRootName = path::iterator::_InRootName,
+    PS_InRootDir = path::iterator::_InRootDir,
+    PS_InFilenames = path::iterator::_InFilenames,
+    PS_InTrailingSep = path::iterator::_InTrailingSep,
+    PS_AtEnd = path::iterator::_AtEnd
+  };
+
+  const string_view_t Path;
+  string_view_t RawEntry;
+  ParserState State;
+
+private:
+  PathParser(string_view_t P, ParserState State) noexcept : Path(P),
+                                                            State(State) {}
+
+public:
+  PathParser(string_view_t P, string_view_t E, unsigned char S)
+      : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
+    // S cannot be '0' or PS_BeforeBegin.
+  }
+
+  static PathParser CreateBegin(string_view_t P) noexcept {
+    PathParser PP(P, PS_BeforeBegin);
+    PP.increment();
+    return PP;
+  }
+
+  static PathParser CreateEnd(string_view_t P) noexcept {
+    PathParser PP(P, PS_AtEnd);
+    return PP;
+  }
+
+  PosPtr peek() const noexcept {
+    auto TkEnd = getNextTokenStartPos();
+    auto End = getAfterBack();
+    return TkEnd == End ? nullptr : TkEnd;
+  }
+
+  void increment() noexcept {
+    const PosPtr End = getAfterBack();
+    const PosPtr Start = getNextTokenStartPos();
+    if (Start == End)
+      return makeState(PS_AtEnd);
+
+    switch (State) {
+    case PS_BeforeBegin: {
+      PosPtr TkEnd = consumeSeparator(Start, End);
+      if (TkEnd)
+        return makeState(PS_InRootDir, Start, TkEnd);
+      else
+        return makeState(PS_InFilenames, Start, consumeName(Start, End));
+    }
+    case PS_InRootDir:
+      return makeState(PS_InFilenames, Start, consumeName(Start, End));
+
+    case PS_InFilenames: {
+      PosPtr SepEnd = consumeSeparator(Start, End);
+      if (SepEnd != End) {
+        PosPtr TkEnd = consumeName(SepEnd, End);
+        if (TkEnd)
+          return makeState(PS_InFilenames, SepEnd, TkEnd);
+      }
+      return makeState(PS_InTrailingSep, Start, SepEnd);
+    }
+
+    case PS_InTrailingSep:
+      return makeState(PS_AtEnd);
+
+    case PS_InRootName:
+    case PS_AtEnd:
+      _LIBCPP_UNREACHABLE();
+    }
+  }
+
+  void decrement() noexcept {
+    const PosPtr REnd = getBeforeFront();
+    const PosPtr RStart = getCurrentTokenStartPos() - 1;
+    if (RStart == REnd) // we're decrementing the begin
+      return makeState(PS_BeforeBegin);
+
+    switch (State) {
+    case PS_AtEnd: {
+      // Try to consume a trailing separator or root directory first.
+      if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) {
+        if (SepEnd == REnd)
+          return makeState(PS_InRootDir, Path.data(), RStart + 1);
+        return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
+      } else {
+        PosPtr TkStart = consumeName(RStart, REnd);
+        return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
+      }
+    }
+    case PS_InTrailingSep:
+      return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
+                       RStart + 1);
+    case PS_InFilenames: {
+      PosPtr SepEnd = consumeSeparator(RStart, REnd);
+      if (SepEnd == REnd)
+        return makeState(PS_InRootDir, Path.data(), RStart + 1);
+      PosPtr TkEnd = consumeName(SepEnd, REnd);
+      return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1);
+    }
+    case PS_InRootDir:
+      // return makeState(PS_InRootName, Path.data(), RStart + 1);
+    case PS_InRootName:
+    case PS_BeforeBegin:
+      _LIBCPP_UNREACHABLE();
+    }
+  }
+
+  /// \brief Return a view with the "preferred representation" of the current
+  ///   element. For example trailing separators are represented as a '.'
+  string_view_t operator*() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+    case PS_AtEnd:
+      return "";
+    case PS_InRootDir:
+      return "/";
+    case PS_InTrailingSep:
+      return "";
+    case PS_InRootName:
+    case PS_InFilenames:
+      return RawEntry;
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  explicit operator bool() const noexcept {
+    return State != PS_BeforeBegin && State != PS_AtEnd;
+  }
+
+  PathParser& operator++() noexcept {
+    increment();
+    return *this;
+  }
+
+  PathParser& operator--() noexcept {
+    decrement();
+    return *this;
+  }
+
+  bool atEnd() const noexcept {
+    return State == PS_AtEnd;
+  }
+
+  bool inRootDir() const noexcept {
+    return State == PS_InRootDir;
+  }
+
+  bool inRootName() const noexcept {
+    return State == PS_InRootName;
+  }
+
+  bool inRootPath() const noexcept {
+    return inRootName() || inRootDir();
+  }
+
+private:
+  void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
+    State = NewState;
+    RawEntry = string_view_t(Start, End - Start);
+  }
+  void makeState(ParserState NewState) noexcept {
+    State = NewState;
+    RawEntry = {};
+  }
+
+  PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
+
+  PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
+
+  /// \brief Return a pointer to the first character after the currently
+  ///   lexed element.
+  PosPtr getNextTokenStartPos() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+      return Path.data();
+    case PS_InRootName:
+    case PS_InRootDir:
+    case PS_InFilenames:
+      return &RawEntry.back() + 1;
+    case PS_InTrailingSep:
+    case PS_AtEnd:
+      return getAfterBack();
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  /// \brief Return a pointer to the first character in the currently lexed
+  ///   element.
+  PosPtr getCurrentTokenStartPos() const noexcept {
+    switch (State) {
+    case PS_BeforeBegin:
+    case PS_InRootName:
+      return &Path.front();
+    case PS_InRootDir:
+    case PS_InFilenames:
+    case PS_InTrailingSep:
+      return &RawEntry.front();
+    case PS_AtEnd:
+      return &Path.back() + 1;
+    }
+    _LIBCPP_UNREACHABLE();
+  }
+
+  PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept {
+    if (P == End || *P != '/')
+      return nullptr;
+    const int Inc = P < End ? 1 : -1;
+    P += Inc;
+    while (P != End && *P == '/')
+      P += Inc;
+    return P;
+  }
+
+  PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
+    if (P == End || *P == '/')
+      return nullptr;
+    const int Inc = P < End ? 1 : -1;
+    P += Inc;
+    while (P != End && *P != '/')
+      P += Inc;
+    return P;
+  }
+};
+
+string_view_pair separate_filename(string_view_t const& s) {
+  if (s == "." || s == ".." || s.empty())
+    return string_view_pair{s, ""};
+  auto pos = s.find_last_of('.');
+  if (pos == string_view_t::npos || pos == 0)
+    return string_view_pair{s, string_view_t{}};
+  return string_view_pair{s.substr(0, pos), s.substr(pos)};
+}
+
+string_view_t createView(PosPtr S, PosPtr E) noexcept {
+  return {S, static_cast<size_t>(E - S) + 1};
+}
+
+} // namespace parser
+} // namespace
+
+//                       POSIX HELPERS
+
+namespace detail {
+namespace {
+
+using value_type = path::value_type;
+using string_type = path::string_type;
+
+struct FileDescriptor {
+  const path& name;
+  int fd = -1;
+  StatT m_stat;
+  file_status m_status;
+
+  template <class... Args>
+  static FileDescriptor create(const path* p, error_code& ec, Args... args) {
+    ec.clear();
+    int fd;
+    if ((fd = ::open(p->c_str(), args...)) == -1) {
+      ec = capture_errno();
+      return FileDescriptor{p};
+    }
+    return FileDescriptor(p, fd);
+  }
+
+  template <class... Args>
+  static FileDescriptor create_with_status(const path* p, error_code& ec,
+                                           Args... args) {
+    FileDescriptor fd = create(p, ec, args...);
+    if (!ec)
+      fd.refresh_status(ec);
+
+    return fd;
+  }
+
+  file_status get_status() const { return m_status; }
+  StatT const& get_stat() const { return m_stat; }
+
+  bool status_known() const { return _VSTD_FS::status_known(m_status); }
+
+  file_status refresh_status(error_code& ec);
+
+  void close() noexcept {
+    if (fd != -1)
+      ::close(fd);
+    fd = -1;
+  }
+
+  FileDescriptor(FileDescriptor&& other)
+      : name(other.name), fd(other.fd), m_stat(other.m_stat),
+        m_status(other.m_status) {
+    other.fd = -1;
+    other.m_status = file_status{};
+  }
+
+  ~FileDescriptor() { close(); }
+
+  FileDescriptor(FileDescriptor const&) = delete;
+  FileDescriptor& operator=(FileDescriptor const&) = delete;
+
+private:
+  explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {}
+};
+
+perms posix_get_perms(const StatT& st) noexcept {
+  return static_cast<perms>(st.st_mode) & perms::mask;
+}
+
+::mode_t posix_convert_perms(perms prms) {
+  return static_cast< ::mode_t>(prms & perms::mask);
+}
+
+file_status create_file_status(error_code& m_ec, path const& p,
+                               const StatT& path_stat, error_code* ec) {
+  if (ec)
+    *ec = m_ec;
+  if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
+    return file_status(file_type::not_found);
+  } else if (m_ec) {
+    ErrorHandler<void> err("posix_stat", ec, &p);
+    err.report(m_ec, "failed to determine attributes for the specified path");
+    return file_status(file_type::none);
+  }
+  // else
+
+  file_status fs_tmp;
+  auto const mode = path_stat.st_mode;
+  if (S_ISLNK(mode))
+    fs_tmp.type(file_type::symlink);
+  else if (S_ISREG(mode))
+    fs_tmp.type(file_type::regular);
+  else if (S_ISDIR(mode))
+    fs_tmp.type(file_type::directory);
+  else if (S_ISBLK(mode))
+    fs_tmp.type(file_type::block);
+  else if (S_ISCHR(mode))
+    fs_tmp.type(file_type::character);
+  else if (S_ISFIFO(mode))
+    fs_tmp.type(file_type::fifo);
+  else if (S_ISSOCK(mode))
+    fs_tmp.type(file_type::socket);
+  else
+    fs_tmp.type(file_type::unknown);
+
+  fs_tmp.permissions(detail::posix_get_perms(path_stat));
+  return fs_tmp;
+}
+
+file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
+  error_code m_ec;
+  if (::stat(p.c_str(), &path_stat) == -1)
+    m_ec = detail::capture_errno();
+  return create_file_status(m_ec, p, path_stat, ec);
+}
+
+file_status posix_stat(path const& p, error_code* ec) {
+  StatT path_stat;
+  return posix_stat(p, path_stat, ec);
+}
+
+file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
+  error_code m_ec;
+  if (::lstat(p.c_str(), &path_stat) == -1)
+    m_ec = detail::capture_errno();
+  return create_file_status(m_ec, p, path_stat, ec);
+}
+
+file_status posix_lstat(path const& p, error_code* ec) {
+  StatT path_stat;
+  return posix_lstat(p, path_stat, ec);
+}
+
+bool posix_ftruncate(const FileDescriptor& fd, size_t to_size, error_code& ec) {
+  if (::ftruncate(fd.fd, to_size) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  ec.clear();
+  return false;
+}
+
+bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
+  if (::fchmod(fd.fd, st.st_mode) == -1) {
+    ec = capture_errno();
+    return true;
+  }
+  ec.clear();
+  return false;
+}
+
+bool stat_equivalent(const StatT& st1, const StatT& st2) {
+  return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+}
+
+file_status FileDescriptor::refresh_status(error_code& ec) {
+  // FD must be open and good.
+  m_status = file_status{};
+  m_stat = {};
+  error_code m_ec;
+  if (::fstat(fd, &m_stat) == -1)
+    m_ec = capture_errno();
+  m_status = create_file_status(m_ec, name, m_stat, &ec);
+  return m_status;
+}
+} // namespace
+} // end namespace detail
+
+using detail::capture_errno;
+using detail::ErrorHandler;
+using detail::StatT;
+using detail::TimeSpec;
+using parser::createView;
+using parser::PathParser;
+using parser::string_view_t;
+
+const bool _FilesystemClock::is_steady;
+
+_FilesystemClock::time_point _FilesystemClock::now() noexcept {
+  typedef chrono::duration<rep> __secs;
+#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
+  typedef chrono::duration<rep, nano> __nsecs;
+  struct timespec tp;
+  if (0 != clock_gettime(CLOCK_REALTIME, &tp))
+    __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
+  return time_point(__secs(tp.tv_sec) +
+                    chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#else
+  typedef chrono::duration<rep, micro> __microsecs;
+  timeval tv;
+  gettimeofday(&tv, 0);
+  return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
+#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
+}
+
+filesystem_error::~filesystem_error() {}
+
+void filesystem_error::__create_what(int __num_paths) {
+  const char* derived_what = system_error::what();
+  __storage_->__what_ = [&]() -> string {
+    const char* p1 = path1().native().empty() ? "\"\"" : path1().c_str();
+    const char* p2 = path2().native().empty() ? "\"\"" : path2().c_str();
+    switch (__num_paths) {
+    default:
+      return detail::format_string("filesystem error: %s", derived_what);
+    case 1:
+      return detail::format_string("filesystem error: %s [%s]", derived_what,
+                                   p1);
+    case 2:
+      return detail::format_string("filesystem error: %s [%s] [%s]",
+                                   derived_what, p1, p2);
+    }
+  }();
+}
+
+static path __do_absolute(const path& p, path* cwd, error_code* ec) {
+  if (ec)
+    ec->clear();
+  if (p.is_absolute())
+    return p;
+  *cwd = __current_path(ec);
+  if (ec && *ec)
+    return {};
+  return (*cwd) / p;
+}
+
+path __absolute(const path& p, error_code* ec) {
+  path cwd;
+  return __do_absolute(p, &cwd, ec);
+}
+
+path __canonical(path const& orig_p, error_code* ec) {
+  path cwd;
+  ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
+
+  path p = __do_absolute(orig_p, &cwd, ec);
+  char buff[PATH_MAX + 1];
+  char* ret;
+  if ((ret = ::realpath(p.c_str(), buff)) == nullptr)
+    return err.report(capture_errno());
+  return {ret};
+}
+
+void __copy(const path& from, const path& to, copy_options options,
+            error_code* ec) {
+  ErrorHandler<void> err("copy", ec, &from, &to);
+
+  const bool sym_status = bool(
+      options & (copy_options::create_symlinks | copy_options::skip_symlinks));
+
+  const bool sym_status2 = bool(options & copy_options::copy_symlinks);
+
+  error_code m_ec1;
+  StatT f_st = {};
+  const file_status f = sym_status || sym_status2
+                            ? detail::posix_lstat(from, f_st, &m_ec1)
+                            : detail::posix_stat(from, f_st, &m_ec1);
+  if (m_ec1)
+    return err.report(m_ec1);
+
+  StatT t_st = {};
+  const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec1)
+                                   : detail::posix_stat(to, t_st, &m_ec1);
+
+  if (not status_known(t))
+    return err.report(m_ec1);
+
+  if (!exists(f) || is_other(f) || is_other(t) ||
+      (is_directory(f) && is_regular_file(t)) ||
+      detail::stat_equivalent(f_st, t_st)) {
+    return err.report(errc::function_not_supported);
+  }
+
+  if (ec)
+    ec->clear();
+
+  if (is_symlink(f)) {
+    if (bool(copy_options::skip_symlinks & options)) {
+      // do nothing
+    } else if (not exists(t)) {
+      __copy_symlink(from, to, ec);
+    } else {
+      return err.report(errc::file_exists);
+    }
+    return;
+  } else if (is_regular_file(f)) {
+    if (bool(copy_options::directories_only & options)) {
+      // do nothing
+    } else if (bool(copy_options::create_symlinks & options)) {
+      __create_symlink(from, to, ec);
+    } else if (bool(copy_options::create_hard_links & options)) {
+      __create_hard_link(from, to, ec);
+    } else if (is_directory(t)) {
+      __copy_file(from, to / from.filename(), options, ec);
+    } else {
+      __copy_file(from, to, options, ec);
+    }
+    return;
+  } else if (is_directory(f) && bool(copy_options::create_symlinks & options)) {
+    return err.report(errc::is_a_directory);
+  } else if (is_directory(f) && (bool(copy_options::recursive & options) ||
+                                 copy_options::none == options)) {
+
+    if (!exists(t)) {
+      // create directory to with attributes from 'from'.
+      __create_directory(to, from, ec);
+      if (ec && *ec) {
+        return;
+      }
+    }
+    directory_iterator it =
+        ec ? directory_iterator(from, *ec) : directory_iterator(from);
+    if (ec && *ec) {
+      return;
+    }
+    error_code m_ec2;
+    for (; it != directory_iterator(); it.increment(m_ec2)) {
+      if (m_ec2) {
+        return err.report(m_ec2);
+      }
+      __copy(it->path(), to / it->path().filename(),
+             options | copy_options::__in_recursive_copy, ec);
+      if (ec && *ec) {
+        return;
+      }
+    }
+  }
+}
+
+namespace detail {
+namespace {
+
+#ifdef _LIBCPP_USE_SENDFILE
+bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
+                             error_code& ec) {
+
+  size_t count = read_fd.get_stat().st_size;
+  do {
+    ssize_t res;
+    if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) {
+      ec = capture_errno();
+      return false;
+    }
+    count -= res;
+  } while (count > 0);
+
+  ec.clear();
+
+  return true;
+}
+#elif defined(_LIBCPP_USE_COPYFILE)
+bool copy_file_impl_copyfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
+                             error_code& ec) {
+  struct CopyFileState {
+    copyfile_state_t state;
+    CopyFileState() { state = copyfile_state_alloc(); }
+    ~CopyFileState() { copyfile_state_free(state); }
+
+  private:
+    CopyFileState(CopyFileState const&) = delete;
+    CopyFileState& operator=(CopyFileState const&) = delete;
+  };
+
+  CopyFileState cfs;
+  if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) {
+    ec = capture_errno();
+    return false;
+  }
+
+  ec.clear();
+  return true;
+}
+#endif
+
+// Note: This function isn't guarded by ifdef's even though it may be unused
+// in order to assure it still compiles.
+__attribute__((unused)) bool copy_file_impl_default(FileDescriptor& read_fd,
+                                                    FileDescriptor& write_fd,
+                                                    error_code& ec) {
+  ifstream in;
+  in.__open(read_fd.fd, ios::binary);
+  if (!in.is_open()) {
+    // This assumes that __open didn't reset the error code.
+    ec = capture_errno();
+    return false;
+  }
+  ofstream out;
+  out.__open(write_fd.fd, ios::binary);
+  if (!out.is_open()) {
+    ec = capture_errno();
+    return false;
+  }
+
+  if (in.good() && out.good()) {
+    using InIt = istreambuf_iterator<char>;
+    using OutIt = ostreambuf_iterator<char>;
+    InIt bin(in);
+    InIt ein;
+    OutIt bout(out);
+    copy(bin, ein, bout);
+  }
+  if (out.fail() || in.fail()) {
+    ec = make_error_code(errc::io_error);
+    return false;
+  }
+
+  ec.clear();
+  return true;
+}
+
+bool copy_file_impl(FileDescriptor& from, FileDescriptor& to, error_code& ec) {
+#if defined(_LIBCPP_USE_SENDFILE)
+  return copy_file_impl_sendfile(from, to, ec);
+#elif defined(_LIBCPP_USE_COPYFILE)
+  return copy_file_impl_copyfile(from, to, ec);
+#else
+  return copy_file_impl_default(from, to, ec);
+#endif
+}
+
+} // namespace
+} // namespace detail
+
+bool __copy_file(const path& from, const path& to, copy_options options,
+                 error_code* ec) {
+  using detail::FileDescriptor;
+  ErrorHandler<bool> err("copy_file", ec, &to, &from);
+
+  error_code m_ec;
+  FileDescriptor from_fd =
+      FileDescriptor::create_with_status(&from, m_ec, O_RDONLY | O_NONBLOCK);
+  if (m_ec)
+    return err.report(m_ec);
+
+  auto from_st = from_fd.get_status();
+  StatT const& from_stat = from_fd.get_stat();
+  if (!is_regular_file(from_st)) {
+    if (not m_ec)
+      m_ec = make_error_code(errc::not_supported);
+    return err.report(m_ec);
+  }
+
+  const bool skip_existing = bool(copy_options::skip_existing & options);
+  const bool update_existing = bool(copy_options::update_existing & options);
+  const bool overwrite_existing =
+      bool(copy_options::overwrite_existing & options);
+
+  StatT to_stat_path;
+  file_status to_st = detail::posix_stat(to, to_stat_path, &m_ec);
+  if (!status_known(to_st))
+    return err.report(m_ec);
+
+  const bool to_exists = exists(to_st);
+  if (to_exists && !is_regular_file(to_st))
+    return err.report(errc::not_supported);
+
+  if (to_exists && detail::stat_equivalent(from_stat, to_stat_path))
+    return err.report(errc::file_exists);
+
+  if (to_exists && skip_existing)
+    return false;
+
+  bool ShouldCopy = [&]() {
+    if (to_exists && update_existing) {
+      auto from_time = detail::extract_mtime(from_stat);
+      auto to_time = detail::extract_mtime(to_stat_path);
+      if (from_time.tv_sec < to_time.tv_sec)
+        return false;
+      if (from_time.tv_sec == to_time.tv_sec &&
+          from_time.tv_nsec <= to_time.tv_nsec)
+        return false;
+      return true;
+    }
+    if (!to_exists || overwrite_existing)
+      return true;
+    return err.report(errc::file_exists);
+  }();
+  if (!ShouldCopy)
+    return false;
+
+  // Don't truncate right away. We may not be opening the file we originally
+  // looked at; we'll check this later.
+  int to_open_flags = O_WRONLY;
+  if (!to_exists)
+    to_open_flags |= O_CREAT;
+  FileDescriptor to_fd = FileDescriptor::create_with_status(
+      &to, m_ec, to_open_flags, from_stat.st_mode);
+  if (m_ec)
+    return err.report(m_ec);
+
+  if (to_exists) {
+    // Check that the file we initially stat'ed is equivalent to the one
+    // we opened.
+    // FIXME: report this better.
+    if (!detail::stat_equivalent(to_stat_path, to_fd.get_stat()))
+      return err.report(errc::bad_file_descriptor);
+
+    // Set the permissions and truncate the file we opened.
+    if (detail::posix_fchmod(to_fd, from_stat, m_ec))
+      return err.report(m_ec);
+    if (detail::posix_ftruncate(to_fd, 0, m_ec))
+      return err.report(m_ec);
+  }
+
+  if (!copy_file_impl(from_fd, to_fd, m_ec)) {
+    // FIXME: Remove the dest file if we failed, and it didn't exist previously.
+    return err.report(m_ec);
+  }
+
+  return true;
+}
+
+void __copy_symlink(const path& existing_symlink, const path& new_symlink,
+                    error_code* ec) {
+  const path real_path(__read_symlink(existing_symlink, ec));
+  if (ec && *ec) {
+    return;
+  }
+  // NOTE: proposal says you should detect if you should call
+  // create_symlink or create_directory_symlink. I don't think this
+  // is needed with POSIX
+  __create_symlink(real_path, new_symlink, ec);
+}
+
+bool __create_directories(const path& p, error_code* ec) {
+  ErrorHandler<bool> err("create_directories", ec, &p);
+
+  error_code m_ec;
+  auto const st = detail::posix_stat(p, &m_ec);
+  if (!status_known(st))
+    return err.report(m_ec);
+  else if (is_directory(st))
+    return false;
+  else if (exists(st))
+    return err.report(errc::file_exists);
+
+  const path parent = p.parent_path();
+  if (!parent.empty()) {
+    const file_status parent_st = status(parent, m_ec);
+    if (not status_known(parent_st))
+      return err.report(m_ec);
+    if (not exists(parent_st)) {
+      __create_directories(parent, ec);
+      if (ec && *ec) {
+        return false;
+      }
+    }
+  }
+  return __create_directory(p, ec);
+}
+
+bool __create_directory(const path& p, error_code* ec) {
+  ErrorHandler<bool> err("create_directory", ec, &p);
+
+  if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
+    return true;
+  if (errno != EEXIST)
+    err.report(capture_errno());
+  return false;
+}
+
+bool __create_directory(path const& p, path const& attributes, error_code* ec) {
+  ErrorHandler<bool> err("create_directory", ec, &p, &attributes);
+
+  StatT attr_stat;
+  error_code mec;
+  auto st = detail::posix_stat(attributes, attr_stat, &mec);
+  if (!status_known(st))
+    return err.report(mec);
+  if (!is_directory(st))
+    return err.report(errc::not_a_directory,
+                      "the specified attribute path is invalid");
+
+  if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
+    return true;
+  if (errno != EEXIST)
+    err.report(capture_errno());
+  return false;
+}
+
+void __create_directory_symlink(path const& from, path const& to,
+                                error_code* ec) {
+  ErrorHandler<void> err("create_directory_symlink", ec, &from, &to);
+  if (::symlink(from.c_str(), to.c_str()) != 0)
+    return err.report(capture_errno());
+}
+
+void __create_hard_link(const path& from, const path& to, error_code* ec) {
+  ErrorHandler<void> err("create_hard_link", ec, &from, &to);
+  if (::link(from.c_str(), to.c_str()) == -1)
+    return err.report(capture_errno());
+}
+
+void __create_symlink(path const& from, path const& to, error_code* ec) {
+  ErrorHandler<void> err("create_symlink", ec, &from, &to);
+  if (::symlink(from.c_str(), to.c_str()) == -1)
+    return err.report(capture_errno());
+}
+
+path __current_path(error_code* ec) {
+  ErrorHandler<path> err("current_path", ec);
+
+  auto size = ::pathconf(".", _PC_PATH_MAX);
+  _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
+
+  auto buff = unique_ptr<char[]>(new char[size + 1]);
+  char* ret;
+  if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr)
+    return err.report(capture_errno(), "call to getcwd failed");
+
+  return {buff.get()};
+}
+
+void __current_path(const path& p, error_code* ec) {
+  ErrorHandler<void> err("current_path", ec, &p);
+  if (::chdir(p.c_str()) == -1)
+    err.report(capture_errno());
+}
+
+bool __equivalent(const path& p1, const path& p2, error_code* ec) {
+  ErrorHandler<bool> err("equivalent", ec, &p1, &p2);
+
+  error_code ec1, ec2;
+  StatT st1 = {}, st2 = {};
+  auto s1 = detail::posix_stat(p1.native(), st1, &ec1);
+  if (!exists(s1))
+    return err.report(errc::not_supported);
+  auto s2 = detail::posix_stat(p2.native(), st2, &ec2);
+  if (!exists(s2))
+    return err.report(errc::not_supported);
+
+  return detail::stat_equivalent(st1, st2);
+}
+
+uintmax_t __file_size(const path& p, error_code* ec) {
+  ErrorHandler<uintmax_t> err("file_size", ec, &p);
+
+  error_code m_ec;
+  StatT st;
+  file_status fst = detail::posix_stat(p, st, &m_ec);
+  if (!exists(fst) || !is_regular_file(fst)) {
+    errc error_kind =
+        is_directory(fst) ? errc::is_a_directory : errc::not_supported;
+    if (!m_ec)
+      m_ec = make_error_code(error_kind);
+    return err.report(m_ec);
+  }
+  // is_regular_file(p) == true
+  return static_cast<uintmax_t>(st.st_size);
+}
+
+uintmax_t __hard_link_count(const path& p, error_code* ec) {
+  ErrorHandler<uintmax_t> err("hard_link_count", ec, &p);
+
+  error_code m_ec;
+  StatT st;
+  detail::posix_stat(p, st, &m_ec);
+  if (m_ec)
+    return err.report(m_ec);
+  return static_cast<uintmax_t>(st.st_nlink);
+}
+
+bool __fs_is_empty(const path& p, error_code* ec) {
+  ErrorHandler<bool> err("is_empty", ec, &p);
+
+  error_code m_ec;
+  StatT pst;
+  auto st = detail::posix_stat(p, pst, &m_ec);
+  if (m_ec)
+    return err.report(m_ec);
+  else if (!is_directory(st) && !is_regular_file(st))
+    return err.report(errc::not_supported);
+  else if (is_directory(st)) {
+    auto it = ec ? directory_iterator(p, *ec) : directory_iterator(p);
+    if (ec && *ec)
+      return false;
+    return it == directory_iterator{};
+  } else if (is_regular_file(st))
+    return static_cast<uintmax_t>(pst.st_size) == 0;
+
+  _LIBCPP_UNREACHABLE();
+}
+
+static file_time_type __extract_last_write_time(const path& p, const StatT& st,
+                                                error_code* ec) {
+  using detail::fs_time;
+  ErrorHandler<file_time_type> err("last_write_time", ec, &p);
+
+  auto ts = detail::extract_mtime(st);
+  if (!fs_time::is_representable(ts))
+    return err.report(errc::value_too_large);
+
+  return fs_time::convert_from_timespec(ts);
+}
+
+file_time_type __last_write_time(const path& p, error_code* ec) {
+  using namespace chrono;
+  ErrorHandler<file_time_type> err("last_write_time", ec, &p);
+
+  error_code m_ec;
+  StatT st;
+  detail::posix_stat(p, st, &m_ec);
+  if (m_ec)
+    return err.report(m_ec);
+  return __extract_last_write_time(p, st, ec);
+}
+
+void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
+  using detail::fs_time;
+  ErrorHandler<void> err("last_write_time", ec, &p);
+
+  error_code m_ec;
+  array<TimeSpec, 2> tbuf;
+#if !defined(_LIBCPP_USE_UTIMENSAT)
+  // This implementation has a race condition between determining the
+  // last access time and attempting to set it to the same value using
+  // ::utimes
+  StatT st;
+  file_status fst = detail::posix_stat(p, st, &m_ec);
+  if (m_ec)
+    return err.report(m_ec);
+  tbuf[0] = detail::extract_atime(st);
+#else
+  tbuf[0].tv_sec = 0;
+  tbuf[0].tv_nsec = UTIME_OMIT;
+#endif
+  if (!fs_time::convert_to_timespec(tbuf[1], new_time))
+    return err.report(errc::value_too_large);
+
+  detail::set_file_times(p, tbuf, m_ec);
+  if (m_ec)
+    return err.report(m_ec);
+}
+
+void __permissions(const path& p, perms prms, perm_options opts,
+                   error_code* ec) {
+  ErrorHandler<void> err("permissions", ec, &p);
+
+  auto has_opt = [&](perm_options o) { return bool(o & opts); };
+  const bool resolve_symlinks = !has_opt(perm_options::nofollow);
+  const bool add_perms = has_opt(perm_options::add);
+  const bool remove_perms = has_opt(perm_options::remove);
+  _LIBCPP_ASSERT(
+      (add_perms + remove_perms + has_opt(perm_options::replace)) == 1,
+      "One and only one of the perm_options constants replace, add, or remove "
+      "is present in opts");
+
+  bool set_sym_perms = false;
+  prms &= perms::mask;
+  if (!resolve_symlinks || (add_perms || remove_perms)) {
+    error_code m_ec;
+    file_status st = resolve_symlinks ? detail::posix_stat(p, &m_ec)
+                                      : detail::posix_lstat(p, &m_ec);
+    set_sym_perms = is_symlink(st);
+    if (m_ec)
+      return err.report(m_ec);
+    _LIBCPP_ASSERT(st.permissions() != perms::unknown,
+                   "Permissions unexpectedly unknown");
+    if (add_perms)
+      prms |= st.permissions();
+    else if (remove_perms)
+      prms = st.permissions() & ~prms;
+  }
+  const auto real_perms = detail::posix_convert_perms(prms);
+
+#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
+  const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0;
+  if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) {
+    return err.report(capture_errno());
+  }
+#else
+  if (set_sym_perms)
+    return err.report(errc::operation_not_supported);
+  if (::chmod(p.c_str(), real_perms) == -1) {
+    return err.report(capture_errno());
+  }
+#endif
+}
+
+path __read_symlink(const path& p, error_code* ec) {
+  ErrorHandler<path> err("read_symlink", ec, &p);
+
+  char buff[PATH_MAX + 1];
+  error_code m_ec;
+  ::ssize_t ret;
+  if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) {
+    return err.report(capture_errno());
+  }
+  _LIBCPP_ASSERT(ret <= PATH_MAX, "TODO");
+  _LIBCPP_ASSERT(ret > 0, "TODO");
+  buff[ret] = 0;
+  return {buff};
+}
+
+bool __remove(const path& p, error_code* ec) {
+  ErrorHandler<bool> err("remove", ec, &p);
+  if (::remove(p.c_str()) == -1) {
+    if (errno != ENOENT)
+      err.report(capture_errno());
+    return false;
+  }
+  return true;
+}
+
+namespace {
+
+uintmax_t remove_all_impl(path const& p, error_code& ec) {
+  const auto npos = static_cast<uintmax_t>(-1);
+  const file_status st = __symlink_status(p, &ec);
+  if (ec)
+    return npos;
+  uintmax_t count = 1;
+  if (is_directory(st)) {
+    for (directory_iterator it(p, ec); !ec && it != directory_iterator();
+         it.increment(ec)) {
+      auto other_count = remove_all_impl(it->path(), ec);
+      if (ec)
+        return npos;
+      count += other_count;
+    }
+    if (ec)
+      return npos;
+  }
+  if (!__remove(p, &ec))
+    return npos;
+  return count;
+}
+
+} // end namespace
+
+uintmax_t __remove_all(const path& p, error_code* ec) {
+  ErrorHandler<uintmax_t> err("remove_all", ec, &p);
+
+  error_code mec;
+  auto count = remove_all_impl(p, mec);
+  if (mec) {
+    if (mec == errc::no_such_file_or_directory)
+      return 0;
+    return err.report(mec);
+  }
+  return count;
+}
+
+void __rename(const path& from, const path& to, error_code* ec) {
+  ErrorHandler<void> err("rename", ec, &from, &to);
+  if (::rename(from.c_str(), to.c_str()) == -1)
+    err.report(capture_errno());
+}
+
+void __resize_file(const path& p, uintmax_t size, error_code* ec) {
+  ErrorHandler<void> err("resize_file", ec, &p);
+  if (::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
+    return err.report(capture_errno());
+}
+
+space_info __space(const path& p, error_code* ec) {
+  ErrorHandler<void> err("space", ec, &p);
+  space_info si;
+  struct statvfs m_svfs = {};
+  if (::statvfs(p.c_str(), &m_svfs) == -1) {
+    err.report(capture_errno());
+    si.capacity = si.free = si.available = static_cast<uintmax_t>(-1);
+    return si;
+  }
+  // Multiply with overflow checking.
+  auto do_mult = [&](uintmax_t& out, uintmax_t other) {
+    out = other * m_svfs.f_frsize;
+    if (other == 0 || out / other != m_svfs.f_frsize)
+      out = static_cast<uintmax_t>(-1);
+  };
+  do_mult(si.capacity, m_svfs.f_blocks);
+  do_mult(si.free, m_svfs.f_bfree);
+  do_mult(si.available, m_svfs.f_bavail);
+  return si;
+}
+
+file_status __status(const path& p, error_code* ec) {
+  return detail::posix_stat(p, ec);
+}
+
+file_status __symlink_status(const path& p, error_code* ec) {
+  return detail::posix_lstat(p, ec);
+}
+
+path __temp_directory_path(error_code* ec) {
+  ErrorHandler<path> err("temp_directory_path", ec);
+
+  const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
+  const char* ret = nullptr;
+
+  for (auto& ep : env_paths)
+    if ((ret = getenv(ep)))
+      break;
+  if (ret == nullptr)
+    ret = "/tmp";
+
+  path p(ret);
+  error_code m_ec;
+  file_status st = detail::posix_stat(p, &m_ec);
+  if (!status_known(st))
+    return err.report(m_ec, "cannot access path \"%s\"", p);
+
+  if (!exists(st) || !is_directory(st))
+    return err.report(errc::not_a_directory, "path \"%s\" is not a directory",
+                      p);
+
+  return p;
+}
+
+path __weakly_canonical(const path& p, error_code* ec) {
+  ErrorHandler<path> err("weakly_canonical", ec, &p);
+
+  if (p.empty())
+    return __canonical("", ec);
+
+  path result;
+  path tmp;
+  tmp.__reserve(p.native().size());
+  auto PP = PathParser::CreateEnd(p.native());
+  --PP;
+  vector<string_view_t> DNEParts;
+
+  while (PP.State != PathParser::PS_BeforeBegin) {
+    tmp.assign(createView(p.native().data(), &PP.RawEntry.back()));
+    error_code m_ec;
+    file_status st = __status(tmp, &m_ec);
+    if (!status_known(st)) {
+      return err.report(m_ec);
+    } else if (exists(st)) {
+      result = __canonical(tmp, ec);
+      break;
+    }
+    DNEParts.push_back(*PP);
+    --PP;
+  }
+  if (PP.State == PathParser::PS_BeforeBegin)
+    result = __canonical("", ec);
+  if (ec)
+    ec->clear();
+  if (DNEParts.empty())
+    return result;
+  for (auto It = DNEParts.rbegin(); It != DNEParts.rend(); ++It)
+    result /= *It;
+  return result.lexically_normal();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//                            path definitions
+///////////////////////////////////////////////////////////////////////////////
+
+constexpr path::value_type path::preferred_separator;
+
+path& path::replace_extension(path const& replacement) {
+  path p = extension();
+  if (not p.empty()) {
+    __pn_.erase(__pn_.size() - p.native().size());
+  }
+  if (!replacement.empty()) {
+    if (replacement.native()[0] != '.') {
+      __pn_ += ".";
+    }
+    __pn_.append(replacement.__pn_);
+  }
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// path.decompose
+
+string_view_t path::__root_name() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName)
+    return *PP;
+  return {};
+}
+
+string_view_t path::__root_directory() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName)
+    ++PP;
+  if (PP.State == PathParser::PS_InRootDir)
+    return *PP;
+  return {};
+}
+
+string_view_t path::__root_path_raw() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (PP.State == PathParser::PS_InRootName) {
+    auto NextCh = PP.peek();
+    if (NextCh && *NextCh == '/') {
+      ++PP;
+      return createView(__pn_.data(), &PP.RawEntry.back());
+    }
+    return PP.RawEntry;
+  }
+  if (PP.State == PathParser::PS_InRootDir)
+    return *PP;
+  return {};
+}
+
+static bool ConsumeRootName(PathParser *PP) {
+  static_assert(PathParser::PS_BeforeBegin == 1 &&
+      PathParser::PS_InRootName == 2,
+      "Values for enums are incorrect");
+  while (PP->State <= PathParser::PS_InRootName)
+    ++(*PP);
+  return PP->State == PathParser::PS_AtEnd;
+}
+
+static bool ConsumeRootDir(PathParser* PP) {
+  static_assert(PathParser::PS_BeforeBegin == 1 &&
+                PathParser::PS_InRootName == 2 &&
+                PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
+  while (PP->State <= PathParser::PS_InRootDir)
+    ++(*PP);
+  return PP->State == PathParser::PS_AtEnd;
+}
+
+string_view_t path::__relative_path() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  if (ConsumeRootDir(&PP))
+    return {};
+  return createView(PP.RawEntry.data(), &__pn_.back());
+}
+
+string_view_t path::__parent_path() const {
+  if (empty())
+    return {};
+  // Determine if we have a root path but not a relative path. In that case
+  // return *this.
+  {
+    auto PP = PathParser::CreateBegin(__pn_);
+    if (ConsumeRootDir(&PP))
+      return __pn_;
+  }
+  // Otherwise remove a single element from the end of the path, and return
+  // a string representing that path
+  {
+    auto PP = PathParser::CreateEnd(__pn_);
+    --PP;
+    if (PP.RawEntry.data() == __pn_.data())
+      return {};
+    --PP;
+    return createView(__pn_.data(), &PP.RawEntry.back());
+  }
+}
+
+string_view_t path::__filename() const {
+  if (empty())
+    return {};
+  {
+    PathParser PP = PathParser::CreateBegin(__pn_);
+    if (ConsumeRootDir(&PP))
+      return {};
+  }
+  return *(--PathParser::CreateEnd(__pn_));
+}
+
+string_view_t path::__stem() const {
+  return parser::separate_filename(__filename()).first;
+}
+
+string_view_t path::__extension() const {
+  return parser::separate_filename(__filename()).second;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.gen
+
+enum PathPartKind : unsigned char {
+  PK_None,
+  PK_RootSep,
+  PK_Filename,
+  PK_Dot,
+  PK_DotDot,
+  PK_TrailingSep
+};
+
+static PathPartKind ClassifyPathPart(string_view_t Part) {
+  if (Part.empty())
+    return PK_TrailingSep;
+  if (Part == ".")
+    return PK_Dot;
+  if (Part == "..")
+    return PK_DotDot;
+  if (Part == "/")
+    return PK_RootSep;
+  return PK_Filename;
+}
+
+path path::lexically_normal() const {
+  if (__pn_.empty())
+    return *this;
+
+  using PartKindPair = pair<string_view_t, PathPartKind>;
+  vector<PartKindPair> Parts;
+  // Guess as to how many elements the path has to avoid reallocating.
+  Parts.reserve(32);
+
+  // Track the total size of the parts as we collect them. This allows the
+  // resulting path to reserve the correct amount of memory.
+  size_t NewPathSize = 0;
+  auto AddPart = [&](PathPartKind K, string_view_t P) {
+    NewPathSize += P.size();
+    Parts.emplace_back(P, K);
+  };
+  auto LastPartKind = [&]() {
+    if (Parts.empty())
+      return PK_None;
+    return Parts.back().second;
+  };
+
+  bool MaybeNeedTrailingSep = false;
+  // Build a stack containing the remaining elements of the path, popping off
+  // elements which occur before a '..' entry.
+  for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
+    auto Part = *PP;
+    PathPartKind Kind = ClassifyPathPart(Part);
+    switch (Kind) {
+    case PK_Filename:
+    case PK_RootSep: {
+      // Add all non-dot and non-dot-dot elements to the stack of elements.
+      AddPart(Kind, Part);
+      MaybeNeedTrailingSep = false;
+      break;
+    }
+    case PK_DotDot: {
+      // Only push a ".." element if there are no elements preceding the "..",
+      // or if the preceding element is itself "..".
+      auto LastKind = LastPartKind();
+      if (LastKind == PK_Filename) {
+        NewPathSize -= Parts.back().first.size();
+        Parts.pop_back();
+      } else if (LastKind != PK_RootSep)
+        AddPart(PK_DotDot, "..");
+      MaybeNeedTrailingSep = LastKind == PK_Filename;
+      break;
+    }
+    case PK_Dot:
+    case PK_TrailingSep: {
+      MaybeNeedTrailingSep = true;
+      break;
+    }
+    case PK_None:
+      _LIBCPP_UNREACHABLE();
+    }
+  }
+  // [fs.path.generic]p6.8: If the path is empty, add a dot.
+  if (Parts.empty())
+    return ".";
+
+  // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
+  // trailing directory-separator.
+  bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
+
+  path Result;
+  Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
+  for (auto& PK : Parts)
+    Result /= PK.first;
+
+  if (NeedTrailingSep)
+    Result /= "";
+
+  return Result;
+}
+
+static int DetermineLexicalElementCount(PathParser PP) {
+  int Count = 0;
+  for (; PP; ++PP) {
+    auto Elem = *PP;
+    if (Elem == "..")
+      --Count;
+    else if (Elem != "." && Elem != "")
+      ++Count;
+  }
+  return Count;
+}
+
+path path::lexically_relative(const path& base) const {
+  { // perform root-name/root-directory mismatch checks
+    auto PP = PathParser::CreateBegin(__pn_);
+    auto PPBase = PathParser::CreateBegin(base.__pn_);
+    auto CheckIterMismatchAtBase = [&]() {
+      return PP.State != PPBase.State &&
+             (PP.inRootPath() || PPBase.inRootPath());
+    };
+    if (PP.inRootName() && PPBase.inRootName()) {
+      if (*PP != *PPBase)
+        return {};
+    } else if (CheckIterMismatchAtBase())
+      return {};
+
+    if (PP.inRootPath())
+      ++PP;
+    if (PPBase.inRootPath())
+      ++PPBase;
+    if (CheckIterMismatchAtBase())
+      return {};
+  }
+
+  // Find the first mismatching element
+  auto PP = PathParser::CreateBegin(__pn_);
+  auto PPBase = PathParser::CreateBegin(base.__pn_);
+  while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
+    ++PP;
+    ++PPBase;
+  }
+
+  // If there is no mismatch, return ".".
+  if (!PP && !PPBase)
+    return ".";
+
+  // Otherwise, determine the number of elements, 'n', which are not dot or
+  // dot-dot minus the number of dot-dot elements.
+  int ElemCount = DetermineLexicalElementCount(PPBase);
+  if (ElemCount < 0)
+    return {};
+
+  // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
+  if (ElemCount == 0 && (PP.atEnd() || *PP == ""))
+    return ".";
+
+  // return a path constructed with 'n' dot-dot elements, followed by the
+  // elements of '*this' after the mismatch.
+  path Result;
+  // FIXME: Reserve enough room in Result that it won't have to re-allocate.
+  while (ElemCount--)
+    Result /= "..";
+  for (; PP; ++PP)
+    Result /= *PP;
+  return Result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.comparisons
+static int CompareRootName(PathParser *LHS, PathParser *RHS) {
+  if (!LHS->inRootName() && !RHS->inRootName())
+    return 0;
+
+  auto GetRootName = [](PathParser *Parser) -> string_view_t {
+    return Parser->inRootName() ? **Parser : "";
+  };
+  int res = GetRootName(LHS).compare(GetRootName(RHS));
+  ConsumeRootName(LHS);
+  ConsumeRootName(RHS);
+  return res;
+}
+
+static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
+  if (!LHS->inRootDir() && RHS->inRootDir())
+    return -1;
+  else if (LHS->inRootDir() && !RHS->inRootDir())
+    return 1;
+  else {
+    ConsumeRootDir(LHS);
+    ConsumeRootDir(RHS);
+    return 0;
+  }
+}
+
+static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
+  auto &LHS = *LHSPtr;
+  auto &RHS = *RHSPtr;
+
+  int res;
+  while (LHS && RHS) {
+    if ((res = (*LHS).compare(*RHS)) != 0)
+      return res;
+    ++LHS;
+    ++RHS;
+  }
+  return 0;
+}
+
+static int CompareEndState(PathParser *LHS, PathParser *RHS) {
+  if (LHS->atEnd() && !RHS->atEnd())
+    return -1;
+  else if (!LHS->atEnd() && RHS->atEnd())
+    return 1;
+  return 0;
+}
+
+int path::__compare(string_view_t __s) const {
+  auto LHS = PathParser::CreateBegin(__pn_);
+  auto RHS = PathParser::CreateBegin(__s);
+  int res;
+
+  if ((res = CompareRootName(&LHS, &RHS)) != 0)
+    return res;
+
+  if ((res = CompareRootDir(&LHS, &RHS)) != 0)
+    return res;
+
+  if ((res = CompareRelative(&LHS, &RHS)) != 0)
+    return res;
+
+  return CompareEndState(&LHS, &RHS);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.nonmembers
+size_t hash_value(const path& __p) noexcept {
+  auto PP = PathParser::CreateBegin(__p.native());
+  size_t hash_value = 0;
+  hash<string_view_t> hasher;
+  while (PP) {
+    hash_value = __hash_combine(hash_value, hasher(*PP));
+    ++PP;
+  }
+  return hash_value;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.itr
+path::iterator path::begin() const {
+  auto PP = PathParser::CreateBegin(__pn_);
+  iterator it;
+  it.__path_ptr_ = this;
+  it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
+  it.__entry_ = PP.RawEntry;
+  it.__stashed_elem_.__assign_view(*PP);
+  return it;
+}
+
+path::iterator path::end() const {
+  iterator it{};
+  it.__state_ = path::iterator::_AtEnd;
+  it.__path_ptr_ = this;
+  return it;
+}
+
+path::iterator& path::iterator::__increment() {
+  PathParser PP(__path_ptr_->native(), __entry_, __state_);
+  ++PP;
+  __state_ = static_cast<_ParserState>(PP.State);
+  __entry_ = PP.RawEntry;
+  __stashed_elem_.__assign_view(*PP);
+  return *this;
+}
+
+path::iterator& path::iterator::__decrement() {
+  PathParser PP(__path_ptr_->native(), __entry_, __state_);
+  --PP;
+  __state_ = static_cast<_ParserState>(PP.State);
+  __entry_ = PP.RawEntry;
+  __stashed_elem_.__assign_view(*PP);
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//                           directory entry definitions
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _LIBCPP_WIN32API
+error_code directory_entry::__do_refresh() noexcept {
+  __data_.__reset();
+  error_code failure_ec;
+
+  StatT full_st;
+  file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
+  if (!status_known(st)) {
+    __data_.__reset();
+    return failure_ec;
+  }
+
+  if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
+    __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+  } else { // we have a symlink
+    __data_.__sym_perms_ = st.permissions();
+    // Get the information about the linked entity.
+    // Ignore errors from stat, since we don't want errors regarding symlink
+    // resolution to be reported to the user.
+    error_code ignored_ec;
+    st = detail::posix_stat(__p_, full_st, &ignored_ec);
+
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+
+    // If we failed to resolve the link, then only partially populate the
+    // cache.
+    if (!status_known(st)) {
+      __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
+      return error_code{};
+    }
+    // Otherwise, we resolved the link, potentially as not existing.
+    // That's OK.
+    __data_.__cache_type_ = directory_entry::_RefreshSymlink;
+  }
+
+  if (_VSTD_FS::is_regular_file(st))
+    __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
+
+  if (_VSTD_FS::exists(st)) {
+    __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
+
+    // Attempt to extract the mtime, and fail if it's not representable using
+    // file_time_type. For now we ignore the error, as we'll report it when
+    // the value is actually used.
+    error_code ignored_ec;
+    __data_.__write_time_ =
+        __extract_last_write_time(__p_, full_st, &ignored_ec);
+  }
+
+  return failure_ec;
+}
+#else
+error_code directory_entry::__do_refresh() noexcept {
+  __data_.__reset();
+  error_code failure_ec;
+
+  file_status st = _VSTD_FS::symlink_status(__p_, failure_ec);
+  if (!status_known(st)) {
+    __data_.__reset();
+    return failure_ec;
+  }
+
+  if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
+    __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+  } else { // we have a symlink
+    __data_.__sym_perms_ = st.permissions();
+    // Get the information about the linked entity.
+    // Ignore errors from stat, since we don't want errors regarding symlink
+    // resolution to be reported to the user.
+    error_code ignored_ec;
+    st = _VSTD_FS::status(__p_, ignored_ec);
+
+    __data_.__type_ = st.type();
+    __data_.__non_sym_perms_ = st.permissions();
+
+    // If we failed to resolve the link, then only partially populate the
+    // cache.
+    if (!status_known(st)) {
+      __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
+      return error_code{};
+    }
+    __data_.__cache_type_ = directory_entry::_RefreshSymlink;
+  }
+
+  // FIXME: This is currently broken, and the implementation only a placeholder.
+  // We need to cache last_write_time, file_size, and hard_link_count here before
+  // the implementation actually works.
+
+  return failure_ec;
+}
+#endif
+
+#ifndef _LIBAUTO_UNDEF_VSTD_FS
+#pragma pop_macro("_VSTD_FS")
+#else
+#undef _VSTD
+#undef _LIBAUTO_UNDEF_VSTD_FS
+#endif
+}  // namespace android::hardware::automotive::filesystem
+/* clang-format on */
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index e529675..21b410a 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -125,6 +125,9 @@
 cc_binary {
     name: "android.hardware.automotive.vehicle@2.0-service",
     defaults: ["vhal_v2_0_defaults"],
+    vintf_fragments: [
+        "android.hardware.automotive.vehicle@2.0-service.xml",
+    ],
     init_rc: ["android.hardware.automotive.vehicle@2.0-service.rc"],
     vendor: true,
     relative_install_path: "hw",
diff --git a/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.xml b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.xml
new file mode 100644
index 0000000..660b03d
--- /dev/null
+++ b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.automotive.vehicle</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index ea75986..83546e2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -439,6 +439,16 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                         .configArray = {(int)VehicleUnit::KILOPASCAL, (int)VehicleUnit::PSI,
+                                         (int)VehicleUnit::BAR},
+                 },
+         .initialValue = {.int32Values = {toInt(VehicleUnit::PSI)}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::CURRENT_GEAR),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -1028,6 +1038,14 @@
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
                         },
         },
+        {
+                .config =
+                        {
+                                .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
+                                .access = VehiclePropertyAccess::READ_WRITE,
+                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                        },
+        },
 };
 
 }  // impl
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 23f9135..82f938c 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2646,9 +2646,9 @@
      * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
      *
      * int32[0]: -108 // request id
-     * int32[1]:  5   // messageType = SwitchUserMessageType::ANDROID_SWITCH
+     * int32[1]:  5   // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
      * int32[2]:  11  // target user id
-     * int32[3]:  11  // target user id flags (none)
+     * int32[3]:  0   // target user id flags (none)
      * int32[4]:  11  // current user
      * int32[5]:  0   // current user flags (none)
      * int32[6]:  3   // number of users
@@ -2664,17 +2664,21 @@
      *
      * 5.ANDROID_POST_SWITCH
      * ---------------------
-     * Called by the Android System after a request to switch a user was made
+     * Called by the Android System after a request to switch a user was made.
      *
      * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
      * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
      * failed:
      *
-     * 1. When it succeeded, it's called when the Android user is in the boot locked state and the
-     *    value of the current and target users ids in the response are different. This would be
-     *    equivalent to receiving an Intent.ACTION_LOCKED_BOOT_COMPLETED in an Android app.
+     * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
+     *    value of the current and target users ids in the response are the same. This would be
+     *    equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
      * 2. When it failed it's called right away and the value of the current and target users ids
-     *    in the response are the same.
+     *    in the response are different (as the current user didn't change to the target).
+     * 3. If a new switch request is made before the HAL responded to the previous one or before
+     *    the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
+     *    the driver could accidentally switch to the wrong user which has lock crentials, then
+     *    switch to the right one before entering the credentials.
      *
      * The HAL can update its internal state once it receives this request, but it doesn't need to
      * reply back to the Android System.
@@ -2824,7 +2828,7 @@
      * int32[0]: 0   (Android user flags)
      * int32[1]: 1   (number of associations being set)
      * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
-     * int32[3]: 1   (1st value: UserIdentificationAssociationSETValue::ASSOCIATE_CURRENT_USER)
+     * int32[3]: 1   (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
      *
      * If the request succeeded, the response would be simply:
      *
diff --git a/biometrics/fingerprint/2.1/default/Android.bp b/biometrics/fingerprint/2.1/default/Android.bp
index 497fa3f..ec4838b 100644
--- a/biometrics/fingerprint/2.1/default/Android.bp
+++ b/biometrics/fingerprint/2.1/default/Android.bp
@@ -2,6 +2,7 @@
     name: "android.hardware.biometrics.fingerprint@2.1-service",
     defaults: ["hidl_defaults"],
     init_rc: ["android.hardware.biometrics.fingerprint@2.1-service.rc"],
+    vintf_fragments: ["android.hardware.biometrics.fingerprint@2.1-service.xml"],
     vendor: true,
     relative_install_path: "hw",
     srcs: [
diff --git a/biometrics/fingerprint/2.1/default/android.hardware.biometrics.fingerprint@2.1-service.xml b/biometrics/fingerprint/2.1/default/android.hardware.biometrics.fingerprint@2.1-service.xml
new file mode 100644
index 0000000..115dd7b
--- /dev/null
+++ b/biometrics/fingerprint/2.1/default/android.hardware.biometrics.fingerprint@2.1-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <transport>hwbinder</transport>
+        <version>2.1</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/bluetooth/a2dp/1.0/vts/functional/Android.bp b/bluetooth/a2dp/1.0/vts/functional/Android.bp
index 5b8410a..df18fcc 100644
--- a/bluetooth/a2dp/1.0/vts/functional/Android.bp
+++ b/bluetooth/a2dp/1.0/vts/functional/Android.bp
@@ -23,5 +23,5 @@
         "android.hardware.bluetooth.a2dp@1.0",
         "libbluetooth-types",
     ],
-    test_suites: ["general-tests", "vts-core"],
+    test_suites: ["general-tests", "vts"],
 }
diff --git a/broadcastradio/common/vts/utils/Android.bp b/broadcastradio/common/vts/utils/Android.bp
index d3edc76..24fea0b 100644
--- a/broadcastradio/common/vts/utils/Android.bp
+++ b/broadcastradio/common/vts/utils/Android.bp
@@ -25,8 +25,5 @@
         "-Wextra",
         "-Werror",
     ],
-    static_libs: [
-        "VtsHalHidlTargetTestBase",
-    ],
     group_static_libs: true,
 }
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index e48f993..2772ba3 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -40,7 +40,15 @@
 		Description: "assemble_vintf -i ${inputs}",
 	}, "inputs")
 
-	kernelConfigTag = dependencyTag{name: "kernel-config"}
+	xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{
+		Command:     `$XmlLintCmd --schema $xsd $in > /dev/null && touch -a $out`,
+		CommandDeps: []string{"$XmlLintCmd"},
+		Restat:      true,
+	}, "xsd")
+
+	kernelConfigTag  = dependencyTag{name: "kernel-config"}
+	schemaTag        = dependencyTag{name: "matrix-schema"}
+	schemaModuleName = "compatibility_matrix_schema"
 )
 
 const (
@@ -62,11 +70,13 @@
 	android.ModuleBase
 	properties vintfCompatibilityMatrixProperties
 
-	genFile android.WritablePath
+	genFile                android.WritablePath
+	additionalDependencies android.WritablePaths
 }
 
 func init() {
 	pctx.HostBinToolVariable("assembleVintfCmd", "assemble_vintf")
+	pctx.HostBinToolVariable("XmlLintCmd", "xmllint")
 	android.RegisterModuleType("vintf_compatibility_matrix", vintfCompatibilityMatrixFactory)
 }
 
@@ -82,6 +92,42 @@
 func (g *vintfCompatibilityMatrixRule) DepsMutator(ctx android.BottomUpMutatorContext) {
 	android.ExtractSourcesDeps(ctx, g.properties.Srcs)
 	ctx.AddDependency(ctx.Module(), kernelConfigTag, g.properties.Kernel_configs...)
+	ctx.AddDependency(ctx.Module(), schemaTag, schemaModuleName)
+}
+
+func (g *vintfCompatibilityMatrixRule) timestampFilePath(ctx android.ModuleContext, path android.Path) android.WritablePath {
+	return android.GenPathWithExt(ctx, "vintf-xmllint", path, "ts")
+}
+
+func (g *vintfCompatibilityMatrixRule) generateValidateBuildAction(ctx android.ModuleContext, path android.Path, schema android.Path) {
+	timestamp := g.timestampFilePath(ctx, path)
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        xmllintXsd,
+		Description: "xmllint-xsd",
+		Input:       path,
+		Output:      timestamp,
+		Implicit:    schema,
+		Args: map[string]string{
+			"xsd": schema.String(),
+		},
+	})
+	g.additionalDependencies = append(g.additionalDependencies, timestamp)
+}
+
+func (g *vintfCompatibilityMatrixRule) getSchema(ctx android.ModuleContext) android.OptionalPath {
+	schemaModule := ctx.GetDirectDepWithTag(schemaModuleName, schemaTag)
+	sfp, ok := schemaModule.(android.SourceFileProducer)
+	if !ok {
+		ctx.ModuleErrorf("Implicit dependency %q has no srcs", ctx.OtherModuleName(schemaModule))
+		return android.OptionalPath{}
+	}
+
+	schemaSrcs := sfp.Srcs()
+	if len(schemaSrcs) != 1 {
+		ctx.PropertyErrorf(`srcs of implicit dependency %q has length %d != 1`, ctx.OtherModuleName(schemaModule), len(schemaSrcs))
+		return android.OptionalPath{}
+	}
+	return android.OptionalPathForPath(schemaSrcs[0])
 }
 
 func (g *vintfCompatibilityMatrixRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -91,7 +137,18 @@
 		outputFilename = g.Name()
 	}
 
+	schema := g.getSchema(ctx)
+	if !schema.Valid() {
+		return
+	}
+
 	inputPaths := android.PathsForModuleSrc(ctx, g.properties.Srcs)
+	for _, srcPath := range inputPaths {
+		g.generateValidateBuildAction(ctx, srcPath, schema.Path())
+	}
+
+	// No need to validate matrices from kernel configs because they are generated by
+	// assemble_vintf.
 	ctx.VisitDirectDepsWithTag(kernelConfigTag, func(m android.Module) {
 		if k, ok := m.(*configs.KernelConfigRule); ok {
 			inputPaths = append(inputPaths, k.OutputPath())
@@ -112,6 +169,7 @@
 			"inputs": strings.Join(inputPaths.Strings(), ":"),
 		},
 	})
+	g.generateValidateBuildAction(ctx, g.genFile, schema.Path())
 
 	ctx.InstallFile(android.PathForModuleInstall(ctx, "etc", relpath), outputFilename, g.genFile)
 }
@@ -126,6 +184,9 @@
 				if proptools.String(g.properties.Stem) != "" {
 					fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", proptools.String(g.properties.Stem))
 				}
+				for _, path := range g.additionalDependencies {
+					fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", path.String())
+				}
 			},
 		},
 	}
diff --git a/current.txt b/current.txt
index 656f5c7..d2b7206 100644
--- a/current.txt
+++ b/current.txt
@@ -1,6 +1,10 @@
 # Do not change this file except to add new interfaces. Changing
 # pre-existing interfaces will fail VTS and break framework-only OTAs
 
+# Test HALs
+
+717c17cd380bb48710dff601d1a03351d4ebc28028353d5d60489248f506523c android.hardware.tests.lazy@1.0::ILazy
+
 # HALs released in Android O
 
 f219c3b5b8c6cb1d659d4c7328f67246abfe1a8613f469826fd3b9ad090417a2 android.hardware.audio@2.0::IDevice
@@ -588,6 +592,7 @@
 cd06a7911b9acd4a653bbf7133888878fbcb3f84be177c7a3f1becaae3d8618f android.hardware.camera.metadata@3.2::types
 a05277065c28ebecd58118bd240fb8c55757361e8648c01f7c4dacdb7f2a95dc android.hardware.camera.metadata@3.3::types
 9cb3df2bde2c6cd5fd96b7c41555420cacd7e276a556c684af91b7461c86460f android.hardware.gnss@1.0::IGnssCallback
+dd6cd9dba4fde99a1bc3cb1728d82309f509a6e6e1993e5042dfa5ffe4af5442 android.hardware.gnss@2.0::IGnssMeasurementCallback
 af334f1fc85c62b343f84b74d0495eed6f495f7fecedb53463db10c202310058 android.hardware.gnss.measurement_corrections@1.0::types
 33a6b20c43af00fdfb305df891bc5911c06d9a9130b912759649932e5a4a6e6d android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControlCallback
 bceee81ec1b59324abd05932b5620fda5a6589597c9cb3953ba7f3ea02cccd3e android.hardware.camera.provider@2.4::ICameraProvider
@@ -655,9 +660,6 @@
 7d2e77ad86766bbc213fa7377eab739f44cc0866e567e6d33c0e27e7f99e27a8 android.hardware.automotive.sv@1.0::ISurroundViewSession
 d34769e55df919739bb46f25ae2e125e9c807733afa94daeca20feadd74de79c android.hardware.automotive.sv@1.0::ISurroundViewStream
 affd9c591f48a69773fcf43dc4a716d292cd4bc5ba2be8649276af0aedea435d android.hardware.automotive.sv@1.0::types
-b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle
-7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback
-6b2564fce1d364baf9ba15a5cb00a8f08f86a5be5387c0ede795328ca536a2c7 android.hardware.automotive.vehicle@2.0::types
 140f8f62100ccf9cd282ae3685a0f4ef0a9f971d77dfbc7350ccb4e04cf295ec android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprint
 82cad99f5feb2ea9bcd4579055edf4af8feb9fc602a6e4827ddd727d254d4991 android.hardware.biometrics.fingerprint@2.2::IBiometricsFingerprintClientCallback
 ae6315fd42196478ac08441cb489d854118001bca5b9b9fd58af5110952be30e android.hardware.biometrics.fingerprint@2.2::types
diff --git a/gnss/2.0/IGnssMeasurementCallback.hal b/gnss/2.0/IGnssMeasurementCallback.hal
index e055f7a..76c7943 100644
--- a/gnss/2.0/IGnssMeasurementCallback.hal
+++ b/gnss/2.0/IGnssMeasurementCallback.hal
@@ -402,6 +402,8 @@
          * Value "C" represents GPS L1 C/A,  GPS L2 C/A, GLONASS G1 C/A, GLONASS G2 C/A, GALILEO E1C,
          * GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C.
          *
+         * value "D" represents BDS B1C D.
+         *
          * Value "I" represents GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, GALILEO E5a+b I,
          * SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I.
          *
@@ -411,7 +413,7 @@
          *
          * Value "N" represents GPS L1 codeless, GPS L2 codeless.
          *
-         * Value "P" represents GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P.
+         * Value "P" represents GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P, BDS B1C P.
          *
          * Value "Q" represents GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, GALILEO E5a+b Q,
          * SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
@@ -423,7 +425,7 @@
          * Value "X" represents GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q),
          * GALILEO E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q),
          * GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q),
-         * LEX(6) (S+L), BDS B1 (I+Q), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
+         * LEX(6) (S+L), BDS B1 (I+Q), BDS B1C (D+P), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
          *
          * Value "Y" represents GPS L1Y, GPS L2Y.
          *
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index 352a990..441e2d7 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -16,11 +16,15 @@
 
 #define LOG_TAG "health_hidl_hal_test"
 
+#include <chrono>
 #include <mutex>
 #include <set>
 #include <string>
+#include <thread>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/hardware/health/1.0/types.h>
 #include <android/hardware/health/2.0/IHealth.h>
 #include <android/hardware/health/2.0/types.h>
 #include <gflags/gflags.h>
@@ -32,48 +36,25 @@
 using ::testing::AssertionFailure;
 using ::testing::AssertionResult;
 using ::testing::AssertionSuccess;
+using namespace std::chrono_literals;
 
 DEFINE_bool(force, false, "Force test healthd even when the default instance is present.");
 
-// If GTEST_SKIP is not implemented, use our own skipping mechanism
-#ifndef GTEST_SKIP
-static std::mutex gSkippedTestsMutex;
-static std::set<std::string> gSkippedTests;
-static std::string GetCurrentTestName() {
-    const auto& info = ::testing::UnitTest::GetInstance()->current_test_info();
-#ifdef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
-    std::string test_suite = info->test_suite_name();
-#else
-    std::string test_suite = info->test_case_name();
-#endif
-    return test_suite + "." + info->name();
-}
-
-#define GTEST_SKIP()                                           \
-    do {                                                       \
-        std::unique_lock<std::mutex> lock(gSkippedTestsMutex); \
-        gSkippedTests.insert(GetCurrentTestName());            \
-        return;                                                \
+// Return expr if it is evaluated to false.
+#define TEST_AND_RETURN(expr) \
+    do {                      \
+        auto res = (expr);    \
+        if (!res) return res; \
     } while (0)
 
-#define SKIP_IF_SKIPPED()                                                      \
-    do {                                                                       \
-        std::unique_lock<std::mutex> lock(gSkippedTestsMutex);                 \
-        if (gSkippedTests.find(GetCurrentTestName()) != gSkippedTests.end()) { \
-            std::cerr << "[  SKIPPED ] " << GetCurrentTestName() << std::endl; \
-            return;                                                            \
-        }                                                                      \
-    } while (0)
-#else
-#define SKIP_IF_SKIPPED()
-#endif
-
 namespace android {
 namespace hardware {
 namespace health {
-namespace V2_0 {
 
 using V1_0::BatteryStatus;
+using V1_0::toString;
+
+namespace V2_0 {
 
 class HealthHidlTest : public ::testing::TestWithParam<std::string> {
    public:
@@ -141,7 +122,6 @@
  * unregisterCallback, and update.
  */
 TEST_P(HealthHidlTest, Callbacks) {
-    SKIP_IF_SKIPPED();
     using namespace std::chrono_literals;
     sp<Callback> firstCallback = new Callback();
     sp<Callback> secondCallback = new Callback();
@@ -178,7 +158,6 @@
 }
 
 TEST_P(HealthHidlTest, UnregisterNonExistentCallback) {
-    SKIP_IF_SKIPPED();
     sp<Callback> callback = new Callback();
     auto ret = mHealth->unregisterCallback(callback);
     ASSERT_OK(ret);
@@ -263,7 +242,6 @@
  * Tests the values returned by getChargeCounter() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getChargeCounter) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
     }));
@@ -273,7 +251,6 @@
  * Tests the values returned by getCurrentNow() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getCurrentNow) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getCurrentNow([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
@@ -283,7 +260,6 @@
  * Tests the values returned by getCurrentAverage() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getCurrentAverage) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getCurrentAverage([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
@@ -293,7 +269,6 @@
  * Tests the values returned by getCapacity() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getCapacity) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getCapacity([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), 0 <= value && value <= 100);
     }));
@@ -303,7 +278,6 @@
  * Tests the values returned by getEnergyCounter() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getEnergyCounter) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getEnergyCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT64_MIN);
     }));
@@ -313,7 +287,6 @@
  * Tests the values returned by getChargeStatus() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getChargeStatus) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getChargeStatus([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyEnum<BatteryStatus>(value));
     }));
@@ -323,7 +296,6 @@
  * Tests the values returned by getStorageInfo() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getStorageInfo) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyStorageInfo(value));
     }));
@@ -333,7 +305,6 @@
  * Tests the values returned by getDiskStats() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getDiskStats) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), true);
     }));
@@ -343,7 +314,6 @@
  * Tests the values returned by getHealthInfo() from interface IHealth.
  */
 TEST_P(HealthHidlTest, getHealthInfo) {
-    SKIP_IF_SKIPPED();
     EXPECT_OK(mHealth->getHealthInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyHealthInfo(value));
     }));
@@ -353,6 +323,357 @@
         PerInstance, HealthHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
         android::hardware::PrintInstanceNameToString);
+
+// For battery current tests, value may not be stable if the battery current has fluctuated.
+// Retry in a bit more time (with the following timeout) and consider the test successful if it
+// has succeed once.
+static constexpr auto gBatteryTestTimeout = 1min;
+// Tests on battery current signs are only enforced on devices launching with Android 11.
+static constexpr int64_t gBatteryTestMinShippingApiLevel = 30;
+static constexpr double gCurrentCompareFactor = 0.50;
+
+// Tuple for all IHealth::get* API return values.
+template <typename T>
+struct HalResult {
+    Result result;
+    T value;
+};
+
+// Needs to be called repeatedly within a period of time to ensure values are initialized.
+static AssertionResult IsBatteryCurrentSignCorrect(HalResult<BatteryStatus> status,
+                                                   HalResult<int32_t> current,
+                                                   bool acceptZeroCurrentAsUnknown) {
+    // getChargeStatus / getCurrentNow / getCurrentAverage / getHealthInfo already tested above.
+    // Here, just skip if not ok.
+    if (status.result != Result::SUCCESS) {
+        return AssertionSuccess() << "getChargeStatus / getHealthInfo returned "
+                                  << toString(status.result) << ", skipping";
+    }
+
+    if (current.result != Result::SUCCESS) {
+        return AssertionSuccess() << "getCurrentNow / getCurrentAverage returned "
+                                  << toString(current.result) << ", skipping";
+    }
+
+    // For IHealth.getCurrentNow/Average, if current is not available, it is expected that
+    // current.result == Result::NOT_SUPPORTED, which is checked above. Hence, zero current is
+    // not treated as unknown values.
+    // For IHealth.getHealthInfo, if current is not available, health_info.current_* == 0.
+    // Caller of this function provides current.result == Result::SUCCESS. Hence, just skip the
+    // check.
+    if (current.value == 0 && acceptZeroCurrentAsUnknown) {
+        return AssertionSuccess()
+               << "current is 0, which indicates the value may not be available. Skipping.";
+    }
+
+    switch (status.value) {
+        case BatteryStatus::UNKNOWN:
+            if (current.value != 0) {
+                // BatteryStatus may be UNKNOWN initially with a non-zero current value, but
+                // after it is initialized, it should be known.
+                return AssertionFailure()
+                       << "BatteryStatus is UNKNOWN but current is not 0. Actual: "
+                       << current.value;
+            }
+            break;
+        case BatteryStatus::CHARGING:
+            if (current.value <= 0) {
+                return AssertionFailure()
+                       << "BatteryStatus is CHARGING but current is not positive. Actual: "
+                       << current.value;
+            }
+            break;
+        case BatteryStatus::NOT_CHARGING:
+            if (current.value > 0) {
+                return AssertionFailure() << "BatteryStatus is " << toString(status.value)
+                                          << " but current is positive. Actual: " << current.value;
+            }
+            break;
+        case BatteryStatus::DISCHARGING:
+            if (current.value >= 0) {
+                return AssertionFailure()
+                       << "BatteryStatus is " << toString(status.value)
+                       << " but current is not negative. Actual: " << current.value;
+            }
+            break;
+        case BatteryStatus::FULL:
+            // Battery current may be positive or negative depending on the load.
+            break;
+        default:
+            return AssertionFailure() << "Unknown BatteryStatus " << toString(status.value);
+    }
+
+    return AssertionSuccess() << "BatteryStatus is " << toString(status.value)
+                              << " and current has the correct sign: " << current.value;
+}
+
+static AssertionResult IsValueSimilar(int32_t dividend, int32_t divisor, double factor) {
+    auto difference = abs(dividend - divisor);
+    if (difference > factor * abs(divisor)) {
+        return AssertionFailure() << dividend << " and " << divisor << " are not similar.";
+    }
+    return AssertionSuccess() << dividend << " and " << divisor << " are similar.";
+}
+
+static AssertionResult IsBatteryCurrentSimilar(HalResult<BatteryStatus> status,
+                                               HalResult<int32_t> currentNow,
+                                               HalResult<int32_t> currentAverage) {
+    if (status.result == Result::SUCCESS && status.value == BatteryStatus::FULL) {
+        // No reason to test on full battery because battery current load fluctuates.
+        return AssertionSuccess() << "Battery is full, skipping";
+    }
+
+    // getCurrentNow / getCurrentAverage / getHealthInfo already tested above. Here, just skip if
+    // not SUCCESS or value 0.
+    if (currentNow.result != Result::SUCCESS || currentNow.value == 0) {
+        return AssertionSuccess() << "getCurrentNow returned " << toString(currentNow.result)
+                                  << " with value " << currentNow.value << ", skipping";
+    }
+
+    if (currentAverage.result != Result::SUCCESS || currentAverage.value == 0) {
+        return AssertionSuccess() << "getCurrentAverage returned "
+                                  << toString(currentAverage.result) << " with value "
+                                  << currentAverage.value << ", skipping";
+    }
+
+    // Check that the two values are similar. Note that the two tests uses a different
+    // divisor to ensure that they are actually pretty similar. For example,
+    // IsValueSimilar(5,10,0.4) returns true, but IsValueSimlar(10,5,0.4) returns false.
+    TEST_AND_RETURN(IsValueSimilar(currentNow.value, currentAverage.value, gCurrentCompareFactor)
+                    << " for now vs. average. Check units.");
+    TEST_AND_RETURN(IsValueSimilar(currentAverage.value, currentNow.value, gCurrentCompareFactor)
+                    << " for average vs. now. Check units.");
+    return AssertionSuccess() << "currentNow = " << currentNow.value
+                              << " and currentAverage = " << currentAverage.value
+                              << " are considered similar.";
+}
+
+// Test that f() returns AssertionSuccess() once in a given period of time.
+template <typename Duration, typename Function>
+static AssertionResult SucceedOnce(Duration d, Function f) {
+    AssertionResult result = AssertionFailure() << "Function never evaluated.";
+    auto end = std::chrono::system_clock::now() + d;
+    while (std::chrono::system_clock::now() <= end) {
+        result = f();
+        if (result) {
+            return result;
+        }
+        std::this_thread::sleep_for(2s);
+    }
+    return result;
+}
+
+uint64_t GetShippingApiLevel() {
+    uint64_t api_level = android::base::GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
+    if (api_level != 0) {
+        return api_level;
+    }
+    return android::base::GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
+}
+
+class BatteryTest : public HealthHidlTest {
+  public:
+    void SetUp() override {
+        HealthHidlTest::SetUp();
+
+        auto shippingApiLevel = GetShippingApiLevel();
+        if (shippingApiLevel < gBatteryTestMinShippingApiLevel) {
+            GTEST_SKIP() << "Skipping on devices with first API level " << shippingApiLevel;
+        }
+    }
+};
+
+TEST_P(BatteryTest, InstantCurrentAgainstChargeStatusInHealthInfo) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<HealthInfo> healthInfo;
+        TEST_AND_RETURN(isOk(mHealth->getHealthInfo([&](auto result, const auto& value) {
+            healthInfo = {result, value};
+        })));
+
+        return IsBatteryCurrentSignCorrect(
+                {healthInfo.result, healthInfo.value.legacy.batteryStatus},
+                {healthInfo.result, healthInfo.value.legacy.batteryCurrent},
+                true /* accept zero current as unknown */);
+    };
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_now becomes stable.";
+}
+
+TEST_P(BatteryTest, AverageCurrentAgainstChargeStatusInHealthInfo) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<HealthInfo> healthInfo;
+        TEST_AND_RETURN(isOk(mHealth->getHealthInfo([&](auto result, const auto& value) {
+            healthInfo = {result, value};
+        })));
+        return IsBatteryCurrentSignCorrect(
+                {healthInfo.result, healthInfo.value.legacy.batteryStatus},
+                {healthInfo.result, healthInfo.value.batteryCurrentAverage},
+                true /* accept zero current as unknown */);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_average becomes stable.";
+}
+
+TEST_P(BatteryTest, InstantCurrentAgainstAverageCurrentInHealthInfo) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<HealthInfo> healthInfo;
+        TEST_AND_RETURN(isOk(mHealth->getHealthInfo([&](auto result, const auto& value) {
+            healthInfo = {result, value};
+        })));
+        return IsBatteryCurrentSimilar({healthInfo.result, healthInfo.value.legacy.batteryStatus},
+                                       {healthInfo.result, healthInfo.value.legacy.batteryCurrent},
+                                       {healthInfo.result, healthInfo.value.batteryCurrentAverage});
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_now and current_average becomes "
+               "stable.";
+}
+
+TEST_P(BatteryTest, InstantCurrentAgainstChargeStatusFromHal) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<BatteryStatus> status;
+        HalResult<int32_t> currentNow;
+        TEST_AND_RETURN(isOk(mHealth->getChargeStatus([&](auto result, auto value) {
+            status = {result, value};
+        })));
+        TEST_AND_RETURN(isOk(mHealth->getCurrentNow([&](auto result, auto value) {
+            currentNow = {result, value};
+        })));
+
+        return IsBatteryCurrentSignCorrect(status, currentNow,
+                                           false /* accept zero current as unknown */);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_now becomes stable.";
+}
+
+TEST_P(BatteryTest, AverageCurrentAgainstChargeStatusFromHal) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<BatteryStatus> status;
+        TEST_AND_RETURN(isOk(mHealth->getChargeStatus([&](auto result, auto value) {
+            status = {result, value};
+        })));
+        HalResult<int32_t> currentAverage;
+        TEST_AND_RETURN(isOk(mHealth->getCurrentAverage([&](auto result, auto value) {
+            currentAverage = {result, value};
+        })));
+        return IsBatteryCurrentSignCorrect(status, currentAverage,
+                                           false /* accept zero current as unknown */);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_average becomes stable.";
+}
+
+TEST_P(BatteryTest, InstantCurrentAgainstAverageCurrentFromHal) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<BatteryStatus> status;
+        TEST_AND_RETURN(isOk(mHealth->getChargeStatus([&](auto result, auto value) {
+            status = {result, value};
+        })));
+        HalResult<int32_t> currentNow;
+        TEST_AND_RETURN(isOk(mHealth->getCurrentNow([&](auto result, auto value) {
+            currentNow = {result, value};
+        })));
+        HalResult<int32_t> currentAverage;
+        TEST_AND_RETURN(isOk(mHealth->getCurrentAverage([&](auto result, auto value) {
+            currentAverage = {result, value};
+        })));
+        return IsBatteryCurrentSimilar(status, currentNow, currentAverage);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when current_average becomes stable.";
+}
+
+AssertionResult IsBatteryStatusCorrect(HalResult<BatteryStatus> status,
+                                       HalResult<HealthInfo> healthInfo) {
+    // getChargetStatus / getHealthInfo is already tested above. Here, just skip if not ok.
+    if (healthInfo.result != Result::SUCCESS) {
+        return AssertionSuccess() << "getHealthInfo returned " << toString(healthInfo.result)
+                                  << ", skipping";
+    }
+    if (status.result != Result::SUCCESS) {
+        return AssertionSuccess() << "getChargeStatus returned " << toString(status.result)
+                                  << ", skipping";
+    }
+
+    const auto& batteryInfo = healthInfo.value.legacy;
+    bool isConnected = batteryInfo.chargerAcOnline || batteryInfo.chargerUsbOnline ||
+                       batteryInfo.chargerWirelessOnline;
+
+    std::stringstream message;
+    message << "BatteryStatus is " << toString(status.value) << " and "
+            << (isConnected ? "" : "no ")
+            << "power source is connected: ac=" << batteryInfo.chargerAcOnline
+            << ", usb=" << batteryInfo.chargerUsbOnline
+            << ", wireless=" << batteryInfo.chargerWirelessOnline;
+
+    switch (status.value) {
+        case BatteryStatus::UNKNOWN: {
+            // Don't enforce anything on isConnected on unknown battery status.
+            // Battery-less devices must report UNKNOWN battery status, but may report true
+            // or false on isConnected.
+        } break;
+        case BatteryStatus::CHARGING:
+        case BatteryStatus::NOT_CHARGING:
+        case BatteryStatus::FULL: {
+            if (!isConnected) {
+                return AssertionFailure() << message.str();
+            }
+        } break;
+        case BatteryStatus::DISCHARGING: {
+            if (isConnected) {
+                return AssertionFailure() << message.str();
+            }
+        } break;
+        default: {
+            return AssertionFailure() << "Unknown battery status value " << toString(status.value);
+        } break;
+    }
+
+    return AssertionSuccess() << message.str();
+}
+
+TEST_P(BatteryTest, ConnectedAgainstStatusFromHal) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<BatteryStatus> status;
+        TEST_AND_RETURN(isOk(mHealth->getChargeStatus([&](auto result, auto value) {
+            status = {result, value};
+        })));
+        HalResult<HealthInfo> healthInfo;
+        TEST_AND_RETURN(isOk(mHealth->getHealthInfo([&](auto result, const auto& value) {
+            healthInfo = {result, value};
+        })));
+        return IsBatteryStatusCorrect(status, healthInfo);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when battery_status becomes stable.";
+}
+
+TEST_P(BatteryTest, ConnectedAgainstStatusInHealthInfo) {
+    auto testOnce = [&]() -> AssertionResult {
+        HalResult<HealthInfo> healthInfo;
+        TEST_AND_RETURN(isOk(mHealth->getHealthInfo([&](auto result, const auto& value) {
+            healthInfo = {result, value};
+        })));
+        return IsBatteryStatusCorrect({healthInfo.result, healthInfo.value.legacy.batteryStatus},
+                                      healthInfo);
+    };
+
+    EXPECT_TRUE(SucceedOnce(gBatteryTestTimeout, testOnce))
+            << "You may want to try again later when getHealthInfo becomes stable.";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, BatteryTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 }  // namespace V2_0
 }  // namespace health
 }  // namespace hardware
diff --git a/identity/aidl/android/hardware/identity/CipherSuite.aidl b/identity/aidl/android/hardware/identity/CipherSuite.aidl
index 20b02a8..f38134b 100644
--- a/identity/aidl/android/hardware/identity/CipherSuite.aidl
+++ b/identity/aidl/android/hardware/identity/CipherSuite.aidl
@@ -24,13 +24,15 @@
 enum CipherSuite {
     /**
      * Specifies that the cipher suite that will be used to secure communications between the reader
-     * is:
+     * and the prover is using the following primitives
      *
-     * - ECDHE with HKDF-SHA-256 for key agreement.
-     * - AES-256 with GCM block mode for authenticated encryption (nonces are incremented by
-     *   one for every message).
-     * - ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
-     *   man-in-the-middle attacks), signing keys are not ephemeral.
+     *  - ECKA-DH (Elliptic Curve Key Agreement Algorithm - Diffie-Hellman, see BSI TR-03111)
+     *  - HKDF-SHA-256 (see RFC 5869)
+     *  - AES-256-GCM (see NIST SP 800-38D)
+     *  - HMAC-SHA-256 (see RFC 2104)
+     *
+     * The exact way these primitives are combined to derive the session key is specified in
+     * section 9.2.1.4 of ISO/IEC 18013-5 (see description of cipher suite '1').
      *
      * At present this is the only supported cipher suite and it is mandatory for all
      * implementations to support it.
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index cc14271..7d14f03 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -48,6 +48,8 @@
      * with the reader.  The reason for generating the key pair in the secure environment is so that
      * the secure environment knows what public key to expect to find in the session transcript.
      *
+     * The generated key must be an EC key using the P-256 curve.
+     *
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
@@ -61,7 +63,8 @@
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
-     * @param publicKey contains the reader's ephemeral public key, in uncompressed form.
+     * @param publicKey contains the reader's ephemeral public key, in uncompressed
+     *        form (e.g. 0x04 || X || Y).
      */
     void setReaderEphemeralPublicKey(in byte[] publicKey);
 
@@ -82,9 +85,9 @@
      * This method be called after createEphemeralKeyPair(), setReaderEphemeralPublicKey(),
      * createAuthChallenge() and before startRetrieveEntry(). This method call is followed by
      * multiple calls of startRetrieveEntryValue(), retrieveEntryValue(), and finally
-     * finishRetrieval().This whole process is called a "credential presentation".
+     * finishRetrieval().
      *
-     * It is permissible to perform multiple credential presentations using the same instance (e.g.
+     * It is permissible to perform data retrievals multiple times using the same instance (e.g.
      * startRetrieval(), then multiple calls of startRetrieveEntryValue(), retrieveEntryValue(),
      * then finally finishRetrieval()) but if this is done, the sessionTranscript parameter
      * must be identical for each startRetrieval() invocation. If this is not the case, this call
@@ -148,6 +151,8 @@
      *     EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
      *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
      *
+     *     EReaderKey.Pub = COSE_Key    ; Ephemeral public key provided by reader
+     *
      * The public key corresponding to the key used to made signature, can be found in the
      * 'x5chain' unprotected header element of the COSE_Sign1 structure (as as described
      * in 'draft-ietf-cose-x509-04'). There will be at least one certificate in said element
@@ -220,13 +225,11 @@
      *
      * It is permissible to keep retrieving values if an access control check fails.
      *
-     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013.5.1"
      *
-     * @param name is the name of the element.
+     * @param name is the name of the element, e.g. "driving_privileges".
      *
-     * @param entrySize is the size of the entry value, if it's a text string or a byte string.
-     *     It must be zero if the entry value is an integer or boolean. If this requirement
-     *     is not met the call fails with STATUS_INVALID_DATA.
+     * @param entrySize is the size of the entry value encoded in CBOR.
      *
      * @param accessControlProfileIds specifies the set of access control profiles that can
      *     authorize access to the provisioned element. If an identifier of a profile
@@ -260,14 +263,12 @@
      * @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
      *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
      *    and the detached content is set to DeviceAuthentication as defined below.
-     *    The key used for the MAC operation is EMacKey and is derived as follows:
-     *
-     *     KDF(ECDH(SDeviceKey.Priv, EReaderKey.Pub))
-     *
-     *    where SDeviceKey.Priv is the key identified by signingKeyBlob. The KDF
-     *    and ECDH functions shall be the same as the ciphersuite selected and
-     *    passed to IIdentityStore.getCredential(). The EMacKey shall be derived
-     *    using a salt of 0x00.
+     *    This code is produced by using the key agreement and key derivation function
+     *    from the ciphersuite with the authentication private key and the reader
+     *    ephemeral public key to compute a shared message authentication code (MAC)
+     *    key, then using the MAC function from the ciphersuite to compute a MAC of
+     *    the authenticated data. See section 9.2.3.5 of ISO/IEC 18013-5 for details
+     *    of this operation.
      *
      *        DeviceAuthentication = [
      *            "DeviceAuthentication",
@@ -308,6 +309,34 @@
     /**
      * Generate a key pair to be used for signing session data and retrieved data items.
      *
+     * The generated key must be an EC key using the P-256 curve.
+     *
+     * This method shall return just a single X.509 certificate which is signed by CredentialKey.
+     * When combined with the certificate chain returned at provisioning time by
+     * getAttestationCertificate() on IWritableIdentityCredential (for the credential key), this
+     * forms a chain all the way from the root of trust to the generated key.
+     *
+     * The public part of a signing key is usually included in issuer-signed data and is
+     * used for anti-cloning purposes or as a mechanism for the issuer to attest to data
+     * generated on the device.
+     *
+     * The following non-optional fields for the X.509 certificate shall be set as follows:
+     *
+     *  - version: INTEGER 2 (means v3 certificate).
+     *
+     *  - serialNumber: INTEGER 1 (fixed value: same on all certs).
+     *
+     *  - signature: must be set to ECDSA.
+     *
+     *  - subject: CN shall be set to "Android Identity Credential Authentication Key".
+     *
+     *  - issuer: shall be set to "credentialStoreName (credentialStoreAuthorName)" using the
+     *    values returned in HardwareInformation.
+     *
+     *  - validity: should be from current time and one year in the future.
+     *
+     *  - subjectPublicKeyInfo: must contain attested public key.
+     *
      * @param out signingKeyBlob contains an encrypted copy of the newly-generated private
      *     signing key.
      *
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 23cb1b7..bd664e8 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -55,8 +55,8 @@
  *
  * - For each namespase, a set of name/value pairs, each with an associated set of access control
  *   profile IDs.  Names are UTF-8 strings of up to 256 bytes in length (most should be much
- *   shorter).  Values stored must be encoed as valid CBOR (https://tools.ietf.org/html/rfc7049) and
- *   the encoeded size is is limited to at most 512 KiB.
+ *   shorter).  Values stored must be encoded as CBOR (https://tools.ietf.org/html/rfc7049) and
+ *   the encoded size is is limited to at most 512 KiB.
  *
  * - A set of access control profiles, each with a profile ID and a specification of the
  *   conditions which satisfy the profile's requirements.
@@ -108,12 +108,13 @@
 @VintfStability
 interface IIdentityCredentialStore {
     /**
-     * Success.
+     * Success. This is never returned but included for completeness and for use by code
+     * using these statuses for internal use.
      */
     const int STATUS_OK = 0;
 
     /**
-     * The operation failed. This is used as a generic catch-all for errors that don't belong
+     * The operation failed.  This is used as a generic catch-all for errors that don't belong
      * in other categories, including memory/resource allocation failures and I/O errors.
      */
     const int STATUS_FAILED = 1;
@@ -124,7 +125,7 @@
     const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
 
     /**
-     * The passed data was invalid. This is a generic catch all for errors that don't belong
+     * The passed data was invalid.  This is a generic catch all for errors that don't belong
      * in other categories related to parameter validation.
      */
     const int STATUS_INVALID_DATA = 3;
@@ -186,16 +187,19 @@
     HardwareInformation getHardwareInformation();
 
     /**
-     * createCredential creates a new Credential.  When a Credential is created, two cryptographic
+     * createCredential creates a new credential.  When a credential is created, two cryptographic
      * keys are created: StorageKey, an AES key used to secure the externalized Credential
-     * contents, and CredentialKeyPair, an EC key pair used to authenticate the store to the IA.  In
-     * addition, all of the Credential data content is imported and a certificate for the
-     * CredentialKeyPair and a signature produced with the CredentialKeyPair are created.  These
+     * contents, and CredentialKey, an EC key pair used to authenticate the store to the IA.
+     *
+     * CredentialKey must be an EC key using the P-256 curve.
+     *
+     * In addition, all of the Credential data content is imported and a certificate for the
+     * CredentialKey and a signature produced with the CredentialKey are created.  These
      * latter values may be checked by an issuing authority to verify that the data was imported
      * into secure hardware and that it was imported unmodified.
      *
      * @param docType is an optional name (may be an empty string) that identifies the type of
-     *     credential being created, e.g. "org.iso.18013-5.2019.mdl" (the doc type of the ISO
+     *     credential being created, e.g. "org.iso.18013.5.1.mDL" (the doc type of the ISO
      *     driving license standard).
      *
      * @param testCredential indicates if this is a test store.  Test credentials must use an
@@ -213,15 +217,8 @@
      * Credential.
      *
      * The cipher suite used to communicate with the remote verifier must also be specified. Currently
-     * only a single cipher-suite is supported and the details of this are as follow:
-     *
-     *  - ECDHE with HKDF-SHA-256 for key agreement.
-     *  - AES-256 with GCM block mode for authenticated encryption (nonces are incremented by one
-     *    for every message).
-     *  - ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
-     *    man-in-the-middle attacks), signing keys are not ephemeral.
-     *
-     * Support for other cipher suites may be added in a future version of this HAL.
+     * only a single cipher-suite is supported. Support for other cipher suites may be added in a
+     * future version of this HAL.
      *
      * This method fails with STATUS_INVALID_DATA if the passed in credentialData cannot be
      * decoded or decrypted.
@@ -233,7 +230,7 @@
      *     return argument of the same name in finishAddingEntries(), in
      *     IWritableIdentityCredential.
      *
-     * @return an IIdentityCredential HIDL interface that provides operations on the Credential.
+     * @return an IIdentityCredential interface that provides operations on the Credential.
      */
     IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData);
 }
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 483b0c7..9673821 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -60,12 +60,50 @@
      *    attestationApplicationId.
      *
      *  - The teeEnforced field in the attestation extension must include
-     *    Tag::IDENTITY_CREDENTIAL_KEY. This tag indicates that the key is an Identity
-     *    Credential key (which can only sign/MAC very specific messages) and not an Android
-     *    Keystore key (which can be used to sign/MAC anything).
+     *
+     *    - Tag::IDENTITY_CREDENTIAL_KEY which indicates that the key is an Identity
+     *      Credential key (which can only sign/MAC very specific messages) and not an Android
+     *      Keystore key (which can be used to sign/MAC anything).
+     *
+     *    - Tag::PURPOSE must be set to SIGN
+     *
+     *    - Tag::KEY_SIZE must be set to the appropriate key size, in bits (e.g. 256)
+     *
+     *    - Tag::ALGORITHM must be set to EC
+     *
+     *    - Tag::NO_AUTH_REQUIRED must be set
+     *
+     *    - Tag::DIGEST must be set to SHA_2_256
+     *
+     *    - Tag::EC_CURVE must be set to P_256
      *
      * Additional authorizations may be needed in the softwareEnforced and teeEnforced
-     * fields - the above is not an exhaustive list.
+     * fields - the above is not an exhaustive list. Specifically, authorizations containing
+     * information about the root of trust, OS version, verified boot state, and so on should
+     * be included.
+     *
+     * Since the chain is required to be generated using Keymaster Attestation, the returned
+     * certificate chain has the following properties:
+     *
+     *  - The certificate chain is of at least length three.
+     *
+     *  - The root of trust is the same as for Keymaster Attestation. This is usually
+     *    a certificate owned by Google but depending on the specific Android device it may
+     *    be another certificate.
+     *
+     * As with any user of attestation, the Issuing Authority (as a relying party) wishing
+     * to issue a credential to a device using these APIs, must carefully examine the
+     * returned certificate chain for all of the above (and more). In particular, the Issuing
+     * Authority should check the root of trust, verified boot state, patch level,
+     * application id, etc.
+     *
+     * This all depends on the needs of the Issuing Authority and the kind of credential but
+     * in general an Issuing Authority should never issue a credential to a device without
+     * verified boot enabled, to an unrecognized application, or if it appears the device
+     * hasn't been updated for a long time.
+     *
+     * See https://github.com/google/android-key-attestation for an example of how to
+     * examine attestations generated from Android devices.
      *
      * @param attestationApplicationId is the DER encoded value to be stored
      *     in Tag::ATTESTATION_APPLICATION_ID. This schema is described in
@@ -105,7 +143,7 @@
      *     be used to reference the profile. If this is not satisfied the call fails with
      *     STATUS_INVALID_DATA.
      *
-     * @param readerCertificate if non-empty, specifies a X.509 certificate (or chain of
+     * @param readerCertificate if non-empty, specifies a single X.509 certificate (not a chain of
      *     certificates) that must be used to authenticate requests (see the readerSignature
      *     parameter in IIdentityCredential.startRetrieval).
      *
@@ -142,7 +180,7 @@
      * @param accessControlProfileIds specifies the set of access control profiles that can
      *     authorize access to the provisioned element.
      *
-     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013.5.1"
      *
      * @param name is the name of the element.
      *
diff --git a/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
index 01d312d..13f0c6d 100644
--- a/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
+++ b/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
@@ -29,7 +29,7 @@
     /**
      * readerCertificate, if non-empty, specifies a single X.509 certificate (not a chain
      * of certificates) that must be used to authenticate requests. For details about how
-     * this is done, see the readerSignature paremter of IIdentityCredential.startRetrieval.
+     * this is done, see the readerSignature parameter of IIdentityCredential.startRetrieval.
      */
     Certificate readerCertificate;
 
diff --git a/keymaster/4.1/support/include/keymasterV4_1/Keymaster4.h b/keymaster/4.1/support/include/keymasterV4_1/Keymaster4.h
index 75d9139..f495796 100644
--- a/keymaster/4.1/support/include/keymasterV4_1/Keymaster4.h
+++ b/keymaster/4.1/support/include/keymasterV4_1/Keymaster4.h
@@ -31,17 +31,11 @@
     // enumerate 4.1. devices.
     using WrappedIKeymasterDevice = V4_0::IKeymasterDevice;
 
-    Keymaster4(sp<V4_1::IKeymasterDevice> km4_1_dev, const hidl_string& instanceName)
-        : Keymaster(V4_1::IKeymasterDevice::descriptor, instanceName),
-          haveVersion_(false),
-          km4_0_dev_(km4_1_dev),
-          km4_1_dev_(km4_1_dev) {}
-
     Keymaster4(sp<V4_0::IKeymasterDevice> km4_0_dev, const hidl_string& instanceName)
         : Keymaster(V4_1::IKeymasterDevice::descriptor, instanceName),
           haveVersion_(false),
           km4_0_dev_(km4_0_dev),
-          km4_1_dev_() {}
+          km4_1_dev_(V4_1::IKeymasterDevice::castFrom(km4_0_dev)) {}
 
     const VersionResult& halVersion() const override {
         const_cast<Keymaster4*>(this)->getVersionIfNeeded();
diff --git a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
index 6332c43..152c063 100644
--- a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
+++ b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h
@@ -115,7 +115,9 @@
     ErrorCode UseHmacKey(const HidlBuf& hmacKeyBlob) {
         auto [result, mac, out_params] =
                 ProcessMessage(hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
-                               AuthorizationSetBuilder().Authorization(TAG_MAC_LENGTH, 128));
+                               AuthorizationSetBuilder()
+                                       .Authorization(TAG_MAC_LENGTH, 128)
+                                       .Digest(Digest::SHA_2_256));
         return result;
     }
 
diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp
index 532521e..ec7357c 100644
--- a/media/omx/1.0/vts/functional/audio/Android.bp
+++ b/media/omx/1.0/vts/functional/audio/Android.bp
@@ -25,7 +25,7 @@
     data: [":media_omx_audio_res"],
     test_config: "VtsHalMediaOmxV1_0TargetAudioEncTest.xml",
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
 
@@ -40,6 +40,6 @@
     data: [":media_omx_audio_res"],
     test_config: "VtsHalMediaOmxV1_0TargetAudioDecTest.xml",
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp
index c7be2cc..8fb627a 100644
--- a/media/omx/1.0/vts/functional/component/Android.bp
+++ b/media/omx/1.0/vts/functional/component/Android.bp
@@ -19,6 +19,6 @@
     defaults: ["VtsHalMediaOmxV1_0Defaults"],
     srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
diff --git a/media/omx/1.0/vts/functional/master/Android.bp b/media/omx/1.0/vts/functional/master/Android.bp
index 0eb2cc9..8e58821 100644
--- a/media/omx/1.0/vts/functional/master/Android.bp
+++ b/media/omx/1.0/vts/functional/master/Android.bp
@@ -19,6 +19,6 @@
     defaults: ["VtsHalMediaOmxV1_0Defaults"],
     srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"],
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
diff --git a/media/omx/1.0/vts/functional/video/Android.bp b/media/omx/1.0/vts/functional/video/Android.bp
index 7e93faa..b35c26c 100644
--- a/media/omx/1.0/vts/functional/video/Android.bp
+++ b/media/omx/1.0/vts/functional/video/Android.bp
@@ -25,7 +25,7 @@
     data: [":media_omx_video_res"],
     test_config: "VtsHalMediaOmxV1_0TargetVideoDecTest.xml",
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
 
@@ -43,6 +43,6 @@
     data: [":media_omx_video_res"],
     test_config: "VtsHalMediaOmxV1_0TargetVideoEncTest.xml",
     test_suites: [
-        "vts-core",
+        "vts",
     ],
 }
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 4c0100e..e590fda 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -535,13 +535,18 @@
     removeValueAndDecrementGreaterValues(&model->main.outputIndexes, index);
 }
 
-static bool removeOperandSkip(size_t operand, const Model& model) {
+static bool removeOperandSkip(size_t operandIndex, const Model& model) {
+    const Operand& operand = model.main.operands[operandIndex];
+    if (operand.numberOfConsumers == 0) {
+        // Removing an unused operand has no effect.
+        return true;
+    }
     for (const Operation& operation : model.main.operations) {
         // Skip removeOperandTest for the following operations.
         // - SPLIT's outputs are not checked during prepareModel.
         if (operation.type == OperationType::SPLIT) {
-            for (const size_t outOprand : operation.outputs) {
-                if (operand == outOprand) {
+            for (const size_t index : operation.outputs) {
+                if (index == operandIndex) {
                     return true;
                 }
             }
@@ -556,8 +561,8 @@
             operation.type == OperationType::UNIDIRECTIONAL_SEQUENCE_RNN ||
             operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_LSTM ||
             operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_RNN) {
-            for (const size_t outOprand : operation.outputs) {
-                if (operand == outOprand) {
+            for (const size_t index : operation.outputs) {
+                if (index == operandIndex) {
                     return true;
                 }
             }
diff --git a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
index ba08ee7..7e0ae9c 100644
--- a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
+++ b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
@@ -19,6 +19,8 @@
 
 #include <cutils/properties.h>
 
+#include <android-base/file.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/power/1.0/IPower.h>
 #include <gtest/gtest.h>
@@ -73,26 +75,16 @@
 TEST_P(PowerHidlTest, TryDifferentGovernors) {
   Return<void> ret;
 
-  unique_fd fd1(open(CPU_GOVERNOR_PATH, O_RDWR));
-  unique_fd fd2(open(AVAILABLE_GOVERNORS_PATH, O_RDONLY));
-  if (fd1 < 0 || fd2 < 0) {
+  std::string old_governor, governors;
+  if (!android::base::ReadFileToString(CPU_GOVERNOR_PATH, &old_governor) ||
+      !android::base::ReadFileToString(AVAILABLE_GOVERNORS_PATH, &governors)) {
     // Files don't exist, so skip the rest of the test case
     SUCCEED();
     return;
   }
-
-  char old_governor[80];
-  ASSERT_LE(0, read(fd1, old_governor, 80));
-
-  char governors[1024];
-  unsigned len = read(fd2, governors, 1024);
-  ASSERT_LE(0u, len);
-  governors[len] = '\0';
-
-  char *saveptr;
-  char *name = strtok_r(governors, " \n", &saveptr);
-  while (name) {
-    ASSERT_LE(0, write(fd1, name, strlen(name)));
+  auto all_governors = android::base::Split(governors, " \n");
+  for (const auto &governor : all_governors) {
+      ASSERT_TRUE(android::base::WriteStringToFile(governor, CPU_GOVERNOR_PATH));
     ret = power->setInteractive(true);
     ASSERT_TRUE(ret.isOk());
 
@@ -104,11 +96,9 @@
 
     power->powerHint(PowerHint::LAUNCH, 1);
     power->powerHint(PowerHint::LAUNCH, 0);
-
-    name = strtok_r(NULL, " \n", &saveptr);
   }
 
-  ASSERT_LE(0, write(fd1, old_governor, strlen(old_governor)));
+  ASSERT_TRUE(android::base::WriteStringToFile(old_governor, CPU_GOVERNOR_PATH));
 }
 
 // Sanity check Power::powerHint on good and bad inputs.
diff --git a/secure_element/1.0/vts/OWNERS b/secure_element/1.0/vts/OWNERS
new file mode 100644
index 0000000..c7963e7
--- /dev/null
+++ b/secure_element/1.0/vts/OWNERS
@@ -0,0 +1,4 @@
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
+zachoverflow@google.com
diff --git a/secure_element/1.1/vts/OWNERS b/secure_element/1.1/vts/OWNERS
new file mode 100644
index 0000000..c7963e7
--- /dev/null
+++ b/secure_element/1.1/vts/OWNERS
@@ -0,0 +1,4 @@
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
+zachoverflow@google.com
diff --git a/secure_element/1.2/vts/OWNERS b/secure_element/1.2/vts/OWNERS
new file mode 100644
index 0000000..c7963e7
--- /dev/null
+++ b/secure_element/1.2/vts/OWNERS
@@ -0,0 +1,4 @@
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
+zachoverflow@google.com
diff --git a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
index 98e4502..9392f14 100644
--- a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
+++ b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
@@ -85,6 +85,7 @@
  * Reset:
  * Calls reset()
  * Checks status
+ * Check onStateChange is received with connected state set to false
  * Check onStateChange is received with connected state set to true
  */
 TEST_P(SecureElementHidlTest, Reset) {
@@ -92,6 +93,10 @@
 
     auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
     EXPECT_TRUE(res.no_timeout);
+    EXPECT_FALSE(res.args->state_);
+
+    res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
+    EXPECT_TRUE(res.no_timeout);
     EXPECT_TRUE(res.args->state_);
 }
 
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index 745ab2d..75f2c28 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -737,6 +737,8 @@
     callback.waitForEvents(sensors, kFiveHundredMs + (5 * maxMinDelay));
     activateAllSensors(false);
 
+    getEnvironment()->unregisterCallback();
+
     for (const SensorInfoType& sensor : sensors) {
         // Skip sensors that did not previously report an event
         if (lastEventTimestampMap.find(sensor.sensorHandle) == lastEventTimestampMap.end()) {
diff --git a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/Directionality.aidl b/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/Directionality.aidl
deleted file mode 100644
index 26eb1b48..0000000
--- a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/Directionality.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.tests.extension.vibrator;
-@Backing(type="int") @VintfStability
-enum Directionality {
-  NONE = 0,
-  TRANSVERSE = 1,
-  LONGITUDINAL = 2,
-}
diff --git a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl b/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
deleted file mode 100644
index ed9a3c6..0000000
--- a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.tests.extension.vibrator;
-@VintfStability
-interface ICustomVibrator {
-  int getVendorCapabilities();
-  void setDirectionality(android.hardware.tests.extension.vibrator.Directionality directionality);
-  int perform(android.hardware.tests.extension.vibrator.VendorEffect effect, android.hardware.vibrator.IVibratorCallback callback);
-  const int CAP_VENDOR_DIRECTIONALITY = 1;
-}
diff --git a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/VendorEffect.aidl b/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/VendorEffect.aidl
deleted file mode 100644
index 4d03a0a..0000000
--- a/tests/extension/vibrator/aidl/aidl_api/test-android.hardware.vibrator-ext/current/android/hardware/tests/extension/vibrator/VendorEffect.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.tests.extension.vibrator;
-@Backing(type="int") @VintfStability
-enum VendorEffect {
-  CRACKLE = 0,
-  WIGGLE = 1,
-}
diff --git a/tests/lazy/1.0/.hidl_for_test b/tests/lazy/1.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/lazy/1.0/.hidl_for_test
diff --git a/tests/lazy/1.0/Android.bp b/tests/lazy/1.0/Android.bp
new file mode 100644
index 0000000..d2f8175
--- /dev/null
+++ b/tests/lazy/1.0/Android.bp
@@ -0,0 +1,14 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.tests.lazy@1.0",
+    root: "android.hardware",
+    system_ext_specific: true,
+    srcs: [
+        "ILazy.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/tests/lazy/1.0/ILazy.hal b/tests/lazy/1.0/ILazy.hal
new file mode 100644
index 0000000..b0be48e
--- /dev/null
+++ b/tests/lazy/1.0/ILazy.hal
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tests.lazy@1.0;
+
+interface ILazy {};
diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp
index 7d55739..b509599 100644
--- a/tv/tuner/1.0/default/Frontend.cpp
+++ b/tv/tuner/1.0/default/Frontend.cpp
@@ -82,6 +82,13 @@
 Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
     ALOGV("%s", __FUNCTION__);
 
+    if (mType == FrontendType::ATSC) {
+        FrontendScanMessage msg;
+        msg.isLocked(true);
+        mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+        mIsLocked = true;
+        return Result::SUCCESS;
+    }
     if (mType != FrontendType::DVBT) {
         return Result::UNAVAILABLE;
     }
diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp
index 51931d6..6025339 100644
--- a/tv/tuner/1.0/default/Lnb.cpp
+++ b/tv/tuner/1.0/default/Lnb.cpp
@@ -27,6 +27,9 @@
 namespace implementation {
 
 Lnb::Lnb() {}
+Lnb::Lnb(int id) {
+    mId = id;
+}
 
 Lnb::~Lnb() {}
 
@@ -66,9 +69,13 @@
     return Result::SUCCESS;
 }
 
+int Lnb::getId() {
+    return mId;
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace tuner
 }  // namespace tv
 }  // namespace hardware
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h
index f285cb9..1e97214 100644
--- a/tv/tuner/1.0/default/Lnb.h
+++ b/tv/tuner/1.0/default/Lnb.h
@@ -38,6 +38,7 @@
 class Lnb : public ILnb {
   public:
     Lnb();
+    Lnb(int id);
 
     virtual Return<Result> setCallback(const sp<ILnbCallback>& callback) override;
 
@@ -51,7 +52,10 @@
 
     virtual Return<Result> close() override;
 
+    int getId();
+
   private:
+    int mId;
     virtual ~Lnb();
 };
 
@@ -62,4 +66,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_
\ No newline at end of file
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index 14a4289..b1f2490 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -88,6 +88,10 @@
     caps = FrontendInfo::FrontendCapabilities();
     caps.atscCaps(FrontendAtscCapabilities());
     mFrontendCaps[7] = caps;
+
+    mLnbs.resize(2);
+    mLnbs[0] = new Lnb(0);
+    mLnbs[1] = new Lnb(1);
 }
 
 Tuner::~Tuner() {}
@@ -194,17 +198,24 @@
     ALOGV("%s", __FUNCTION__);
 
     vector<LnbId> lnbIds;
+    lnbIds.resize(mLnbs.size());
+    for (int i = 0; i < lnbIds.size(); i++) {
+        lnbIds[i] = mLnbs[i]->getId();
+    }
 
     _hidl_cb(Result::SUCCESS, lnbIds);
     return Void();
 }
 
-Return<void> Tuner::openLnbById(LnbId /* lnbId */, openLnbById_cb _hidl_cb) {
+Return<void> Tuner::openLnbById(LnbId lnbId, openLnbById_cb _hidl_cb) {
     ALOGV("%s", __FUNCTION__);
 
-    sp<ILnb> lnb = new Lnb();
+    if (lnbId >= mLnbs.size()) {
+        _hidl_cb(Result::INVALID_ARGUMENT, nullptr);
+        return Void();
+    }
 
-    _hidl_cb(Result::SUCCESS, lnb);
+    _hidl_cb(Result::SUCCESS, mLnbs[lnbId]);
     return Void();
 }
 
diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h
index ada0f81..5de568f 100644
--- a/tv/tuner/1.0/default/Tuner.h
+++ b/tv/tuner/1.0/default/Tuner.h
@@ -21,6 +21,7 @@
 #include <map>
 #include "Demux.h"
 #include "Frontend.h"
+#include "Lnb.h"
 
 using namespace std;
 
@@ -77,6 +78,7 @@
     // The last used demux id. Initial value is -1.
     // First used id will be 0.
     int mLastUsedId = -1;
+    vector<sp<Lnb>> mLnbs;
 };
 
 }  // namespace implementation
diff --git a/tv/tuner/1.0/vts/functional/DemuxTests.h b/tv/tuner/1.0/vts/functional/DemuxTests.h
index 31b3e7b..6e1e395 100644
--- a/tv/tuner/1.0/vts/functional/DemuxTests.h
+++ b/tv/tuner/1.0/vts/functional/DemuxTests.h
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/tv/tuner/1.0/IDemux.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
@@ -53,4 +51,4 @@
 
     sp<ITuner> mService;
     sp<IDemux> mDemux;
-};
\ No newline at end of file
+};
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h
index 39462dc..dc798c9 100644
--- a/tv/tuner/1.0/vts/functional/FilterTests.h
+++ b/tv/tuner/1.0/vts/functional/FilterTests.h
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/tv/tuner/1.0/IFilter.h>
 #include <android/hardware/tv/tuner/1.0/IFilterCallback.h>
@@ -64,6 +62,8 @@
 
 using ::testing::AssertionResult;
 
+using namespace std;
+
 enum FilterEventType : uint8_t {
     UNDEFINED,
     SECTION,
@@ -224,4 +224,4 @@
     vector<uint32_t> mUsedFilterIds;
 
     uint32_t mFilterId = -1;
-};
\ No newline at end of file
+};
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h
index 701be82..1a9bec9 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.h
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/tv/tuner/1.0/IFrontend.h>
 #include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
@@ -66,6 +64,8 @@
 
 using ::testing::AssertionResult;
 
+using namespace std;
+
 #define INVALID_ID -1
 #define WAIT_TIMEOUT 3000000000
 
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 1c25c51..a74fa02 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -43,6 +43,8 @@
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
 
+using namespace std;
+
 typedef enum {
     TS_VIDEO0,
     TS_VIDEO1,
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 96d24c1..98d9064 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -16,6 +16,7 @@
     name: "android.hardware.usb@1.0-service",
     defaults: ["hidl_defaults"],
     init_rc: ["android.hardware.usb@1.0-service.rc"],
+    vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
diff --git a/usb/1.0/default/android.hardware.usb@1.0-service.xml b/usb/1.0/default/android.hardware.usb@1.0-service.xml
new file mode 100644
index 0000000..971c872
--- /dev/null
+++ b/usb/1.0/default/android.hardware.usb@1.0-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.usb</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/wifi/1.0/vts/functional/wifi_hidl_call_util.h b/wifi/1.0/vts/functional/wifi_hidl_call_util.h
index f3ca517..3be14c3 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_call_util.h
+++ b/wifi/1.0/vts/functional/wifi_hidl_call_util.h
@@ -16,13 +16,12 @@
 
 #pragma once
 
+#include <gtest/gtest.h>
 #include <functional>
 #include <tuple>
 #include <type_traits>
 #include <utility>
 
-#include <VtsHalHidlTargetTestBase.h>
-
 namespace {
 namespace detail {
 template <typename>
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index c1542dc..3ff33a5 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -16,8 +16,6 @@
 
 #include <android/log.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-
 #include <wifi_system/interface_tool.h>
 
 #include "wifi_hidl_call_util.h"
diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
index 7db0526..e311c84 100644
--- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -260,8 +260,8 @@
 
 /*
  * SetScanningMacOui:
- * Ensures that calls to set scanning MAC OUI will return a success status
- * code.
+ * Ensures that calls to set scanning MAC OUI will return a NOT_SUPPORTED
+ * code since it is now deprecated.
  */
 TEST_P(WifiStaIfaceHidlTest, SetScanningMacOui) {
     if (!isCapabilitySupported(
@@ -271,7 +271,7 @@
     }
     const android::hardware::hidl_array<uint8_t, 3> kOui{
         std::array<uint8_t, 3>{{0x10, 0x22, 0x33}}};
-    EXPECT_EQ(WifiStatusCode::SUCCESS,
+    EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
               HIDL_INVOKE(wifi_sta_iface_, setScanningMacOui, kOui).code);
 }
 
diff --git a/wifi/1.4/default/Android.mk b/wifi/1.4/default/Android.mk
index ab76ff6..8573e8e 100644
--- a/wifi/1.4/default/Android.mk
+++ b/wifi/1.4/default/Android.mk
@@ -156,6 +156,11 @@
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
     libgtest \
+    android.hardware.wifi@1.0 \
+    android.hardware.wifi@1.1 \
+    android.hardware.wifi@1.2 \
+    android.hardware.wifi@1.3 \
+    android.hardware.wifi@1.4 \
     android.hardware.wifi@1.0-service-lib
 LOCAL_SHARED_LIBRARIES := \
     libbase \
@@ -165,10 +170,5 @@
     libnl \
     libutils \
     libwifi-hal \
-    libwifi-system-iface \
-    android.hardware.wifi@1.0 \
-    android.hardware.wifi@1.1 \
-    android.hardware.wifi@1.2 \
-    android.hardware.wifi@1.3 \
-    android.hardware.wifi@1.4
+    libwifi-system-iface
 include $(BUILD_NATIVE_TEST)
diff --git a/wifi/1.4/default/tests/mock_wifi_iface_util.h b/wifi/1.4/default/tests/mock_wifi_iface_util.h
index 6cc81e4..3b36f13 100644
--- a/wifi/1.4/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.4/default/tests/mock_wifi_iface_util.h
@@ -40,6 +40,7 @@
     MOCK_METHOD2(registerIfaceEventHandlers,
                  void(const std::string&, IfaceEventHandlers));
     MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
+    MOCK_METHOD2(setUpState, bool(const std::string&, bool));
 };
 }  // namespace iface_util
 }  // namespace implementation
diff --git a/wifi/1.4/default/tests/mock_wifi_legacy_hal.h b/wifi/1.4/default/tests/mock_wifi_legacy_hal.h
index 6942c1e..3bb7b54 100644
--- a/wifi/1.4/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.4/default/tests/mock_wifi_legacy_hal.h
@@ -57,6 +57,10 @@
     MOCK_METHOD3(nanDataInterfaceDelete,
                  wifi_error(const std::string&, transaction_id,
                             const std::string&));
+    MOCK_METHOD2(createVirtualInterface,
+                 wifi_error(const std::string& ifname,
+                            wifi_interface_type iftype));
+    MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
 };
 }  // namespace legacy_hal
 }  // namespace implementation
diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
index d35adbc..d5b1a50 100644
--- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
@@ -292,6 +292,7 @@
         // mock).
         property_set("wifi.interface", "wlan0");
         property_set("wifi.concurrent.interface", "wlan1");
+        property_set("wifi.aware.interface", nullptr);
     }
 };
 
@@ -773,6 +774,28 @@
         });
 }
 
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
+    property_set("wifi.aware.interface", nullptr);
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
+    removeIface(IfaceType::NAN, "wlan0");
+    EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
+    property_set("wifi.aware.interface", "aware0");
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    EXPECT_CALL(*iface_util_, setUpState("aware0", true))
+        .WillOnce(testing::Return(true));
+    ASSERT_EQ(createIface(IfaceType::NAN), "aware0");
+
+    EXPECT_CALL(*iface_util_, setUpState("aware0", false))
+        .WillOnce(testing::Return(true));
+    removeIface(IfaceType::NAN, "aware0");
+}
+
 ////////// V1 Iface Combinations when AP creation is disabled //////////
 class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
    public:
diff --git a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
index 9022792..70424db 100644
--- a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -131,7 +131,7 @@
             bind(CaptureIfaceEventHandlers, std::placeholders::_1,
                  std::placeholders::_2, &captured_iface_event_handlers)));
     sp<WifiNanIface> nan_iface =
-        new WifiNanIface(kIfaceName, legacy_hal_, iface_util_);
+        new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_);
 
     // Register a mock nan event callback.
     sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp
index 4c9fad1..23dd13b 100644
--- a/wifi/1.4/default/wifi_chip.cpp
+++ b/wifi/1.4/default/wifi_chip.cpp
@@ -107,6 +107,15 @@
     return buffer.data();
 }
 
+// Returns the dedicated iface name if one is defined.
+std::string getNanIfaceName() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
+        return {};
+    }
+    return buffer.data();
+}
+
 void setActiveWlanIfaceNameProperty(const std::string& ifname) {
     auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
     if (res != 0) {
@@ -864,9 +873,16 @@
     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
-    // These are still assumed to be based on wlan0.
-    std::string ifname = getFirstActiveWlanIfaceName();
-    sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
+    bool is_dedicated_iface = true;
+    std::string ifname = getNanIfaceName();
+    if (ifname.empty()) {
+        // Use the first shared STA iface (wlan0) if a dedicated aware iface is
+        // not defined.
+        ifname = getFirstActiveWlanIfaceName();
+        is_dedicated_iface = false;
+    }
+    sp<WifiNanIface> iface =
+        new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
     nan_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
@@ -1298,13 +1314,18 @@
                 LOG(ERROR) << "Error converting ring buffer status";
                 return;
             }
-            const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
-            if (target != shared_ptr_this->ringbuffer_map_.end()) {
-                Ringbuffer& cur_buffer = target->second;
-                cur_buffer.append(data);
-            } else {
-                LOG(ERROR) << "Ringname " << name << " not found";
-                return;
+            {
+                std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
+                const auto& target =
+                    shared_ptr_this->ringbuffer_map_.find(name);
+                if (target != shared_ptr_this->ringbuffer_map_.end()) {
+                    Ringbuffer& cur_buffer = target->second;
+                    cur_buffer.append(data);
+                } else {
+                    LOG(ERROR) << "Ringname " << name << " not found";
+                    return;
+                }
+                // unlock
             }
         };
     legacy_hal::wifi_error legacy_status =
@@ -1579,25 +1600,29 @@
         return false;
     }
     // write ringbuffers to file
-    for (const auto& item : ringbuffer_map_) {
-        const Ringbuffer& cur_buffer = item.second;
-        if (cur_buffer.getData().empty()) {
-            continue;
-        }
-        const std::string file_path_raw =
-            kTombstoneFolderPath + item.first + "XXXXXXXXXX";
-        const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
-        if (dump_fd == -1) {
-            PLOG(ERROR) << "create file failed";
-            return false;
-        }
-        unique_fd file_auto_closer(dump_fd);
-        for (const auto& cur_block : cur_buffer.getData()) {
-            if (write(dump_fd, cur_block.data(),
-                      sizeof(cur_block[0]) * cur_block.size()) == -1) {
-                PLOG(ERROR) << "Error writing to file";
+    {
+        std::unique_lock<std::mutex> lk(lock_t);
+        for (const auto& item : ringbuffer_map_) {
+            const Ringbuffer& cur_buffer = item.second;
+            if (cur_buffer.getData().empty()) {
+                continue;
+            }
+            const std::string file_path_raw =
+                kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+            const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
+            if (dump_fd == -1) {
+                PLOG(ERROR) << "create file failed";
+                return false;
+            }
+            unique_fd file_auto_closer(dump_fd);
+            for (const auto& cur_block : cur_buffer.getData()) {
+                if (write(dump_fd, cur_block.data(),
+                          sizeof(cur_block[0]) * cur_block.size()) == -1) {
+                    PLOG(ERROR) << "Error writing to file";
+                }
             }
         }
+        // unlock
     }
     return true;
 }
diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h
index 3323ade..98e18bb 100644
--- a/wifi/1.4/default/wifi_chip.h
+++ b/wifi/1.4/default/wifi_chip.h
@@ -19,6 +19,7 @@
 
 #include <list>
 #include <map>
+#include <mutex>
 
 #include <android-base/macros.h>
 #include <android/hardware/wifi/1.4/IWifiChip.h>
@@ -272,6 +273,7 @@
     bool is_valid_;
     // Members pertaining to chip configuration.
     uint32_t current_mode_id_;
+    std::mutex lock_t;
     std::vector<IWifiChip::ChipMode> modes_;
     // The legacy ring buffer callback API has only a global callback
     // registration mechanism. Use this to check if we have already
diff --git a/wifi/1.4/default/wifi_iface_util.cpp b/wifi/1.4/default/wifi_iface_util.cpp
index 2883b46..036c97b 100644
--- a/wifi/1.4/default/wifi_iface_util.cpp
+++ b/wifi/1.4/default/wifi_iface_util.cpp
@@ -110,6 +110,14 @@
     address[0] &= ~kMacAddressMulticastMask;
     return address;
 }
+
+bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
+    if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
+        LOG(ERROR) << "SetUpState to " << request_up << " failed";
+        return false;
+    }
+    return true;
+}
 }  // namespace iface_util
 }  // namespace implementation
 }  // namespace V1_4
diff --git a/wifi/1.4/default/wifi_iface_util.h b/wifi/1.4/default/wifi_iface_util.h
index 35edff6..f83d717 100644
--- a/wifi/1.4/default/wifi_iface_util.h
+++ b/wifi/1.4/default/wifi_iface_util.h
@@ -56,6 +56,7 @@
     virtual void registerIfaceEventHandlers(const std::string& iface_name,
                                             IfaceEventHandlers handlers);
     virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+    virtual bool setUpState(const std::string& iface_name, bool request_up);
 
    private:
     std::array<uint8_t, 6> createRandomMacAddress();
diff --git a/wifi/1.4/default/wifi_legacy_hal.cpp b/wifi/1.4/default/wifi_legacy_hal.cpp
index f596195..29123bf 100644
--- a/wifi/1.4/default/wifi_legacy_hal.cpp
+++ b/wifi/1.4/default/wifi_legacy_hal.cpp
@@ -801,13 +801,6 @@
         cmd_id, getIfaceHandle(iface_name));
 }
 
-wifi_error WifiLegacyHal::setScanningMacOui(const std::string& iface_name,
-                                            const std::array<uint8_t, 3>& oui) {
-    std::vector<uint8_t> oui_internal(oui.data(), oui.data() + oui.size());
-    return global_func_table_.wifi_set_scanning_mac_oui(
-        getIfaceHandle(iface_name), oui_internal.data());
-}
-
 wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
                                                 wifi_power_scenario scenario) {
     return global_func_table_.wifi_select_tx_power_scenario(
diff --git a/wifi/1.4/default/wifi_legacy_hal.h b/wifi/1.4/default/wifi_legacy_hal.h
index c21563e..9964460 100644
--- a/wifi/1.4/default/wifi_legacy_hal.h
+++ b/wifi/1.4/default/wifi_legacy_hal.h
@@ -252,8 +252,6 @@
         const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms);
     wifi_error stopSendingOffloadedPacket(const std::string& iface_name,
                                           uint32_t cmd_id);
-    wifi_error setScanningMacOui(const std::string& iface_name,
-                                 const std::array<uint8_t, 3>& oui);
     virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
                                              wifi_power_scenario scenario);
     virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
@@ -373,9 +371,9 @@
                               std::array<int8_t, 2> code);
 
     // interface functions.
-    wifi_error createVirtualInterface(const std::string& ifname,
-                                      wifi_interface_type iftype);
-    wifi_error deleteVirtualInterface(const std::string& ifname);
+    virtual wifi_error createVirtualInterface(const std::string& ifname,
+                                              wifi_interface_type iftype);
+    virtual wifi_error deleteVirtualInterface(const std::string& ifname);
 
    private:
     // Retrieve interface handles for all the available interfaces.
diff --git a/wifi/1.4/default/wifi_nan_iface.cpp b/wifi/1.4/default/wifi_nan_iface.cpp
index 073101c..5764d35 100644
--- a/wifi/1.4/default/wifi_nan_iface.cpp
+++ b/wifi/1.4/default/wifi_nan_iface.cpp
@@ -29,13 +29,22 @@
 using hidl_return_util::validateAndCall;
 
 WifiNanIface::WifiNanIface(
-    const std::string& ifname,
+    const std::string& ifname, bool is_dedicated_iface,
     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
     const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
     : ifname_(ifname),
+      is_dedicated_iface_(is_dedicated_iface),
       legacy_hal_(legacy_hal),
       iface_util_(iface_util),
       is_valid_(true) {
+    if (is_dedicated_iface_) {
+        // If using a dedicated iface, set the iface up first.
+        if (!iface_util_.lock()->setUpState(ifname_, true)) {
+            // Fatal failure, invalidate the iface object.
+            invalidate();
+            return;
+        }
+    }
     // Register all the callbacks here. these should be valid for the lifetime
     // of the object. Whenever the mode changes legacy HAL will remove
     // all of these callbacks.
@@ -534,6 +543,10 @@
     event_cb_handler_.invalidate();
     event_cb_handler_1_2_.invalidate();
     is_valid_ = false;
+    if (is_dedicated_iface_) {
+        // If using a dedicated iface, set the iface down.
+        iface_util_.lock()->setUpState(ifname_, false);
+    }
 }
 
 bool WifiNanIface::isValid() { return is_valid_; }
diff --git a/wifi/1.4/default/wifi_nan_iface.h b/wifi/1.4/default/wifi_nan_iface.h
index c16628b..06edbf2 100644
--- a/wifi/1.4/default/wifi_nan_iface.h
+++ b/wifi/1.4/default/wifi_nan_iface.h
@@ -38,7 +38,7 @@
  */
 class WifiNanIface : public V1_4::IWifiNanIface {
    public:
-    WifiNanIface(const std::string& ifname,
+    WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
                  const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
@@ -165,6 +165,7 @@
     std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
 
     std::string ifname_;
+    bool is_dedicated_iface_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     bool is_valid_;
diff --git a/wifi/1.4/default/wifi_sta_iface.cpp b/wifi/1.4/default/wifi_sta_iface.cpp
index e2ea6e4..49f383a 100644
--- a/wifi/1.4/default/wifi_sta_iface.cpp
+++ b/wifi/1.4/default/wifi_sta_iface.cpp
@@ -578,10 +578,9 @@
 }
 
 WifiStatus WifiStaIface::setScanningMacOuiInternal(
-    const std::array<uint8_t, 3>& oui) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->setScanningMacOui(ifname_, oui);
-    return createWifiStatusFromLegacyError(legacy_status);
+    const std::array<uint8_t, 3>& /* oui */) {
+    // deprecated.
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
 
 WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
diff --git a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp
index 295c86e..4035fb8 100644
--- a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp
+++ b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -64,6 +64,14 @@
 
         wifi_rtt_controller_ = getWifiRttController();
         ASSERT_NE(nullptr, wifi_rtt_controller_.get());
+
+        // Check RTT support before we run the test.
+        std::pair<WifiStatus, RttCapabilities> status_and_caps;
+        status_and_caps =
+            HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_4);
+        if (status_and_caps.first.code == WifiStatusCode::ERROR_NOT_SUPPORTED) {
+            GTEST_SKIP() << "Skipping this test since RTT is not supported.";
+        }
     }
 
     virtual void TearDown() override { stopWifi(GetInstanceName()); }
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
index 6058fd2..d4063fe 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 
 #include <android/hidl/manager/1.0/IServiceManager.h>
@@ -148,4 +147,4 @@
     sp<::android::hardware::wifi::hostapd::V1_1::IHostapd> hostapd_1_1 =
         ::android::hardware::wifi::hostapd::V1_1::IHostapd::castFrom(hostapd);
     return hostapd_1_1.get() != nullptr;
-}
\ No newline at end of file
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 6fe6fc5..3815323 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <cutils/properties.h>
 
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp
index 480929a..46d5a61 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 
 #include "supplicant_hidl_test_utils.h"
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 2b63ad0..7b96b87 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -16,8 +16,6 @@
 
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-
 #include <VtsCoreUtil.h>
 #include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/supplicant/1.2/ISupplicantP2pIface.h>
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.cpp
index dbf2b91..424c107 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 
 #include "supplicant_hidl_test_utils.h"