Merge "Add reason to focus change event log"
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 26a1644..ded74ba 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -117,10 +117,12 @@
 // --- FocusEntry ---
 
 // Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
-FocusEntry::FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus)
+FocusEntry::FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
+                       std::string_view reason)
       : EventEntry(id, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
         connectionToken(connectionToken),
-        hasFocus(hasFocus) {}
+        hasFocus(hasFocus),
+        reason(reason) {}
 
 FocusEntry::~FocusEntry() {}
 
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 740d0f9..5fd772e 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -112,8 +112,10 @@
 struct FocusEntry : EventEntry {
     sp<IBinder> connectionToken;
     bool hasFocus;
+    std::string_view reason;
 
-    FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus);
+    FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
+               std::string_view reason);
     virtual void appendDescription(std::string& msg) const;
 
 protected:
diff --git a/services/inputflinger/dispatcher/EventLogTags.logtags b/services/inputflinger/dispatcher/EventLogTags.logtags
index 9c0f80e..2836467 100644
--- a/services/inputflinger/dispatcher/EventLogTags.logtags
+++ b/services/inputflinger/dispatcher/EventLogTags.logtags
@@ -36,7 +36,7 @@
 # 62000 - 62199 reserved for inputflinger
 
 62000 input_interaction (windows|4)
-62001 input_focus (window|3)
+62001 input_focus (window|3),(reason|3)
 
 # NOTE - the range 1000000-2000000 is reserved for partners and others who
 # want to define their own log tags without conflicting with the core platform.
\ No newline at end of file
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 3464b8f..443e2ca 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1076,7 +1076,8 @@
     return true;
 }
 
-void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
+void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus,
+                                              std::string_view reason) {
     if (mPendingEvent != nullptr) {
         // Move the pending event to the front of the queue. This will give the chance
         // for the pending event to get dispatched to the newly focused window
@@ -1085,7 +1086,7 @@
     }
 
     FocusEntry* focusEntry =
-            new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus);
+            new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus, reason);
 
     // This event should go to the front of the queue, but behind all other focus events
     // Find the last focus event, and insert right after it
@@ -1108,7 +1109,8 @@
     entry->dispatchInProgress = true;
     std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
             channel->getName();
-    android_log_event_list(LOGTAG_INPUT_FOCUS) << message << LOG_ID_EVENTS;
+    std::string reason = std::string("reason=").append(entry->reason);
+    android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
     dispatchEventLocked(currentTime, entry, {target});
 }
 
@@ -3829,33 +3831,8 @@
             getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
 
     if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
-        if (oldFocusedWindowHandle != nullptr) {
-            if (DEBUG_FOCUS) {
-                ALOGD("Focus left window: %s in display %" PRId32,
-                      oldFocusedWindowHandle->getName().c_str(), displayId);
-            }
-            std::shared_ptr<InputChannel> focusedInputChannel =
-                    getInputChannelLocked(oldFocusedWindowHandle->getToken());
-            if (focusedInputChannel != nullptr) {
-                CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
-                                           "focus left window");
-                synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
-                enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
-            }
-            mFocusedWindowHandlesByDisplay.erase(displayId);
-        }
-        if (newFocusedWindowHandle != nullptr) {
-            if (DEBUG_FOCUS) {
-                ALOGD("Focus entered window: %s in display %" PRId32,
-                      newFocusedWindowHandle->getName().c_str(), displayId);
-            }
-            mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
-            enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
-        }
-
-        if (mFocusedDisplayId == displayId) {
-            onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
-        }
+        onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle, displayId,
+                             "setInputWindowsLocked");
     }
 
     std::unordered_map<int32_t, TouchState>::iterator stateIt =
@@ -3969,7 +3946,7 @@
             // Sanity check
             sp<InputWindowHandle> newFocusedWindowHandle =
                     getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
-            onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
+            notifyFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
 
             if (newFocusedWindowHandle == nullptr) {
                 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
@@ -4642,8 +4619,8 @@
     postCommandLocked(std::move(commandEntry));
 }
 
-void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
-                                           const sp<InputWindowHandle>& newFocus) {
+void InputDispatcher::notifyFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
+                                               const sp<InputWindowHandle>& newFocus) {
     sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
     sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
     std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
@@ -5222,5 +5199,37 @@
  *  when requesting the focus change. This determines which request gets
  *  precedence if there is a focus change request from another source such as pointer down.
  */
-void InputDispatcher::setFocusedWindow(const FocusRequest&) {}
+void InputDispatcher::setFocusedWindow(const FocusRequest& request) {}
+
+void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocusedWindowHandle,
+                                           const sp<InputWindowHandle>& newFocusedWindowHandle,
+                                           int32_t displayId, std::string_view reason) {
+    if (oldFocusedWindowHandle) {
+        if (DEBUG_FOCUS) {
+            ALOGD("Focus left window: %s in display %" PRId32,
+                  oldFocusedWindowHandle->getName().c_str(), displayId);
+        }
+        std::shared_ptr<InputChannel> focusedInputChannel =
+                getInputChannelLocked(oldFocusedWindowHandle->getToken());
+        if (focusedInputChannel) {
+            CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+                                       "focus left window");
+            synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
+            enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/, reason);
+        }
+        mFocusedWindowHandlesByDisplay.erase(displayId);
+    }
+    if (newFocusedWindowHandle) {
+        if (DEBUG_FOCUS) {
+            ALOGD("Focus entered window: %s in display %" PRId32,
+                  newFocusedWindowHandle->getName().c_str(), displayId);
+        }
+        mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
+        enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/, reason);
+    }
+
+    if (mFocusedDisplayId == displayId) {
+        notifyFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
+    }
+}
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 0ff914f..10d5abe 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -178,7 +178,8 @@
     void dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) REQUIRES(mLock);
 
     // Enqueues a focus event.
-    void enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) REQUIRES(mLock);
+    void enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus,
+                                 std::string_view reason) REQUIRES(mLock);
 
     // Adds an event to a queue of recent events for debugging purposes.
     void addRecentEventLocked(EventEntry* entry) REQUIRES(mLock);
@@ -500,7 +501,10 @@
     void onDispatchCycleBrokenLocked(nsecs_t currentTime, const sp<Connection>& connection)
             REQUIRES(mLock);
     void onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
-                              const sp<InputWindowHandle>& newFocus) REQUIRES(mLock);
+                              const sp<InputWindowHandle>& newFocus, int32_t displayId,
+                              std::string_view reason) REQUIRES(mLock);
+    void notifyFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
+                                  const sp<InputWindowHandle>& newFocus) REQUIRES(mLock);
     void onAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
     void onAnrLocked(const std::shared_ptr<InputApplicationHandle>& application) REQUIRES(mLock);
     void updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)