Merge "Traces with real-to-elapsed time offset"
diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
index 585ea3c..1c9a5ea 100644
--- a/include/input/KeyCharacterMap.h
+++ b/include/input/KeyCharacterMap.h
@@ -18,6 +18,7 @@
 #define _LIBINPUT_KEY_CHARACTER_MAP_H
 
 #include <stdint.h>
+#include <list>
 
 #ifdef __linux__
 #include <binder/IBinder.h>
@@ -152,29 +153,22 @@
 
 private:
     struct Behavior {
-        Behavior();
-        Behavior(const Behavior& other);
-
-        /* The next behavior in the list, or NULL if none. */
-        Behavior* next;
-
         /* The meta key modifiers for this behavior. */
-        int32_t metaState;
+        int32_t metaState = 0;
 
         /* The character to insert. */
-        char16_t character;
+        char16_t character = 0;
 
         /* The fallback keycode if the key is not handled. */
-        int32_t fallbackKeyCode;
+        int32_t fallbackKeyCode = 0;
 
         /* The replacement keycode if the key has to be replaced outright. */
-        int32_t replacementKeyCode;
+        int32_t replacementKeyCode = 0;
     };
 
     struct Key {
         Key();
         Key(const Key& other);
-        ~Key();
 
         /* The single character label printed on the key, or 0 if none. */
         char16_t label;
@@ -184,7 +178,7 @@
 
         /* The list of key behaviors sorted from most specific to least specific
          * meta key binding. */
-        Behavior* firstBehavior;
+        std::list<Behavior> behaviors;
     };
 
     class Parser {
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/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6e8c886..c793523 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1085,16 +1085,6 @@
     return physicalDisplayIds;
 }
 
-status_t SurfaceComposerClient::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) {
-    int64_t displayId;
-    binder::Status status =
-            ComposerServiceAIDL::getComposerService()->getPrimaryPhysicalDisplayId(&displayId);
-    if (status.isOk()) {
-        *id = *DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
-    }
-    return statusTFromBinderStatus(status);
-}
-
 std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() {
     ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
     return instance.getInternalDisplayId();
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 730d758..3c220fc 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -94,8 +94,6 @@
      */
     long[] getPhysicalDisplayIds();
 
-    long getPrimaryPhysicalDisplayId();
-
     /**
      * Get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or
      * a DisplayEventReceiver hotplug event.
diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h
index 91eb6b4..d51f685 100644
--- a/libs/gui/fuzzer/libgui_fuzzer_utils.h
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -71,7 +71,6 @@
                 (override));
     MOCK_METHOD(binder::Status, destroyDisplay, (const sp<IBinder>&), (override));
     MOCK_METHOD(binder::Status, getPhysicalDisplayIds, (std::vector<int64_t>*), (override));
-    MOCK_METHOD(binder::Status, getPrimaryPhysicalDisplayId, (int64_t*), (override));
     MOCK_METHOD(binder::Status, getPhysicalDisplayToken, (int64_t, sp<IBinder>*), (override));
     MOCK_METHOD(binder::Status, setPowerMode, (const sp<IBinder>&, int), (override));
     MOCK_METHOD(binder::Status, getSupportedFrameTimestamps, (std::vector<FrameEvent>*),
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index bc33c29..20c38d8 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -351,7 +351,6 @@
 
     //! Get stable IDs for connected physical displays
     static std::vector<PhysicalDisplayId> getPhysicalDisplayIds();
-    static status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*);
     static std::optional<PhysicalDisplayId> getInternalDisplayId();
 
     //! Get token for a physical display given its stable ID
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 391a0aa..71f2ad4 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -745,10 +745,6 @@
         return binder::Status::ok();
     }
 
-    binder::Status getPrimaryPhysicalDisplayId(int64_t* /*outDisplayId*/) override {
-        return binder::Status::ok();
-    }
-
     binder::Status getPhysicalDisplayToken(int64_t /*displayId*/,
                                            sp<IBinder>* /*outDisplay*/) override {
         return binder::Status::ok();
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 5cb844e..422e6e0 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -345,12 +345,12 @@
         // Try to find the most general behavior that maps to this character.
         // For example, the base key behavior will usually be last in the list.
         // However, if we find a perfect meta state match for one behavior then use that one.
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character) {
+        for (const Behavior& behavior : key->behaviors) {
+            if (behavior.character) {
                 for (size_t i = 0; i < numChars; i++) {
-                    if (behavior->character == chars[i]) {
-                        result = behavior->character;
-                        if ((behavior->metaState & metaState) == behavior->metaState) {
+                    if (behavior.character == chars[i]) {
+                        result = behavior.character;
+                        if ((behavior.metaState & metaState) == behavior.metaState) {
                             goto ExactMatch;
                         }
                         break;
@@ -485,12 +485,10 @@
                                                                  int32_t metaState) const {
     const Key* key;
     if (getKey(keyCode, &key)) {
-        const Behavior* behavior = key->firstBehavior;
-        while (behavior) {
-            if (matchesMetaState(metaState, behavior->metaState)) {
-                return behavior;
+        for (const Behavior& behavior : key->behaviors) {
+            if (matchesMetaState(metaState, behavior.metaState)) {
+                return &behavior;
             }
-            behavior = behavior->next;
         }
     }
     return nullptr;
@@ -538,12 +536,12 @@
         // Try to find the most general behavior that maps to this character.
         // For example, the base key behavior will usually be last in the list.
         const Behavior* found = nullptr;
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character == ch) {
-                found = behavior;
+        for (const Behavior& behavior : key->behaviors) {
+            if (behavior.character == ch) {
+                found = &behavior;
             }
         }
-        if (found) {
+        if (found != nullptr) {
             *outKeyCode = mKeys.keyAt(i);
             *outMetaState = found->metaState;
             return true;
@@ -701,7 +699,6 @@
         key->number = number;
         map->mKeys.add(keyCode, key);
 
-        Behavior* lastBehavior = nullptr;
         while (parcel->readInt32()) {
             int32_t metaState = parcel->readInt32();
             char16_t character = parcel->readInt32();
@@ -711,17 +708,12 @@
                 return nullptr;
             }
 
-            Behavior* behavior = new Behavior();
-            behavior->metaState = metaState;
-            behavior->character = character;
-            behavior->fallbackKeyCode = fallbackKeyCode;
-            behavior->replacementKeyCode = replacementKeyCode;
-            if (lastBehavior) {
-                lastBehavior->next = behavior;
-            } else {
-                key->firstBehavior = behavior;
-            }
-            lastBehavior = behavior;
+            key->behaviors.push_back({
+                    .metaState = metaState,
+                    .character = character,
+                    .fallbackKeyCode = fallbackKeyCode,
+                    .replacementKeyCode = replacementKeyCode,
+            });
         }
 
         if (parcel->errorCheck()) {
@@ -772,13 +764,12 @@
         parcel->writeInt32(keyCode);
         parcel->writeInt32(key->label);
         parcel->writeInt32(key->number);
-        for (const Behavior* behavior = key->firstBehavior; behavior != nullptr;
-                behavior = behavior->next) {
+        for (const Behavior& behavior : key->behaviors) {
             parcel->writeInt32(1);
-            parcel->writeInt32(behavior->metaState);
-            parcel->writeInt32(behavior->character);
-            parcel->writeInt32(behavior->fallbackKeyCode);
-            parcel->writeInt32(behavior->replacementKeyCode);
+            parcel->writeInt32(behavior.metaState);
+            parcel->writeInt32(behavior.character);
+            parcel->writeInt32(behavior.fallbackKeyCode);
+            parcel->writeInt32(behavior.replacementKeyCode);
         }
         parcel->writeInt32(0);
     }
@@ -799,38 +790,10 @@
 
 // --- KeyCharacterMap::Key ---
 
-KeyCharacterMap::Key::Key() :
-        label(0), number(0), firstBehavior(nullptr) {
-}
+KeyCharacterMap::Key::Key() : label(0), number(0) {}
 
-KeyCharacterMap::Key::Key(const Key& other) :
-        label(other.label), number(other.number),
-        firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : nullptr) {
-}
-
-KeyCharacterMap::Key::~Key() {
-    Behavior* behavior = firstBehavior;
-    while (behavior) {
-        Behavior* next = behavior->next;
-        delete behavior;
-        behavior = next;
-    }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
-        next(nullptr), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) {
-}
-
-KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
-        next(other.next ? new Behavior(*other.next) : nullptr),
-        metaState(other.metaState), character(other.character),
-        fallbackKeyCode(other.fallbackKeyCode),
-        replacementKeyCode(other.replacementKeyCode) {
-}
-
+KeyCharacterMap::Key::Key(const Key& other)
+      : label(other.label), number(other.number), behaviors(other.behaviors) {}
 
 // --- KeyCharacterMap::Parser ---
 
@@ -1208,23 +1171,21 @@
 #endif
             break;
         case PROPERTY_META: {
-            for (Behavior* b = key->firstBehavior; b; b = b->next) {
-                if (b->metaState == property.metaState) {
+            for (const Behavior& b : key->behaviors) {
+                if (b.metaState == property.metaState) {
                     ALOGE("%s: Duplicate key behavior for modifier.",
                             mTokenizer->getLocation().string());
                     return BAD_VALUE;
                 }
             }
-            Behavior* newBehavior = new Behavior(behavior);
-            newBehavior->metaState = property.metaState;
-            newBehavior->next = key->firstBehavior;
-            key->firstBehavior = newBehavior;
-#if DEBUG_PARSER
-            ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
-                    mKeyCode,
-                    newBehavior->metaState, newBehavior->character,
-                    newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode);
-#endif
+            Behavior newBehavior = behavior;
+            newBehavior.metaState = property.metaState;
+            key->behaviors.push_front(newBehavior);
+            ALOGD_IF(DEBUG_PARSER,
+                     "Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
+                     mKeyCode, key->behaviors.front().metaState, key->behaviors.front().character,
+                     key->behaviors.front().fallbackKeyCode,
+                     key->behaviors.front().replacementKeyCode);
             break;
         }
         }
@@ -1237,8 +1198,8 @@
     if (!key->number) {
         char16_t digit = 0;
         char16_t symbol = 0;
-        for (Behavior* b = key->firstBehavior; b; b = b->next) {
-            char16_t ch = b->character;
+        for (const Behavior& b : key->behaviors) {
+            char16_t ch = b.character;
             if (ch) {
                 if (ch >= '0' && ch <= '9') {
                     digit = ch;
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/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index c069248..17ee54f 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -46,6 +46,8 @@
 static const float MIN_FREEFORM_GESTURE_WIDTH_IN_MILLIMETER = 30;
 // --- Static Definitions ---
 
+static const DisplayViewport kUninitializedViewport;
+
 template <typename T>
 inline static void swap(T& a, T& b) {
     T temp = a;
@@ -392,10 +394,10 @@
     }
 
     if (changes && resetNeeded) {
-        // If device was reset, cancel touch event and update touch spot state.
-        cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
-        mCurrentCookedState.clear();
-        updateTouchSpots();
+        // If the device needs to be reset, cancel any ongoing gestures and reset the state.
+        cancelTouch(when, when);
+        reset(when);
+
         // Send reset, unless this is the first time the device has been configured,
         // in which case the reader will call reset itself after all mappers are ready.
         NotifyDeviceResetArgs args(getContext()->getNextId(), when, getDeviceId());
@@ -886,7 +888,7 @@
 }
 
 void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) {
-    DeviceMode oldDeviceMode = mDeviceMode;
+    const DeviceMode oldDeviceMode = mDeviceMode;
 
     resolveExternalStylusPresence();
 
@@ -915,31 +917,24 @@
         mDeviceMode = DeviceMode::UNSCALED;
     }
 
-    // Ensure we have valid X and Y axes.
+    const std::optional<DisplayViewport> newViewportOpt = findViewport();
+
+    // Ensure the device is valid and can be used.
     if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
         ALOGW("Touch device '%s' did not report support for X or Y axis!  "
               "The device will be inoperable.",
               getDeviceName().c_str());
         mDeviceMode = DeviceMode::DISABLED;
-        return;
-    }
-
-    // Get associated display dimensions.
-    std::optional<DisplayViewport> newViewport = findViewport();
-    if (!newViewport) {
+    } else if (!newViewportOpt) {
         ALOGI("Touch device '%s' could not query the properties of its associated "
               "display.  The device will be inoperable until the display size "
               "becomes available.",
               getDeviceName().c_str());
         mDeviceMode = DeviceMode::DISABLED;
-        return;
-    }
-
-    if (!newViewport->isActive) {
+    } else if (!newViewportOpt->isActive) {
         ALOGI("Disabling %s (device %i) because the associated viewport is not active",
               getDeviceName().c_str(), getDeviceId());
         mDeviceMode = DeviceMode::DISABLED;
-        return;
     }
 
     // Raw width and height in the natural orientation.
@@ -951,12 +946,13 @@
     const float rawMeanResolution =
             (rawXResolution > 0 && rawYResolution > 0) ? (rawXResolution + rawYResolution) / 2 : 0;
 
-    const bool viewportChanged = mViewport != *newViewport;
+    const DisplayViewport& newViewport = newViewportOpt.value_or(kUninitializedViewport);
+    const bool viewportChanged = mViewport != newViewport;
     bool skipViewportUpdate = false;
     if (viewportChanged) {
-        const bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation;
-        const bool viewportDisplayIdChanged = mViewport.displayId != newViewport->displayId;
-        mViewport = *newViewport;
+        const bool viewportOrientationChanged = mViewport.orientation != newViewport.orientation;
+        const bool viewportDisplayIdChanged = mViewport.displayId != newViewport.displayId;
+        mViewport = newViewport;
 
         if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) {
             // Convert rotated viewport to the natural orientation.
@@ -1118,10 +1114,6 @@
             mPointerGestureMaxSwipeWidth =
                     std::max(mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal,
                              minFreeformGestureWidth);
-
-            // Abort current pointer usages because the state has changed.
-            const nsecs_t readTime = when; // synthetic event
-            abortPointerUsage(when, readTime, 0 /*policyFlags*/);
         }
 
         // Inform the dispatcher about the changes.
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index e80a956..a0e6192 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2945,6 +2945,8 @@
         mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
                                                             *mFakeListener);
         mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
+        // Consume the device reset notification generated when adding a new device.
+        mFakeListener->assertNotifyDeviceResetWasCalled();
     }
 
     void SetUp() override {
@@ -2969,6 +2971,8 @@
             mReader->loopOnce();
         }
         mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
+        // Loop the reader to flush the input listener queue.
+        mReader->loopOnce();
     }
 
     std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
@@ -2992,6 +2996,8 @@
         configureDevice(0);
         mDevice->reset(ARBITRARY_TIME);
         mapper.reset(ARBITRARY_TIME);
+        // Loop the reader to flush the input listener queue.
+        mReader->loopOnce();
         return mapper;
     }
 
@@ -3017,6 +3023,7 @@
         event.code = code;
         event.value = value;
         mapper.process(&event);
+        // Loop the reader to flush the input listener queue.
         mReader->loopOnce();
     }
 
@@ -4913,7 +4920,6 @@
     ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
 
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
-    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
     ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
 
     process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
@@ -6724,6 +6730,61 @@
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
 }
 
+TEST_F(SingleTouchInputMapperTest,
+       Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
+    NotifyMotionArgs motionArgs;
+
+    // Start a new gesture.
+    processDown(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+
+    // Make the viewport inactive. This will put the device in disabled mode.
+    auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
+    viewport->isActive = false;
+    mFakePolicy->updateViewport(*viewport);
+    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+    // We should receive a cancel event for the ongoing gesture.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
+    // Then we should be notified that the device was reset.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
+
+    // No events are generated while the viewport is inactive.
+    processMove(mapper, 101, 201);
+    processSync(mapper);
+    processDown(mapper, 102, 202);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+    // Make the viewport active again. The device should resume processing events.
+    viewport->isActive = true;
+    mFakePolicy->updateViewport(*viewport);
+    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+    // The device is reset because it changes back to direct mode, without generating any events.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+    // Start a new gesture.
+    processDown(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+
+    // No more events.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
+}
+
 // --- TouchDisplayProjectionTest ---
 
 class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
@@ -8581,27 +8642,27 @@
     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
     configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
 
-    // Finger move
+    // The ongoing touch should be canceled immediately
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
+
+    // Finger move is ignored
     x += 10, y += 10;
     processPosition(mapper, x, y);
     processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
 
     // Reactivate display viewport
     displayViewport.isActive = true;
     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
     configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
 
-    // Finger move again
+    // Finger move again starts new gesture
     x += 10, y += 10;
     processPosition(mapper, x, y);
     processSync(mapper);
-
-    // Gesture is aborted, so events after display is activated won't be dispatched until there is
-    // no pointer on the touch device.
-    mFakeListener->assertNotifyMotionWasNotCalled();
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
 }
 
 TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8e19c35..de12d62 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -607,12 +607,6 @@
     return displayIds;
 }
 
-status_t SurfaceFlinger::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) const {
-    Mutex::Autolock lock(mStateLock);
-    *id = getPrimaryDisplayIdLocked();
-    return NO_ERROR;
-}
-
 sp<IBinder> SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
     Mutex::Autolock lock(mStateLock);
     return getPhysicalDisplayTokenLocked(displayId);
@@ -2065,7 +2059,11 @@
     }
 
     // Save this once per commit + composite to ensure consistency
-    mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession();
+    // TODO (b/240619471): consider removing active display check once AOD is fixed
+    const auto activeDisplay =
+            FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayToken));
+    mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession() && activeDisplay &&
+            activeDisplay->getPowerMode() == hal::PowerMode::ON;
     if (mPowerHintSessionEnabled) {
         const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
         // get stable vsync period from display mode
@@ -7234,20 +7232,6 @@
     return binder::Status::ok();
 }
 
-binder::Status SurfaceComposerAIDL::getPrimaryPhysicalDisplayId(int64_t* outDisplayId) {
-    status_t status = checkAccessPermission();
-    if (status != OK) {
-        return binderStatusFromStatusT(status);
-    }
-
-    PhysicalDisplayId id;
-    status = mFlinger->getPrimaryPhysicalDisplayId(&id);
-    if (status == NO_ERROR) {
-        *outDisplayId = id.value;
-    }
-    return binderStatusFromStatusT(status);
-}
-
 binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId,
                                                             sp<IBinder>* outDisplay) {
     const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8fddb70..361fa2e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -498,7 +498,6 @@
         Mutex::Autolock lock(mStateLock);
         return getPhysicalDisplayIdsLocked();
     }
-    status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const EXCLUDES(mStateLock);
 
     sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const;
     status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
@@ -1396,7 +1395,6 @@
                                  sp<IBinder>* outDisplay) override;
     binder::Status destroyDisplay(const sp<IBinder>& display) override;
     binder::Status getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) override;
-    binder::Status getPrimaryPhysicalDisplayId(int64_t* outDisplayId) override;
     binder::Status getPhysicalDisplayToken(int64_t displayId, sp<IBinder>* outDisplay) override;
     binder::Status setPowerMode(const sp<IBinder>& display, int mode) override;
     binder::Status getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) override;
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
index a747cdd..18e0a1c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
@@ -97,6 +97,7 @@
                     .setNativeWindow(mNativeWindow)
                     .setPowerMode(hal::PowerMode::ON)
                     .inject();
+    mFlinger.mutableActiveDisplayToken() = mDisplay->getDisplayToken();
 }
 
 void SurfaceFlingerPowerHintTest::setupScheduler() {
@@ -150,5 +151,28 @@
     mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count());
 }
 
+TEST_F(SurfaceFlingerPowerHintTest, inactiveOnDisplayDoze) {
+    ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true));
+
+    mDisplay->setPowerMode(hal::PowerMode::DOZE);
+
+    const std::chrono::nanoseconds mockVsyncPeriod = 15ms;
+    EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(0);
+
+    const nsecs_t now = systemTime();
+    const std::chrono::nanoseconds mockHwcRunTime = 20ms;
+    EXPECT_CALL(*mDisplaySurface,
+                prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc))
+            .Times(1);
+    EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _))
+            .WillOnce([mockHwcRunTime] {
+                std::this_thread::sleep_for(mockHwcRunTime);
+                return hardware::graphics::composer::V2_1::Error::NONE;
+            });
+    EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration()).Times(0);
+    static constexpr bool kVsyncId = 123; // arbitrary
+    mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count());
+}
+
 } // namespace
 } // namespace android