Fix race reading input configuration during system startup.

Change-Id: I9360c4ec5c29937fce06b44ffc71fca58c8b3d5f
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 024aec5..29ca9a4 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -53,10 +53,6 @@
     private final Context mContext;
     private final WindowManagerService mWindowManagerService;
     
-    private int mTouchScreenConfig;
-    private int mKeyboardConfig;
-    private int mNavigationConfig;
-    
     private static native void nativeInit(Callbacks callbacks);
     private static native void nativeStart();
     private static native void nativeSetDisplaySize(int displayId, int width, int height);
@@ -79,6 +75,7 @@
     private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
     private static native void nativeSetFocusedApplication(InputApplication application);
     private static native InputDevice nativeGetInputDevice(int deviceId);
+    private static native void nativeGetInputConfiguration(Configuration configuration);
     private static native int[] nativeGetInputDeviceIds();
     private static native String nativeDump();
     
@@ -114,10 +111,6 @@
         
         this.mCallbacks = new Callbacks();
         
-        mTouchScreenConfig = Configuration.TOUCHSCREEN_NOTOUCH;
-        mKeyboardConfig = Configuration.KEYBOARD_NOKEYS;
-        mNavigationConfig = Configuration.NAVIGATION_NONAV;
-        
         init();
     }
     
@@ -154,9 +147,7 @@
             throw new IllegalArgumentException("config must not be null.");
         }
         
-        config.touchscreen = mTouchScreenConfig;
-        config.keyboard = mKeyboardConfig;
-        config.navigation = mNavigationConfig;
+        nativeGetInputConfiguration(config);
     }
     
     /**
@@ -367,12 +358,7 @@
         }
         
         @SuppressWarnings("unused")
-        public void notifyConfigurationChanged(long whenNanos,
-                int touchScreenConfig, int keyboardConfig, int navigationConfig) {
-            mTouchScreenConfig = touchScreenConfig;
-            mKeyboardConfig = keyboardConfig;
-            mNavigationConfig = navigationConfig;
-            
+        public void notifyConfigurationChanged(long whenNanos) {
             mWindowManagerService.sendNewConfiguration();
         }
         
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index d27c2c6..e3bae56 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -138,6 +138,14 @@
     jfieldID mMotionRanges;
 } gInputDeviceClassInfo;
 
+static struct {
+    jclass clazz;
+
+    jfieldID touchscreen;
+    jfieldID keyboard;
+    jfieldID navigation;
+} gConfigurationClassInfo;
+
 // ----------------------------------------------------------------------------
 
 static inline nsecs_t now() {
@@ -698,11 +706,7 @@
 
     JNIEnv* env = jniEnv();
 
-    InputConfiguration config;
-    mInputManager->getReader()->getInputConfiguration(& config);
-
-    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged,
-            when, config.touchScreen, config.keyboard, config.navigation);
+    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
     checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
 }
 
@@ -1270,6 +1274,20 @@
     return deviceIdsObj;
 }
 
+static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
+        jclass clazz, jobject configObj) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    InputConfiguration config;
+    gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
+
+    env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
+    env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
+    env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
+}
+
 static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
     if (checkInputManagerUnitialized(env)) {
         return NULL;
@@ -1316,6 +1334,8 @@
             (void*) android_server_InputManager_nativeGetInputDevice },
     { "nativeGetInputDeviceIds", "()[I",
             (void*) android_server_InputManager_nativeGetInputDeviceIds },
+    { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
+            (void*) android_server_InputManager_nativeGetInputConfiguration },
     { "nativeDump", "()Ljava/lang/String;",
             (void*) android_server_InputManager_nativeDump },
 };
@@ -1343,7 +1363,7 @@
     FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
 
     GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
-            "notifyConfigurationChanged", "(JIII)V");
+            "notifyConfigurationChanged", "(J)V");
 
     GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
             "notifyLidSwitchChanged", "(JZ)V");
@@ -1543,6 +1563,19 @@
     GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
             "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
 
+    // Configuration
+
+    FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
+
+    GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
+            "touchscreen", "I");
+
+    GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
+            "keyboard", "I");
+
+    GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
+            "navigation", "I");
+
     return 0;
 }