Merge "fs_mgr: Use /proc/mounts to check if /cache is mounted" into main
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 5393e25..267571b 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -12,6 +12,7 @@
         "-Wno-unused-argument",
         "-Wno-unused-function",
         "-Wno-nullability-completeness",
+        "-Wno-reorder-init-list",
         "-Os",
         "-fno-finite-loops",
         "-DANDROID_DEBUGGABLE=0",
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 2b72847..4301f0e 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -430,31 +430,6 @@
 // ---------------------------------------------------------------------------
 // Path functions
 
-static void setPathName(String8& s, const char* name) {
-    size_t len = strlen(name);
-    char* buf = s.lockBuffer(len);
-
-    memcpy(buf, name, len);
-
-    // remove trailing path separator, if present
-    if (len > 0 && buf[len - 1] == OS_PATH_SEPARATOR) len--;
-    buf[len] = '\0';
-
-    s.unlockBuffer(len);
-}
-
-String8 String8::getPathLeaf(void) const
-{
-    const char* cp;
-    const char*const buf = mString;
-
-    cp = strrchr(buf, OS_PATH_SEPARATOR);
-    if (cp == nullptr)
-        return String8(*this);
-    else
-        return String8(cp+1);
-}
-
 String8 String8::getPathDir(void) const
 {
     const char* cp;
@@ -467,40 +442,14 @@
         return String8(str, cp - str);
 }
 
-String8 String8::walkPath(String8* outRemains) const
-{
-    const char* cp;
-    const char*const str = mString;
-    const char* buf = str;
-
-    cp = strchr(buf, OS_PATH_SEPARATOR);
-    if (cp == buf) {
-        // don't include a leading '/'.
-        buf = buf+1;
-        cp = strchr(buf, OS_PATH_SEPARATOR);
-    }
-
-    if (cp == nullptr) {
-        String8 res = buf != str ? String8(buf) : *this;
-        if (outRemains) *outRemains = String8("");
-        return res;
-    }
-
-    String8 res(buf, cp-buf);
-    if (outRemains) *outRemains = String8(cp+1);
-    return res;
-}
-
 /*
  * Helper function for finding the start of an extension in a pathname.
  *
  * Returns a pointer inside mString, or NULL if no extension was found.
  */
-char* String8::find_extension(void) const
-{
+static const char* find_extension(const char* str) {
     const char* lastSlash;
     const char* lastDot;
-    const char* const str = mString;
 
     // only look at the filename
     lastSlash = strrchr(str, OS_PATH_SEPARATOR);
@@ -515,67 +464,16 @@
         return nullptr;
 
     // looks good, ship it
-    return const_cast<char*>(lastDot);
+    return lastDot;
 }
 
 String8 String8::getPathExtension(void) const
 {
-    char* ext;
-
-    ext = find_extension();
+    auto ext = find_extension(mString);
     if (ext != nullptr)
         return String8(ext);
     else
         return String8("");
 }
 
-String8 String8::getBasePath(void) const
-{
-    char* ext;
-    const char* const str = mString;
-
-    ext = find_extension();
-    if (ext == nullptr)
-        return String8(*this);
-    else
-        return String8(str, ext - str);
-}
-
-String8& String8::appendPath(const char* name)
-{
-    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
-    if (name[0] != OS_PATH_SEPARATOR) {
-        if (*name == '\0') {
-            // nothing to do
-            return *this;
-        }
-
-        size_t len = length();
-        if (len == 0) {
-            // no existing filename, just use the new one
-            setPathName(*this, name);
-            return *this;
-        }
-
-        // make room for oldPath + '/' + newPath
-        int newlen = strlen(name);
-
-        char* buf = lockBuffer(len+1+newlen);
-
-        // insert a '/' if needed
-        if (buf[len-1] != OS_PATH_SEPARATOR)
-            buf[len++] = OS_PATH_SEPARATOR;
-
-        memcpy(buf+len, name, newlen+1);
-        len += newlen;
-
-        unlockBuffer(len);
-
-        return *this;
-    } else {
-        setPathName(*this, name);
-        return *this;
-    }
-}
-
 }; // namespace android
diff --git a/libutils/String8_fuzz.cpp b/libutils/String8_fuzz.cpp
index 6f7a54f..cbce050 100644
--- a/libutils/String8_fuzz.cpp
+++ b/libutils/String8_fuzz.cpp
@@ -68,30 +68,6 @@
                     int start_index = dataProvider->ConsumeIntegralInRange<int>(0, str1->size());
                     str1->find(str2->c_str(), start_index);
                 },
-
-                // Path handling
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->getBasePath();
-                },
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->getPathExtension();
-                },
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->getPathLeaf();
-                },
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    str1->getPathDir();
-                },
-                [](FuzzedDataProvider*, android::String8* str1, android::String8*) -> void {
-                    std::shared_ptr<android::String8> path_out_str =
-                            std::make_shared<android::String8>();
-                    str1->walkPath(path_out_str.get());
-                    path_out_str->clear();
-                },
-                [](FuzzedDataProvider* dataProvider, android::String8* str1,
-                   android::String8*) -> void {
-                    str1->appendPath(dataProvider->ConsumeBytesWithTerminator<char>(5).data());
-                },
 };
 
 void fuzzFormat(FuzzedDataProvider* dataProvider, android::String8* str1, bool shouldAppend) {
diff --git a/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump b/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
index 46badde..8881b44 100644
--- a/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
+++ b/libutils/abi-dumps/arm64/source-based/libutils.so.lsdump
@@ -704,9 +704,6 @@
    "name" : "_ZN7android7RefBaseD2Ev"
   },
   {
-   "name" : "_ZN7android7String810appendPathEPKc"
-  },
-  {
    "name" : "_ZN7android7String810lockBufferEm"
   },
   {
@@ -1145,15 +1142,6 @@
    "name" : "_ZNK7android7String810getPathDirEv"
   },
   {
-   "name" : "_ZNK7android7String811getBasePathEv"
-  },
-  {
-   "name" : "_ZNK7android7String811getPathLeafEv"
-  },
-  {
-   "name" : "_ZNK7android7String814find_extensionEv"
-  },
-  {
    "name" : "_ZNK7android7String816getPathExtensionEv"
   },
   {
@@ -1163,9 +1151,6 @@
    "name" : "_ZNK7android7String86lengthEv"
   },
   {
-   "name" : "_ZNK7android7String88walkPathEPS0_"
-  },
-  {
    "name" : "_ZNK7android8String1610startsWithEPKDs"
   },
   {
@@ -6809,22 +6794,6 @@
    "source_file" : "system/core/libutils/include/utils/RefBase.h"
   },
   {
-   "function_name" : "android::String8::appendPath",
-   "linker_set_key" : "_ZN7android7String810appendPathEPKc",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    },
-    {
-     "referenced_type" : "_ZTIPKc"
-    }
-   ],
-   "return_type" : "_ZTIRN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::lockBuffer",
    "linker_set_key" : "_ZN7android7String810lockBufferEm",
    "parameters" :
@@ -9104,6 +9073,7 @@
    "source_file" : "system/core/libutils/include/utils/RefBase.h"
   },
   {
+   "access" : "private",
    "function_name" : "android::String8::getPathDir",
    "linker_set_key" : "_ZNK7android7String810getPathDirEv",
    "parameters" :
@@ -9117,46 +9087,7 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::getBasePath",
-   "linker_set_key" : "_ZNK7android7String811getBasePathEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
-   "function_name" : "android::String8::getPathLeaf",
-   "linker_set_key" : "_ZNK7android7String811getPathLeafEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "access" : "private",
-   "function_name" : "android::String8::find_extension",
-   "linker_set_key" : "_ZNK7android7String814find_extensionEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIPc",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::getPathExtension",
    "linker_set_key" : "_ZNK7android7String816getPathExtensionEv",
    "parameters" :
@@ -9203,23 +9134,6 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::walkPath",
-   "linker_set_key" : "_ZNK7android7String88walkPathEPS0_",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    },
-    {
-     "default_arg" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String16::startsWith",
    "linker_set_key" : "_ZNK7android8String1610startsWithEPKDs",
    "parameters" :
diff --git a/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump b/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
index 219c766..e8236ea 100644
--- a/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
+++ b/libutils/abi-dumps/arm_arm64/source-based/libutils.so.lsdump
@@ -704,9 +704,6 @@
    "name" : "_ZN7android7RefBaseD2Ev"
   },
   {
-   "name" : "_ZN7android7String810appendPathEPKc"
-  },
-  {
    "name" : "_ZN7android7String810lockBufferEj"
   },
   {
@@ -1145,15 +1142,6 @@
    "name" : "_ZNK7android7String810getPathDirEv"
   },
   {
-   "name" : "_ZNK7android7String811getBasePathEv"
-  },
-  {
-   "name" : "_ZNK7android7String811getPathLeafEv"
-  },
-  {
-   "name" : "_ZNK7android7String814find_extensionEv"
-  },
-  {
    "name" : "_ZNK7android7String816getPathExtensionEv"
   },
   {
@@ -1163,9 +1151,6 @@
    "name" : "_ZNK7android7String86lengthEv"
   },
   {
-   "name" : "_ZNK7android7String88walkPathEPS0_"
-  },
-  {
    "name" : "_ZNK7android8String1610startsWithEPKDs"
   },
   {
@@ -6805,22 +6790,6 @@
    "source_file" : "system/core/libutils/include/utils/RefBase.h"
   },
   {
-   "function_name" : "android::String8::appendPath",
-   "linker_set_key" : "_ZN7android7String810appendPathEPKc",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    },
-    {
-     "referenced_type" : "_ZTIPKc"
-    }
-   ],
-   "return_type" : "_ZTIRN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::lockBuffer",
    "linker_set_key" : "_ZN7android7String810lockBufferEj",
    "parameters" :
@@ -9100,6 +9069,7 @@
    "source_file" : "system/core/libutils/include/utils/RefBase.h"
   },
   {
+   "access" : "private",
    "function_name" : "android::String8::getPathDir",
    "linker_set_key" : "_ZNK7android7String810getPathDirEv",
    "parameters" :
@@ -9113,46 +9083,7 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::getBasePath",
-   "linker_set_key" : "_ZNK7android7String811getBasePathEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
-   "function_name" : "android::String8::getPathLeaf",
-   "linker_set_key" : "_ZNK7android7String811getPathLeafEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "access" : "private",
-   "function_name" : "android::String8::find_extension",
-   "linker_set_key" : "_ZNK7android7String814find_extensionEv",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIPc",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String8::getPathExtension",
    "linker_set_key" : "_ZNK7android7String816getPathExtensionEv",
    "parameters" :
@@ -9199,23 +9130,6 @@
    "source_file" : "system/core/libutils/include/utils/String8.h"
   },
   {
-   "function_name" : "android::String8::walkPath",
-   "linker_set_key" : "_ZNK7android7String88walkPathEPS0_",
-   "parameters" :
-   [
-    {
-     "is_this_ptr" : true,
-     "referenced_type" : "_ZTIPKN7android7String8E"
-    },
-    {
-     "default_arg" : true,
-     "referenced_type" : "_ZTIPN7android7String8E"
-    }
-   ],
-   "return_type" : "_ZTIN7android7String8E",
-   "source_file" : "system/core/libutils/include/utils/String8.h"
-  },
-  {
    "function_name" : "android::String16::startsWith",
    "linker_set_key" : "_ZNK7android8String1610startsWithEPKDs",
    "parameters" :
diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h
index ec2a324..1fa3723 100644
--- a/libutils/include/utils/String16.h
+++ b/libutils/include/utils/String16.h
@@ -24,6 +24,11 @@
 #include <utils/String8.h>
 #include <utils/TypeHelpers.h>
 
+#if __has_include(<string_view>)
+#include <string_view>
+#define HAS_STRING_VIEW
+#endif
+
 // ---------------------------------------------------------------------------
 
 namespace android {
@@ -88,6 +93,7 @@
             bool                startsWith(const char16_t* prefix) const;
 
             bool                contains(const char16_t* chrs) const;
+    inline  bool                contains(const String16& other) const;
 
             status_t            replaceAll(char16_t replaceThis,
                                            char16_t withThis);
@@ -110,6 +116,12 @@
 
     inline                      operator const char16_t*() const;
 
+#ifdef HAS_STRING_VIEW
+    // Implicit cast to std::u16string is not implemented on purpose - u16string_view is much
+    // lighter and if one needs, they can still create u16string from u16string_view.
+    inline                      operator std::u16string_view() const;
+#endif
+
     // Static and non-static String16 behave the same for the users, so
     // this method isn't of much use for the users. It is public for testing.
             bool                isStaticString() const;
@@ -256,6 +268,11 @@
     return size();
 }
 
+inline bool String16::contains(const String16& other) const
+{
+    return contains(other.c_str());
+}
+
 inline String16& String16::operator=(const String16& other)
 {
     setTo(other);
@@ -345,8 +362,15 @@
     return mString;
 }
 
+inline String16::operator std::u16string_view() const
+{
+    return {mString, length()};
+}
+
 }  // namespace android
 
 // ---------------------------------------------------------------------------
 
+#undef HAS_STRING_VIEW
+
 #endif // ANDROID_STRING16_H
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index 2a3d679..c807473 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -18,7 +18,6 @@
 #define ANDROID_STRING8_H
 
 #include <iostream>
-#include <string>
 
 #include <utils/Errors.h>
 #include <utils/Unicode.h>
@@ -27,6 +26,16 @@
 #include <string.h> // for strcmp
 #include <stdarg.h>
 
+#if __has_include(<string>)
+#include <string>
+#define HAS_STRING
+#endif
+
+#if __has_include(<string_view>)
+#include <string_view>
+#define HAS_STRING_VIEW
+#endif
+
 // ---------------------------------------------------------------------------
 
 namespace android {
@@ -109,6 +118,10 @@
 
     inline                      operator const char*() const;
 
+#ifdef HAS_STRING_VIEW
+    inline explicit             operator std::string_view() const;
+#endif
+
             char*               lockBuffer(size_t size);
             void                unlockBuffer();
             status_t            unlockBuffer(size_t size);
@@ -116,90 +129,24 @@
             // return the index of the first byte of other in this at or after
             // start, or -1 if not found
             ssize_t             find(const char* other, size_t start = 0) const;
+    inline  ssize_t             find(const String8& other, size_t start = 0) const;
 
             // return true if this string contains the specified substring
     inline  bool                contains(const char* other) const;
+    inline  bool                contains(const String8& other) const;
 
             // removes all occurrence of the specified substring
             // returns true if any were found and removed
             bool                removeAll(const char* other);
+    inline  bool                removeAll(const String8& other);
 
             void                toLower();
 
-
-    /*
-     * These methods operate on the string as if it were a path name.
-     */
-
-    /*
-     * Get just the filename component.
-     *
-     * "/tmp/foo/bar.c" --> "bar.c"
-     */
-    String8 getPathLeaf(void) const;
-
-    /*
-     * Remove the last (file name) component, leaving just the directory
-     * name.
-     *
-     * "/tmp/foo/bar.c" --> "/tmp/foo"
-     * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
-     * "bar.c" --> ""
-     */
-    String8 getPathDir(void) const;
-
-    /*
-     * Retrieve the front (root dir) component.  Optionally also return the
-     * remaining components.
-     *
-     * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
-     * "/tmp" --> "tmp" (remain = "")
-     * "bar.c" --> "bar.c" (remain = "")
-     */
-    String8 walkPath(String8* outRemains = nullptr) const;
-
-    /*
-     * Return the filename extension.  This is the last '.' and any number
-     * of characters that follow it.  The '.' is included in case we
-     * decide to expand our definition of what constitutes an extension.
-     *
-     * "/tmp/foo/bar.c" --> ".c"
-     * "/tmp" --> ""
-     * "/tmp/foo.bar/baz" --> ""
-     * "foo.jpeg" --> ".jpeg"
-     * "foo." --> ""
-     */
-    String8 getPathExtension(void) const;
-
-    /*
-     * Return the path without the extension.  Rules for what constitutes
-     * an extension are described in the comment for getPathExtension().
-     *
-     * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
-     */
-    String8 getBasePath(void) const;
-
-    /*
-     * Add a component to the pathname.  We guarantee that there is
-     * exactly one path separator between the old path and the new.
-     * If there is no existing name, we just copy the new name in.
-     *
-     * If leaf is a fully qualified path (i.e. starts with '/', it
-     * replaces whatever was there before.
-     */
-    String8& appendPath(const char* leaf);
-    String8& appendPath(const String8& leaf) { return appendPath(leaf.c_str()); }
-
-    /*
-     * Like appendPath(), but does not affect this string.  Returns a new one instead.
-     */
-    String8 appendPathCopy(const char* leaf) const
-                                             { String8 p(*this); p.appendPath(leaf); return p; }
-    String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.c_str()); }
-
 private:
+            String8 getPathDir(void) const;
+            String8 getPathExtension(void) const;
+
             status_t            real_append(const char* other, size_t numChars);
-            char*               find_extension(void) const;
 
             const char* mString;
 };
@@ -255,11 +202,26 @@
     return length();
 }
 
+inline ssize_t String8::find(const String8& other, size_t start) const
+{
+    return find(other.c_str(), start);
+}
+
 inline bool String8::contains(const char* other) const
 {
     return find(other) >= 0;
 }
 
+inline bool String8::contains(const String8& other) const
+{
+    return contains(other.c_str());
+}
+
+inline bool String8::removeAll(const String8& other)
+{
+    return removeAll(other.c_str());
+}
+
 inline String8& String8::operator=(const String8& other)
 {
     setTo(other);
@@ -368,8 +330,18 @@
     return mString;
 }
 
+#ifdef HAS_STRING_VIEW
+inline String8::operator std::string_view() const
+{
+    return {mString, length()};
+}
+#endif
+
 }  // namespace android
 
 // ---------------------------------------------------------------------------
 
+#undef HAS_STRING
+#undef HAS_STRING_VIEW
+
 #endif // ANDROID_STRING8_H