Merge "Use global capabilities for Display without a valid HWC display ID."
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index d97ffbf..990fd43 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -871,7 +871,11 @@
             is_java_process ? 5 : 20, fd);
 
         if (ret == -1) {
-            dprintf(fd, "dumping failed, likely due to a timeout\n");
+            // For consistency, the header and footer to this message match those
+            // dumped by debuggerd in the success case.
+            dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
+            dprintf(fd, "Dump failed, likely due to a timeout.\n");
+            dprintf(fd, "---- end %d ----", pid);
             timeout_failures++;
             continue;
         }
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 799151a..2f6ef79 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -75,7 +75,8 @@
 
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken) {
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& commands) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
 
@@ -91,6 +92,7 @@
 
         data.writeUint32(flags);
         data.writeStrongBinder(applyToken);
+        commands.write(data);
         remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
     }
 
@@ -750,7 +752,9 @@
 
             uint32_t stateFlags = data.readUint32();
             sp<IBinder> applyToken = data.readStrongBinder();
-            setTransactionState(state, displays, stateFlags, applyToken);
+            InputWindowCommands inputWindowCommands;
+            inputWindowCommands.read(data);
+            setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands);
             return NO_ERROR;
         }
         case BOOT_FINISHED: {
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 35ce6e3..e5170ab 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -379,4 +379,36 @@
     }
 }
 
+// ------------------------------- InputWindowCommands ----------------------------------------
+
+void InputWindowCommands::merge(const InputWindowCommands& other) {
+    transferTouchFocusCommands
+            .insert(transferTouchFocusCommands.end(),
+                    std::make_move_iterator(other.transferTouchFocusCommands.begin()),
+                    std::make_move_iterator(other.transferTouchFocusCommands.end()));
+}
+
+void InputWindowCommands::clear() {
+    transferTouchFocusCommands.clear();
+}
+
+void InputWindowCommands::write(Parcel& output) const {
+    output.writeUint32(static_cast<uint32_t>(transferTouchFocusCommands.size()));
+    for (const auto& transferTouchFocusCommand : transferTouchFocusCommands) {
+        output.writeStrongBinder(transferTouchFocusCommand.fromToken);
+        output.writeStrongBinder(transferTouchFocusCommand.toToken);
+    }
+}
+
+void InputWindowCommands::read(const Parcel& input) {
+    size_t count = input.readUint32();
+    transferTouchFocusCommands.clear();
+    for (size_t i = 0; i < count; i++) {
+        TransferTouchFocusCommand transferTouchFocusCommand;
+        transferTouchFocusCommand.fromToken = input.readStrongBinder();
+        transferTouchFocusCommand.toToken = input.readStrongBinder();
+        transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+    }
+}
+
 }; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5b004e2..e043762 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -166,6 +166,7 @@
     mEarlyWakeup(other.mEarlyWakeup) {
     mDisplayStates = other.mDisplayStates;
     mComposerStates = other.mComposerStates;
+    mInputWindowCommands = other.mInputWindowCommands;
 }
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
@@ -199,6 +200,8 @@
     }
     other.mListenerCallbacks.clear();
 
+    mInputWindowCommands.merge(other.mInputWindowCommands);
+
     return *this;
 }
 
@@ -265,8 +268,8 @@
     mEarlyWakeup = false;
 
     sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
-
-    sf->setTransactionState(composerStates, displayStates, flags, applyToken);
+    sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands);
+    mInputWindowCommands.clear();
     mStatus = NO_ERROR;
     return NO_ERROR;
 }
@@ -804,6 +807,16 @@
     s->what |= layer_state_t::eInputInfoChanged;
     return *this;
 }
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::transferTouchFocus(
+        const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    InputWindowCommands::TransferTouchFocusCommand transferTouchFocusCommand;
+    transferTouchFocusCommand.fromToken = fromToken;
+    transferTouchFocusCommand.toToken = toToken;
+    mInputWindowCommands.transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+    return *this;
+}
+
 #endif
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8cb40e7..e0ff410 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -42,6 +42,7 @@
 struct DisplayState;
 struct DisplayInfo;
 struct DisplayStatInfo;
+struct InputWindowCommands;
 class LayerDebugInfo;
 class HdrCapabilities;
 class IDisplayEventConnection;
@@ -125,7 +126,8 @@
     /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken) = 0;
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& inputWindowCommands) = 0;
 
     /* signal that we're done booting.
      * Requires ACCESS_SURFACE_FLINGER permission
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 02c6be2..e7564f5 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -228,6 +228,20 @@
     status_t read(const Parcel& input);
 };
 
+struct InputWindowCommands {
+    struct TransferTouchFocusCommand {
+        sp<IBinder> fromToken;
+        sp<IBinder> toToken;
+    };
+
+    std::vector<TransferTouchFocusCommand> transferTouchFocusCommands;
+
+    void merge(const InputWindowCommands& other);
+    void clear();
+    void write(Parcel& output) const;
+    void read(const Parcel& input);
+};
+
 static inline int compare_type(const ComposerState& lhs, const ComposerState& rhs) {
     if (lhs.client < rhs.client) return -1;
     if (lhs.client > rhs.client) return 1;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8e3ba78..9765cdd 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -219,6 +219,7 @@
         bool                        mAnimation = false;
         bool                        mEarlyWakeup = false;
 
+        InputWindowCommands mInputWindowCommands;
         int mStatus = NO_ERROR;
 
         layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -335,6 +336,7 @@
 
 #ifndef NO_INPUT
         Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
+        Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 #endif
 
         Transaction& destroySurface(const sp<SurfaceControl>& sc);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index c56304f..13fac7f 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -559,7 +559,8 @@
     sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; }
     void setTransactionState(const Vector<ComposerState>& /*state*/,
                              const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
-                             const sp<IBinder>& /*applyToken*/) override {}
+                             const sp<IBinder>& /*applyToken*/,
+                             const InputWindowCommands& /*inputWindowCommands*/) override {}
     void bootFinished() override {}
     bool authenticateSurfaceTexture(
             const sp<IGraphicBufferProducer>& /*surface*/) const override {
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 0d8d34f..843eb37 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -22,6 +22,7 @@
 
     shared_libs: [
         "libinputflinger_base",
+        "libinputreporter",
         "libinputreader",
         "libbase",
         "libbinder",
@@ -125,6 +126,35 @@
     ],
 }
 
+cc_library_shared {
+    name: "libinputreporter",
+
+    srcs: [
+        "InputReporter.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+    ],
+
+    header_libs: [
+        "libinputflinger_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libinputflinger_headers",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+}
+
 subdirs = [
     "host",
     "tests",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 7fa9cb6..6173452 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -257,6 +257,7 @@
     mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
     mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
     mLooper = new Looper(false);
+    mReporter = createInputReporter();
 
     mKeyRepeatState.lastKeyEntry = nullptr;
 
@@ -841,6 +842,7 @@
     if (*dropReason != DROP_REASON_NOT_DROPPED) {
         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+        mReporter->reportDroppedKey(entry->sequenceNum);
         return true;
     }
 
@@ -4025,6 +4027,10 @@
 bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
         DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
     if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
+        if (!handled) {
+            // Report the key as unhandled, since the fallback was not handled.
+            mReporter->reportUnhandledKey(keyEntry->sequenceNum);
+        }
         return false;
     }
 
@@ -4192,6 +4198,9 @@
 #if DEBUG_OUTBOUND_EVENT_DETAILS
             ALOGD("Unhandled key event: No fallback key.");
 #endif
+
+            // Report the key as unhandled, since there is no fallback key.
+            mReporter->reportUnhandledKey(keyEntry->sequenceNum);
         }
     }
     return false;
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 05b5dad..7e6de6a 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -37,6 +37,7 @@
 #include <unordered_map>
 
 #include "InputListener.h"
+#include "InputReporter.h"
 
 
 namespace android {
@@ -1186,6 +1187,8 @@
     void traceInboundQueueLengthLocked();
     void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
     void traceWaitQueueLengthLocked(const sp<Connection>& connection);
+
+    sp<InputReporter> mReporter;
 };
 
 /* Enqueues and dispatches input events, endlessly. */
diff --git a/services/inputflinger/InputReporter.cpp b/services/inputflinger/InputReporter.cpp
new file mode 100644
index 0000000..cf4220f
--- /dev/null
+++ b/services/inputflinger/InputReporter.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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 "InputReporter.h"
+
+namespace android {
+
+// --- InputReporter ---
+
+void InputReporter::reportUnhandledKey(uint32_t sequenceNum) {
+  // do nothing
+}
+
+void InputReporter::reportDroppedKey(uint32_t sequenceNum) {
+  // do nothing
+}
+
+sp<InputReporter> createInputReporter() {
+  return new InputReporter();
+}
+
+} // namespace android
diff --git a/services/inputflinger/include/InputReporter.h b/services/inputflinger/include/InputReporter.h
new file mode 100644
index 0000000..c86dcda
--- /dev/null
+++ b/services/inputflinger/include/InputReporter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef _UI_INPUT_REPORTER_H
+#define _UI_INPUT_REPORTER_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+/*
+ * The interface used by the InputDispatcher to report information about input events after
+ * it is sent to the application, such as if a key is unhandled or dropped.
+ */
+class InputReporter: public virtual RefBase {
+protected:
+    virtual ~InputReporter() { }
+
+public:
+    // Report a key that was not handled by the system or apps.
+    // A key event is unhandled if:
+    //   - The event was not handled and there is no fallback key; or
+    //   - The event was not handled and it has a fallback key,
+    //       but the fallback key was not handled.
+    virtual void reportUnhandledKey(uint32_t sequenceNum);
+
+    // Report a key that was dropped by InputDispatcher.
+    // A key can be dropped for several reasons. See the enum
+    // InputDispatcher::DropReason for details.
+    virtual void reportDroppedKey(uint32_t sequenceNum);
+};
+
+/*
+ * Factory method for InputReporter.
+ */
+sp<InputReporter> createInputReporter();
+
+} // namespace android
+
+#endif // _UI_INPUT_REPORTER_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02cd9d9..4d68559 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3337,7 +3337,7 @@
             if (composerStateContainsUnsignaledFences(states)) {
                 break;
             }
-            applyTransactionState(states, displays, flags);
+            applyTransactionState(states, displays, flags, mInputWindowCommands);
             transactionQueue.pop();
         }
 
@@ -3383,7 +3383,8 @@
 
 void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
                                          const Vector<DisplayState>& displays, uint32_t flags,
-                                         const sp<IBinder>& applyToken) {
+                                         const sp<IBinder>& applyToken,
+                                         const InputWindowCommands& inputWindowCommands) {
     ATRACE_CALL();
     Mutex::Autolock _l(mStateLock);
 
@@ -3399,11 +3400,12 @@
         return;
     }
 
-    applyTransactionState(states, displays, flags);
+    applyTransactionState(states, displays, flags, inputWindowCommands);
 }
 
 void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
-                                           const Vector<DisplayState>& displays, uint32_t flags) {
+                                           const Vector<DisplayState>& displays, uint32_t flags,
+                                           const InputWindowCommands& inputWindowCommands) {
     uint32_t transactionFlags = 0;
 
     if (flags & eAnimation) {
@@ -3444,6 +3446,8 @@
         setDestroyStateLocked(state);
     }
 
+    transactionFlags |= addInputWindowCommands(inputWindowCommands);
+
     // If a synchronous transaction is explicitly requested without any changes, force a transaction
     // anyway. This can be used as a flush mechanism for previous async transactions.
     // Empty animation transaction can be used to simulate back-pressure, so also force a
@@ -3781,6 +3785,16 @@
     }
 }
 
+uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
+    uint32_t flags = 0;
+    if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
+        flags |= eTraversalNeeded;
+    }
+
+    mInputWindowCommands.merge(inputWindowCommands);
+    return flags;
+}
+
 status_t SurfaceFlinger::createLayer(
         const String8& name,
         const sp<Client>& client,
@@ -3995,7 +4009,7 @@
     d.width = 0;
     d.height = 0;
     displays.add(d);
-    setTransactionState(state, displays, 0, nullptr);
+    setTransactionState(state, displays, 0, nullptr, mInputWindowCommands);
 
     const auto display = getDisplayDevice(displayToken);
     if (!display) return;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 822bb18..c37f159 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -443,7 +443,8 @@
     virtual sp<IBinder> getBuiltInDisplay(int32_t id);
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken);
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& inputWindowCommands);
     virtual void bootFinished();
     virtual bool authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -555,8 +556,8 @@
      * Transactions
      */
     void applyTransactionState(const Vector<ComposerState>& state,
-                               const Vector<DisplayState>& displays, uint32_t flags)
-            REQUIRES(mStateLock);
+                               const Vector<DisplayState>& displays, uint32_t flags,
+                               const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock);
     bool flushTransactionQueues();
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t peekTransactionFlags();
@@ -570,6 +571,7 @@
     uint32_t setClientStateLocked(const ComposerState& composerState);
     uint32_t setDisplayStateLocked(const DisplayState& s);
     void setDestroyStateLocked(const ComposerState& composerState);
+    uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
 
     /* ------------------------------------------------------------------------
      * Layer management
@@ -1020,6 +1022,8 @@
     sp<Scheduler::ConnectionHandle> mSfConnectionHandle;
 
     sp<IInputFlinger> mInputFlinger;
+
+    InputWindowCommands mInputWindowCommands;
 };
 }; // namespace android