Merge "Add synchronous SurfaceFlinger tracing"
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7b045af..576f0fd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1850,16 +1850,18 @@
 
     bool refreshNeeded;
     {
-        ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+        mTracePostComposition = mTracing.flagIsSet(SurfaceTracing::TRACE_COMPOSITION) ||
+                mTracing.flagIsSet(SurfaceTracing::TRACE_SYNC) ||
+                mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS);
+        const bool tracePreComposition = mTracingEnabled && !mTracePostComposition;
+        ConditionalLockGuard<std::mutex> lock(mTracingLock, tracePreComposition);
 
         mFrameTimeline->setSfWakeUp(vsyncId, frameStart);
 
         refreshNeeded = handleMessageTransaction();
         refreshNeeded |= handleMessageInvalidate();
-        if (mTracingEnabled) {
-            mAddCompositionStateToTrace =
-                    mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
-            if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
+        if (tracePreComposition) {
+            if (mVisibleRegionsDirty) {
                 mTracing.notifyLocked("visibleRegionsDirty");
             }
         }
@@ -2009,12 +2011,15 @@
     modulateVsync(&VsyncModulator::onDisplayRefresh, usedGpuComposition);
 
     mLayersWithQueuedFrames.clear();
-    if (mVisibleRegionsDirty) {
-        mVisibleRegionsDirty = false;
-        if (mTracingEnabled && mAddCompositionStateToTrace) {
+    if (mTracingEnabled && mTracePostComposition) {
+        // This may block if SurfaceTracing is running in sync mode.
+        if (mVisibleRegionsDirty) {
             mTracing.notify("visibleRegionsDirty");
+        } else if (mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS)) {
+            mTracing.notify("bufferLatched");
         }
     }
+    mVisibleRegionsDirty = false;
 
     if (mCompositionEngine->needsAnotherUpdate()) {
         signalLayerUpdate();
@@ -4279,7 +4284,7 @@
 
 status_t SurfaceFlinger::dumpCritical(int fd, const DumpArgs&, bool asProto) {
     if (asProto && mTracing.isEnabled()) {
-        mTracing.writeToFileAsync();
+        mTracing.writeToFile();
     }
 
     return doDump(fd, DumpArgs(), asProto);
@@ -5103,19 +5108,19 @@
             }
             case 1025: { // Set layer tracing
                 n = data.readInt32();
+                bool tracingEnabledChanged;
                 if (n) {
                     ALOGD("LayerTracing enabled");
-                    mTracingEnabledChanged = mTracing.enable();
-                    reply->writeInt32(NO_ERROR);
+                    tracingEnabledChanged = mTracing.enable();
+                    if (tracingEnabledChanged) {
+                        schedule([&]() MAIN_THREAD { mTracing.notify("start"); }).wait();
+                    }
                 } else {
                     ALOGD("LayerTracing disabled");
-                    mTracingEnabledChanged = mTracing.disable();
-                    if (mTracingEnabledChanged) {
-                        reply->writeInt32(mTracing.writeToFile());
-                    } else {
-                        reply->writeInt32(NO_ERROR);
-                    }
+                    tracingEnabledChanged = mTracing.disable();
                 }
+                mTracingEnabledChanged = tracingEnabledChanged;
+                reply->writeInt32(NO_ERROR);
                 return NO_ERROR;
             }
             case 1026: { // Get layer tracing status
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5bb5a0d..9db09f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1134,7 +1134,7 @@
     SurfaceTracing mTracing{*this};
     std::mutex mTracingLock;
     bool mTracingEnabled = false;
-    bool mAddCompositionStateToTrace = false;
+    bool mTracePostComposition = false;
     std::atomic<bool> mTracingEnabledChanged = false;
 
     const std::shared_ptr<TimeStats> mTimeStats;
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index d84ce69..1d1f0c5 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
 #undef LOG_TAG
 #define LOG_TAG "SurfaceTracing"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
@@ -32,65 +29,65 @@
 
 namespace android {
 
-SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
-      : mFlinger(flinger), mSfLock(flinger.mTracingLock) {}
+SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger) : mFlinger(flinger) {}
 
-void SurfaceTracing::mainLoop() {
-    bool enabled = addFirstEntry();
-    while (enabled) {
-        LayersTraceProto entry = traceWhenNotified();
-        enabled = addTraceToBuffer(entry);
-    }
-}
-
-bool SurfaceTracing::addFirstEntry() {
-    LayersTraceProto entry;
-    {
-        std::scoped_lock lock(mSfLock);
-        entry = traceLayersLocked("tracing.enable");
-    }
-    return addTraceToBuffer(entry);
-}
-
-LayersTraceProto SurfaceTracing::traceWhenNotified() {
-    std::unique_lock<std::mutex> lock(mSfLock);
-    mCanStartTrace.wait(lock);
-    android::base::ScopedLockAssertion assumeLock(mSfLock);
-    LayersTraceProto entry = traceLayersLocked(mWhere);
-    mTracingInProgress = false;
-    mMissedTraceEntries = 0;
-    lock.unlock();
-    return entry;
-}
-
-bool SurfaceTracing::addTraceToBuffer(LayersTraceProto& entry) {
+bool SurfaceTracing::enable() {
     std::scoped_lock lock(mTraceLock);
-    mBuffer.emplace(std::move(entry));
-    if (mWriteToFile) {
-        writeProtoFileLocked();
-        mWriteToFile = false;
+    if (mEnabled) {
+        return false;
     }
+
+    if (flagIsSet(TRACE_SYNC)) {
+        runner = std::make_unique<SurfaceTracing::Runner>(mFlinger, mConfig);
+    } else {
+        runner = std::make_unique<SurfaceTracing::AsyncRunner>(mFlinger, mConfig,
+                                                               mFlinger.mTracingLock);
+    }
+    mEnabled = true;
+    return true;
+}
+
+bool SurfaceTracing::disable() {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return false;
+    }
+    mEnabled = false;
+    runner->stop();
+    return true;
+}
+
+bool SurfaceTracing::isEnabled() const {
+    std::scoped_lock lock(mTraceLock);
     return mEnabled;
 }
 
+status_t SurfaceTracing::writeToFile() {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return STATUS_OK;
+    }
+    return runner->writeToFile();
+}
+
 void SurfaceTracing::notify(const char* where) {
-    std::scoped_lock lock(mSfLock);
-    notifyLocked(where);
+    if (mEnabled) {
+        runner->notify(where);
+    }
 }
 
 void SurfaceTracing::notifyLocked(const char* where) {
-    mWhere = where;
-    if (mTracingInProgress) {
-        mMissedTraceEntries++;
+    if (mEnabled) {
+        runner->notifyLocked(where);
     }
-    mTracingInProgress = true;
-    mCanStartTrace.notify_one();
 }
 
-void SurfaceTracing::writeToFileAsync() {
+void SurfaceTracing::dump(std::string& result) const {
     std::scoped_lock lock(mTraceLock);
-    mWriteToFile = true;
-    mCanStartTrace.notify_one();
+    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
+    if (mEnabled) {
+        runner->dump(result);
+    }
 }
 
 void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
@@ -101,12 +98,12 @@
 }
 
 void SurfaceTracing::LayersTraceBuffer::emplace(LayersTraceProto&& proto) {
-    auto protoSize = proto.ByteSize();
+    size_t protoSize = static_cast<size_t>(proto.ByteSize());
     while (mUsedInBytes + protoSize > mSizeInBytes) {
         if (mStorage.empty()) {
             return;
         }
-        mUsedInBytes -= mStorage.front().ByteSize();
+        mUsedInBytes -= static_cast<size_t>(mStorage.front().ByteSize());
         mStorage.pop();
     }
     mUsedInBytes += protoSize;
@@ -115,7 +112,7 @@
 }
 
 void SurfaceTracing::LayersTraceBuffer::flush(LayersTraceFileProto* fileProto) {
-    fileProto->mutable_entry()->Reserve(mStorage.size());
+    fileProto->mutable_entry()->Reserve(static_cast<int>(mStorage.size()));
 
     while (!mStorage.empty()) {
         auto entry = fileProto->add_entry();
@@ -124,85 +121,21 @@
     }
 }
 
-bool SurfaceTracing::enable() {
-    std::scoped_lock lock(mTraceLock);
-
-    if (mEnabled) {
-        return false;
-    }
-
-    mBuffer.reset(mBufferSize);
-    mEnabled = true;
-    mThread = std::thread(&SurfaceTracing::mainLoop, this);
-    return true;
+SurfaceTracing::Runner::Runner(SurfaceFlinger& flinger, SurfaceTracing::Config& config)
+      : mFlinger(flinger), mConfig(config) {
+    mBuffer.setSize(mConfig.bufferSize);
 }
 
-status_t SurfaceTracing::writeToFile() {
-    std::thread thread;
-    {
-        std::scoped_lock lock(mTraceLock);
-        thread = std::move(mThread);
-    }
-    thread.join();
-    return mLastErr;
+void SurfaceTracing::Runner::notify(const char* where) {
+    LayersTraceProto entry = traceLayers(where);
+    mBuffer.emplace(std::move(entry));
 }
 
-bool SurfaceTracing::disable() {
-    std::scoped_lock lock(mTraceLock);
-
-    if (!mEnabled) {
-        return false;
-    }
-
-    mEnabled = false;
-    mWriteToFile = true;
-    mCanStartTrace.notify_all();
-    return true;
+status_t SurfaceTracing::Runner::stop() {
+    return writeToFile();
 }
 
-bool SurfaceTracing::isEnabled() const {
-    std::scoped_lock lock(mTraceLock);
-    return mEnabled;
-}
-
-void SurfaceTracing::setBufferSize(size_t bufferSizeInByte) {
-    std::scoped_lock lock(mTraceLock);
-    mBufferSize = bufferSizeInByte;
-    mBuffer.setSize(bufferSizeInByte);
-}
-
-void SurfaceTracing::setTraceFlags(uint32_t flags) {
-    std::scoped_lock lock(mSfLock);
-    mTraceFlags = flags;
-}
-
-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));
-
-    if (flagIsSetLocked(SurfaceTracing::TRACE_EXTRA)) {
-        mFlinger.dumpOffscreenLayersProto(layers);
-    }
-    entry.mutable_layers()->Swap(&layers);
-
-    if (mTraceFlags & SurfaceTracing::TRACE_HWC) {
-        std::string hwcDump;
-        mFlinger.dumpHwc(hwcDump);
-        entry.set_hwc_blob(hwcDump);
-    }
-    if (!flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION)) {
-        entry.set_excludes_composition_state(true);
-    }
-    entry.set_missed_entries(mMissedTraceEntries);
-
-    return entry;
-}
-
-void SurfaceTracing::writeProtoFileLocked() {
+status_t SurfaceTracing::Runner::writeToFile() {
     ATRACE_CALL();
 
     LayersTraceFileProto fileProto;
@@ -211,33 +144,114 @@
     fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
                                LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
     mBuffer.flush(&fileProto);
-    mBuffer.reset(mBufferSize);
+    mBuffer.reset(mConfig.bufferSize);
 
     if (!fileProto.SerializeToString(&output)) {
         ALOGE("Could not save the proto file! Permission denied");
-        mLastErr = PERMISSION_DENIED;
+        return PERMISSION_DENIED;
     }
 
     // -rw-r--r--
     const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-    if (!android::base::WriteStringToFile(output, kDefaultFileName, mode, getuid(), getgid(),
+    if (!android::base::WriteStringToFile(output, DEFAULT_FILE_NAME, mode, getuid(), getgid(),
                                           true)) {
         ALOGE("Could not save the proto file! There are missing fields");
-        mLastErr = PERMISSION_DENIED;
+        return PERMISSION_DENIED;
     }
 
-    mLastErr = NO_ERROR;
+    return NO_ERROR;
 }
 
-void SurfaceTracing::dump(std::string& result) const {
-    std::scoped_lock lock(mTraceLock);
-    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
+LayersTraceProto SurfaceTracing::Runner::traceLayers(const char* where) {
+    ATRACE_CALL();
+
+    LayersTraceProto entry;
+    entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
+    entry.set_where(where);
+    LayersProto layers(mFlinger.dumpDrawingStateProto(mConfig.flags));
+
+    if (flagIsSet(SurfaceTracing::TRACE_EXTRA)) {
+        mFlinger.dumpOffscreenLayersProto(layers);
+    }
+    entry.mutable_layers()->Swap(&layers);
+
+    if (flagIsSet(SurfaceTracing::TRACE_HWC)) {
+        std::string hwcDump;
+        mFlinger.dumpHwc(hwcDump);
+        entry.set_hwc_blob(hwcDump);
+    }
+    if (!flagIsSet(SurfaceTracing::TRACE_COMPOSITION)) {
+        entry.set_excludes_composition_state(true);
+    }
+    entry.set_missed_entries(mMissedTraceEntries);
+
+    return entry;
+}
+
+void SurfaceTracing::Runner::dump(std::string& result) const {
     base::StringAppendF(&result, "  number of entries: %zu (%.2fMB / %.2fMB)\n",
                         mBuffer.frameCount(), float(mBuffer.used()) / float(1_MB),
                         float(mBuffer.size()) / float(1_MB));
 }
 
-} // namespace android
+SurfaceTracing::AsyncRunner::AsyncRunner(SurfaceFlinger& flinger, SurfaceTracing::Config& config,
+                                         std::mutex& sfLock)
+      : SurfaceTracing::Runner(flinger, config), mSfLock(sfLock) {
+    mEnabled = true;
+    mThread = std::thread(&AsyncRunner::loop, this);
+}
 
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
+void SurfaceTracing::AsyncRunner::loop() {
+    while (mEnabled) {
+        LayersTraceProto entry;
+        bool entryAdded = traceWhenNotified(&entry);
+        if (entryAdded) {
+            mBuffer.emplace(std::move(entry));
+        }
+        if (mWriteToFile) {
+            Runner::writeToFile();
+            mWriteToFile = false;
+        }
+    }
+}
+
+bool SurfaceTracing::AsyncRunner::traceWhenNotified(LayersTraceProto* outProto) {
+    std::unique_lock<std::mutex> lock(mSfLock);
+    mCanStartTrace.wait(lock);
+    if (!mAddEntry) {
+        return false;
+    }
+    *outProto = traceLayers(mWhere);
+    mAddEntry = false;
+    mMissedTraceEntries = 0;
+    return true;
+}
+
+void SurfaceTracing::AsyncRunner::notify(const char* where) {
+    std::scoped_lock lock(mSfLock);
+    notifyLocked(where);
+}
+
+void SurfaceTracing::AsyncRunner::notifyLocked(const char* where) {
+    mWhere = where;
+    if (mAddEntry) {
+        mMissedTraceEntries++;
+    }
+    mAddEntry = true;
+    mCanStartTrace.notify_one();
+}
+
+status_t SurfaceTracing::AsyncRunner::writeToFile() {
+    mWriteToFile = true;
+    mCanStartTrace.notify_one();
+    return STATUS_OK;
+}
+
+status_t SurfaceTracing::AsyncRunner::stop() {
+    mEnabled = false;
+    mCanStartTrace.notify_one();
+    mThread.join();
+    return Runner::writeToFile();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index f208eb8..576bba7 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -32,25 +32,31 @@
 namespace android {
 
 class SurfaceFlinger;
-
 constexpr auto operator""_MB(unsigned long long const num) {
     return num * 1024 * 1024;
 }
 /*
- * SurfaceTracing records layer states during surface flinging.
+ * SurfaceTracing records layer states during surface flinging. Manages tracing state and
+ * configuration.
  */
 class SurfaceTracing {
 public:
-    explicit SurfaceTracing(SurfaceFlinger& flinger);
+    SurfaceTracing(SurfaceFlinger& flinger);
     bool enable();
     bool disable();
     status_t writeToFile();
     bool isEnabled() const;
+    /*
+     * Adds a trace entry, must be called from the drawing thread or while holding the
+     * SurfaceFlinger tracing lock.
+     */
     void notify(const char* where);
-    void notifyLocked(const char* where) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */;
+    /*
+     * Adds a trace entry, called while holding the SurfaceFlinger tracing lock.
+     */
+    void notifyLocked(const char* where) /* REQUIRES(mSfLock) */;
 
-    void setBufferSize(size_t bufferSizeInByte);
-    void writeToFileAsync();
+    void setBufferSize(size_t bufferSizeInBytes) { mConfig.bufferSize = bufferSizeInBytes; }
     void dump(std::string& result) const;
 
     enum : uint32_t {
@@ -59,18 +65,34 @@
         TRACE_COMPOSITION = 1 << 2,
         TRACE_EXTRA = 1 << 3,
         TRACE_HWC = 1 << 4,
-        TRACE_ALL = 0xffffffff
+        // Add non-geometry composition changes to the trace.
+        TRACE_BUFFERS = 1 << 5,
+        // Add entries from the drawing thread post composition.
+        TRACE_SYNC = 1 << 6,
+        TRACE_ALL = TRACE_CRITICAL | TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,
     };
-    void setTraceFlags(uint32_t flags);
-    bool flagIsSetLocked(uint32_t flags) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */ {
-        return (mTraceFlags & flags) == flags;
-    }
+    void setTraceFlags(uint32_t flags) { mConfig.flags = flags; }
+    bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
 
 private:
-    static constexpr auto kDefaultBufferCapInByte = 5_MB;
-    static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
+    class Runner;
+    static constexpr auto DEFAULT_BUFFER_SIZE = 5_MB;
+    static constexpr auto DEFAULT_FILE_NAME = "/data/misc/wmtrace/layers_trace.pb";
 
-    class LayersTraceBuffer { // ring buffer
+    SurfaceFlinger& mFlinger;
+    mutable std::mutex mTraceLock;
+    bool mEnabled = false;
+    std::unique_ptr<Runner> runner;
+
+    struct Config {
+        uint32_t flags = TRACE_CRITICAL | TRACE_INPUT;
+        size_t bufferSize = DEFAULT_BUFFER_SIZE;
+    } mConfig;
+
+    /*
+     * ring buffer.
+     */
+    class LayersTraceBuffer {
     public:
         size_t size() const { return mSizeInBytes; }
         size_t used() const { return mUsedInBytes; }
@@ -83,35 +105,59 @@
 
     private:
         size_t mUsedInBytes = 0U;
-        size_t mSizeInBytes = 0U;
+        size_t mSizeInBytes = DEFAULT_BUFFER_SIZE;
         std::queue<LayersTraceProto> mStorage;
     };
 
-    void mainLoop();
-    bool addFirstEntry();
-    LayersTraceProto traceWhenNotified();
-    LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
+    /*
+     * Implements a synchronous way of adding trace entries. This must be called
+     * from the drawing thread.
+     */
+    class Runner {
+    public:
+        Runner(SurfaceFlinger& flinger, SurfaceTracing::Config& config);
+        virtual ~Runner() = default;
+        virtual status_t stop();
+        virtual status_t writeToFile();
+        virtual void notify(const char* where);
+        /* Cannot be called with a synchronous runner. */
+        virtual void notifyLocked(const char* /* where */) {}
+        void dump(std::string& result) const;
 
-    // Returns true if trace is enabled.
-    bool addTraceToBuffer(LayersTraceProto& entry);
-    void writeProtoFileLocked() REQUIRES(mTraceLock);
+    protected:
+        bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
+        SurfaceFlinger& mFlinger;
+        SurfaceTracing::Config mConfig;
+        SurfaceTracing::LayersTraceBuffer mBuffer;
+        uint32_t mMissedTraceEntries = 0;
+        LayersTraceProto traceLayers(const char* where);
+    };
 
-    SurfaceFlinger& mFlinger;
-    status_t mLastErr = NO_ERROR;
-    std::thread mThread;
-    std::condition_variable mCanStartTrace;
+    /*
+     * Implements asynchronous way to add trace entries called from a separate thread while holding
+     * the SurfaceFlinger tracing lock. Trace entries may be missed if the tracing thread is not
+     * scheduled in time.
+     */
+    class AsyncRunner : public Runner {
+    public:
+        AsyncRunner(SurfaceFlinger& flinger, SurfaceTracing::Config& config, std::mutex& sfLock);
+        virtual ~AsyncRunner() = default;
+        status_t stop() override;
+        status_t writeToFile() override;
+        void notify(const char* where) override;
+        void notifyLocked(const char* where);
 
-    std::mutex& mSfLock;
-    uint32_t mTraceFlags GUARDED_BY(mSfLock) = TRACE_CRITICAL | TRACE_INPUT;
-    const char* mWhere GUARDED_BY(mSfLock) = "";
-    uint32_t mMissedTraceEntries GUARDED_BY(mSfLock) = 0;
-    bool mTracingInProgress GUARDED_BY(mSfLock) = false;
-
-    mutable std::mutex mTraceLock;
-    LayersTraceBuffer mBuffer GUARDED_BY(mTraceLock);
-    size_t mBufferSize GUARDED_BY(mTraceLock) = kDefaultBufferCapInByte;
-    bool mEnabled GUARDED_BY(mTraceLock) = false;
-    bool mWriteToFile GUARDED_BY(mTraceLock) = false;
+    private:
+        std::mutex& mSfLock;
+        std::condition_variable mCanStartTrace;
+        std::thread mThread;
+        const char* mWhere = "";
+        bool mWriteToFile = false;
+        bool mEnabled = false;
+        bool mAddEntry = false;
+        void loop();
+        bool traceWhenNotified(LayersTraceProto* outProto);
+    };
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto
index acf621e..990f3cf 100644
--- a/services/surfaceflinger/layerproto/layerstrace.proto
+++ b/services/surfaceflinger/layerproto/layerstrace.proto
@@ -42,7 +42,7 @@
 /* one window manager trace entry. */
 message LayersTraceProto {
     /* required: elapsed realtime in nanos since boot of when this entry was logged */
-    optional fixed64 elapsed_realtime_nanos = 1;
+    optional sfixed64 elapsed_realtime_nanos = 1;
 
     /* where the trace originated */
     optional string where = 2;
@@ -56,5 +56,5 @@
     optional bool excludes_composition_state = 5;
 
     /* Number of missed entries since the last entry was recorded. */
-    optional int32 missed_entries = 6;
+    optional uint32 missed_entries = 6;
 }