Properly synchronize interactivity state.

Volatile doesn't provide any guarantees with respect to write
visibility, so it's possible that PowerManager will tell InputManager
about a change in interactivity state, but the actual dispatching
thread will never observe it.

Also, add logging about NativeInputManager state.

Bug: 22422588
Change-Id: Ifc3add992b9009d920d80a0315ff89c9574be20d
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index f3edbd1..e29d0a9 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -27,6 +27,8 @@
 
 #include "JNIHelp.h"
 #include "jni.h"
+#include <atomic>
+#include <cinttypes>
 #include <limits.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/Log.h>
@@ -56,6 +58,8 @@
 #include "com_android_server_input_InputApplicationHandle.h"
 #include "com_android_server_input_InputWindowHandle.h"
 
+#define INDENT "  "
+
 namespace android {
 
 // The exponent used to calculate the pointer speed scaling factor.
@@ -126,6 +130,10 @@
     return a > b ? a : b;
 }
 
+static inline const char* toString(bool value) {
+    return value ? "true" : "false";
+}
+
 static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
         const sp<InputApplicationHandle>& inputApplicationHandle) {
     if (inputApplicationHandle == NULL) {
@@ -262,7 +270,7 @@
         wp<PointerController> pointerController;
     } mLocked;
 
-    volatile bool mInteractive;
+    std::atomic<bool> mInteractive;
 
     void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
     void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
@@ -292,6 +300,7 @@
         mLocked.pointerGesturesEnabled = true;
         mLocked.showTouches = false;
     }
+    mInteractive = true;
 
     sp<EventHub> eventHub = new EventHub();
     mInputManager = new InputManager(eventHub, this, this);
@@ -305,6 +314,21 @@
 }
 
 void NativeInputManager::dump(String8& dump) {
+    dump.append("Input Manager State:\n");
+    {
+        dump.appendFormat(INDENT "Interactive: %s\n", toString(mInteractive.load()));
+    }
+    {
+        AutoMutex _l(mLock);
+        dump.appendFormat(INDENT "System UI Visibility: 0x%0" PRIx32 "\n",
+                mLocked.systemUiVisibility);
+        dump.appendFormat(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
+        dump.appendFormat(INDENT "Pointer Gestures Enabled: %s\n",
+                toString(mLocked.pointerGesturesEnabled));
+        dump.appendFormat(INDENT "Show Touches: %s\n", toString(mLocked.showTouches));
+    }
+    dump.append("\n");
+
     mInputManager->getReader()->dump(dump);
     dump.append("\n");
 
@@ -830,7 +854,8 @@
     // - Ignore untrusted events and pass them along.
     // - Ask the window manager what to do with normal events and trusted injected events.
     // - For normal events wake and brighten the screen if currently off or dim.
-    if (mInteractive) {
+    bool interactive = mInteractive.load();
+    if (interactive) {
         policyFlags |= POLICY_FLAG_INTERACTIVE;
     }
     if ((policyFlags & POLICY_FLAG_TRUSTED)) {
@@ -854,7 +879,7 @@
 
         handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
     } else {
-        if (mInteractive) {
+        if (interactive) {
             policyFlags |= POLICY_FLAG_PASS_TO_USER;
         }
     }
@@ -866,7 +891,8 @@
     // - No special filtering for injected events required at this time.
     // - Filter normal events based on screen state.
     // - For normal events brighten (but do not wake) the screen if currently dim.
-    if (mInteractive) {
+    bool interactive = mInteractive.load();
+    if (interactive) {
         policyFlags |= POLICY_FLAG_INTERACTIVE;
     }
     if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
@@ -885,7 +911,7 @@
             handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
         }
     } else {
-        if (mInteractive) {
+        if (interactive) {
             policyFlags |= POLICY_FLAG_PASS_TO_USER;
         }
     }