Implement android::String access methods that avoid C string cast

Bug: 295394788
Test: m checkbuild
Change-Id: If25fd69319171e8c549fc8fcfd95a0819291d8e6
diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h
index b48b907..fb94174 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 {
@@ -91,6 +96,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);
@@ -113,6 +119,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;
@@ -264,6 +276,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);
@@ -353,8 +370,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 ea25c6a..3893018 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 {
@@ -113,6 +122,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);
@@ -120,13 +133,16 @@
             // 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();
 
@@ -264,11 +280,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);
@@ -377,8 +408,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