[libcamera-devel,v3,1/4] android: Import libutils/libui headers from vndk v33
diff mbox series

Message ID 20230923-gralloc-api-v4-v3-1-9a9e039284ba@baylibre.com
State New
Headers show
Series
  • android: switch over to modern gralloc API via libui
Related show

Commit Message

Mattijs Korpershoek Sept. 23, 2023, 4:23 p.m. UTC
In order to switch to the more modern GraphicBufferAllocator class, we need
additional compile-time dependencies.

Import all the needed headers from the Android Vendor Native Development
Kit (vndk) and add them to the android_includes.

These have been imported from:
URL: https://android.googlesource.com/platform/prebuilts/vndk/v33/
rev: 390028a9da88 ("Update VNDK snapshot v33 to build 9948968. am: 3042508aee am: 7092391a46")

No changes have been made to the files, besides adding the SPDX comment.

Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
---
 .../native/libs/ui/include/ui/PixelFormat.h        |  75 +++++++
 include/android/meson.build                        |   2 +
 .../system/core/libutils/include/utils/Compat.h    |  94 +++++++++
 .../system/core/libutils/include/utils/Errors.h    |  78 ++++++++
 .../system/core/libutils/include/utils/Mutex.h     | 219 +++++++++++++++++++++
 .../system/core/libutils/include/utils/Singleton.h | 102 ++++++++++
 .../system/core/libutils/include/utils/Timers.h    | 103 ++++++++++
 7 files changed, 673 insertions(+)

Comments

Laurent Pinchart Sept. 24, 2023, 3:51 p.m. UTC | #1
Hi Mattijs,

Thank you for the patch.

On Sat, Sep 23, 2023 at 06:23:31PM +0200, Mattijs Korpershoek via libcamera-devel wrote:
> In order to switch to the more modern GraphicBufferAllocator class, we need
> additional compile-time dependencies.
> 
> Import all the needed headers from the Android Vendor Native Development
> Kit (vndk) and add them to the android_includes.
> 
> These have been imported from:
> URL: https://android.googlesource.com/platform/prebuilts/vndk/v33/

This doesn't look like the upstream for those files, it's a prebuild
repository for binaries, with header files that are regularly imported
from upstream. for frameworks/native the upstream seems to be
https://android.googlesource.com/platform/frameworks/native/, while for
system/core it seems to be
https://android.googlesource.com/platform/system/core/.

If we import files from those repositories, I think we should update the
headers already included in libcamera to the same version. Mixing two
versions seems dangerous.

> rev: 390028a9da88 ("Update VNDK snapshot v33 to build 9948968. am: 3042508aee am: 7092391a46")

Would it make sense to go for a tagged release instead of the latest
commit in the main branch ?

> No changes have been made to the files, besides adding the SPDX comment.
> 
> Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
> ---
>  .../native/libs/ui/include/ui/PixelFormat.h        |  75 +++++++
>  include/android/meson.build                        |   2 +
>  .../system/core/libutils/include/utils/Compat.h    |  94 +++++++++
>  .../system/core/libutils/include/utils/Errors.h    |  78 ++++++++
>  .../system/core/libutils/include/utils/Mutex.h     | 219 +++++++++++++++++++++
>  .../system/core/libutils/include/utils/Singleton.h | 102 ++++++++++
>  .../system/core/libutils/include/utils/Timers.h    | 103 ++++++++++
>  7 files changed, 673 insertions(+)

[snip]
Mattijs Korpershoek Sept. 30, 2023, 7:51 a.m. UTC | #2
Hi Laurent,

Thank you for your review.

On dim., sept. 24, 2023 at 18:51, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:

> Hi Mattijs,
>
> Thank you for the patch.
>
> On Sat, Sep 23, 2023 at 06:23:31PM +0200, Mattijs Korpershoek via libcamera-devel wrote:
>> In order to switch to the more modern GraphicBufferAllocator class, we need
>> additional compile-time dependencies.
>> 
>> Import all the needed headers from the Android Vendor Native Development
>> Kit (vndk) and add them to the android_includes.
>> 
>> These have been imported from:
>> URL: https://android.googlesource.com/platform/prebuilts/vndk/v33/
>
> This doesn't look like the upstream for those files, it's a prebuild
> repository for binaries, with header files that are regularly imported
> from upstream. for frameworks/native the upstream seems to be
> https://android.googlesource.com/platform/frameworks/native/, while for
> system/core it seems to be
> https://android.googlesource.com/platform/system/core/.

That's correct, and intentional. The vndk is known to provide stable
headers. However the VND and the NDK might be different versions.

>
> If we import files from those repositories, I think we should update the
> headers already included in libcamera to the same version. Mixing two
> versions seems dangerous.

Indeed

>
>> rev: 390028a9da88 ("Update VNDK snapshot v33 to build 9948968. am: 3042508aee am: 7092391a46")
>
> Would it make sense to go for a tagged release instead of the latest
> commit in the main branch ?

Yes it makes sense. I will either pick a tag from source or a release
version of the NDK.
I will add a first commit to update all existing headers to that known version.

Then I will add these headers here.

>
>> No changes have been made to the files, besides adding the SPDX comment.
>> 
>> Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
>> ---
>>  .../native/libs/ui/include/ui/PixelFormat.h        |  75 +++++++
>>  include/android/meson.build                        |   2 +
>>  .../system/core/libutils/include/utils/Compat.h    |  94 +++++++++
>>  .../system/core/libutils/include/utils/Errors.h    |  78 ++++++++
>>  .../system/core/libutils/include/utils/Mutex.h     | 219 +++++++++++++++++++++
>>  .../system/core/libutils/include/utils/Singleton.h | 102 ++++++++++
>>  .../system/core/libutils/include/utils/Timers.h    | 103 ++++++++++
>>  7 files changed, 673 insertions(+)
>
> [snip]
>
> -- 
> Regards,
>
> Laurent Pinchart

Patch
diff mbox series

diff --git a/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h b/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h
new file mode 100644
index 000000000000..2add09462218
--- /dev/null
+++ b/include/android/frameworks/native/libs/ui/include/ui/PixelFormat.h
@@ -0,0 +1,75 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * 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.
+ */
+
+//
+
+// Pixel formats used across the system.
+// These formats might not all be supported by all renderers, for instance
+// skia or SurfaceFlinger are not required to support all of these formats
+// (either as source or destination)
+
+
+#ifndef UI_PIXELFORMAT_H
+#define UI_PIXELFORMAT_H
+
+#include <hardware/hardware.h>
+
+namespace android {
+
+enum {
+    //
+    // these constants need to match those
+    // in graphics/PixelFormat.java & pixelflinger/format.h
+    //
+    PIXEL_FORMAT_UNKNOWN    =   0,
+    PIXEL_FORMAT_NONE       =   0,
+
+    // logical pixel formats used by the SurfaceFlinger -----------------------
+    PIXEL_FORMAT_CUSTOM         = -4,
+        // Custom pixel-format described by a PixelFormatInfo structure
+
+    PIXEL_FORMAT_TRANSLUCENT    = -3,
+        // System chooses a format that supports translucency (many alpha bits)
+
+    PIXEL_FORMAT_TRANSPARENT    = -2,
+        // System chooses a format that supports transparency
+        // (at least 1 alpha bit)
+
+    PIXEL_FORMAT_OPAQUE         = -1,
+        // System chooses an opaque format (no alpha bits required)
+
+    // real pixel formats supported for rendering -----------------------------
+
+    PIXEL_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,    // 4x8-bit RGBA
+    PIXEL_FORMAT_RGBX_8888    = HAL_PIXEL_FORMAT_RGBX_8888,    // 4x8-bit RGB0
+    PIXEL_FORMAT_RGB_888      = HAL_PIXEL_FORMAT_RGB_888,      // 3x8-bit RGB
+    PIXEL_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,      // 16-bit RGB
+    PIXEL_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,    // 4x8-bit BGRA
+    PIXEL_FORMAT_RGBA_5551    = 6,                             // 16-bit ARGB
+    PIXEL_FORMAT_RGBA_4444    = 7,                             // 16-bit ARGB
+    PIXEL_FORMAT_RGBA_FP16    = HAL_PIXEL_FORMAT_RGBA_FP16,    // 64-bit RGBA
+    PIXEL_FORMAT_RGBA_1010102 = HAL_PIXEL_FORMAT_RGBA_1010102, // 32-bit RGBA
+    PIXEL_FORMAT_R_8          = 0x38,
+};
+
+typedef int32_t PixelFormat;
+
+uint32_t bytesPerPixel(PixelFormat format);
+
+}; // namespace android
+
+#endif // UI_PIXELFORMAT_H
diff --git a/include/android/meson.build b/include/android/meson.build
index da2504f2e493..59a4f36b523b 100644
--- a/include/android/meson.build
+++ b/include/android/meson.build
@@ -1,7 +1,9 @@ 
 # SPDX-License-Identifier: CC0-1.0
 
 android_includes = ([
+    include_directories('frameworks/native/libs/ui/include/'),
     include_directories('hardware/libhardware/include/'),
     include_directories('metadata/'),
     include_directories('system/core/include'),
+    include_directories('system/core/libutils/include/'),
 ])
diff --git a/include/android/system/core/libutils/include/utils/Compat.h b/include/android/system/core/libutils/include/utils/Compat.h
new file mode 100644
index 000000000000..bba568bd3226
--- /dev/null
+++ b/include/android/system/core/libutils/include/utils/Compat.h
@@ -0,0 +1,94 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2010 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 __LIB_UTILS_COMPAT_H
+#define __LIB_UTILS_COMPAT_H
+
+#include <unistd.h>
+
+#if !defined(__MINGW32__)
+#include <sys/mman.h>
+#endif
+
+#if defined(__APPLE__)
+
+/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */
+static_assert(sizeof(off_t) >= 8, "This code requires that Mac OS have at least a 64-bit off_t.");
+typedef off_t off64_t;
+
+static inline void* mmap64(void* addr, size_t length, int prot, int flags, int fd, off64_t offset) {
+    return mmap(addr, length, prot, flags, fd, offset);
+}
+
+static inline off64_t lseek64(int fd, off64_t offset, int whence) {
+    return lseek(fd, offset, whence);
+}
+
+static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) {
+    return pread(fd, buf, nbytes, offset);
+}
+
+static inline ssize_t pwrite64(int fd, const void* buf, size_t nbytes, off64_t offset) {
+    return pwrite(fd, buf, nbytes, offset);
+}
+
+static inline int ftruncate64(int fd, off64_t length) {
+    return ftruncate(fd, length);
+}
+
+#endif /* __APPLE__ */
+
+#if defined(_WIN32)
+#define O_CLOEXEC O_NOINHERIT
+#define O_NOFOLLOW 0
+#define DEFFILEMODE 0666
+#endif /* _WIN32 */
+
+#define ZD "%zd"
+#define ZD_TYPE ssize_t
+
+/*
+ * Needed for cases where something should be constexpr if possible, but not
+ * being constexpr is fine if in pre-C++11 code (such as a const static float
+ * member variable).
+ */
+#if __cplusplus >= 201103L
+#define CONSTEXPR constexpr
+#else
+#define CONSTEXPR
+#endif
+
+/* TEMP_FAILURE_RETRY is not available on macOS, but still useful there. */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp)                \
+    ({                                         \
+        __typeof__(exp) _rc;                   \
+        do {                                   \
+            _rc = (exp);                       \
+        } while (_rc == -1 && errno == EINTR); \
+        _rc;                                   \
+    })
+#endif
+
+#if defined(_WIN32)
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
+#endif
+
+#endif /* __LIB_UTILS_COMPAT_H */
diff --git a/include/android/system/core/libutils/include/utils/Errors.h b/include/android/system/core/libutils/include/utils/Errors.h
new file mode 100644
index 000000000000..f812844eacc4
--- /dev/null
+++ b/include/android/system/core/libutils/include/utils/Errors.h
@@ -0,0 +1,78 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2007 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
+
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <string>
+
+namespace android {
+
+/**
+ * The type used to return success/failure from frameworks APIs.
+ * See the anonymous enum below for valid values.
+ */
+typedef int32_t status_t;
+
+/*
+ * Error codes. 
+ * All error codes are negative values.
+ */
+
+enum {
+    OK                = 0,    // Preferred constant for checking success.
+#ifndef NO_ERROR
+    // Win32 #defines NO_ERROR as well.  It has the same value, so there's no
+    // real conflict, though it's a bit awkward.
+    NO_ERROR          = OK,   // Deprecated synonym for `OK`. Prefer `OK` because it doesn't conflict with Windows.
+#endif
+
+    UNKNOWN_ERROR       = (-2147483647-1), // INT32_MIN value
+
+    NO_MEMORY           = -ENOMEM,
+    INVALID_OPERATION   = -ENOSYS,
+    BAD_VALUE           = -EINVAL,
+    BAD_TYPE            = (UNKNOWN_ERROR + 1),
+    NAME_NOT_FOUND      = -ENOENT,
+    PERMISSION_DENIED   = -EPERM,
+    NO_INIT             = -ENODEV,
+    ALREADY_EXISTS      = -EEXIST,
+    DEAD_OBJECT         = -EPIPE,
+    FAILED_TRANSACTION  = (UNKNOWN_ERROR + 2),
+#if !defined(_WIN32)
+    BAD_INDEX           = -EOVERFLOW,
+    NOT_ENOUGH_DATA     = -ENODATA,
+    WOULD_BLOCK         = -EWOULDBLOCK, 
+    TIMED_OUT           = -ETIMEDOUT,
+    UNKNOWN_TRANSACTION = -EBADMSG,
+#else    
+    BAD_INDEX           = -E2BIG,
+    NOT_ENOUGH_DATA     = (UNKNOWN_ERROR + 3),
+    WOULD_BLOCK         = (UNKNOWN_ERROR + 4),
+    TIMED_OUT           = (UNKNOWN_ERROR + 5),
+    UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
+#endif    
+    FDS_NOT_ALLOWED     = (UNKNOWN_ERROR + 7),
+    UNEXPECTED_NULL     = (UNKNOWN_ERROR + 8),
+};
+
+// Human readable name of error
+std::string statusToString(status_t status);
+
+}  // namespace android
diff --git a/include/android/system/core/libutils/include/utils/Mutex.h b/include/android/system/core/libutils/include/utils/Mutex.h
new file mode 100644
index 000000000000..72d20bdca888
--- /dev/null
+++ b/include/android/system/core/libutils/include/utils/Mutex.h
@@ -0,0 +1,219 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2007 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 _LIBS_UTILS_MUTEX_H
+#define _LIBS_UTILS_MUTEX_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if !defined(_WIN32)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+#include <utils/Timers.h>
+
+// Enable thread safety attributes only with clang.
+// The attributes can be safely erased when compiling with other compilers.
+#if defined(__clang__) && (!defined(SWIG))
+#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
+#else
+#define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
+#endif
+
+#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
+
+#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+
+#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+
+#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
+
+#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
+
+#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
+
+#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
+
+#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
+
+#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
+
+#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
+
+#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE_SHARED(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
+
+#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
+
+#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
+
+#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
+
+#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Condition;
+
+/*
+ * NOTE: This class is for code that builds on Win32.  Its usage is
+ * deprecated for code which doesn't build for Win32.  New code which
+ * doesn't build for Win32 should use std::mutex and std::lock_guard instead.
+ *
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class CAPABILITY("mutex") Mutex {
+  public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+    Mutex();
+    explicit Mutex(const char* name);
+    explicit Mutex(int type, const char* name = nullptr);
+    ~Mutex();
+
+    // lock or unlock the mutex
+    status_t lock() ACQUIRE();
+    void unlock() RELEASE();
+
+    // lock if possible; returns 0 on success, error otherwise
+    status_t tryLock() TRY_ACQUIRE(0);
+
+#if defined(__ANDROID__)
+    // Lock the mutex, but don't wait longer than timeoutNs (relative time).
+    // Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
+    //
+    // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep
+    // capabilities consistent across host OSes, this method is only available
+    // when building Android binaries.
+    //
+    // FIXME?: pthread_mutex_timedlock is based on CLOCK_REALTIME,
+    // which is subject to NTP adjustments, and includes time during suspend,
+    // so a timeout may occur even though no processes could run.
+    // Not holding a partial wakelock may lead to a system suspend.
+    status_t timedLock(nsecs_t timeoutNs) TRY_ACQUIRE(0);
+#endif
+
+    // Manages the mutex automatically. It'll be locked when Autolock is
+    // constructed and released when Autolock goes out of scope.
+    class SCOPED_CAPABILITY Autolock {
+      public:
+        inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { mLock.lock(); }
+        inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { mLock.lock(); }
+        inline ~Autolock() RELEASE() { mLock.unlock(); }
+
+      private:
+        Mutex& mLock;
+        // Cannot be copied or moved - declarations only
+        Autolock(const Autolock&);
+        Autolock& operator=(const Autolock&);
+    };
+
+  private:
+    friend class Condition;
+
+    // A mutex cannot be copied
+    Mutex(const Mutex&);
+    Mutex& operator=(const Mutex&);
+
+#if !defined(_WIN32)
+    pthread_mutex_t mMutex;
+#else
+    void _init();
+    void* mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if !defined(_WIN32)
+
+inline Mutex::Mutex() {
+    pthread_mutex_init(&mMutex, nullptr);
+}
+inline Mutex::Mutex(__attribute__((unused)) const char* name) {
+    pthread_mutex_init(&mMutex, nullptr);
+}
+inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
+    if (type == SHARED) {
+        pthread_mutexattr_t attr;
+        pthread_mutexattr_init(&attr);
+        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_mutex_init(&mMutex, &attr);
+        pthread_mutexattr_destroy(&attr);
+    } else {
+        pthread_mutex_init(&mMutex, nullptr);
+    }
+}
+inline Mutex::~Mutex() {
+    pthread_mutex_destroy(&mMutex);
+}
+inline status_t Mutex::lock() {
+    return -pthread_mutex_lock(&mMutex);
+}
+inline void Mutex::unlock() {
+    pthread_mutex_unlock(&mMutex);
+}
+inline status_t Mutex::tryLock() {
+    return -pthread_mutex_trylock(&mMutex);
+}
+#if defined(__ANDROID__)
+inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
+    timeoutNs += systemTime(SYSTEM_TIME_REALTIME);
+    const struct timespec ts = {
+        /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
+        /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
+    };
+    return -pthread_mutex_timedlock(&mMutex, &ts);
+}
+#endif
+
+#endif // !defined(_WIN32)
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Automatic mutex.  Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+
+typedef Mutex::Autolock AutoMutex;
+
+// ---------------------------------------------------------------------------
+}  // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_MUTEX_H
diff --git a/include/android/system/core/libutils/include/utils/Singleton.h b/include/android/system/core/libutils/include/utils/Singleton.h
new file mode 100644
index 000000000000..154aed8f28e5
--- /dev/null
+++ b/include/android/system/core/libutils/include/utils/Singleton.h
@@ -0,0 +1,102 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2007 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_UTILS_SINGLETON_H
+#define ANDROID_UTILS_SINGLETON_H
+
+#include <stdint.h>
+
+// some vendor code assumes they have atoi() after including this file.
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <utils/Mutex.h>
+#include <cutils/compiler.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+// Singleton<TYPE> may be used in multiple libraries, only one of which should
+// define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE.
+// Turn off -Wundefined-var-template so other users don't get:
+// instantiation of variable 'android::Singleton<TYPE>::sLock' required here,
+// but no definition is available
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-var-template"
+#endif
+
+// DO NOT USE: Please use scoped static initialization. For instance:
+//     MyClass& getInstance() {
+//         static MyClass gInstance(...);
+//         return gInstance;
+//     }
+template <typename TYPE>
+class ANDROID_API Singleton
+{
+public:
+    static TYPE& getInstance() {
+        Mutex::Autolock _l(sLock);
+        TYPE* instance = sInstance;
+        if (instance == nullptr) {
+            instance = new TYPE();
+            sInstance = instance;
+        }
+        return *instance;
+    }
+
+    static bool hasInstance() {
+        Mutex::Autolock _l(sLock);
+        return sInstance != nullptr;
+    }
+    
+protected:
+    ~Singleton() { }
+    Singleton() { }
+
+private:
+    Singleton(const Singleton&);
+    Singleton& operator = (const Singleton&);
+    static Mutex sLock;
+    static TYPE* sInstance;
+};
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+/*
+ * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
+ * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
+ * and avoid to have a copy of them in each compilation units Singleton<TYPE>
+ * is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
+ */
+
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
+    template<> ::android::Mutex  \
+        (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE);  \
+    template<> TYPE* ::android::Singleton< TYPE >::sInstance(nullptr);  /* NOLINT */ \
+    template class ::android::Singleton< TYPE >;
+
+
+// ---------------------------------------------------------------------------
+}  // namespace android
+
+#endif // ANDROID_UTILS_SINGLETON_H
+
diff --git a/include/android/system/core/libutils/include/utils/Timers.h b/include/android/system/core/libutils/include/utils/Timers.h
new file mode 100644
index 000000000000..40acafabc099
--- /dev/null
+++ b/include/android/system/core/libutils/include/utils/Timers.h
@@ -0,0 +1,103 @@ 
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <utils/Compat.h>
+
+// ------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int64_t nsecs_t;       // nano-seconds
+
+static CONSTEXPR inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000000000;
+}
+
+static CONSTEXPR inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000000;
+}
+
+static CONSTEXPR inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000;
+}
+
+static CONSTEXPR inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)
+{
+    return secs/1000000000;
+}
+
+static CONSTEXPR inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)
+{
+    return secs/1000000;
+}
+
+static CONSTEXPR inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)
+{
+    return secs/1000;
+}
+
+static CONSTEXPR inline nsecs_t s2ns(nsecs_t v)  {return seconds_to_nanoseconds(v);}
+static CONSTEXPR inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}
+static CONSTEXPR inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}
+static CONSTEXPR inline nsecs_t ns2s(nsecs_t v)  {return nanoseconds_to_seconds(v);}
+static CONSTEXPR inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}
+static CONSTEXPR inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}
+
+static CONSTEXPR inline nsecs_t seconds(nsecs_t v)      { return s2ns(v); }
+static CONSTEXPR inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }
+static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
+
+enum {
+    SYSTEM_TIME_REALTIME = 0,   // system-wide realtime clock
+    SYSTEM_TIME_MONOTONIC = 1,  // monotonic time since unspecified starting point
+    SYSTEM_TIME_PROCESS = 2,    // high-resolution per-process clock
+    SYSTEM_TIME_THREAD = 3,     // high-resolution per-thread clock
+    SYSTEM_TIME_BOOTTIME = 4,   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
+};
+
+// return the system-time according to the specified clock
+#ifdef __cplusplus
+nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
+#else
+nsecs_t systemTime(int clock);
+#endif // def __cplusplus
+
+/**
+ * Returns the number of milliseconds to wait between the reference time and the timeout time.
+ * If the timeout is in the past relative to the reference time, returns 0.
+ * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
+ * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
+ * Otherwise, returns the difference between the reference time and timeout time
+ * rounded up to the next millisecond.
+ */
+int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif