Build native android graphics library for desktop

The purpose of this is to be able to use the native graphics code from
the Android platform directly in Android Studio (running on desktop) to
do layout rendering.

This creates a host library that is a subset of libandroid_runtime
including only the JNI files relevant to Android graphics. It also
includes LayoutlibLoader.cpp which is used to load the JNI when using
it as part of layoutlib (the graphics library for Android Studio).

This also creates libhwui-host, a host library that is a subset of
libhwui.

Bug: 117921091
Test: lunch sdk && m libandroid_runtime
Change-Id: I3850020d2d4c13c85e377476bc463d3eb6a01c6d
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 43d1c95..47f22d6 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -398,3 +398,59 @@
         "hwuimacro",
     ]
 }
+
+cc_library_host_shared {
+    name: "libhwui-host",
+
+    defaults: [
+        "skia_deps",
+    ],
+    whole_static_libs: ["libskia"],
+
+    srcs: [
+        "hwui/AnimatedImageDrawable.cpp",
+        "hwui/AnimatedImageThread.cpp",
+        "hwui/Bitmap.cpp",
+        "hwui/Canvas.cpp",
+        "hwui/Typeface.cpp",
+        "hwui/MinikinSkia.cpp",
+        "hwui/MinikinUtils.cpp",
+        "hwui/PaintImpl.cpp",
+        "utils/Blur.cpp",
+        "utils/LinearAllocator.cpp",
+        "utils/VectorDrawableUtils.cpp",
+        "Animator.cpp",
+        "Interpolator.cpp",
+        "Matrix.cpp",
+        "PathParser.cpp",
+        "Properties.cpp",
+        "PropertyValuesAnimatorSet.cpp",
+        "PropertyValuesHolder.cpp",
+        "SkiaCanvas.cpp",
+        "VectorDrawable.cpp",
+    ],
+    include_dirs: [
+        "external/skia/include/private",
+        "external/skia/src/core",
+        "external/vulkan-headers/include",
+        "system/core/base/include",
+    ],
+    cpp_std: "experimental",
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wno-unused-variable",
+    ],
+    shared_libs: [
+        "libbase",
+        "libharfbuzz_ng",
+        "libminikin",
+    ],
+    static_libs: [
+        "libandroidfw",
+        "libutils",
+    ],
+    export_include_dirs: ["."],
+    export_static_lib_headers: [
+        "libarect",
+    ],
+}
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 74cf1fd..93b9dec 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -155,9 +155,11 @@
         RenderNode* oldTarget = mTarget;
         mTarget = mStagingTarget;
         mStagingTarget = nullptr;
+#ifdef __ANDROID__ // Layoutlib does not support RenderNode
         if (oldTarget && oldTarget != mTarget) {
             oldTarget->onAnimatorTargetChanged(this);
         }
+#endif
     }
 
     if (!mHasStartValue) {
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index c300593..72243d2 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -27,7 +27,13 @@
 
     static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& sourceBitmap);
 
+#ifdef __ANDROID__
     static bool hasFP16Support();
+#else
+    static bool hasFP16Support() {
+        return true;
+    }
+#endif
 };
 
 }  // namespace android::uirenderer
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 2196b0f..1253beb 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -17,11 +17,14 @@
 #include "Properties.h"
 #include "Debug.h"
 #include "DeviceInfo.h"
+#ifdef __ANDROID__
 #include "HWUIProperties.sysprop.h"
+#endif
 #include "SkTraceEventCommon.h"
 
 #include <algorithm>
 #include <cstdlib>
+#include <optional>
 
 #include <android-base/properties.h>
 #include <cutils/compiler.h>
@@ -30,6 +33,16 @@
 namespace android {
 namespace uirenderer {
 
+#ifndef __ANDROID__ // Layoutlib does not compile HWUIProperties.sysprop as it depends on cutils properties
+std::optional<bool> use_vulkan() {
+    return base::GetBoolProperty("ro.hwui.use_vulkan", false);
+}
+
+std::optional<std::int32_t> render_ahead() {
+    return base::GetIntProperty("ro.hwui.render_ahead", 0);
+}
+#endif
+
 bool Properties::debugLayersUpdates = false;
 bool Properties::debugOverdraw = false;
 bool Properties::showDirtyRegions = false;
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 12ba091..05a6d0d 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -16,7 +16,9 @@
 #pragma once
 
 #include "CanvasProperty.h"
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 #include "DeferredLayerUpdater.h"
+#endif
 #include "RenderNode.h"
 #include "VectorDrawable.h"
 #include "hwui/Canvas.h"
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 5418b33..89ad1b9 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -487,6 +487,7 @@
 }
 
 void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context) {
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     SkRect dst;
     sk_sp<SkSurface> surface = mCache.getSurface(&dst);
     bool canReuseSurface = surface && dst.width() >= mProperties.getScaledWidth() &&
@@ -514,6 +515,7 @@
         }
         mCache.dirty = false;
     }
+#endif
 }
 
 void Tree::Cache::setAtlas(sp<skiapipeline::VectorDrawableAtlas> newAtlas,
@@ -526,6 +528,7 @@
 
 sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) {
     sk_sp<SkSurface> surface;
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     sp<skiapipeline::VectorDrawableAtlas> atlas = mAtlas.promote();
     if (atlas.get() && mAtlasKey != INVALID_ATLAS_KEY) {
         auto atlasEntry = atlas->getEntry(mAtlasKey);
@@ -533,17 +536,20 @@
         surface = atlasEntry.surface;
         mAtlasKey = atlasEntry.key;
     }
+#endif
 
     return surface;
 }
 
 void Tree::Cache::clear() {
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     sp<skiapipeline::VectorDrawableAtlas> lockAtlas = mAtlas.promote();
     if (lockAtlas.get()) {
         lockAtlas->releaseEntry(mAtlasKey);
     }
     mAtlas = nullptr;
     mAtlasKey = INVALID_ATLAS_KEY;
+#endif
 }
 
 void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) {
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 2846cb1..675b738 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -17,7 +17,11 @@
 #pragma once
 
 #include <private/hwui/WebViewFunctor.h>
+#ifdef __ANDROID__ // Layoutlib does not support render thread
 #include <renderthread/RenderProxy.h>
+#else
+#include <utils/Log.h>
+#endif
 
 #include <utils/LightRefBase.h>
 #include <mutex>
@@ -34,7 +38,11 @@
 
     class Handle : public LightRefBase<Handle> {
     public:
-        ~Handle() { renderthread::RenderProxy::destroyFunctor(id()); }
+        ~Handle() {
+#ifdef __ANDROID__ // Layoutlib does not support render thread
+            renderthread::RenderProxy::destroyFunctor(id());
+#endif
+        }
 
         int id() const { return mReference.id(); }
 
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 8d4e7e0..7677f9c 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -24,6 +24,12 @@
 
 #include <optional>
 
+#ifdef __APPLE__
+    // macOS SDK 10.10 does not support CLOCK_MONOTONIC, which is not an issue since
+    // the value of the argument is not used in the host definition of systemTime
+#define CLOCK_MONOTONIC
+#endif
+
 namespace android {
 
 AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 219d040..4c2f0ad 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -17,17 +17,23 @@
 
 #include "HardwareBitmapUploader.h"
 #include "Properties.h"
+#ifdef __ANDROID__  // Layoutlib does not support render thread
 #include "renderthread/RenderProxy.h"
+#endif
 #include "utils/Color.h"
 #include <utils/Trace.h>
 
+#ifndef _WIN32
 #include <sys/mman.h>
+#endif
 
 #include <cutils/ashmem.h>
 #include <log/log.h>
 
+#ifndef _WIN32
 #include <binder/IServiceManager.h>
 #include <private/gui/ComposerService.h>
+#endif
 #include <ui/PixelFormat.h>
 
 #include <SkCanvas.h>
@@ -76,6 +82,7 @@
 }
 
 sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info, size_t rowBytes) {
+#ifdef __ANDROID__
     // Create new ashmem region with read/write priv
     int fd = ashmem_create_region("bitmap", size);
     if (fd < 0) {
@@ -94,10 +101,17 @@
         return nullptr;
     }
     return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes));
+#else
+    return Bitmap::allocateHeapBitmap(size, info, rowBytes);
+#endif
 }
 
 sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(const SkBitmap& bitmap) {
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     return uirenderer::HardwareBitmapUploader::allocateHardwareBitmap(bitmap);
+#else
+    return Bitmap::allocateHeapBitmap(bitmap.info());
+#endif
 }
 
 sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap) {
@@ -133,6 +147,7 @@
 }
 
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer, SkColorType colorType,
                                  sk_sp<SkColorSpace> colorSpace, SkAlphaType alphaType,
                                  BitmapPalette palette) {
@@ -140,9 +155,13 @@
                                          colorType, alphaType, colorSpace);
     return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info, palette));
 }
+#endif
 
 sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr,
                                  size_t size, bool readOnly) {
+#ifdef _WIN32 // ashmem not implemented on Windows
+     return nullptr;
+#else
     if (info.colorType() == kUnknown_SkColorType) {
         LOG_ALWAYS_FATAL("unknown bitmap configuration");
         return nullptr;
@@ -163,6 +182,7 @@
         bitmap->setImmutable();
     }
     return bitmap;
+#endif
 }
 
 void Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
@@ -217,6 +237,7 @@
     mPixelStorage.ashmem.size = mappedSize;
 }
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info, BitmapPalette palette)
         : SkPixelRef(info.width(), info.height(), nullptr,
                      bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride())
@@ -230,6 +251,7 @@
     mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer),
                                               mInfo.alphaType(), mInfo.refColorSpace());
 }
+#endif
 
 Bitmap::~Bitmap() {
     switch (mPixelStorageType) {
@@ -238,17 +260,23 @@
                                             mPixelStorage.external.context);
             break;
         case PixelStorageType::Ashmem:
+#ifndef _WIN32 // ashmem not implemented on Windows
             munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size);
+#endif
             close(mPixelStorage.ashmem.fd);
             break;
         case PixelStorageType::Heap:
             free(mPixelStorage.heap.address);
+#ifdef __ANDROID__
             mallopt(M_PURGE, 0);
+#endif
             break;
         case PixelStorageType::Hardware:
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
             auto buffer = mPixelStorage.hardware.buffer;
             buffer->decStrong(buffer);
             mPixelStorage.hardware.buffer = nullptr;
+#endif
             break;
     }
 }
@@ -307,11 +335,13 @@
 }
 
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     if (isHardware()) {
         outBitmap->allocPixels(mInfo);
         uirenderer::renderthread::RenderProxy::copyHWBitmapInto(this, outBitmap);
         return;
     }
+#endif
     outBitmap->setInfo(mInfo, rowBytes());
     outBitmap->setPixelRef(sk_ref_sp(this), 0, 0);
 }
@@ -321,12 +351,14 @@
     bounds->set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
 }
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 GraphicBuffer* Bitmap::graphicBuffer() {
     if (isHardware()) {
         return mPixelStorage.hardware.buffer;
     }
     return nullptr;
 }
+#endif
 
 sk_sp<SkImage> Bitmap::makeImage() {
     sk_sp<SkImage> image = mImage;
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index dd98b25..c7e18d1 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -23,7 +23,9 @@
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
 #include <cutils/compiler.h>
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 #include <ui/GraphicBuffer.h>
+#endif
 
 namespace android {
 
@@ -71,11 +73,13 @@
     /* The createFrom factories construct a new Bitmap object by wrapping the already allocated
      * memory that is provided as an input param.
      */
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer,
                                     SkColorType colorType,
                                     sk_sp<SkColorSpace> colorSpace,
                                     SkAlphaType alphaType = kPremul_SkAlphaType,
                                     BitmapPalette palette = BitmapPalette::Unknown);
+#endif
     static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr,
                                     size_t size, bool readOnly);
     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
@@ -105,7 +109,9 @@
 
     PixelStorageType pixelStorageType() const { return mPixelStorageType; }
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     GraphicBuffer* graphicBuffer();
+#endif
 
     /**
      * Creates or returns a cached SkImage and is safe to be invoked from either
@@ -136,7 +142,9 @@
     Bitmap(void* address, void* context, FreeFunc freeFunc, const SkImageInfo& info,
            size_t rowBytes);
     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes);
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     Bitmap(GraphicBuffer* buffer, const SkImageInfo& info, BitmapPalette palette);
+#endif
 
     virtual ~Bitmap();
     void* getStorage() const;
@@ -165,9 +173,11 @@
             void* address;
             size_t size;
         } heap;
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
         struct {
             GraphicBuffer* buffer;
         } hardware;
+#endif
     } mPixelStorage;
 
     sk_sp<SkImage> mImage;  // Cache is used only for HW Bitmaps with Skia pipeline.
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index a48c860..e2ddb91 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -30,7 +30,11 @@
 namespace android {
 
 Canvas* Canvas::create_recording_canvas(int width, int height, uirenderer::RenderNode* renderNode) {
+#ifdef __ANDROID__ // Layoutlib does not support recording canvas
     return new uirenderer::skiapipeline::SkiaRecordingCanvas(renderNode, width, height);
+#else
+    return NULL;
+#endif
 }
 
 static inline void drawStroke(SkScalar left, SkScalar right, SkScalar top, SkScalar thickness,
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index c4d8aa6..ccc328c 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -18,7 +18,9 @@
 
 #include <fcntl.h>  // For tests.
 #include <pthread.h>
+#ifndef _WIN32
 #include <sys/mman.h>  // For tests.
+#endif
 #include <sys/stat.h>  // For tests.
 
 #include "MinikinSkia.h"
@@ -171,6 +173,7 @@
 }
 
 void Typeface::setRobotoTypefaceForTest() {
+#ifndef _WIN32
     const char* kRobotoFont = "/system/fonts/Roboto-Regular.ttf";
 
     int fd = open(kRobotoFont, O_RDONLY);
@@ -198,5 +201,6 @@
     hwTypeface->fStyle = minikin::FontStyle();
 
     Typeface::setDefault(hwTypeface);
+#endif
 }
 }  // namespace android
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 9a5a00f..ad251f2 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -17,7 +17,9 @@
 #ifndef CACHEMANAGER_H
 #define CACHEMANAGER_H
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 #include <GrContext.h>
+#endif
 #include <SkSurface.h>
 #include <ui/DisplayInfo.h>
 #include <utils/String8.h>
@@ -42,7 +44,9 @@
 public:
     enum class TrimMemoryMode { Complete, UiHidden };
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     void configureContext(GrContextOptions* context, const void* identity, ssize_t size);
+#endif
     void trimMemory(TrimMemoryMode mode);
     void trimStaleResources();
     void dumpMemoryUsage(String8& log, const RenderState* renderState = nullptr);
@@ -57,11 +61,15 @@
 
     explicit CacheManager(const DisplayInfo& display);
 
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     void reset(sk_sp<GrContext> grContext);
+#endif
     void destroy();
 
     const size_t mMaxSurfaceArea;
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     sk_sp<GrContext> mGrContext;
+#endif
 
     int mMaxResources = 0;
     const size_t mMaxResourceBytes;
diff --git a/libs/hwui/utils/TraceUtils.h b/libs/hwui/utils/TraceUtils.h
index 1869d00..e61b4be 100644
--- a/libs/hwui/utils/TraceUtils.h
+++ b/libs/hwui/utils/TraceUtils.h
@@ -16,6 +16,7 @@
 #ifndef TRACE_UTILS_H
 #define TRACE_UTILS_H
 
+#include <cutils/trace.h>
 #include <utils/Trace.h>
 
 #define ATRACE_FORMAT(fmt, ...)           \