Properly protect mFrameMetricsReporter

This field actually requires a special lock, mFrameMetricsReporterMutex.
But there isn't a GUARDED_BY annotation for it. And even if there was,
the compiler feature of -Wthread-safety was not active in this code, so
this error would not have been caught.

To fix this, enable the compiler annotation and add GUARDED_BY
annotation to mFrameMetricsReporter.
And finally, use this lock to properly protect this field.

Bug: 192330836
Test: atest hwui_unit_tests
Change-Id: I76950bfa01bbd7ccdc54c4e8c114430b5aeddf1a
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 0a232d6..2c299fa 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -47,6 +47,7 @@
         "-DATRACE_TAG=ATRACE_TAG_VIEW",
         "-DLOG_TAG=\"OpenGLRenderer\"",
         "-Wall",
+        "-Wthread-safety",
         "-Wno-unused-parameter",
         "-Wunreachable-code",
         "-Werror",
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index dd977c3..34e5577 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -99,7 +99,7 @@
     mFrameIntervalLegacy = frameIntervalNanos;
 }
 
-void JankTracker::calculateLegacyJank(FrameInfo& frame) {
+void JankTracker::calculateLegacyJank(FrameInfo& frame) REQUIRES(mDataMutex) {
     // Fast-path for jank-free frames
     int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted);
     if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) {
@@ -257,7 +257,7 @@
     }
 }
 
-void JankTracker::recomputeThresholds(int64_t frameBudget) {
+void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex) {
     if (mThresholdsFrameBudget == frameBudget) {
         return;
     }
@@ -308,7 +308,7 @@
     dprintf(fd, "\n---PROFILEDATA---\n\n");
 }
 
-void JankTracker::reset() {
+void JankTracker::reset() REQUIRES(mDataMutex) {
     mFrames.clear();
     mData->reset();
     (*mGlobalData)->reset();
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 0d2574c..bdb784d 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -62,7 +62,7 @@
     // Calculates the 'legacy' jank information, i.e. with outdated refresh rate information and
     // without GPU completion or deadlined information.
     void calculateLegacyJank(FrameInfo& frame);
-    void dumpStats(int fd) { dumpData(fd, &mDescription, mData.get()); }
+    void dumpStats(int fd) NO_THREAD_SAFETY_ANALYSIS { dumpData(fd, &mDescription, mData.get()); }
     void dumpFrames(int fd);
     void reset();
 
diff --git a/libs/hwui/ProfileDataContainer.cpp b/libs/hwui/ProfileDataContainer.cpp
index 41afc0e..dd78847 100644
--- a/libs/hwui/ProfileDataContainer.cpp
+++ b/libs/hwui/ProfileDataContainer.cpp
@@ -27,7 +27,7 @@
 namespace android {
 namespace uirenderer {
 
-void ProfileDataContainer::freeData() {
+void ProfileDataContainer::freeData() REQUIRES(mJankDataMutex) {
     if (mIsMapped) {
         munmap(mData, sizeof(ProfileData));
     } else {
diff --git a/libs/hwui/ProfileDataContainer.h b/libs/hwui/ProfileDataContainer.h
index a61b8dc..7d1b46c 100644
--- a/libs/hwui/ProfileDataContainer.h
+++ b/libs/hwui/ProfileDataContainer.h
@@ -37,8 +37,9 @@
     void rotateStorage();
     void switchStorageToAshmem(int ashmemfd);
 
-    ProfileData* get() { return mData; }
-    ProfileData* operator->() { return mData; }
+    ProfileData* get() NO_THREAD_SAFETY_ANALYSIS { return mData; }
+
+    ProfileData* operator->() NO_THREAD_SAFETY_ANALYSIS { return mData; }
 
     std::mutex& getDataMutex() { return mJankDataMutex; }
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 81cee61..adea418 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -614,6 +614,7 @@
             mCurrentFrameInfo->markFrameCompleted();
             mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
                     = mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
+            std::scoped_lock lock(mFrameMetricsReporterMutex);
             mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter);
         }
     }
@@ -638,9 +639,12 @@
 }
 
 void CanvasContext::reportMetricsWithPresentTime() {
-    if (mFrameMetricsReporter == nullptr) {
-        return;
-    }
+    {  // acquire lock
+        std::scoped_lock lock(mFrameMetricsReporterMutex);
+        if (mFrameMetricsReporter == nullptr) {
+            return;
+        }
+    }  // release lock
     if (mNativeSurface == nullptr) {
         return;
     }
@@ -665,7 +669,22 @@
             nullptr /*outReleaseTime*/);
 
     forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
-    mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+    {  // acquire lock
+        std::scoped_lock lock(mFrameMetricsReporterMutex);
+        if (mFrameMetricsReporter != nullptr) {
+            mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+        }
+    }  // release lock
+}
+
+FrameInfo* CanvasContext::getFrameInfoFromLast4(uint64_t frameNumber) {
+    std::scoped_lock lock(mLast4FrameInfosMutex);
+    for (size_t i = 0; i < mLast4FrameInfos.size(); i++) {
+        if (mLast4FrameInfos[i].second == frameNumber) {
+            return mLast4FrameInfos[i].first;
+        }
+    }
+    return nullptr;
 }
 
 void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
@@ -679,22 +698,13 @@
     nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);
     uint64_t frameNumber = functions.getFrameNumberFunc(stats);
 
-    FrameInfo* frameInfo = nullptr;
-    {
-        std::lock_guard(instance->mLast4FrameInfosMutex);
-        for (size_t i = 0; i < instance->mLast4FrameInfos.size(); i++) {
-            if (instance->mLast4FrameInfos[i].second == frameNumber) {
-                frameInfo = instance->mLast4FrameInfos[i].first;
-                break;
-            }
-        }
-    }
+    FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber);
 
     if (frameInfo != nullptr) {
         frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
                 frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
         frameInfo->set(FrameInfoIndex::GpuCompleted) = gpuCompleteTime;
-        std::lock_guard(instance->mFrameMetricsReporterMutex);
+        std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
         instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter);
     }
 }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 85af3e4..6dbfcc3 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -160,6 +160,7 @@
     void setContentDrawBounds(const Rect& bounds) { mContentDrawBounds = bounds; }
 
     void addFrameMetricsObserver(FrameMetricsObserver* observer) {
+        std::scoped_lock lock(mFrameMetricsReporterMutex);
         if (mFrameMetricsReporter.get() == nullptr) {
             mFrameMetricsReporter.reset(new FrameMetricsReporter());
         }
@@ -168,10 +169,10 @@
     }
 
     void removeFrameMetricsObserver(FrameMetricsObserver* observer) {
+        std::scoped_lock lock(mFrameMetricsReporterMutex);
         if (mFrameMetricsReporter.get() != nullptr) {
             mFrameMetricsReporter->removeObserver(observer);
             if (!mFrameMetricsReporter->hasObservers()) {
-                std::lock_guard lock(mFrameMetricsReporterMutex);
                 mFrameMetricsReporter.reset(nullptr);
             }
         }
@@ -245,6 +246,8 @@
      */
     void reportMetricsWithPresentTime();
 
+    FrameInfo* getFrameInfoFromLast4(uint64_t frameNumber);
+
     // The same type as Frame.mWidth and Frame.mHeight
     int32_t mLastFrameWidth = 0;
     int32_t mLastFrameHeight = 0;
@@ -305,7 +308,8 @@
     std::string mName;
     JankTracker mJankTracker;
     FrameInfoVisualizer mProfiler;
-    std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
+    std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter
+            GUARDED_BY(mFrameMetricsReporterMutex);
     std::mutex mFrameMetricsReporterMutex;
 
     std::set<RenderNode*> mPrefetchedLayers;