[HWUI] Get DeviceInfo through stable ABI

This also removes the dependency on ui/DeviceInfo other than in test
code.

Bug: 136263392
Bug: 136263238
Test: builds, boots
Change-Id: I6a4687e981359f0e6beb83be8a5501ed7fd16f15
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 0505fe3..6ba9699 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -260,6 +260,7 @@
                 "libhidltransport",
                 "libhwbinder",
                 "libvintf",
+                "libnativedisplay",
                 "libnativewindow",
                 "libdl",
                 "libdl_android",
@@ -439,6 +440,7 @@
             ],
             shared_libs: [
                 "libandroidfw",
+                "libnativedisplay",
                 "libnativewindow",
                 "libgui",
                 "libpdfium",
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ae90f11..b19aa2f 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -88,6 +88,7 @@
                 "libvulkan",
                 "libui",
                 "libgui",
+                "libnativedisplay",
                 "libnativewindow",
                 "libprotobuf-cpp-lite",
                 "libft2",
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index a0d3ff9..41e9b4b 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -15,74 +15,21 @@
  */
 
 #include <DeviceInfo.h>
-
-#include "Properties.h"
-
 #include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
 #include <ui/GraphicTypes.h>
 
 #include <mutex>
 #include <thread>
 
-#include <log/log.h>
+#include "Properties.h"
 
 namespace android {
 namespace uirenderer {
 
-static constexpr android::DisplayInfo sDummyDisplay{
-        1080,   // w
-        1920,   // h
-        320.0,  // xdpi
-        320.0,  // ydpi
-        60.0,   // fps
-        2.0,    // density
-        0,      // orientation
-        false,  // secure?
-        0,      // appVsyncOffset
-        0,      // presentationDeadline
-        1080,   // viewportW
-        1920,   // viewportH
-};
-
 DeviceInfo* DeviceInfo::get() {
-        static DeviceInfo sDeviceInfo;
-        return &sDeviceInfo;
-}
-
-static DisplayInfo QueryDisplayInfo() {
-    if (Properties::isolatedProcess) {
-        return sDummyDisplay;
-    }
-
-    const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
-    LOG_ALWAYS_FATAL_IF(token == nullptr,
-                        "Failed to get display info because internal display is disconnected");
-
-    DisplayInfo displayInfo;
-    status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
-    return displayInfo;
-}
-
-static float QueryMaxRefreshRate() {
-    if (Properties::isolatedProcess) {
-        return sDummyDisplay.fps;
-    }
-
-    const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
-    LOG_ALWAYS_FATAL_IF(token == nullptr,
-                        "Failed to get display info because internal display is disconnected");
-
-    Vector<DisplayInfo> configs;
-    configs.reserve(10);
-    status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
-    LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
-    float max = 0.0f;
-    for (auto& info : configs) {
-        max = std::max(max, info.fps);
-    }
-    return max;
+    static DeviceInfo sDeviceInfo;
+    return &sDeviceInfo;
 }
 
 static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
@@ -123,14 +70,17 @@
     }
 }
 
-DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
+DeviceInfo::DeviceInfo() {
 #if HWUI_NULL_GPU
         mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
 #else
         mMaxTextureSize = -1;
 #endif
-    mDisplayInfo = QueryDisplayInfo();
-    queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+        updateDisplayInfo();
+        queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+}
+DeviceInfo::~DeviceInfo() {
+    ADisplay_release(mDisplays);
 }
 
 int DeviceInfo::maxTextureSize() const {
@@ -143,7 +93,36 @@
 }
 
 void DeviceInfo::onDisplayConfigChanged() {
-    mDisplayInfo = QueryDisplayInfo();
+    updateDisplayInfo();
+}
+
+void DeviceInfo::updateDisplayInfo() {
+    if (Properties::isolatedProcess) {
+        return;
+    }
+
+    if (mCurrentConfig == nullptr) {
+        mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays);
+        LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0,
+                            "Failed to get physical displays: no connected display: %d!", mDisplaysSize);
+        for (size_t i = 0; i < mDisplaysSize; i++) {
+            ADisplayType type = ADisplay_getDisplayType(mDisplays[i]);
+            if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) {
+                mPhysicalDisplayIndex = i;
+                break;
+            }
+        }
+        LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!");
+        mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]);
+    }
+    status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig);
+    LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
+    mWidth = ADisplayConfig_getWidth(mCurrentConfig);
+    mHeight = ADisplayConfig_getHeight(mCurrentConfig);
+    mDensity = ADisplayConfig_getDensity(mCurrentConfig);
+    mRefreshRate = ADisplayConfig_getFps(mCurrentConfig);
+    mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
+    mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 0e3f119..3431583 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,8 +16,8 @@
 #ifndef DEVICEINFO_H
 #define DEVICEINFO_H
 
+#include <apex/display.h>
 #include <SkImageInfo.h>
-#include <ui/DisplayInfo.h>
 
 #include "utils/Macros.h"
 
@@ -33,28 +33,44 @@
 
 public:
     static DeviceInfo* get();
+    static float getMaxRefreshRate() { return get()->mMaxRefreshRate; }
+    static int32_t getWidth() { return get()->mWidth; }
+    static int32_t getHeight() { return get()->mHeight; }
+    static float getDensity() { return get()->mDensity; }
+    static float getRefreshRate() { return get()->mRefreshRate; }
+    static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
+    static int64_t getAppOffset() { return get()->mAppOffset; }
 
     // this value is only valid after the GPU has been initialized and there is a valid graphics
     // context or if you are using the HWUI_NULL_GPU
     int maxTextureSize() const;
-    const DisplayInfo& displayInfo() const { return mDisplayInfo; }
     sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
     SkColorType getWideColorType() const { return mWideColorType; }
-    float getMaxRefreshRate() const { return mMaxRefreshRate; }
 
     void onDisplayConfigChanged();
 
 private:
     friend class renderthread::RenderThread;
     static void setMaxTextureSize(int maxTextureSize);
+    void updateDisplayInfo();
 
     DeviceInfo();
+    ~DeviceInfo();
 
     int mMaxTextureSize;
-    DisplayInfo mDisplayInfo;
     sk_sp<SkColorSpace> mWideColorSpace;
     SkColorType mWideColorType;
-    const float mMaxRefreshRate;
+    ADisplayConfig* mCurrentConfig = nullptr;
+    ADisplay** mDisplays = nullptr;
+    int mDisplaysSize = 0;
+    int mPhysicalDisplayIndex = -1;
+    float mMaxRefreshRate = 60.0;
+    int32_t mWidth = 1080;
+    int32_t mHeight = 1920;
+    float mDensity = 2.0;
+    float mRefreshRate = 60.0;
+    int64_t mCompositorOffset = 0;
+    int64_t mAppOffset = 0;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index eae3584..10e7160 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -16,8 +16,10 @@
 
 #include "JankTracker.h"
 
+#include <cutils/ashmem.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <log/log.h>
 #include <statslog.h>
 #include <sys/mman.h>
 
@@ -25,11 +27,9 @@
 #include <cmath>
 #include <cstdio>
 #include <limits>
-
-#include <cutils/ashmem.h>
-#include <log/log.h>
 #include <sstream>
 
+#include "DeviceInfo.h"
 #include "Properties.h"
 #include "utils/TimeUtils.h"
 #include "utils/Trace.h"
@@ -79,11 +79,11 @@
 // and filter it out of the frame profile data
 static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
 
-JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) {
+JankTracker::JankTracker(ProfileDataContainer* globalData) {
     mGlobalData = globalData;
-    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
-    nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
-    nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset;
+    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / DeviceInfo::getRefreshRate());
+    nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
+    nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
     // There are two different offset cases. If the offsetDelta is positive
     // and small, then the intention is to give apps extra time by leveraging
     // pipelining between the UI & RT threads. If the offsetDelta is large or
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 08059268..4460266 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -23,7 +23,6 @@
 #include "utils/RingBuffer.h"
 
 #include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
 
 #include <array>
 #include <memory>
@@ -49,7 +48,7 @@
 // TODO: Replace DrawProfiler with this
 class JankTracker {
 public:
-    explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo);
+    explicit JankTracker(ProfileDataContainer* globalData);
 
     void setDescription(JankTrackerType type, const std::string&& name) {
         mDescription.type = type;
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4e7df88..446e81e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -16,7 +16,6 @@
 
 #include "Properties.h"
 #include "Debug.h"
-#include "DeviceInfo.h"
 #ifdef __ANDROID__
 #include "HWUIProperties.sysprop.h"
 #endif
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e979448..24f6035 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,7 +16,10 @@
 
 #pragma once
 
+#ifdef __ANDROID__ // Layoutlib does not support device info
 #include "DeviceInfo.h"
+#endif // __ANDROID__
+
 #include "Outline.h"
 #include "Rect.h"
 #include "RevealClip.h"
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index dc07f0d..b78c50a 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -16,6 +16,7 @@
 
 #include "CacheManager.h"
 
+#include "DeviceInfo.h"
 #include "Layer.h"
 #include "Properties.h"
 #include "RenderThread.h"
@@ -42,8 +43,8 @@
 #define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
 #define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
 
-CacheManager::CacheManager(const DisplayInfo& display)
-        : mMaxSurfaceArea(display.w * display.h)
+CacheManager::CacheManager()
+        : mMaxSurfaceArea(DeviceInfo::getWidth() * DeviceInfo::getHeight())
         , mMaxResourceBytes(mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER)
         , mBackgroundResourceBytes(mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE)
         // This sets the maximum size for a single texture atlas in the GPU font cache. If
@@ -52,9 +53,9 @@
         , mMaxGpuFontAtlasBytes(GrNextSizePow2(mMaxSurfaceArea))
         // This sets the maximum size of the CPU font cache to be at least the same size as the
         // total number of GPU font caches (i.e. 4 separate GPU atlases).
-        , mMaxCpuFontCacheBytes(std::max(mMaxGpuFontAtlasBytes*4, SkGraphics::GetFontCacheLimit()))
+        , mMaxCpuFontCacheBytes(
+                  std::max(mMaxGpuFontAtlasBytes * 4, SkGraphics::GetFontCacheLimit()))
         , mBackgroundCpuFontCacheBytes(mMaxCpuFontCacheBytes * BACKGROUND_RETENTION_PERCENTAGE) {
-
     SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes);
 
     mVectorDrawableAtlas = new skiapipeline::VectorDrawableAtlas(
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index d7977cc..dacb7bd 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -21,7 +21,6 @@
 #include <GrContext.h>
 #endif
 #include <SkSurface.h>
-#include <ui/DisplayInfo.h>
 #include <utils/String8.h>
 #include <vector>
 
@@ -59,7 +58,7 @@
 private:
     friend class RenderThread;
 
-    explicit CacheManager(const DisplayInfo& display);
+    explicit CacheManager();
 
 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     void reset(sk_sp<GrContext> grContext);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 93fd0c8..323f622 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -102,13 +102,13 @@
         , mGenerationID(0)
         , mOpaque(!translucent)
         , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
-        , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo())
+        , mJankTracker(&thread.globalProfileData())
         , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos())
         , mContentDrawBounds(0, 0, 0, 0)
         , mRenderPipeline(std::move(renderPipeline)) {
     rootRenderNode->makeRoot();
     mRenderNodes.emplace_back(rootRenderNode);
-    mProfiler.setDensity(DeviceInfo::get()->displayInfo().density);
+    mProfiler.setDensity(DeviceInfo::getDensity());
     setRenderAheadDepth(Properties::defaultRenderAhead);
 }
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index ee1a7ce..a446858 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -179,12 +179,11 @@
     mEglManager = new EglManager();
     mRenderState = new RenderState(*this);
     mVkManager = new VulkanManager();
-    mCacheManager = new CacheManager(DeviceInfo::get()->displayInfo());
+    mCacheManager = new CacheManager();
 }
 
 void RenderThread::setupFrameInterval() {
-    auto& displayInfo = DeviceInfo::get()->displayInfo();
-    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / displayInfo.fps);
+    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / DeviceInfo::getRefreshRate());
     mTimeLord.setFrameInterval(frameIntervalNanos);
     mDispatchFrameDelay = static_cast<nsecs_t>(frameIntervalNanos * .25f);
 }
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5aa1af3..bdd80721 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -29,7 +29,6 @@
 #include <GrContext.h>
 #include <SkBitmap.h>
 #include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
 #include <utils/Looper.h>
 #include <utils/Thread.h>
 
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index 3f1ef93..c83a3c8 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -33,7 +33,8 @@
 }
 
 RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
-    DisplayInfo displayInfo = DeviceInfo::get()->displayInfo();
+    int32_t width = DeviceInfo::get()->getWidth();
+    int32_t height = DeviceInfo::get()->getHeight();
     GrContext* grContext = renderThread.getGrContext();
     ASSERT_TRUE(grContext != nullptr);
 
@@ -42,7 +43,7 @@
     std::vector<sk_sp<SkSurface>> surfaces;
 
     while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
-        SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+        SkImageInfo info = SkImageInfo::MakeA8(width, height);
         sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
         surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
 
@@ -52,8 +53,7 @@
     }
 
     // create an image and pin it so that we have something with a unique key in the cache
-    sk_sp<Bitmap> bitmap =
-            Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
+    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
     sk_sp<SkImage> image = bitmap->makeImage();
     ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));