Merge "Expose gl/hwc switch counts from timestats." into rvc-dev
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5ee6a9f..2944ac5 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -262,6 +262,17 @@
   return "";
 }
 
+static std::string MapPropertyToArgWithBackup(const std::string& property,
+                                              const std::string& backupProperty,
+                                              const std::string& format,
+                                              const std::string& default_value = "") {
+  std::string value = GetProperty(property, default_value);
+  if (!value.empty()) {
+    return StringPrintf(format.c_str(), value.c_str());
+  }
+  return MapPropertyToArg(backupProperty, format, default_value);
+}
+
 // Determines which binary we should use for execution (the debug or non-debug version).
 // e.g. dex2oatd vs dex2oat
 static const char* select_execution_binary(const char* binary, const char* debug_binary,
@@ -321,6 +332,7 @@
                const char* compiler_filter,
                bool debuggable,
                bool post_bootcomplete,
+               bool for_restore,
                bool background_job_compile,
                int profile_fd,
                const char* class_loader_context,
@@ -336,14 +348,24 @@
         std::string dex2oat_Xms_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xms", "-Xms%s");
         std::string dex2oat_Xmx_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xmx", "-Xmx%s");
 
-        const char* threads_property = post_bootcomplete
-                ? "dalvik.vm.dex2oat-threads"
-                : "dalvik.vm.boot-dex2oat-threads";
-        std::string dex2oat_threads_arg = MapPropertyToArg(threads_property, "-j%s");
-        const char* cpu_set_property = post_bootcomplete
-                ? "dalvik.vm.dex2oat-cpu-set"
-                : "dalvik.vm.boot-dex2oat-cpu-set";
-        std::string dex2oat_cpu_set_arg = MapPropertyToArg(cpu_set_property, "--cpu-set=%s");
+        std::string threads_format = "-j%s";
+        std::string dex2oat_threads_arg = post_bootcomplete
+                ? (for_restore
+                    ? MapPropertyToArgWithBackup(
+                            "dalvik.vm.restore-dex2oat-threads",
+                            "dalvik.vm.dex2oat-threads",
+                            threads_format)
+                    : MapPropertyToArg("dalvik.vm.dex2oat-threads", threads_format))
+                : MapPropertyToArg("dalvik.vm.boot-dex2oat-threads", threads_format);
+        std::string cpu_set_format = "--cpu-set=%s";
+        std::string dex2oat_cpu_set_arg = post_bootcomplete
+                ? (for_restore
+                    ? MapPropertyToArgWithBackup(
+                            "dalvik.vm.restore-dex2oat-cpu-set",
+                            "dalvik.vm.dex2oat-cpu-set",
+                            cpu_set_format)
+                    : MapPropertyToArg("dalvik.vm.dex2oat-cpu-set", cpu_set_format))
+                : MapPropertyToArg("dalvik.vm.boot-dex2oat-cpu-set", cpu_set_format);
 
         std::string bootclasspath;
         char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH");
@@ -2075,6 +2097,7 @@
     bool enable_hidden_api_checks = (dexopt_flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) != 0;
     bool generate_compact_dex = (dexopt_flags & DEXOPT_GENERATE_COMPACT_DEX) != 0;
     bool generate_app_image = (dexopt_flags & DEXOPT_GENERATE_APP_IMAGE) != 0;
+    bool for_restore = (dexopt_flags & DEXOPT_FOR_RESTORE) != 0;
 
     // Check if we're dealing with a secondary dex file and if we need to compile it.
     std::string oat_dir_str;
@@ -2191,6 +2214,7 @@
                       compiler_filter,
                       debuggable,
                       boot_complete,
+                      for_restore,
                       background_job_compile,
                       reference_profile_fd.get(),
                       class_loader_context,
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index c928631..b5ee481 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -55,6 +55,7 @@
 constexpr int DEXOPT_ENABLE_HIDDEN_API_CHECKS = 1 << 10;
 constexpr int DEXOPT_GENERATE_COMPACT_DEX = 1 << 11;
 constexpr int DEXOPT_GENERATE_APP_IMAGE = 1 << 12;
+constexpr int DEXOPT_FOR_RESTORE = 1 << 13; // TODO(b/135202722): remove
 
 /* all known values for dexopt flags */
 constexpr int DEXOPT_MASK =
@@ -69,7 +70,8 @@
     | DEXOPT_IDLE_BACKGROUND_JOB
     | DEXOPT_ENABLE_HIDDEN_API_CHECKS
     | DEXOPT_GENERATE_COMPACT_DEX
-    | DEXOPT_GENERATE_APP_IMAGE;
+    | DEXOPT_GENERATE_APP_IMAGE
+    | DEXOPT_FOR_RESTORE;
 
 // NOTE: keep in sync with StorageManager
 constexpr int FLAG_STORAGE_DE = 1 << 0;
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index d773790..18f8268 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -83,7 +83,7 @@
 static_assert(DEXOPT_GENERATE_COMPACT_DEX == 1 << 11, "DEXOPT_GENERATE_COMPACT_DEX unexpected");
 static_assert(DEXOPT_GENERATE_APP_IMAGE == 1 << 12, "DEXOPT_GENERATE_APP_IMAGE unexpected");
 
-static_assert(DEXOPT_MASK           == (0x1dfe | DEXOPT_IDLE_BACKGROUND_JOB),
+static_assert(DEXOPT_MASK           == (0x3dfe | DEXOPT_IDLE_BACKGROUND_JOB),
               "DEXOPT_MASK unexpected.");
 
 
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 69fefa1..1435456 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -653,6 +653,15 @@
                         DEX2OAT_FROM_SCRATCH);
 }
 
+TEST_F(DexoptTest, DexoptPrimaryPublicRestore) {
+    LOG(INFO) << "DexoptPrimaryPublicRestore";
+    CompilePrimaryDexOk("verify",
+                        DEXOPT_FOR_RESTORE | DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+                        app_oat_dir_.c_str(),
+                        kTestAppGid,
+                        DEX2OAT_FROM_SCRATCH);
+}
+
 TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
     LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
     binder::Status status;
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h
index c44db51..edaf8f5 100644
--- a/include/input/InputWindow.h
+++ b/include/input/InputWindow.h
@@ -123,17 +123,17 @@
     // input windows that have the same token.
     sp<IBinder> token;
     // This uniquely identifies the input window.
-    int32_t id = 0;
+    int32_t id = -1;
     std::string name;
-    int32_t layoutParamsFlags;
-    int32_t layoutParamsType;
-    nsecs_t dispatchingTimeout;
+    int32_t layoutParamsFlags = 0;
+    int32_t layoutParamsType = 0;
+    nsecs_t dispatchingTimeout = -1;
 
     /* These values are filled in by SurfaceFlinger. */
-    int32_t frameLeft;
-    int32_t frameTop;
-    int32_t frameRight;
-    int32_t frameBottom;
+    int32_t frameLeft = -1;
+    int32_t frameTop = -1;
+    int32_t frameRight = -1;
+    int32_t frameBottom = -1;
 
     /*
      * SurfaceFlinger consumes this value to shrink the computed frame. This is
@@ -145,7 +145,7 @@
 
     // A global scaling factor for all windows. Unlike windowScaleX/Y this results
     // in scaling of the TOUCH_MAJOR/TOUCH_MINOR axis.
-    float globalScaleFactor;
+    float globalScaleFactor = 1.0f;
 
     // Scaling factors applied to individual windows.
     float windowXScale = 1.0f;
@@ -156,18 +156,18 @@
      * to absolute coordinates by SurfaceFlinger once the frame is computed.
      */
     Region touchableRegion;
-    bool visible;
-    bool canReceiveKeys;
-    bool hasFocus;
-    bool hasWallpaper;
-    bool paused;
-    int32_t ownerPid;
-    int32_t ownerUid;
-    int32_t inputFeatures;
-    int32_t displayId;
+    bool visible = false;
+    bool canReceiveKeys = false;
+    bool hasFocus = false;
+    bool hasWallpaper = false;
+    bool paused = false;
+    int32_t ownerPid = -1;
+    int32_t ownerUid = -1;
+    int32_t inputFeatures = 0;
+    int32_t displayId = ADISPLAY_ID_NONE;
     int32_t portalToDisplayId = ADISPLAY_ID_NONE;
     InputApplicationInfo applicationInfo;
-    bool replaceTouchableRegionWithCrop;
+    bool replaceTouchableRegionWithCrop = false;
     wp<IBinder> touchableRegionCropHandle;
 
     void addTouchableRegion(const Rect& region);
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index a87ccd6..d929a59 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -722,5 +722,8 @@
     ASSERT_EQ(2, events->frameNumber);
     ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
     ASSERT_GE(events->postedTime, postedTimeB);
+
+    // wait for any callbacks that have not been received
+    adapter.waitForCallbacks();
 }
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 82fb99e..3264642 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -169,19 +169,22 @@
 
 #pragma clang diagnostic pop
 
-class ConditionalLock {
-public:
-    ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) {
-        if (lock) {
-            mMutex.lock();
-        }
+template <typename Mutex>
+struct ConditionalLockGuard {
+    ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) {
+        if (lock) mutex.lock();
     }
-    ~ConditionalLock() { if (mLocked) mMutex.unlock(); }
-private:
-    Mutex& mMutex;
-    bool mLocked;
+
+    ~ConditionalLockGuard() {
+        if (lock) mutex.unlock();
+    }
+
+    Mutex& mutex;
+    const bool lock;
 };
 
+using ConditionalLock = ConditionalLockGuard<Mutex>;
+
 // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity.
 constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV / 160.f;
 
@@ -1953,8 +1956,15 @@
             // potentially trigger a display handoff.
             updateVrFlinger();
 
+            if (mTracingEnabledChanged) {
+                mTracingEnabled = mTracing.isEnabled();
+                mTracingEnabledChanged = false;
+            }
+
             bool refreshNeeded;
-            withTracingLock([&]() {
+            {
+                ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
                 refreshNeeded = handleMessageTransaction();
                 refreshNeeded |= handleMessageInvalidate();
                 if (mTracingEnabled) {
@@ -1964,7 +1974,7 @@
                         mTracing.notifyLocked("visibleRegionsDirty");
                     }
                 }
-            });
+            }
 
             // Layers need to get updated (in the previous line) before we can use them for
             // choosing the refresh rate.
@@ -3044,26 +3054,6 @@
     mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
 }
 
-void SurfaceFlinger::withTracingLock(std::function<void()> lockedOperation) {
-    if (mTracingEnabledChanged) {
-        mTracingEnabled = mTracing.isEnabled();
-        mTracingEnabledChanged = false;
-    }
-
-    // Synchronize with Tracing thread
-    std::unique_lock<std::mutex> lock;
-    if (mTracingEnabled) {
-        lock = std::unique_lock<std::mutex>(mDrawingStateLock);
-    }
-
-    lockedOperation();
-
-    // Synchronize with Tracing thread
-    if (mTracingEnabled) {
-        lock.unlock();
-    }
-}
-
 void SurfaceFlinger::commitOffscreenLayers() {
     for (Layer* offscreenLayer : mOffscreenLayers) {
         offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) {
@@ -4570,11 +4560,13 @@
     result.append("\n");
 }
 
-LayersProto SurfaceFlinger::dumpDrawingStateProto(
-        uint32_t traceFlags, const sp<const DisplayDevice>& displayDevice) const {
+LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
+    // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread.
+    const auto display = getDefaultDisplayDeviceLocked();
+
     LayersProto layersProto;
     for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
-        layer->writeToProto(layersProto, traceFlags, displayDevice);
+        layer->writeToProto(layersProto, traceFlags, display);
     }
 
     return layersProto;
@@ -4606,10 +4598,7 @@
 
 LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
     LayersProto layersProto;
-    postMessageSync(new LambdaMessage([&]() {
-        const auto& displayDevice = getDefaultDisplayDeviceLocked();
-        layersProto = dumpDrawingStateProto(traceFlags, displayDevice);
-    }));
+    postMessageSync(new LambdaMessage([&] { layersProto = dumpDrawingStateProto(traceFlags); }));
     return layersProto;
 }
 
@@ -5136,20 +5125,12 @@
                 n = data.readInt32();
                 if (n) {
                     ALOGD("LayerTracing enabled");
-                    Mutex::Autolock lock(mStateLock);
-                    mTracingEnabledChanged = true;
-                    mTracing.enable();
+                    mTracingEnabledChanged = mTracing.enable();
                     reply->writeInt32(NO_ERROR);
                 } else {
                     ALOGD("LayerTracing disabled");
-                    bool writeFile = false;
-                    {
-                        Mutex::Autolock lock(mStateLock);
-                        mTracingEnabledChanged = true;
-                        writeFile = mTracing.disable();
-                    }
-
-                    if (writeFile) {
+                    mTracingEnabledChanged = mTracing.disable();
+                    if (mTracingEnabledChanged) {
                         reply->writeInt32(mTracing.writeToFile());
                     } else {
                         reply->writeInt32(NO_ERROR);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f3c481a..eb0afc8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -929,8 +929,7 @@
     void dumpDisplayIdentificationData(std::string& result) const;
     void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
     void dumpWideColorInfo(std::string& result) const;
-    LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL,
-                                      const sp<const DisplayDevice>& displayDevice = nullptr) const;
+    LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
     void dumpOffscreenLayersProto(LayersProto& layersProto,
                                   uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
     // Dumps state from HW Composer
@@ -938,7 +937,6 @@
     LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
             EXCLUDES(mStateLock);
     void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
-    void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
 
     bool isLayerTripleBufferingDisabled() const {
         return this->mLayerTripleBufferingDisabled;
@@ -980,9 +978,6 @@
     SortedVector<sp<Layer>> mLayersPendingRemoval;
     bool mTraversalNeededMainThread = false;
 
-    // guards access to the mDrawing state if tracing is enabled.
-    mutable std::mutex mDrawingStateLock;
-
     // global color transform states
     Daltonizer mDaltonizer;
     float mGlobalSaturationFactor = 1.0f;
@@ -1057,10 +1052,13 @@
     bool mPropagateBackpressure = true;
     bool mPropagateBackpressureClientComposition = false;
     std::unique_ptr<SurfaceInterceptor> mInterceptor;
+
     SurfaceTracing mTracing{*this};
+    std::mutex mTracingLock;
     bool mTracingEnabled = false;
     bool mAddCompositionStateToTrace = false;
-    bool mTracingEnabledChanged GUARDED_BY(mStateLock) = false;
+    std::atomic<bool> mTracingEnabledChanged = false;
+
     const std::shared_ptr<TimeStats> mTimeStats;
     const std::unique_ptr<FrameTracer> mFrameTracer;
     bool mUseHwcVirtualDisplays = false;
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index f0b895d..d84ce69 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -33,7 +33,7 @@
 namespace android {
 
 SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
-      : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
+      : mFlinger(flinger), mSfLock(flinger.mTracingLock) {}
 
 void SurfaceTracing::mainLoop() {
     bool enabled = addFirstEntry();
@@ -44,21 +44,19 @@
 }
 
 bool SurfaceTracing::addFirstEntry() {
-    const auto displayDevice = mFlinger.getDefaultDisplayDevice();
     LayersTraceProto entry;
     {
         std::scoped_lock lock(mSfLock);
-        entry = traceLayersLocked("tracing.enable", displayDevice);
+        entry = traceLayersLocked("tracing.enable");
     }
     return addTraceToBuffer(entry);
 }
 
 LayersTraceProto SurfaceTracing::traceWhenNotified() {
-    const auto displayDevice = mFlinger.getDefaultDisplayDevice();
     std::unique_lock<std::mutex> lock(mSfLock);
     mCanStartTrace.wait(lock);
     android::base::ScopedLockAssertion assumeLock(mSfLock);
-    LayersTraceProto entry = traceLayersLocked(mWhere, displayDevice);
+    LayersTraceProto entry = traceLayersLocked(mWhere);
     mTracingInProgress = false;
     mMissedTraceEntries = 0;
     lock.unlock();
@@ -126,15 +124,17 @@
     }
 }
 
-void SurfaceTracing::enable() {
+bool SurfaceTracing::enable() {
     std::scoped_lock lock(mTraceLock);
 
     if (mEnabled) {
-        return;
+        return false;
     }
+
     mBuffer.reset(mBufferSize);
     mEnabled = true;
     mThread = std::thread(&SurfaceTracing::mainLoop, this);
+    return true;
 }
 
 status_t SurfaceTracing::writeToFile() {
@@ -176,14 +176,13 @@
     mTraceFlags = flags;
 }
 
-LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where,
-                                                   const sp<const DisplayDevice>& displayDevice) {
+LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
     ATRACE_CALL();
 
     LayersTraceProto entry;
     entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry.set_where(where);
-    LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags, displayDevice));
+    LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
 
     if (flagIsSetLocked(SurfaceTracing::TRACE_EXTRA)) {
         mFlinger.dumpOffscreenLayersProto(layers);
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index e90fc4d..f208eb8 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -27,8 +27,6 @@
 #include <queue>
 #include <thread>
 
-#include "DisplayDevice.h"
-
 using namespace android::surfaceflinger;
 
 namespace android {
@@ -44,7 +42,7 @@
 class SurfaceTracing {
 public:
     explicit SurfaceTracing(SurfaceFlinger& flinger);
-    void enable();
+    bool enable();
     bool disable();
     status_t writeToFile();
     bool isEnabled() const;
@@ -92,9 +90,7 @@
     void mainLoop();
     bool addFirstEntry();
     LayersTraceProto traceWhenNotified();
-    LayersTraceProto traceLayersLocked(const char* where,
-                                       const sp<const DisplayDevice>& displayDevice)
-            REQUIRES(mSfLock);
+    LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
 
     // Returns true if trace is enabled.
     bool addTraceToBuffer(LayersTraceProto& entry);