Merge "SF: Remove static screen stats"
diff --git a/Android.bp b/Android.bp
index dec6716..615a7a8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -64,14 +64,20 @@
     name: "framework_native_aidl_binder",
     srcs: ["aidl/binder/**/*.aidl"],
     path: "aidl/binder",
-    visibility: ["//frameworks/native"],
+    visibility: [
+        "//frameworks/native",
+        "//frameworks/native/libs/gui",
+    ],
 }
 
 filegroup {
     name: "framework_native_aidl_gui",
     srcs: ["aidl/gui/**/*.aidl"],
     path: "aidl/gui",
-    visibility: ["//frameworks/native"],
+    visibility: [
+        "//frameworks/native",
+        "//frameworks/native/libs/gui",
+    ],
 }
 
 filegroup {
@@ -82,7 +88,7 @@
     ],
 }
 
-cc_library_headers{
+cc_library_headers {
     name: "libandroid_headers_private",
     export_include_dirs: ["include/private"],
 }
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 862fc2a..254efae 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -133,6 +133,14 @@
     }
 }
 
+fn interface_cast<T: FromIBinder + ?Sized>(service: Option<SpIBinder>) -> Result<Strong<T>> {
+    if let Some(service) = service {
+        FromIBinder::try_from(service)
+    } else {
+        Err(StatusCode::NAME_NOT_FOUND)
+    }
+}
+
 pub mod unstable_api {
     use super::{sys, SpIBinder};
 
@@ -780,21 +788,13 @@
 /// Retrieve an existing service for a particular interface, blocking for a few
 /// seconds if it doesn't yet exist.
 pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
-    let service = get_service(name);
-    match service {
-        Some(service) => FromIBinder::try_from(service),
-        None => Err(StatusCode::NAME_NOT_FOUND),
-    }
+    interface_cast(get_service(name))
 }
 
 /// Retrieve an existing service for a particular interface, or start it if it
 /// is configured as a dynamic service and isn't yet started.
 pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
-    let service = wait_for_service(name);
-    match service {
-        Some(service) => FromIBinder::try_from(service),
-        None => Err(StatusCode::NAME_NOT_FOUND),
-    }
+    interface_cast(wait_for_service(name))
 }
 
 /// Check if a service is declared (e.g. in a VINTF manifest)
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index d7bc500..e138212 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -184,7 +184,8 @@
     ],
 
     srcs: [
-        ":framework_native_aidl",
+        ":framework_native_aidl_binder",
+        ":framework_native_aidl_gui",
         ":inputconstants_aidl",
         ":libgui_bufferqueue_sources",
 
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index 45c958e..31bf895 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -2,9 +2,8 @@
 alecmouri@google.com
 chaviw@google.com
 chrisforbes@google.com
-jessehall@google.com
 lpy@google.com
-mathias@google.com
+jreck@google.com
 racarr@google.com
 vishnun@google.com
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index c793523..d16ddb9 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1269,6 +1269,12 @@
         mStatus = BAD_INDEX;
         return *this;
     }
+    if (alpha < 0.0f || alpha > 1.0f) {
+        ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f", alpha);
+        mStatus = BAD_VALUE;
+        return *this;
+
+    }
     s->what |= layer_state_t::eAlphaChanged;
     s->alpha = alpha;
 
diff --git a/libs/gui/include/gui/JankInfo.h b/libs/gui/include/gui/JankInfo.h
index ce9716f..1dddeba 100644
--- a/libs/gui/include/gui/JankInfo.h
+++ b/libs/gui/include/gui/JankInfo.h
@@ -24,9 +24,9 @@
     None = 0x0,
     // Jank that occurs in the layers below SurfaceFlinger
     DisplayHAL = 0x1,
-    // SF took too long on the CPU
+    // SF took too long on the CPU; deadline missed during HWC
     SurfaceFlingerCpuDeadlineMissed = 0x2,
-    // SF took too long on the GPU
+    // SF took too long on the GPU; deadline missed during GPU composition
     SurfaceFlingerGpuDeadlineMissed = 0x4,
     // Either App or GPU took too long on the frame
     AppDeadlineMissed = 0x8,
diff --git a/libs/sensor/fuzz/sensor_fuzzer/Android.bp b/libs/sensor/fuzz/sensor_fuzzer/Android.bp
new file mode 100644
index 0000000..cb17484
--- /dev/null
+++ b/libs/sensor/fuzz/sensor_fuzzer/Android.bp
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+cc_fuzz {
+    name: "sensor_fuzzer",
+    srcs: [
+        "sensor_fuzzer.cpp",
+    ],
+    shared_libs: [
+        "libsensor",
+        "libbinder",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libhardware",
+        "libpermission",
+    ],
+    export_shared_lib_headers: [
+        "libbinder",
+        "libpermission",
+        "libhardware",
+    ],
+}
diff --git a/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp b/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp
new file mode 100644
index 0000000..129f430
--- /dev/null
+++ b/libs/sensor/fuzz/sensor_fuzzer/sensor_fuzzer.cpp
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <sensor/Sensor.h>
+using namespace android;
+
+const int MAX_STR_LEN = 32;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+    struct sensor_t sensor_type;
+    sensor_type.name = fdp.ConsumeBytesAsString(MAX_STR_LEN).c_str();
+    sensor_type.vendor = fdp.ConsumeBytesAsString(MAX_STR_LEN).c_str();
+    sensor_type.stringType = "";
+    sensor_type.requiredPermission = "";
+    sensor_type.version = fdp.ConsumeIntegral<int>();
+    sensor_type.handle = fdp.ConsumeIntegral<int>();
+    sensor_type.type = fdp.ConsumeIntegral<int>();
+    sensor_type.maxRange = fdp.ConsumeFloatingPoint<float>();
+    sensor_type.resolution = fdp.ConsumeFloatingPoint<float>();
+    sensor_type.power = fdp.ConsumeFloatingPoint<float>();
+    sensor_type.minDelay = fdp.ConsumeIntegral<int32_t>();
+    sensor_type.fifoReservedEventCount = fdp.ConsumeIntegral<uint32_t>();
+    sensor_type.fifoMaxEventCount = fdp.ConsumeIntegral<uint32_t>();
+    int halVersion = fdp.ConsumeIntegral<int>();
+    Sensor sensor1(&sensor_type, halVersion);
+    uint8_t buffer[size];
+    for (int i = 0; i < size; i++) buffer[i] = data[i];
+    sensor1.flatten(buffer, size);
+    std::vector<uint8_t> buffer1(sensor1.getFlattenedSize());
+    auto ab = sensor1.unflatten(buffer1.data(), buffer1.size());
+    return 0;
+}
+
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index 8c164ed..c8bd5e4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -55,7 +55,8 @@
     MOCK_METHOD(void, setRequiresClientComposition,
                 (DisplayId displayId, bool requiresClientComposition), (override));
     MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
-    MOCK_METHOD(void, setPresentFenceTime, (nsecs_t presentFenceTime), (override));
+    MOCK_METHOD(void, setSfPresentTiming, (nsecs_t presentFenceTime, nsecs_t presentEndTime),
+                (override));
     MOCK_METHOD(void, setHwcPresentDelayedTime,
                 (DisplayId displayId,
                  std::chrono::steady_clock::time_point earliestFrameStartTime));
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 62078ba..929f9dc 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -315,7 +315,8 @@
     mExpectedPresentTimes.append(expectedPresentTime);
 }
 
-void PowerAdvisor::setPresentFenceTime(nsecs_t presentFenceTime) {
+void PowerAdvisor::setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) {
+    mLastSfPresentEndTime = presentEndTime;
     mLastPresentFenceTime = presentFenceTime;
 }
 
@@ -334,13 +335,7 @@
 }
 
 void PowerAdvisor::setCompositeEnd(nsecs_t compositeEnd) {
-    mLastCompositeEndTime = compositeEnd;
-    // calculate the postcomp time here as well
-    std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::hwcPresentEndTime);
-    DisplayTimingData& timingData = mDisplayTimingData[displays.back()];
-    mLastPostcompDuration = compositeEnd -
-            (timingData.skippedValidate ? *timingData.hwcValidateEndTime
-                                        : *timingData.hwcPresentEndTime);
+    mLastPostcompDuration = compositeEnd - mLastSfPresentEndTime;
 }
 
 void PowerAdvisor::setDisplays(std::vector<DisplayId>& displayIds) {
@@ -399,7 +394,7 @@
             getOrderedDisplayIds(&DisplayTimingData::hwcPresentStartTime);
     DisplayTimeline referenceTiming, estimatedTiming;
 
-    // Iterate over the displays in the same order they are presented
+    // Iterate over the displays that use hwc in the same order they are presented
     for (DisplayId displayId : displayIds) {
         if (mDisplayTimingData.count(displayId) == 0) {
             continue;
@@ -451,8 +446,11 @@
     }
     ATRACE_INT64("Idle duration", idleDuration);
 
+    nsecs_t estimatedFlingerEndTime = earlyHint ? estimatedEndTime : mLastSfPresentEndTime;
+
     // Don't count time spent idly waiting in the estimate as we could do more work in that time
     estimatedEndTime -= idleDuration;
+    estimatedFlingerEndTime -= idleDuration;
 
     // We finish the frame when both present and the gpu are done, so wait for the later of the two
     // Also add the frame delay duration since the target did not move while we were delayed
@@ -460,7 +458,10 @@
             std::max(estimatedEndTime, estimatedGpuEndTime.value_or(0)) - mCommitStartTimes[0];
 
     // We finish SurfaceFlinger when post-composition finishes, so add that in here
-    nsecs_t flingerDuration = estimatedEndTime + mLastPostcompDuration - mCommitStartTimes[0];
+    nsecs_t flingerDuration =
+            estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes[0];
+
+    // Combine the two timings into a single normalized one
     nsecs_t combinedDuration = combineTimingEstimates(totalDuration, flingerDuration);
 
     return std::make_optional(combinedDuration);
@@ -640,9 +641,8 @@
 
     mSupportsPowerHint = checkPowerHintSessionSupported();
 
-    mAllowedActualDeviation =
-            base::GetIntProperty<nsecs_t>("debug.sf.allowed_actual_deviation",
-                                          std::chrono::nanoseconds(250us).count());
+    // Currently set to 0 to disable rate limiter by default
+    mAllowedActualDeviation = base::GetIntProperty<nsecs_t>("debug.sf.allowed_actual_deviation", 0);
 }
 
 AidlPowerHalWrapper::~AidlPowerHalWrapper() {
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index a93744f..859cf3d 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -72,8 +72,8 @@
                                      nsecs_t presentEndTime) = 0;
     // Reports the expected time that the current frame will present to the display
     virtual void setExpectedPresentTime(nsecs_t expectedPresentTime) = 0;
-    // Reports the most recent present fence time once it's known at the end of the frame
-    virtual void setPresentFenceTime(nsecs_t presentFenceTime) = 0;
+    // Reports the most recent present fence time and end time once known
+    virtual void setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) = 0;
     // Reports whether a display used client composition this frame
     virtual void setRequiresClientComposition(DisplayId displayId,
                                               bool requiresClientComposition) = 0;
@@ -142,7 +142,7 @@
     void setSkippedValidate(DisplayId displayId, bool skipped) override;
     void setRequiresClientComposition(DisplayId displayId, bool requiresClientComposition) override;
     void setExpectedPresentTime(nsecs_t expectedPresentTime) override;
-    void setPresentFenceTime(nsecs_t presentFenceTime) override;
+    void setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) override;
     void setHwcPresentDelayedTime(
             DisplayId displayId,
             std::chrono::steady_clock::time_point earliestFrameStartTime) override;
@@ -245,8 +245,6 @@
 
     // Current frame's delay
     nsecs_t mFrameDelayDuration = 0;
-    // Last frame's composite end time
-    nsecs_t mLastCompositeEndTime = -1;
     // Last frame's post-composition duration
     nsecs_t mLastPostcompDuration = 0;
     // Buffer of recent commit start times
@@ -255,6 +253,8 @@
     RingBuffer<nsecs_t, 2> mExpectedPresentTimes;
     // Most recent present fence time, set at the end of the frame once known
     nsecs_t mLastPresentFenceTime = -1;
+    // Most recent present fence time, set at the end of the frame once known
+    nsecs_t mLastSfPresentEndTime = -1;
     // Target for the entire pipeline including gpu
     std::optional<nsecs_t> mTotalFrameTargetDuration;
     // Updated list of display IDs
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 3e69b5c..c73a75c 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -109,11 +109,11 @@
         jankType &= ~JankType::DisplayHAL;
     }
     if (jankType & JankType::SurfaceFlingerCpuDeadlineMissed) {
-        janks.emplace_back("SurfaceFlinger CPU Deadline Missed");
+        janks.emplace_back("SurfaceFlinger deadline missed (while in HWC)");
         jankType &= ~JankType::SurfaceFlingerCpuDeadlineMissed;
     }
     if (jankType & JankType::SurfaceFlingerGpuDeadlineMissed) {
-        janks.emplace_back("SurfaceFlinger GPU Deadline Missed");
+        janks.emplace_back("SurfaceFlinger deadline missed (while in GPU comp)");
         jankType &= ~JankType::SurfaceFlingerGpuDeadlineMissed;
     }
     if (jankType & JankType::AppDeadlineMissed) {
@@ -986,11 +986,8 @@
                                     mJankClassificationThresholds.presentThreshold) {
                     // Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame
                     // was presented more than a vsync late.
-                    if (mGpuFence != FenceTime::NO_FENCE &&
-                        mSurfaceFlingerActuals.endTime - mSurfaceFlingerActuals.startTime <
-                                mRefreshRate.getPeriodNsecs()) {
-                        // If SF was in GPU composition and the CPU work finished before the vsync
-                        // period, classify it as GPU deadline missed.
+                    if (mGpuFence != FenceTime::NO_FENCE) {
+                        // If SF was in GPU composition, classify it as GPU deadline missed.
                         mJankType = JankType::SurfaceFlingerGpuDeadlineMissed;
                     } else {
                         mJankType = JankType::SurfaceFlingerCpuDeadlineMissed;
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 27f4311..cc9f7cf 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -100,14 +100,8 @@
         return getExpectedCallbackTime(nextVsyncTime, timing);
     }
 
-    bool const alreadyDispatchedForVsync = mLastDispatchTime &&
-            ((*mLastDispatchTime + mMinVsyncDistance) >= nextVsyncTime &&
-             (*mLastDispatchTime - mMinVsyncDistance) <= nextVsyncTime);
-    if (alreadyDispatchedForVsync) {
-        nextVsyncTime =
-                tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance);
-        nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
-    }
+    nextVsyncTime = adjustVsyncIfNeeded(tracker, nextVsyncTime);
+    nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
 
     auto const nextReadyTime = nextVsyncTime - timing.readyDuration;
     mScheduleTiming = timing;
@@ -123,6 +117,25 @@
     return mWorkloadUpdateInfo.has_value();
 }
 
+nsecs_t VSyncDispatchTimerQueueEntry::adjustVsyncIfNeeded(VSyncTracker& tracker,
+                                                          nsecs_t nextVsyncTime) const {
+    bool const alreadyDispatchedForVsync = mLastDispatchTime &&
+            ((*mLastDispatchTime + mMinVsyncDistance) >= nextVsyncTime &&
+             (*mLastDispatchTime - mMinVsyncDistance) <= nextVsyncTime);
+    const nsecs_t currentPeriod = tracker.currentPeriod();
+    bool const nextVsyncTooClose = mLastDispatchTime &&
+            (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod;
+    if (alreadyDispatchedForVsync) {
+        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance);
+    }
+
+    if (nextVsyncTooClose) {
+        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod);
+    }
+
+    return nextVsyncTime;
+}
+
 void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) {
     if (!mArmedInfo && !mWorkloadUpdateInfo) {
         return;
@@ -136,7 +149,9 @@
     const auto earliestReadyBy = now + mScheduleTiming.workDuration + mScheduleTiming.readyDuration;
     const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.earliestVsync);
 
-    const auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(earliestVsync);
+    const auto nextVsyncTime =
+            adjustVsyncIfNeeded(tracker, /*nextVsyncTime*/
+                                tracker.nextAnticipatedVSyncTimeFrom(earliestVsync));
     const auto nextReadyTime = nextVsyncTime - mScheduleTiming.readyDuration;
     const auto nextWakeupTime = nextReadyTime - mScheduleTiming.workDuration;
 
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
index 4923031..4f2f87a 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
@@ -84,6 +84,8 @@
     void dump(std::string& result) const;
 
 private:
+    nsecs_t adjustVsyncIfNeeded(VSyncTracker& tracker, nsecs_t nextVsyncTime) const;
+
     const std::string mName;
     const VSyncDispatch::Callback mCallback;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b1a445c..03a7eb6 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -460,14 +460,14 @@
 }
 
 LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
-    if (base::GetBoolProperty("debug.sf.latch_unsignaled"s, false)) {
-        return LatchUnsignaledConfig::Always;
-    }
-
     if (base::GetBoolProperty("debug.sf.auto_latch_unsignaled"s, true)) {
         return LatchUnsignaledConfig::AutoSingleLayer;
     }
 
+    if (base::GetBoolProperty("debug.sf.latch_unsignaled"s, false)) {
+        return LatchUnsignaledConfig::Always;
+    }
+
     return LatchUnsignaledConfig::Disabled;
 }
 
@@ -2232,7 +2232,8 @@
 
     // Send a power hint hint after presentation is finished
     if (mPowerHintSessionEnabled) {
-        mPowerAdvisor->setPresentFenceTime(mPreviousPresentFences[0].fenceTime->getSignalTime());
+        mPowerAdvisor->setSfPresentTiming(mPreviousPresentFences[0].fenceTime->getSignalTime(),
+                                          systemTime());
         if (mPowerHintSessionMode.late) {
             mPowerAdvisor->sendActualWorkDuration();
         }
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index afa3e50..566d553 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -89,6 +89,9 @@
     LayersTraceFileProto fileProto;
     fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
                                LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
+                                                   systemTime(SYSTEM_TIME_MONOTONIC));
+    fileProto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);
     return fileProto;
 }
 
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp
index af0594e..cb5320b 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.cpp
+++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp
@@ -134,6 +134,9 @@
     proto::TransactionTraceFile proto;
     proto.set_magic_number(uint64_t(proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_H) << 32 |
                            proto::TransactionTraceFile_MagicNumber_MAGIC_NUMBER_L);
+    auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
+                                                   systemTime(SYSTEM_TIME_MONOTONIC));
+    proto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);
     return proto;
 }
 
diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto
index 7def024..804a499 100644
--- a/services/surfaceflinger/layerproto/layerstrace.proto
+++ b/services/surfaceflinger/layerproto/layerstrace.proto
@@ -38,6 +38,10 @@
 
     optional fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */
     repeated LayersTraceProto entry = 2;
+
+    /* offset between real-time clock and elapsed time clock in nanoseconds.
+       Calculated as: systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC) */
+    optional fixed64 real_to_elapsed_time_offset_nanos = 3;
 }
 
 /* one layers trace entry. */
diff --git a/services/surfaceflinger/layerproto/transactions.proto b/services/surfaceflinger/layerproto/transactions.proto
index 4f99b19..49487ee 100644
--- a/services/surfaceflinger/layerproto/transactions.proto
+++ b/services/surfaceflinger/layerproto/transactions.proto
@@ -36,6 +36,10 @@
 
     fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */
     repeated TransactionTraceEntry entry = 2;
+
+    /* offset between real-time clock and elapsed time clock in nanoseconds.
+       Calculated as: systemTime(SYSTEM_TIME_REALTIME) - systemTime(SYSTEM_TIME_MONOTONIC) */
+    fixed64 real_to_elapsed_time_offset_nanos = 3;
 }
 
 message TransactionTraceEntry {
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 756db8a..874fa7c 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -1680,7 +1680,7 @@
     EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
     EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
     EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
-    EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
+    EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
 
     // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
     mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
@@ -2184,6 +2184,50 @@
     EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
 }
 
+TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
+    auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+    auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+    auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+    int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
+    int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
+    // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
+    mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
+    mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
+    auto displayFrame = getDisplayFrame(0);
+    gpuFence1->signalForTest(36);
+    presentFence1->signalForTest(52);
+
+    // Fences haven't been flushed yet, so it should be 0
+    EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
+
+    addEmptyDisplayFrame();
+    displayFrame = getDisplayFrame(0);
+
+    // Fences have flushed, so the present timestamps should be updated
+    EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
+    EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+    EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+    EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
+
+    // Case 2: No GPU fence so it will not use GPU composition.
+    mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
+    mFrameTimeline->setSfPresent(66, presentFence2);
+    auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
+    presentFence2->signalForTest(90);
+
+    // Fences for the frame haven't been flushed yet, so it should be 0
+    EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
+
+    addEmptyDisplayFrame();
+
+    // Fences have flushed, so the present timestamps should be updated
+    EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
+    EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+    EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+    EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
+}
+
 TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
     EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
 }
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index b7f968d..f660753 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -44,6 +44,8 @@
         ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
                 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
         ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
+        ON_CALL(*this, currentPeriod())
+                .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
     }
 
     MOCK_METHOD1(addVsyncTimestamp, bool(nsecs_t));
@@ -62,6 +64,8 @@
         return (timePoint - (timePoint % mPeriod) + mPeriod);
     }
 
+    nsecs_t getCurrentPeriod() const { return mPeriod; }
+
 protected:
     nsecs_t const mPeriod;
 };
@@ -393,6 +397,43 @@
     EXPECT_THAT(cb1.mCalls[0], Eq(1063));
 }
 
+TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
+    EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
+            .Times(4)
+            .WillOnce(Return(1000))
+            .WillOnce(Return(2000))
+            .WillOnce(Return(2500))
+            .WillOnce(Return(4000));
+
+    Sequence seq;
+    EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
+    EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
+    EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
+
+    CountingCallback cb(mDispatch);
+
+    mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
+
+    advanceToNextCallback();
+
+    ASSERT_THAT(cb.mCalls.size(), Eq(1));
+    EXPECT_THAT(cb.mCalls[0], Eq(1000));
+
+    mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+
+    advanceToNextCallback();
+
+    ASSERT_THAT(cb.mCalls.size(), Eq(2));
+    EXPECT_THAT(cb.mCalls[1], Eq(2000));
+
+    mDispatch.schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+
+    advanceToNextCallback();
+
+    ASSERT_THAT(cb.mCalls.size(), Eq(3));
+    EXPECT_THAT(cb.mCalls[2], Eq(4000));
+}
+
 TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
     EXPECT_CALL(mStubTracker, nextAnticipatedVSyncTimeFrom(_))
             .Times(4)
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index d6dca45..aede250 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -53,7 +53,8 @@
     MOCK_METHOD(void, setRequiresClientComposition,
                 (DisplayId displayId, bool requiresClientComposition), (override));
     MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
-    MOCK_METHOD(void, setPresentFenceTime, (nsecs_t presentFenceTime), (override));
+    MOCK_METHOD(void, setSfPresentTiming, (nsecs_t presentFenceTime, nsecs_t presentEndTime),
+                (override));
     MOCK_METHOD(void, setHwcPresentDelayedTime,
                 (DisplayId displayId,
                  std::chrono::steady_clock::time_point earliestFrameStartTime));