libutils_binder: isolate headers

This isolated all libutils_binder headers from libutils
except for RefBase use of CallStack.h. This header can
be disabled with a macro option easily.

Bug: N/A
Test: N/A
Change-Id: I83af091fc17b5418ab9e4d7fc41fb43792ec547d
diff --git a/libutils/binder/Android.bp b/libutils/binder/Android.bp
index e2eddb3..a049f3d 100644
--- a/libutils/binder/Android.bp
+++ b/libutils/binder/Android.bp
@@ -10,6 +10,7 @@
     ],
     native_bridge_supported: true,
 
+    export_include_dirs: ["include"],
     srcs: [
         "Errors.cpp",
         "RefBase.cpp",
diff --git a/libutils/binder/RefBase.cpp b/libutils/binder/RefBase.cpp
index c7055fb..4b0cc16 100644
--- a/libutils/binder/RefBase.cpp
+++ b/libutils/binder/RefBase.cpp
@@ -20,8 +20,6 @@
 #include <memory>
 #include <mutex>
 
-#include <android-base/macros.h>
-
 #include <fcntl.h>
 #include <log/log.h>
 
@@ -65,7 +63,7 @@
 #endif
 
 #if CALLSTACK_ENABLED
-#include <utils/CallStack.h>
+#include "../../include/utils/CallStack.h"
 #endif
 
 // ---------------------------------------------------------------------------
@@ -536,7 +534,7 @@
     case INITIAL_STRONG_VALUE:
         refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
                 std::memory_order_relaxed);
-        FALLTHROUGH_INTENDED;
+        [[fallthrough]];
     case 0:
         refs->mBase->onFirstRef();
     }
diff --git a/libutils/binder/String8.cpp b/libutils/binder/String8.cpp
index 6a75484..749bfcb 100644
--- a/libutils/binder/String8.cpp
+++ b/libutils/binder/String8.cpp
@@ -19,7 +19,6 @@
 
 #include <utils/String8.h>
 
-#include <utils/Compat.h>
 #include <log/log.h>
 #include <utils/String16.h>
 
@@ -430,6 +429,13 @@
 // ---------------------------------------------------------------------------
 // Path functions
 
+// TODO: we should remove all the path functions from String8
+#if defined(_WIN32)
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
+#endif
+
 String8 String8::getPathDir(void) const
 {
     const char* cp;
diff --git a/libutils/binder/Unicode.cpp b/libutils/binder/Unicode.cpp
index 364a177..2ed2d4f 100644
--- a/libutils/binder/Unicode.cpp
+++ b/libutils/binder/Unicode.cpp
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "unicode"
 
-#include <android-base/macros.h>
 #include <limits.h>
 #include <utils/Unicode.h>
 
@@ -92,11 +91,11 @@
     switch (bytes)
     {   /* note: everything falls through. */
         case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-            FALLTHROUGH_INTENDED;
+            [[fallthrough]];
         case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-            FALLTHROUGH_INTENDED;
+            [[fallthrough]];
         case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-            FALLTHROUGH_INTENDED;
+            [[fallthrough]];
         case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
     }
 }
@@ -304,15 +303,15 @@
 
     while (in < end) {
         char16_t w = *in++;
-        if (LIKELY(w < 0x0080)) {
+        if (w < 0x0080) [[likely]] {
             utf8_len += 1;
             continue;
         }
-        if (LIKELY(w < 0x0800)) {
+        if (w < 0x0800) [[likely]] {
             utf8_len += 2;
             continue;
         }
-        if (LIKELY(!is_any_surrogate(w))) {
+        if (!is_any_surrogate(w)) [[likely]] {
             utf8_len += 3;
             continue;
         }
@@ -345,20 +344,20 @@
 
     while (in < in_end) {
         char16_t w = *in++;
-        if (LIKELY(w < 0x0080)) {
+        if (w < 0x0080) [[likely]] {
             if (out + 1 > out_end)
                 return err_out();
             *out++ = (char)(w & 0xff);
             continue;
         }
-        if (LIKELY(w < 0x0800)) {
+        if (w < 0x0800) [[likely]] {
             if (out + 2 > out_end)
                 return err_out();
             *out++ = (char)(0xc0 | ((w >> 6) & 0x1f));
             *out++ = (char)(0x80 | ((w >> 0) & 0x3f));
             continue;
         }
-        if (LIKELY(!is_any_surrogate(w))) {
+        if (!is_any_surrogate(w)) [[likely]] {
             if (out + 3 > out_end)
                 return err_out();
             *out++ = (char)(0xe0 | ((w >> 12) & 0xf));
@@ -420,25 +419,25 @@
     while (in < in_end) {
         uint8_t c = *in;
         utf16_len++;
-        if (LIKELY((c & 0x80) == 0)) {
+        if ((c & 0x80) == 0) [[likely]] {
             in++;
             continue;
         }
-        if (UNLIKELY(c < 0xc0)) {
+        if (c < 0xc0) [[unlikely]] {
             ALOGW("Invalid UTF-8 leading byte: 0x%02x", c);
             in++;
             continue;
         }
-        if (LIKELY(c < 0xe0)) {
+        if (c < 0xe0) [[likely]] {
             in += 2;
             continue;
         }
-        if (LIKELY(c < 0xf0)) {
+        if (c < 0xf0) [[likely]] {
             in += 3;
             continue;
         } else {
             uint8_t c2, c3, c4;
-            if (UNLIKELY(c >= 0xf8)) {
+            if (c >= 0xf8) [[unlikely]] {
                 ALOGW("Invalid UTF-8 leading byte: 0x%02x", c);
             }
             c2 = in[1]; c3 = in[2]; c4 = in[3];
@@ -487,25 +486,25 @@
 
     while (in < in_end && out < out_end) {
         c = *in++;
-        if (LIKELY((c & 0x80) == 0)) {
+        if ((c & 0x80) == 0) [[likely]] {
             *out++ = (char16_t)(c);
             continue;
         }
-        if (UNLIKELY(c < 0xc0)) {
+        if (c < 0xc0) [[unlikely]] {
             ALOGW("Invalid UTF-8 leading byte: 0x%02x", c);
             *out++ = (char16_t)(c);
             continue;
         }
-        if (LIKELY(c < 0xe0)) {
-            if (UNLIKELY(in + 1 > in_end)) {
+        if (c < 0xe0) [[likely]] {
+            if (in + 1 > in_end) [[unlikely]] {
                 return err_in();
             }
             c2 = *in++;
             *out++ = (char16_t)(((c & 0x1f) << 6) | (c2 & 0x3f));
             continue;
         }
-        if (LIKELY(c < 0xf0)) {
-            if (UNLIKELY(in + 2 > in_end)) {
+        if (c < 0xf0) [[likely]] {
+            if (in + 2 > in_end) [[unlikely]] {
                 return err_in();
             }
             c2 = *in++; c3 = *in++;
@@ -513,19 +512,19 @@
                                 ((c2 & 0x3f) << 6) | (c3 & 0x3f));
             continue;
         } else {
-            if (UNLIKELY(in + 3 > in_end)) {
+            if (in + 3 > in_end) [[unlikely]] {
                 return err_in();
             }
-            if (UNLIKELY(c >= 0xf8)) {
+            if (c >= 0xf8) [[unlikely]] {
                 ALOGW("Invalid UTF-8 leading byte: 0x%02x", c);
             }
             // Multiple UTF16 characters with surrogates
             c2 = *in++; c3 = *in++; c4 = *in++;
             w = utf8_4b_to_utf32(c, c2, c3, c4);
-            if (UNLIKELY(w < 0x10000)) {
+            if (w < 0x10000) [[unlikely]] {
                 *out++ = (char16_t)(w);
             } else {
-                if (UNLIKELY(out + 2 > out_end)) {
+                if (out + 2 > out_end) [[unlikely]] {
                     // Ooops.... not enough room for this surrogate pair.
                     return out;
                 }
diff --git a/libutils/binder/include/utils/LightRefBase.h b/libutils/binder/include/utils/LightRefBase.h
new file mode 100644
index 0000000..40edf67
--- /dev/null
+++ b/libutils/binder/include/utils/LightRefBase.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/*
+ * See documentation in RefBase.h
+ */
+
+#include <atomic>
+
+#include <sys/types.h>
+
+namespace android {
+
+class ReferenceRenamer;
+
+void LightRefBase_reportIncStrongRequireStrongFailed(const void* thiz);
+
+template <class T>
+class LightRefBase
+{
+public:
+    inline LightRefBase() : mCount(0) { }
+    inline void incStrong(__attribute__((unused)) const void* id) const {
+        mCount.fetch_add(1, std::memory_order_relaxed);
+    }
+    inline void incStrongRequireStrong(__attribute__((unused)) const void* id) const {
+        if (0 == mCount.fetch_add(1, std::memory_order_relaxed)) {
+            LightRefBase_reportIncStrongRequireStrongFailed(this);
+        }
+    }
+    inline void decStrong(__attribute__((unused)) const void* id) const {
+        if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
+            std::atomic_thread_fence(std::memory_order_acquire);
+            delete static_cast<const T*>(this);
+        }
+    }
+    //! DEBUGGING ONLY: Get current strong ref count.
+    inline int32_t getStrongCount() const {
+        return mCount.load(std::memory_order_relaxed);
+    }
+
+protected:
+    inline ~LightRefBase() { }
+
+private:
+    friend class ReferenceMover;
+    inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { }
+    inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { }
+
+private:
+    mutable std::atomic<int32_t> mCount;
+};
+
+// This is a wrapper around LightRefBase that simply enforces a virtual
+// destructor to eliminate the template requirement of LightRefBase
+class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {
+public:
+    virtual ~VirtualLightRefBase() = default;
+};
+
+}  // namespace android
diff --git a/libutils/binder/include/utils/TypeHelpers.h b/libutils/binder/include/utils/TypeHelpers.h
new file mode 100644
index 0000000..1554f52
--- /dev/null
+++ b/libutils/binder/include/utils/TypeHelpers.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TYPE_HELPERS_H
+#define ANDROID_TYPE_HELPERS_H
+
+#include <new>
+#include <type_traits>
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*
+ * Types traits
+ */
+
+template <typename T> struct trait_trivial_ctor { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor { enum { value = false }; };
+template <typename T> struct trait_trivial_copy { enum { value = false }; };
+template <typename T> struct trait_trivial_move { enum { value = false }; };
+template <typename T> struct trait_pointer      { enum { value = false }; };
+template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
+
+template <typename TYPE>
+struct traits {
+    enum {
+        // whether this type is a pointer
+        is_pointer          = trait_pointer<TYPE>::value,
+        // whether this type's constructor is a no-op
+        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
+        // whether this type's destructor is a no-op
+        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
+        // whether this type type can be copy-constructed with memcpy
+        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
+        // whether this type can be moved with memmove
+        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
+    };
+};
+
+template <typename T, typename U>
+struct aggregate_traits {
+    enum {
+        is_pointer          = false,
+        has_trivial_ctor    =
+            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+        has_trivial_dtor    =
+            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+        has_trivial_copy    =
+            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+        has_trivial_move    =
+            traits<T>::has_trivial_move && traits<U>::has_trivial_move
+    };
+};
+
+#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
+    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
+    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
+    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
+
+#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
+    template<> struct trait_trivial_move< T >   { enum { value = true }; };
+
+#define ANDROID_BASIC_TYPES_TRAITS( T ) \
+    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
+    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
+    ANDROID_TRIVIAL_COPY_TRAIT( T ) \
+    ANDROID_TRIVIAL_MOVE_TRAIT( T )
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+
+ANDROID_BASIC_TYPES_TRAITS( void )
+ANDROID_BASIC_TYPES_TRAITS( bool )
+ANDROID_BASIC_TYPES_TRAITS( char )
+ANDROID_BASIC_TYPES_TRAITS( unsigned char )
+ANDROID_BASIC_TYPES_TRAITS( short )
+ANDROID_BASIC_TYPES_TRAITS( unsigned short )
+ANDROID_BASIC_TYPES_TRAITS( int )
+ANDROID_BASIC_TYPES_TRAITS( unsigned int )
+ANDROID_BASIC_TYPES_TRAITS( long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long )
+ANDROID_BASIC_TYPES_TRAITS( long long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
+ANDROID_BASIC_TYPES_TRAITS( float )
+ANDROID_BASIC_TYPES_TRAITS( double )
+
+// ---------------------------------------------------------------------------
+
+
+/*
+ * compare and order types
+ */
+
+template<typename TYPE> inline
+int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
+    return (lhs < rhs) ? 1 : 0;
+}
+
+template<typename TYPE> inline
+int compare_type(const TYPE& lhs, const TYPE& rhs) {
+    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
+}
+
+/*
+ * create, destroy, copy and move types...
+ */
+
+template<typename TYPE> inline
+void construct_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_ctor) {
+        while (n > 0) {
+            n--;
+            new(p++) TYPE;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void destroy_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_dtor) {
+        while (n > 0) {
+            n--;
+            p->~TYPE();
+            p++;
+        }
+    }
+}
+
+template<typename TYPE>
+typename std::enable_if<traits<TYPE>::has_trivial_copy>::type
+inline
+copy_type(TYPE* d, const TYPE* s, size_t n) {
+    memcpy(d,s,n*sizeof(TYPE));
+}
+
+template<typename TYPE>
+typename std::enable_if<!traits<TYPE>::has_trivial_copy>::type
+inline
+copy_type(TYPE* d, const TYPE* s, size_t n) {
+    while (n > 0) {
+        n--;
+        new(d) TYPE(*s);
+        d++, s++;
+    }
+}
+
+template<typename TYPE> inline
+void splat_type(TYPE* where, const TYPE* what, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n > 0) {
+            n--;
+            new(where) TYPE(*what);
+            where++;
+        }
+    } else {
+        while (n > 0) {
+            n--;
+            *where++ = *what;
+        }
+    }
+}
+
+template<typename TYPE>
+struct use_trivial_move : public std::integral_constant<bool,
+    (traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
+    || traits<TYPE>::has_trivial_move
+> {};
+
+template<typename TYPE>
+typename std::enable_if<use_trivial_move<TYPE>::value>::type
+inline
+move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    memmove(d, s, n*sizeof(TYPE));
+}
+
+template<typename TYPE>
+typename std::enable_if<!use_trivial_move<TYPE>::value>::type
+inline
+move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    d += n;
+    s += n;
+    while (n > 0) {
+        n--;
+        --d, --s;
+        if (!traits<TYPE>::has_trivial_copy) {
+            new(d) TYPE(*s);
+        } else {
+            *d = *s;
+        }
+        if (!traits<TYPE>::has_trivial_dtor) {
+            s->~TYPE();
+        }
+    }
+}
+
+template<typename TYPE>
+typename std::enable_if<use_trivial_move<TYPE>::value>::type
+inline
+move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    memmove(d, s, n*sizeof(TYPE));
+}
+
+template<typename TYPE>
+typename std::enable_if<!use_trivial_move<TYPE>::value>::type
+inline
+move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    while (n > 0) {
+        n--;
+        if (!traits<TYPE>::has_trivial_copy) {
+            new(d) TYPE(*s);
+        } else {
+            *d = *s;
+        }
+        if (!traits<TYPE>::has_trivial_dtor) {
+            s->~TYPE();
+        }
+        d++, s++;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+/*
+ * a key/value pair
+ */
+
+template <typename KEY, typename VALUE>
+struct key_value_pair_t {
+    typedef KEY key_t;
+    typedef VALUE value_t;
+
+    KEY     key;
+    VALUE   value;
+    key_value_pair_t() { }
+    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
+    key_value_pair_t& operator=(const key_value_pair_t& o) {
+        key = o.key;
+        value = o.value;
+        return *this;
+    }
+    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
+    explicit key_value_pair_t(const KEY& k) : key(k) { }
+    inline bool operator < (const key_value_pair_t& o) const {
+        return strictly_order_type(key, o.key);
+    }
+    inline const KEY& getKey() const {
+        return key;
+    }
+    inline const VALUE& getValue() const {
+        return value;
+    }
+};
+
+template <typename K, typename V>
+struct trait_trivial_ctor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
+template <typename K, typename V>
+struct trait_trivial_dtor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
+template <typename K, typename V>
+struct trait_trivial_copy< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
+template <typename K, typename V>
+struct trait_trivial_move< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Hash codes.
+ */
+typedef uint32_t hash_t;
+
+template <typename TKey>
+hash_t hash_type(const TKey& key);
+
+/* Built-in hash code specializations */
+#define ANDROID_INT32_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
+#define ANDROID_INT64_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_t((value >> 32) ^ value); }
+#define ANDROID_REINTERPRET_HASH(T, R) \
+        template <> inline hash_t hash_type(const T& value) { \
+            R newValue; \
+            static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \
+            memcpy(&newValue, &value, sizeof(newValue)); \
+            return hash_type(newValue); \
+        }
+
+ANDROID_INT32_HASH(bool)
+ANDROID_INT32_HASH(int8_t)
+ANDROID_INT32_HASH(uint8_t)
+ANDROID_INT32_HASH(int16_t)
+ANDROID_INT32_HASH(uint16_t)
+ANDROID_INT32_HASH(int32_t)
+ANDROID_INT32_HASH(uint32_t)
+ANDROID_INT64_HASH(int64_t)
+ANDROID_INT64_HASH(uint64_t)
+ANDROID_REINTERPRET_HASH(float, uint32_t)
+ANDROID_REINTERPRET_HASH(double, uint64_t)
+
+template <typename T> inline hash_t hash_type(T* const & value) {
+    return hash_type(uintptr_t(value));
+}
+
+}  // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_TYPE_HELPERS_H