Merge "Support sorting in storage UI."
diff --git a/api/current.txt b/api/current.txt
index d40832c..d5ae85f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33379,6 +33379,7 @@
     method public static int getType(char);
     method public static int getType(int);
     method public static char highSurrogate(int);
+    method public static boolean isAlphabetic(int);
     method public static boolean isBmpCodePoint(int);
     method public static boolean isDefined(char);
     method public static boolean isDefined(int);
@@ -33389,6 +33390,7 @@
     method public static boolean isISOControl(int);
     method public static boolean isIdentifierIgnorable(char);
     method public static boolean isIdentifierIgnorable(int);
+    method public static boolean isIdeographic(int);
     method public static boolean isJavaIdentifierPart(char);
     method public static boolean isJavaIdentifierPart(int);
     method public static boolean isJavaIdentifierStart(char);
@@ -33515,48 +33517,84 @@
     method public static java.lang.Character.UnicodeBlock of(char);
     method public static java.lang.Character.UnicodeBlock of(int);
     field public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+    field public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock ARABIC;
     field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
     field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock ARMENIAN;
     field public static final java.lang.Character.UnicodeBlock ARROWS;
+    field public static final java.lang.Character.UnicodeBlock AVESTAN;
+    field public static final java.lang.Character.UnicodeBlock BALINESE;
+    field public static final java.lang.Character.UnicodeBlock BAMUM;
+    field public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+    field public static final java.lang.Character.UnicodeBlock BATAK;
     field public static final java.lang.Character.UnicodeBlock BENGALI;
     field public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
     field public static final java.lang.Character.UnicodeBlock BOPOMOFO;
     field public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
     field public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+    field public static final java.lang.Character.UnicodeBlock BRAHMI;
     field public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+    field public static final java.lang.Character.UnicodeBlock BUGINESE;
     field public static final java.lang.Character.UnicodeBlock BUHID;
     field public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock CARIAN;
+    field public static final java.lang.Character.UnicodeBlock CHAM;
     field public static final java.lang.Character.UnicodeBlock CHEROKEE;
     field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
     field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
     field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
     field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock CJK_STROKES;
     field public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
     field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
     field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
     field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
     field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+    field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
     field public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
     field public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+    field public static final java.lang.Character.UnicodeBlock COPTIC;
+    field public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+    field public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+    field public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
     field public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
     field public static final java.lang.Character.UnicodeBlock CYRILLIC;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
     field public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
     field public static final java.lang.Character.UnicodeBlock DESERET;
     field public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+    field public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
     field public static final java.lang.Character.UnicodeBlock DINGBATS;
+    field public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+    field public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+    field public static final java.lang.Character.UnicodeBlock EMOTICONS;
     field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
     field public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
     field public static final java.lang.Character.UnicodeBlock GEORGIAN;
+    field public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
     field public static final java.lang.Character.UnicodeBlock GOTHIC;
     field public static final java.lang.Character.UnicodeBlock GREEK;
     field public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
@@ -33565,6 +33603,8 @@
     field public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
     field public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
     field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
     field public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
     field public static final java.lang.Character.UnicodeBlock HANUNOO;
     field public static final java.lang.Character.UnicodeBlock HEBREW;
@@ -33572,12 +33612,20 @@
     field public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
     field public static final java.lang.Character.UnicodeBlock HIRAGANA;
     field public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+    field public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
     field public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock JAVANESE;
+    field public static final java.lang.Character.UnicodeBlock KAITHI;
+    field public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
     field public static final java.lang.Character.UnicodeBlock KANBUN;
     field public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
     field public static final java.lang.Character.UnicodeBlock KANNADA;
     field public static final java.lang.Character.UnicodeBlock KATAKANA;
     field public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+    field public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
     field public static final java.lang.Character.UnicodeBlock KHMER;
     field public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock LAO;
@@ -33585,58 +33633,96 @@
     field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
     field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
     field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+    field public static final java.lang.Character.UnicodeBlock LEPCHA;
     field public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock LIMBU;
     field public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
     field public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+    field public static final java.lang.Character.UnicodeBlock LISU;
     field public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+    field public static final java.lang.Character.UnicodeBlock LYCIAN;
+    field public static final java.lang.Character.UnicodeBlock LYDIAN;
+    field public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
     field public static final java.lang.Character.UnicodeBlock MALAYALAM;
+    field public static final java.lang.Character.UnicodeBlock MANDAIC;
     field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+    field public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
     field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
     field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
     field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
     field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+    field public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
     field public static final java.lang.Character.UnicodeBlock MONGOLIAN;
     field public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock MYANMAR;
+    field public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+    field public static final java.lang.Character.UnicodeBlock NKO;
     field public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
     field public static final java.lang.Character.UnicodeBlock OGHAM;
     field public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+    field public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+    field public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+    field public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+    field public static final java.lang.Character.UnicodeBlock OL_CHIKI;
     field public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
     field public static final java.lang.Character.UnicodeBlock ORIYA;
     field public static final java.lang.Character.UnicodeBlock OSMANYA;
+    field public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+    field public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+    field public static final java.lang.Character.UnicodeBlock PHOENICIAN;
     field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
     field public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+    field public static final java.lang.Character.UnicodeBlock REJANG;
+    field public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock RUNIC;
+    field public static final java.lang.Character.UnicodeBlock SAMARITAN;
+    field public static final java.lang.Character.UnicodeBlock SAURASHTRA;
     field public static final java.lang.Character.UnicodeBlock SHAVIAN;
     field public static final java.lang.Character.UnicodeBlock SINHALA;
     field public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
     field public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
     field public static final java.lang.Character.UnicodeBlock SPECIALS;
+    field public static final java.lang.Character.UnicodeBlock SUNDANESE;
     field public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
     field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
     field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
     field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
     field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
     field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
     field public static final deprecated java.lang.Character.UnicodeBlock SURROGATES_AREA;
+    field public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
     field public static final java.lang.Character.UnicodeBlock SYRIAC;
     field public static final java.lang.Character.UnicodeBlock TAGALOG;
     field public static final java.lang.Character.UnicodeBlock TAGBANWA;
     field public static final java.lang.Character.UnicodeBlock TAGS;
     field public static final java.lang.Character.UnicodeBlock TAI_LE;
+    field public static final java.lang.Character.UnicodeBlock TAI_THAM;
+    field public static final java.lang.Character.UnicodeBlock TAI_VIET;
     field public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock TAMIL;
     field public static final java.lang.Character.UnicodeBlock TELUGU;
     field public static final java.lang.Character.UnicodeBlock THAANA;
     field public static final java.lang.Character.UnicodeBlock THAI;
     field public static final java.lang.Character.UnicodeBlock TIBETAN;
+    field public static final java.lang.Character.UnicodeBlock TIFINAGH;
+    field public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock UGARITIC;
     field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+    field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock VAI;
     field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
     field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
     field public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
     field public static final java.lang.Character.UnicodeBlock YI_RADICALS;
     field public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ffcc297..04ab0a5 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -25,6 +25,7 @@
 import android.os.Build.VERSION_CODES;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.provider.Settings;
 
 import java.net.InetAddress;
@@ -1309,4 +1310,67 @@
         } catch (RemoteException e) {
         }
     }
+
+    /**
+     * The ResultReceiver resultCode for checkMobileProvisioning (CMP_RESULT_CODE)
+     */
+
+    /**
+     * No connection was possible to the network.
+     * {@hide}
+     */
+    public static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
+
+    /**
+     * A connection was made to the internet, all is well.
+     * {@hide}
+     */
+    public static final int CMP_RESULT_CODE_CONNECTABLE = 1;
+
+    /**
+     * A connection was made but there was a redirection, we appear to be in walled garden.
+     * This is an indication of a warm sim on a mobile network.
+     * {@hide}
+     */
+    public static final int CMP_RESULT_CODE_REDIRECTED = 2;
+
+    /**
+     * A connection was made but no dns server was available to resolve a name to address.
+     * This is an indication of a warm sim on a mobile network.
+     *
+     * {@hide}
+     */
+    public static final int CMP_RESULT_CODE_NO_DNS = 3;
+
+    /**
+     * A connection was made but could not open a TCP connection.
+     * This is an indication of a warm sim on a mobile network.
+     * {@hide}
+     */
+    public static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 4;
+
+    /**
+     * Check mobile provisioning. The resultCode passed to
+     * onReceiveResult will be one of the CMP_RESULT_CODE_xxxx values above.
+     * This may take a minute or more to complete.
+     *
+     * @param sendNotificaiton, when true a notification will be sent to user.
+     * @param suggestedTimeOutMs, timeout in milliseconds
+     * @param resultReceiver needs to  be supplied to receive the result
+     *
+     * @return time out that will be used, maybe less that suggestedTimeOutMs
+     * -1 if an error.
+     *
+     * {@hide}
+     */
+    public int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs,
+            ResultReceiver resultReceiver) {
+        int timeOutMs = -1;
+        try {
+            timeOutMs = mService.checkMobileProvisioning(sendNotification, suggestedTimeOutMs,
+                    resultReceiver);
+        } catch (RemoteException e) {
+        }
+        return timeOutMs;
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index e5d6e51..3dbe078 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
+import android.os.ResultReceiver;
 
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
@@ -131,4 +132,6 @@
     void supplyMessenger(int networkType, in Messenger messenger);
 
     int findConnectionTypeForIface(in String iface);
+
+    int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs, in ResultReceiver resultReceiver);
 }
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index e85dbcd..5a1daed 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -494,6 +494,19 @@
     }
 
     /**
+     * Eanble/disable FailFast
+     *
+     * @param enabled is DctConstants.ENABLED/DISABLED
+     */
+    public void setEnableFailFastMobileData(int enabled) {
+        if (DBG) log("setEnableFailFastMobileData(enabled=" + enabled + ")");
+        final AsyncChannel channel = mDataConnectionTrackerAc;
+        if (channel != null) {
+            channel.sendMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled);
+        }
+    }
+
+    /**
      * carrier dependency is met/unmet
      * @param met
      */
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 0a694c7..20e5011 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -194,6 +194,7 @@
 	libnetutils \
 	libui \
 	libgui \
+	libinput \
 	libcamera_client \
 	libskia \
 	libsqlite \
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 9fc01e1..f768ce8 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -25,7 +25,7 @@
 #include <android_runtime/android_util_AssetManager.h>
 #include <android_runtime/android_view_Surface.h>
 #include <android_runtime/AndroidRuntime.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 
 #include <gui/Surface.h>
 
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 9fa9fe4..ce475e0 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -21,7 +21,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <binder/Parcel.h>
 #include <utils/Log.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_view_InputChannel.h"
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h
index 0967021..2ba2dc0 100644
--- a/core/jni/android_view_InputChannel.h
+++ b/core/jni/android_view_InputChannel.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index e3a54a8..8ef5d0b 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 
 #include <android_runtime/AndroidRuntime.h>
 #include <nativehelper/jni.h>
diff --git a/core/jni/android_view_InputDevice.h b/core/jni/android_view_InputDevice.h
index 78651ba..ac38eb1 100644
--- a/core/jni/android_view_InputDevice.h
+++ b/core/jni/android_view_InputDevice.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/InputDevice.h>
+#include <input/InputDevice.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 8e1e04a..b254de7 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -29,7 +29,7 @@
 #include <utils/Looper.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index b46eb4b..e4b65a1 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -29,7 +29,7 @@
 #include <utils/Looper.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index ec56afa..7532c9d 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -23,7 +23,7 @@
 #include <android/input.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_InputQueue.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/Looper.h>
 #include <utils/TypeHelpers.h>
 #include <ScopedLocalRef.h>
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index 3e56a89..ffe2dea 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -16,8 +16,8 @@
 
 #include <android_runtime/AndroidRuntime.h>
 
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/Input.h>
+#include <input/KeyCharacterMap.h>
+#include <input/Input.h>
 #include <binder/Parcel.h>
 
 #include <nativehelper/jni.h>
diff --git a/core/jni/android_view_KeyCharacterMap.h b/core/jni/android_view_KeyCharacterMap.h
index 04024f6..e8465c2 100644
--- a/core/jni/android_view_KeyCharacterMap.h
+++ b/core/jni/android_view_KeyCharacterMap.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/KeyCharacterMap.h>
+#include <input/KeyCharacterMap.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
index 36a98f9..17a0677 100644
--- a/core/jni/android_view_KeyEvent.cpp
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -20,7 +20,7 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include "android_view_KeyEvent.h"
 
 namespace android {
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index e69fb74..73c0683 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -20,7 +20,7 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include "android_os_Parcel.h"
 #include "android_view_MotionEvent.h"
 #include "android_util_Binder.h"
diff --git a/core/jni/android_view_VelocityTracker.cpp b/core/jni/android_view_VelocityTracker.cpp
index c2fa3be..90ba2ba 100644
--- a/core/jni/android_view_VelocityTracker.cpp
+++ b/core/jni/android_view_VelocityTracker.cpp
@@ -20,8 +20,8 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
-#include <androidfw/VelocityTracker.h>
+#include <input/Input.h>
+#include <input/VelocityTracker.h>
 #include "android_view_MotionEvent.h"
 
 #include <ScopedUtfChars.h>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d844076..7076922 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -783,6 +783,15 @@
     <!-- IP address of the dns server to use if nobody else suggests one -->
     <string name="config_default_dns_server" translatable="false">8.8.8.8</string>
 
+    <!-- The default mobile provisioning url. Empty by default, maybe overridden by
+         an mcc/mnc specific config.xml -->
+    <string name="mobile_provisioning_url" translatable="false"></string>
+
+    <!-- This url is used as the default url when redirection is detected. Any
+         should work as all url's get redirected. But maybe overridden by
+         if needed. -->
+    <string name="mobile_redirected_provisioning_url" translatable="false">http://google.com</string>
+
     <!-- The default character set for GsmAlphabet -->
     <!-- Empty string means MBCS is not considered -->
     <string name="gsm_alphabet_default_charset" translatable="false"></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 38aa2a0..b58fcfc 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -682,6 +682,8 @@
   <java-symbol type="string" name="preposition_for_time" />
   <java-symbol type="string" name="progress_erasing" />
   <java-symbol type="string" name="progress_unmounting" />
+  <java-symbol type="string" name="mobile_provisioning_url" />
+  <java-symbol type="string" name="mobile_redirected_provisioning_url" />
   <java-symbol type="string" name="reboot_safemode_confirm" />
   <java-symbol type="string" name="reboot_safemode_title" />
   <java-symbol type="string" name="relationTypeAssistant" />
diff --git a/docs/downloads/training/BasicSyncAdapter.zip b/docs/downloads/training/BasicSyncAdapter.zip
new file mode 100644
index 0000000..25aa8bb
--- /dev/null
+++ b/docs/downloads/training/BasicSyncAdapter.zip
Binary files differ
diff --git a/docs/html/training/sync-adapters/creating-authenticator.jd b/docs/html/training/sync-adapters/creating-authenticator.jd
new file mode 100644
index 0000000..1b272e7
--- /dev/null
+++ b/docs/html/training/sync-adapters/creating-authenticator.jd
@@ -0,0 +1,290 @@
+page.title=Creating a Stub Authenticator
+
+trainingnavtop=true
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#CreateAuthenticator">Add a Stub Authenticator Component</a>
+    </li>
+    <li>
+        <a href="#CreateAuthenticatorService">Bind the Authenticator to the Framework</a>
+    </li>
+    <li>
+        <a href="#CreateAuthenticatorFile">Add the Authenticator Metadata File</a>
+    </li>
+    <li>
+        <a href="#DeclareAuthenticator">Declare the Authenticator in the Manifest</a>
+    </li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/bound-services.html">Bound Services</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
+ <p class="filename">BasicSyncAdapter.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    The sync adapter framework assumes that your sync adapter transfers data between device storage
+    associated with an account and server storage that requires login access. For this reason, the
+    framework expects you to provide a component called an authenticator as part of your sync
+    adapter. This component plugs into the Android accounts and authentication framework and
+    provides a standard interface for handling user credentials such as login information.
+</p>
+<p>
+    Even if your app doesn't use accounts, you still need to provide an authenticator component.
+    If you don't use accounts or server login, the information handled by the authenticator is
+    ignored, so you can provide an authenticator component that contains stub method
+    implementations. You also need to provide a bound {@link android.app.Service} that
+    allows the sync adapter framework to call the authenticator's methods.
+</p>
+<p>
+    This lesson shows you how to define all the parts of a stub authenticator that you need to
+    satisfy the requirements of the sync adapter framework. If you need to provide a real
+    authenticator that handles user accounts, read the reference documentation for
+    {@link android.accounts.AbstractAccountAuthenticator}.
+</p>
+
+<h2 id="CreateAuthenticator">Add a Stub Authenticator Component</h2>
+<p>
+    To add a stub authenticator component to your app, create a class that extends
+    {@link android.accounts.AbstractAccountAuthenticator}, and then stub out the required methods,
+    either by returning {@code null} or by throwing an exception.
+</p>
+<p>
+    The following snippet shows an example of a stub authenticator class:
+</p>
+<pre>
+/*
+ * Implement AbstractAccountAuthenticator and stub out all
+ * of its methods
+ */
+public class Authenticator extends AbstractAccountAuthenticator {
+    // Simple constructor
+    public Authenticator(Context context) {
+        super(context);
+    }
+    // Editing properties is not supported
+    &#64;Override
+    public Bundle editProperties(
+            AccountAuthenticatorResponse r, String s) {
+        throw new UnsupportedOperationException();
+    }
+    // Don't add additional accounts
+    &#64;Override
+    public Bundle addAccount(
+            AccountAuthenticatorResponse r,
+            String s,
+            String s2,
+            String[] strings,
+            Bundle bundle) throws NetworkErrorException {
+        return null;
+    }
+    // Ignore attempts to confirm credentials
+    &#64;Override
+    public Bundle confirmCredentials(
+            AccountAuthenticatorResponse r,
+            Account account,
+            Bundle bundle) throws NetworkErrorException {
+        return null;
+    }
+    // Getting an authentication token is not supported
+    &#64;Override
+    public Bundle getAuthToken(
+            AccountAuthenticatorResponse r,
+            Account account,
+            String s,
+            Bundle bundle) throws NetworkErrorException {
+        throw new UnsupportedOperationException();
+    }
+    // Getting a label for the auth token is not supported
+    &#64;Override
+    public String getAuthTokenLabel(String s) {
+        throw new UnsupportedOperationException();
+    }
+    // Updating user credentials is not supported
+    &#64;Override
+    public Bundle updateCredentials(
+            AccountAuthenticatorResponse r,
+            Account account,
+            String s, Bundle bundle) throws NetworkErrorException {
+        throw new UnsupportedOperationException();
+    }
+    // Checking features for the account is not supported
+    &#64;Override
+    public Bundle hasFeatures(
+        AccountAuthenticatorResponse r,
+        Account account, String[] strings) throws NetworkErrorException {
+        throw new UnsupportedOperationException();
+    }
+}
+</pre>
+<h2 id="CreateAuthenticatorService">Bind the Authenticator to the Framework</h2>
+<p>
+    In order for the sync adapter framework to access your authenticator, you must create a bound
+    Service for it. This service provides an Android binder object that allows the framework
+    to call your authenticator and pass data between the authenticator and the framework.
+</p>
+<p>
+    Since the framework starts this {@link android.app.Service} the first time it needs to
+    access the authenticator, you can also use the service to instantiate the authenticator,
+    by calling the authenticator constructor in the
+    {@link android.app.Service#onCreate Service.onCreate()} method of the service.
+</p>
+<p>
+    The following snippet shows you how to define the bound {@link android.app.Service}:
+</p>
+<pre>
+/**
+ * A bound Service that instantiates the authenticator
+ * when started.
+ */
+public class AuthenticatorService extends Service {
+    ...
+    // Instance field that stores the authenticator object
+    private Authenticator mAuthenticator;
+    &#64;Override
+    public void onCreate() {
+        // Create a new authenticator object
+        mAuthenticator = new Authenticator(this);
+    }
+    /*
+     * When the system binds to this Service to make the RPC call
+     * return the authenticator's IBinder.
+     */
+    &#64;Override
+    public IBinder onBind(Intent intent) {
+        return mAuthenticator.getIBinder();
+    }
+}
+</pre>
+
+<h2 id="CreateAuthenticatorFile">Add the Authenticator Metadata File</h2>
+<p>
+    To plug your authenticator component into the sync adapter and account frameworks, you need to
+    provide these framework with metadata that describes the component. This metadata declares the
+    account type you've created for your sync adapter and declares user interface elements
+    that the system displays if you want to make your account type visible to the user. Declare this
+    metadata in a XML file stored in the {@code /res/xml/} directory in your app project.
+    You can give any name to the file, although it's usually called {@code authenticator.xml}.
+</p>
+<p>
+    This XML file contains a single element <code>&lt;account-authenticator&gt;</code> that
+    has the following attributes:
+</p>
+<dl>
+    <dt>
+        <code>android:accountType</code>
+    </dt>
+    <dd>
+        The sync adapter framework requires each sync adapter to have an account type, in the form
+        of a domain name. The framework uses the account type as part of the sync adapter's
+        internal identification. For servers that require login, the account type along with a
+        user account is sent to the server as part of the login credentials.
+    <p>
+        If your server doesn't require login, you still have to provide an account type. For the
+        value, use a domain name that you control. While the framework uses it to manage your
+        sync adapter, the value is not sent to your server.
+    </p>
+    </dd>
+    <dt>
+        <code>android:icon</code>
+    </dt>
+    <dd>
+        Pointer to a <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable</a>
+        resource containing an icon. If you make the sync adapter visible by specifying the
+        attribute <code>android:userVisible="true"</code> in <code>res/xml/syncadapter.xml</code>,
+        then you must provide this icon resource. It appears in the <b>Accounts</b> section of
+        the system's Settings app.
+    </dd>
+    <dt>
+        <code>android:smallIcon</code>
+    </dt>
+    <dd>
+        Pointer to a <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable</a>
+        resource containing a small version of the icon. This resource may be used instead of
+        <code>android:icon</code> in the <b>Accounts</b> section of the system's Settings app,
+        depending on the screen size.
+    </dd>
+    <dt>
+        <code>android:label</code>
+    </dt>
+    <dd>
+        Localizable string that identifies the account type to users. If you make the sync adapter
+        visible by specifying the attribute <code>android:userVisible="true"</code> in
+        <code>res/xml/syncadapter.xml</code>, then you should provide this string. It appears in the
+        <b>Accounts</b> section of the system's Settings app, next to the icon you define for the
+        authenticator.
+    </dd>
+</dl>
+<p>
+    The following snippet shows the XML file for the authenticator you created previously:
+</p>
+<pre>the
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;account-authenticator
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:accountType="example.com"
+        android:icon="&#64;drawable/ic_launcher"
+        android:smallIcon="&#64;drawable/ic_launcher"
+        android:label="&#64;string/app_name"/&gt;
+</pre>
+
+<h2 id="DeclareAuthenticator">Declare the Authenticator in the Manifest</h2>
+<p>
+    In a previous step, you created a bound {@link android.app.Service} that links the authenticator
+    to the sync adapter framework. To identify this service to the system, declare it in your app
+    manifest by adding the following
+    <code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+    element as a child element of
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>:
+</p>
+<pre>
+    &lt;service
+            android:name="com.example.android.syncadapter.AuthenticatorService"&gt;
+        &lt;intent-filter&gt;
+            &lt;action android:name="android.accounts.AccountAuthenticator"/&gt;
+        &lt;/intent-filter&gt;
+        &lt;meta-data
+            android:name="android.accounts.AccountAuthenticator"
+            android:resource="@xml/authenticator" /&gt;
+    &lt;/service&gt;
+</pre>
+<p>
+    The
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+    element sets up a filter that's triggered by the intent action
+    {@code android.accounts.AccountAuthenticator}, which sent by the system to run the
+    authenticator. When the filter is triggered, the system starts {@code AuthenticatorService},
+    the bound {@link android.app.Service} you have provided to wrap the authenticator.
+</p>
+<p>
+    The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+    element declares the metadata for the authenticator. The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>
+    attribute links the meta-data to the authentication framework. The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#rsrc">android:resource</a></code>
+    element specifies the name of the authenticator metadata file you created previously.
+</p>
+<p>
+    Besides an authenticator, a sync adapter also requires a content provider. If your app doesn't
+    use a content provider already, go to the next lesson to learn how to create a stub content
+    provider; otherwise, go to the lesson <a href="creating-sync-adapter.html"
+    >Creating a Sync Adapter</a>.
+</p>
diff --git a/docs/html/training/sync-adapters/creating-stub-provider.jd b/docs/html/training/sync-adapters/creating-stub-provider.jd
new file mode 100644
index 0000000..8f6eba0
--- /dev/null
+++ b/docs/html/training/sync-adapters/creating-stub-provider.jd
@@ -0,0 +1,203 @@
+page.title=Creating a Stub Content Provider
+
+trainingnavtop=true
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#CreateProvider">Add a Stub Content Provider</a>
+    </li>
+    <li>
+        <a href="#DeclareProvider">Declare the Provider in the Manifest</a>
+    </li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"
+        >Content Provider Basics</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
+ <p class="filename">BasicSyncAdapter.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    The sync adapter framework is designed to work with device data managed by the flexible and
+    highly secure content provider framework. For this reason, the sync adapter framework expects
+    that an app that uses the framework has already defined a content provider for its local data.
+    If the sync adapter framework tries to run your sync adapter, and your app doesn't have a
+    content provider, your sync adapter crashes.
+</p>
+<p>
+    If you're developing a new app that transfers data from a server to the device, you should
+    strongly consider storing the local data in a content provider. Besides their importance for
+    sync adapters, content providers offer a variety of security benefits and are specifically
+    designed to handle data storage on Android systems. To learn more about creating a content
+    provider, see <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"
+    >Creating a Content Provider</a>.
+</p>
+<p>
+    However, if you're already storing local data in another form, you can still use a sync
+    adapter to handle data transfer. To satisfy the sync adapter framework requirement for a
+    content provider, add a stub content provider to your app. A stub provider implements the
+    content provider class, but all of its required methods return {@code null} or {@code 0}. If you
+    add a stub provider, you can then use a sync adapter to transfer data from any storage
+    mechanism you choose.
+</p>
+<p>
+    If you already have a content provider in your app, you don't need a stub content provider.
+    In that case, you can skip this lesson and proceed to the lesson
+    <a href="creating-sync-adapter.html">Creating a Sync Adapter</a>. If you don't yet have a
+    content provider, this lesson shows you how to add a stub content provider that allows you to
+    plug your sync adapter into the framework.
+</p>
+<h2 id="CreateProvider">Add a Stub Content Provider</h2>
+<p>
+    To create a stub content provider for your app, extend the class
+    {@link android.content.ContentProvider} and stub out its required methods. The following
+    snippet shows you how to create the stub provider:
+</p>
+<pre>
+/*
+ * Define an implementation of ContentProvider that stubs out
+ * all methods
+ */
+public class StubProvider extends ContentProvider {
+    /*
+     * Always return true, indicating that the
+     * provider loaded correctly.
+     */
+    &#64;Override
+    public boolean onCreate() {
+        return true;
+    }
+    /*
+     * Return an empty String for MIME type
+     */
+    &#64;Override
+    public String getType() {
+        return new String();
+    }
+    /*
+     * query() always returns no results
+     *
+     */
+    &#64;Override
+    public Cursor query(
+            Uri uri,
+            String[] projection,
+            String selection,
+            String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+    /*
+     * insert() always returns null (no URI)
+     */
+    &#64;Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+    /*
+     * delete() always returns "no rows affected" (0)
+     */
+    &#64;Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+    /*
+     * update() always returns "no rows affected" (0)
+     */
+    public int update(
+            Uri uri,
+            ContentValues values,
+            String selection,
+            String[] selectionArgs) {
+        return 0;
+    }
+}
+</pre>
+<h2 id="DeclareProvider">Declare the Provider in the Manifest</h2>
+<p>
+    The sync adapter framework verifies that your app has a content provider by checking that your
+    app has declared a provider in its app manifest. To declare the stub provider in the
+    manifest, add a <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
+    >&lt;provider&gt;</a></code> element with  the following attributes:
+</p>
+<dl>
+    <dt>
+        <code>android:name="com.example.android.datasync.provider.StubProvider"</code>
+    </dt>
+    <dd>
+        Specifies the fully-qualified name of the class that implements the stub content provider.
+    </dd>
+    <dt>
+        <code>android:authorities="com.example.android.datasync.provider"</code>
+    </dt>
+    <dd>
+        A URI authority that identifies the stub content provider. Make this value your app's
+        package name with the string ".provider" appended to it. Even though you're declaring your
+        stub provider to the system, nothing tries to access the provider itself.
+   </dd>
+    <dt>
+        <code>android:exported="false"</code>
+    </dt>
+    <dd>
+        Determines whether other apps can access the content provider. For your stub content
+        provider, set the value to {@code false}, since there's no need to allow other apps to see
+        the provider. This value doesn't affect the interaction between the sync adapter framework
+        and the content provider.
+    </dd>
+    <dt>
+        <code>android:syncable="true"</code>
+    </dt>
+    <dd>
+        Sets a flag that indicates that the provider is syncable. If you set this flag to
+        {@code true}, you don't have to call {@link android.content.ContentResolver#setIsSyncable
+        setIsSyncable()} in your code. The flag allows the sync adapter framework to make data
+        transfers with the content provider, but transfers only occur if you do them explicitly.
+    </dd>
+</dl>
+<p>
+    The following snippet shows you how to add the
+    <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
+    >&lt;provider&gt;</a></code> element to the app manifest:
+</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.network.sync.BasicSyncAdapter"
+    android:versionCode="1"
+    android:versionName="1.0" &gt;
+    &lt;application
+        android:allowBackup="true"
+        android:icon="&#64;drawable/ic_launcher"
+        android:label="&#64;string/app_name"
+        android:theme="&#64;style/AppTheme" &gt;
+    ...
+    &lt;provider
+        android:name="com.example.android.datasync.provider.StubProvider"
+        android:authorities="com.example.android.datasync.provider"
+        android:export="false"
+        android:syncable="true"/&gt;
+    ...
+    &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+<p>
+    Now that you have created the dependencies required by the sync adapter framework, you can
+    create the component that encapsulates your data transfer code. This component is called a
+    sync adapter. The next lesson shows you how to add this component to your app.
+</p>
diff --git a/docs/html/training/sync-adapters/creating-sync-adapter.jd b/docs/html/training/sync-adapters/creating-sync-adapter.jd
new file mode 100644
index 0000000..7c59c8c
--- /dev/null
+++ b/docs/html/training/sync-adapters/creating-sync-adapter.jd
@@ -0,0 +1,658 @@
+page.title=Creating a Sync Adapter
+
+trainingnavtop=true
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#CreateSyncAdapter"
+        >Create the Sync Adapter Class</a>
+    </li>
+    <li>
+        <a href="#CreateSyncAdapterService">Bind the Sync Adapter to the Framework</a>
+    </li>
+    <li>
+        <a href="#CreateAccountTypeAccount"
+        >Add the Account Required by the Framework</a>
+    </li>
+    <li>
+        <a href="#CreateSyncAdapterMetadata">Add the Sync Adapter Metadata File</a>
+    </li>
+    <li>
+        <a href="#DeclareSyncAdapterManifest">Declare the Sync Adapter in the Manifest</a>
+    </li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/bound-services.html">Bound Services</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+    </li>
+    <li>
+        <a href="{@docRoot}training/id-auth/custom_auth.html">Creating a Custom Account Type</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
+ <p class="filename">BasicSyncAdapter.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    The sync adapter component in your app encapsulates the code for the tasks that transfer
+    data between the device and a server. Based on the scheduling and triggers you provide in
+    your app, the sync adapter framework runs the code in the sync adapter component. To add a
+    sync adapter component to your app, you need to add the following pieces:
+<dl>
+    <dt>
+        Sync adapter class.
+    </dt>
+    <dd>
+        A class that wraps your data transfer code in an interface compatible with the sync adapter
+        framework.
+    </dd>
+    <dt>
+        Bound {@link android.app.Service}.
+    </dt>
+    <dd>
+        A component that allows the sync adapter framework to run the code in your sync adapter
+        class.
+    </dd>
+    <dt>
+        Sync adapter XML metadata file.
+    </dt>
+    <dd>
+        A file containing information about your sync adapter. The framework reads this file to
+        find out how to load and schedule your data transfer.
+    </dd>
+    <dt>
+        Declarations in the app manifest.
+    </dt>
+    <dd>
+        XML that declares the bound service and points to sync adapter-specific metadata.
+    </dd>
+</dl>
+<p>
+    This lesson shows you how to define these elements.
+</p>
+<h2 id="CreateSyncAdapter">Create a Sync Adapter Class</h2>
+<p>
+    In this part of the lesson you learn how to create the sync adapter class that encapsulates the
+    data transfer code. Creating the class includes extending the sync adapter base class, defining
+    constructors for the class, and implementing the method where you define the data transfer
+    tasks.
+</p>
+<h3>Extend the base sync adapter class AbstractThreadedSyncAdapter</h3>
+<p>
+    To create the sync adapter component, start by extending
+    {@link android.content.AbstractThreadedSyncAdapter} and writing its constructors. Use the
+    constructors to run setup tasks each time your sync adapter component is created from
+    scratch, just as you use {@link android.app.Activity#onCreate Activity.onCreate()} to set up an
+    activity. For example, if your app uses a content provider to store data, use the constructors
+    to get a {@link android.content.ContentResolver} instance. Since a second form of the
+    constructor was added in Android platform version 3.0 to support the {@code parallelSyncs}
+    argument, you need to create two forms of the constructor to maintain compatibility.
+</p>
+<p class="note">
+    <strong>Note:</strong> The sync adapter framework is designed to work with sync adapter
+    components that are singleton instances. Instantiating the sync adapter component is covered
+    in more detail in the section
+    <a href="#CreateSyncAdapterService">Bind the Sync Adapter to the Framework</a>.
+</p>
+<p>
+    The following example shows you how to implement
+    {@link android.content.AbstractThreadedSyncAdapter}and its constructors:
+</p>
+<pre style="clear: right">
+/**
+ * Handle the transfer of data between a server and an
+ * app, using the Android sync adapter framework.
+ */
+public class SyncAdapter extends AbstractThreadedSyncAdapter {
+    ...
+    // Global variables
+    // Define a variable to contain a content resolver instance
+    ContentResolver mContentResolver;
+    /**
+     * Set up the sync adapter
+     */
+    public SyncAdapter(Context context, boolean autoInitialize) {
+        super(context, autoInitialize);
+        /*
+         * If your app uses a content resolver, get an instance of it
+         * from the incoming Context
+         */
+        mContentResolver = context.getContentResolver();
+    }
+    ...
+    /**
+     * Set up the sync adapter. This form of the
+     * constructor maintains compatibility with Android 3.0
+     * and later platform versions
+     */
+    public SyncAdapter(
+            Context context,
+            boolean autoInitialize,
+            boolean allowParallelSyncs) {
+        super(context, autoInitialize, allowParallelSyncs);
+        /*
+         * If your app uses a content resolver, get an instance of it
+         * from the incoming Context
+         */
+        mContentResolver = context.getContentResolver();
+        ...
+    }
+</pre>
+<h3>Add the data transfer code to onPerformSync()</h3>
+<p>
+    The sync adapter component does not automatically do data transfer. Instead, it
+    encapsulates your data transfer code, so that the sync adapter framework can run the
+    data transfer in the background, without involvement from your app. When the framework is ready
+    to sync your application's data, it invokes your implementation of the method
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}.
+</p>
+<p>
+    To facilitate the transfer of data from your main app code to the sync adapter component,
+    the sync adapter framework calls
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} with the
+    following arguments:
+</p>
+<dl>
+    <dt>
+        Account
+    </dt>
+    <dd>
+        An {@link android.accounts.Account} object associated with the event that triggered
+        the sync adapter. If your server doesn't use accounts, you don't need to use the
+        information in this object.
+    </dd>
+    <dt>
+        Extras
+    </dt>
+    <dd>
+        A {@link android.os.Bundle} containing flags sent by the event that triggered the sync
+        adapter.
+    </dd>
+    <dt>
+        Authority
+    </dt>
+    <dd>
+        The authority of a content provider in the system. Your app has to have access to
+        this provider. Usually, the authority corresponds to a content provider in your own app.
+    </dd>
+    <dt>
+        Content provider client
+    </dt>
+    <dd>
+        A {@link android.content.ContentProviderClient} for the content provider pointed to by the
+        authority argument. A {@link android.content.ContentProviderClient} is a lightweight public
+        interface to a content provider. It has the same basic functionality as a
+        {@link android.content.ContentResolver}. If you're using a content provider to store data
+        for your app, you can connect to the provider with this object. Otherwise, you can ignore
+        it.
+    </dd>
+    <dt>
+        Sync result
+    </dt>
+    <dd>
+        A {@link android.content.SyncResult} object that you use to send information to the sync
+        adapter framework.
+    </dd>
+</dl>
+<p>
+    The following snippet shows the overall structure of
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}:
+</p>
+<pre>
+    /*
+     * Specify the code you want to run in the sync adapter. The entire
+     * sync adapter runs in a background thread, so you don't have to set
+     * up your own background processing.
+     */
+    &#64;Override
+    public void onPerformSync(
+            Account account,
+            Bundle extras,
+            String authority,
+            ContentProviderClient provider,
+            SyncResult syncResult) {
+    /*
+     * Put the data transfer code here.
+     */
+    ...
+    }
+</pre>
+<p>
+    While the actual implementation of
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} is specific to
+    your app's data synchronization requirements and server connection protocols, there are a few
+    general tasks your implementation should perform:
+</p>
+<dl>
+    <dt>
+        Connecting to a server
+    </dt>
+    <dd>
+        Although you can assume that the network is available when your data transfer starts, the
+        sync adapter framework doesn't automatically connect to a server.
+    </dd>
+    <dt>
+        Downloading and uploading data
+    </dt>
+    <dd>
+        A sync adapter doesn't automate any data transfer tasks. If you want to download
+        data from a server and store it in a content provider, you have to provide the code that
+        requests the data, downloads it, and inserts it in the provider. Similarly, if you want to
+        send data to a server, you have to read it from a file, database, or provider, and send
+        the necessary upload request. You also have to handle network errors that occur while your
+        data transfer is running.
+    </dd>
+    <dt>
+        Handling data conflicts or determining how current the data is
+    </dt>
+    <dd>
+        A sync adapter doesn't automatically handle conflicts between data on the server and data
+        on the device. Also, it doesn't automatically detect if the data on the server is newer than
+        the data on the device, or vice versa. Instead, you have to provide your own algorithms for
+        handling this situation.
+    </dd>
+    <dt>
+        Clean up.
+    </dt>
+    <dd>
+        Always close connections to a server and clean up temp files and caches at the end of
+        your data transfer.
+    </dd>
+</dl>
+<p class="note">
+    <strong>Note:</strong> The sync adapter framework runs
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} on a
+    background thread, so you don't have to set up your own background processing.
+</p>
+<p>
+    In addition to your sync-related tasks, you should try to combine your regular
+    network-related tasks and add them to
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()}.
+    By concentrating all of your network tasks in this method, you conserve the battery power that's
+    needed to start and stop the network interfaces. To learn more about making network access more
+    efficient, see the training class <a href="{@docRoot}training/efficient-downloads/index.html"
+    >Transferring Data Without Draining the Battery</a>, which describes several network access
+    tasks you can include in your data transfer code.
+</p>
+<h2 id="CreateSyncAdapterService">Bind the Sync Adapter to the Framework</h2>
+<p>
+    You now have your data transfer code encapsulated in a sync adapter component, but you have
+    to provide the framework with access to your code. To do this, you need to create a bound
+    {@link android.app.Service} that passes a special Android binder object from the sync adapter
+    component to the framework. With this binder object, the framework can invoke the
+    {@link android.content.AbstractThreadedSyncAdapter#onPerformSync onPerformSync()} method and
+    pass data to it.
+</p>
+<p>
+    Instantiate your sync adapter component as a singleton in the
+    {@link android.app.Service#onCreate onCreate()} method of the service. By instantiating
+    the component in {@link android.app.Service#onCreate onCreate()}, you defer
+    creating it until the service starts, which happens when the framework first tries to run your
+    data transfer. You need to instantiate the component in a thread-safe manner, in case the sync
+    adapter framework queues up multiple executions of your sync adapter in response to triggers or
+    scheduling.
+</p>
+<p>
+    For example, the following snippet shows you how to create a class that implements the
+    bound {@link android.app.Service}, instantiates your sync adapter component, and gets the
+    Android binder object:
+</p>
+<pre>
+package com.example.android.syncadapter;
+/**
+ * Define a Service that returns an {@link android.os.IBinder} for the
+ * sync adapter class, allowing the sync adapter framework to call
+ * onPerformSync().
+ */
+public class SyncService extends Service {
+    // Storage for an instance of the sync adapter
+    private static SyncAdapter sSyncAdapter = null;
+    // Object to use as a thread-safe lock
+    private static final Object sSyncAdapterLock = new Object();
+    /*
+     * Instantiate the sync adapter object.
+     */
+    &#64;Override
+    public void onCreate() {
+        /*
+         * Create the sync adapter as a singleton.
+         * Set the sync adapter as syncable
+         * Disallow parallel syncs
+         */
+        synchronized (sSyncAdapterLock) {
+            if (sSyncAdapter == null) {
+                sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
+            }
+        }
+    }
+    /**
+     * Return an object that allows the system to invoke
+     * the sync adapter.
+     *
+     */
+    &#64;Override
+    public IBinder onBind(Intent intent) {
+        /*
+         * Get the object that allows external processes
+         * to call onPerformSync(). The object is created
+         * in the base class code when the SyncAdapter
+         * constructors call super()
+         */
+        return sSyncAdapter.getSyncAdapterBinder();
+    }
+}
+</pre>
+<p class="note">
+    <strong>Note:</strong> To see a more detailed example of a bound service for a sync adapter,
+    see the sample app.
+</p>
+<h2 id="CreateAccountTypeAccount">Add the Account Required by the Framework</h2>
+<p>
+    The sync adapter framework requires each sync adapter to have an account type. You declared
+    the account type value in the section
+    <a href="creating-authenticator.html#CreateAuthenticatorFile"
+    >Add the Authenticator Metadata File</a>. Now you have to set up this account type in the
+    Android system. To set up the account type, add a dummy account that uses the account type
+    by calling {@link android.accounts.AccountManager#addAccountExplicitly addAccountExplicitly()}.
+</p>
+<p>
+    The best place to call the method is in the
+    {@link android.support.v4.app.FragmentActivity#onCreate onCreate()} method of your app's
+    opening activity. The following code snippet shows you how to do this:
+</p>
+<pre>
+public class MainActivity extends FragmentActivity {
+    ...
+    ...
+    // Constants
+    // The authority for the sync adapter's content provider
+    public static final String AUTHORITY = "com.example.android.datasync.provider"
+    // An account type, in the form of a domain name
+    public static final String ACCOUNT_TYPE = "example.com";
+    // The account name
+    public static final String ACCOUNT = "dummyaccount";
+    // Instance fields
+    Account mAccount;
+    ...
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ...
+        // Create the dummy account
+        mAccount = CreateSyncAccount(this);
+        ...
+    }
+    ...
+    /**
+     * Create a new dummy account for the sync adapter
+     *
+     * @param context The application context
+     */
+    public static Account CreateSyncAccount(Context context) {
+        // Create the account type and default account
+        Account newAccount = new Account(
+                ACCOUNT, ACCOUNT_TYPE);
+        // Get an instance of the Android account manager
+        AccountManager accountManager =
+                (AccountManager) context.getSystemService(
+                        ACCOUNT_SERVICE);
+        /*
+         * Add the account and account type, no password or user data
+         * If successful, return the Account object, otherwise report an error.
+         */
+        if (accountManager.addAccountExplicitly(newAccount, null, null))) {
+            /*
+             * If you don't set android:syncable="true" in
+             * in your &lt;provider&gt; element in the manifest,
+             * then call context.setIsSyncable(account, AUTHORITY, 1)
+             * here.
+             */
+        } else {
+            /*
+             * The account exists or some other error occurred. Log this, report it,
+             * or handle it internally.
+             */
+        }
+    }
+    ...
+}
+</pre>
+<h2 id="CreateSyncAdapterMetadata">Add the Sync Adapter Metadata File</h2>
+<p>
+    To plug your sync adapter component into the framework, you need to provide the framework
+    with metadata that describes the component and provides additional flags. The metadata specifies
+    the account type you've created for your sync adapter, declares a content provider authority
+    associated with your app, controls a part of the system user interface related to sync adapters,
+    and declares other sync-related flags. Declare this metadata in a special XML file stored in
+    the {@code /res/xml/} directory in your app project. You can give any name to the file,
+    although it's usually called {@code syncadapter.xml}.
+</p>
+<p>
+    This XML file contains a single XML element <code>&lt;sync-adapter&gt;</code> that has the
+    following attributes:
+</p>
+<dl>
+    <dt><code>android:contentAuthority</code></dt>
+    <dd>
+        The URI authority for your content provider. If you created a stub content provider for
+        your app in the previous lesson <a href="creating-stub-provider.html"
+        >Creating a Stub Content Provider</a>, use the value you specified for the
+        attribute
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">android:authorities</a></code>
+        in the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
+        >&lt;provider&gt;</a></code> element you added to your app manifest. This attribute is
+        described in more detail in the section
+        <a href="creating-stub-provider.html#DeclareProvider"
+        >Declare the Provider in the Manifest</a>.
+        <br/>
+        If you're transferring data from a content provider to a server with your sync adapter, this
+        value should be the same as the content URI authority you're using for that data. This value
+        is also one of the authorities you specify in the
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">android:authorities</a></code>
+        attribute of the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"
+        >&lt;provider&gt;</a></code> element that declares your provider in your app manifest.
+    </dd>
+    <dt><code>android:accountType</code></dt>
+    <dd>
+        The account type required by the sync adapter framework. The value must be the same
+        as the account type value you provided when you created the authenticator metadata file, as
+        described in the section <a href="creating-authenticator.html#CreateAuthenticatorFile"
+        >Add the Authenticator Metadata File</a>. It's also the value you specified for the
+        constant {@code ACCOUNT_TYPE} in the code snippet in the section
+        <a href="#CreateAccountTypeAccount">Add the Account Required by the Framework</a>.
+    </dd>
+    <dt>Settings attributes</dt>
+    <dd>
+        <dl>
+            <dt>
+                {@code android:userVisible}
+            </dt>
+            <dd>
+                Sets the visibility of the sync adapter's account type. By default, the
+                account icon and label associated with the account type are visible in the
+                <b>Accounts</b> section of the system's Settings app, so you should make your sync
+                adapter invisible unless you have an account type or domain that's easily associated
+                with your app. If you make your account type invisible, you can still allow users to
+                control your sync adapter with a user interface in one of your app's activities.
+            </dd>
+            <dt>
+                {@code android:supportsUploading}
+            </dt>
+            <dd>
+                Allows you to upload data to the cloud. Set this to {@code false} if your app only
+                downloads data.
+            </dd>
+            <dt>
+                {@code android:allowParallelSyncs}
+            </dt>
+            <dd>
+                Allows multiple instances of your sync adapter component to run at the same time.
+                Use this if your app supports multiple user accounts and you want to allow multiple
+                users to transfer data in parallel. This flag has no effect if you never run
+                multiple data transfers.
+            </dd>
+            <dt>
+                {@code android:isAlwaysSyncable}
+            </dt>
+            <dd>
+                Indicates to the sync adapter framework that it can run your sync adapter at any
+                time you've specified. If you want to programmatically control when your sync
+                adapter can run, set this flag to {@code false}, and then call
+                {@link android.content.ContentResolver#requestSync requestSync()} to run the
+                sync adapter. To learn more about running a sync adapter, see the lesson
+                <a href="running-sync-adapter.html">Running a Sync Adapter</a>
+            </dd>
+        </dl>
+    </dd>
+</dl>
+<p>
+    The following example shows the XML for a sync adapter that uses a single dummy account and
+    only does downloads.
+</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;sync-adapter
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:contentAuthority="com.example.android.datasync.provider"
+        android:accountType="com.android.example.datasync"
+        android:userVisible="false"
+        android:supportsUploading="false"
+        android:allowParallelSyncs="false"
+        android:isAlwaysSyncable="true"/&gt;
+</pre>
+
+<h2 id="DeclareSyncAdapterManifest">Declare the Sync Adapter in the Manifest</h2>
+<p>
+    Once you've added the sync adapter component to your app, you have to request permissions
+    related to using the component, and you have to declare the bound {@link android.app.Service}
+    you've added.
+</p>
+<p>
+    Since the sync adapter component runs code that transfers data between the network and the
+    device, you need to request permission to access the Internet. In addition, your app needs
+    to request permission to read and write sync adapter settings, so you can control the sync
+    adapter programmatically from other components in your app. You also need to request a
+    special permission that allows your app to use the authenticator component you created
+    in the lesson <a href="creating-authenticator.html">Creating a Stub Authenticator</a>.
+</p>
+<p>
+    To request these permissions, add the following to your app manifest as child elements of
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>:
+</p>
+<dl>
+    <dt>
+        {@link android.Manifest.permission#INTERNET android.permission.INTERNET}
+    </dt>
+    <dd>
+        Allows the sync adapter code to access the Internet so that it can download or upload data
+        from the device to a server. You don't need to add this permission again if you were
+        requesting it previously.
+    </dd>
+    <dt>
+{@link android.Manifest.permission#READ_SYNC_SETTINGS android.permission.READ_SYNC_SETTINGS}
+    </dt>
+    <dd>
+        Allows your app to read the current sync adapter settings. For example, you need this
+        permission in order to call {@link android.content.ContentResolver#getIsSyncable
+        getIsSyncable()}.
+    </dd>
+    <dt>
+{@link android.Manifest.permission#WRITE_SYNC_SETTINGS android.permission.WRITE_SYNC_SETTINGS}
+    </dt>
+    <dd>
+        Allows your app to control sync adapter settings. You need this permission in order to
+        set periodic sync adapter runs using {@link android.content.ContentResolver#addPeriodicSync
+        addPeriodicSync()}. This permission is <b>not</b> required to call
+        {@link android.content.ContentResolver#requestSync requestSync()}. To learn more about
+        running the sync adapter, see <a href="running-sync-adapter.html"
+        >Running A Sync Adapter</a>.
+    </dd>
+    <dt>
+{@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS android.permission.AUTHENTICATE_ACCOUNTS}
+    </dt>
+    <dd>
+        Allows you to use the authenticator component you created in the lesson
+        <a href="creating-authenticator.html">Creating a Stub Authenticator</a>.
+    </dd>
+</dl>
+<p>
+    The following snippet shows how to add the permissions:
+</p>
+<pre>
+&lt;manifest&gt;
+...
+    &lt;uses-permission
+            android:name="android.permission.INTERNET"/&gt;
+    &lt;uses-permission
+            android:name="android.permission.READ_SYNC_SETTINGS"/&gt;
+    &lt;uses-permission
+            android:name="android.permission.WRITE_SYNC_SETTINGS"/&gt;
+    &lt;uses-permission
+            android:name="android.permission.AUTHENTICATE_ACCOUNTS"/&gt;
+...
+&lt;/manifest&gt;
+</pre>
+<p>
+    Finally, to declare the bound {@link android.app.Service} that the framework uses to
+    interact with your sync adapter, add the following XML to your app manifest as a child element
+    of <code><a href="{@docRoot}guide/topics/manifest/application-element.html"
+    >&lt;application&gt;</a></code>:
+</p>
+<pre>
+        &lt;service
+                android:name="com.example.android.datasync.SyncService"
+                android:exported="true"
+                android:process=":sync"&gt;
+            &lt;intent-filter&gt;com.example.android.datasync.provider
+                &lt;action android:name="android.content.SyncAdapter"/&gt;
+            &lt;/intent-filter&gt;
+            &lt;meta-data android:name="android.content.SyncAdapter"
+                    android:resource="&#64;xml/syncadapter" /&gt;
+        &lt;/service&gt;
+</pre>
+<p>
+    The
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+    element sets up a filter that's triggered by the intent action
+    {@code android.content.SyncAdapter}, sent by the system to run the sync adapter. When the filter
+    is triggered, the system starts the bound service you've created, which in this example is
+    {@code SyncService}. The attribute
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html#exported">android:exported="true"</a></code>
+    allows processes other than your app (including the system) to access the
+    {@link android.app.Service}. The attribute
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html#proc">android:process=":sync"</a></code>
+    tells the system to run the {@link android.app.Service} in a global shared process named
+    {@code sync}. If you have multiple sync adapters in your app they can share this process,
+    which reduces overhead.
+</p>
+<p>
+    The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+    element provides provides the name of the sync adapter metadata XML file you created previously.
+    The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>
+    attribute indicates that this metadata is for the sync adapter framework. The
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#rsrc">android:resource</a></code>
+    element specifies the name of the metadata file.
+</p>
+<p>
+    You now have all of the components for your sync adapter. The next lesson shows you how to
+    tell the sync adapter framework to run your sync adapter, either in response to an event or on
+    a regular schedule.
+</p>
diff --git a/docs/html/training/sync-adapters/index.jd b/docs/html/training/sync-adapters/index.jd
new file mode 100644
index 0000000..1f7977b
--- /dev/null
+++ b/docs/html/training/sync-adapters/index.jd
@@ -0,0 +1,135 @@
+page.title=Transferring Data Using Sync Adapters
+
+trainingnavtop=true
+startpage=true
+
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+    <li>Android 3.0 (API Level 11) or higher</li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/bound-services.html">Bound Services</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+    </li>
+    <li>
+        <a href="{@docRoot}training/id-auth/custom_auth.html">Creating a Custom Account Type</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
+ <p class="filename">BasicSyncAdapter.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    Synchronizing data between an Android device and web servers can make your application
+    significantly more useful and compelling for your users. For example, transferring data to a web
+    server makes a useful backup, and transferring data from a server makes it available to the user
+    even when the device is offline. In some cases, users may find it easier to enter and edit their
+    data in a web interface and then have that data available on their device, or they may want to
+    collect data over time and then upload it to a central storage area.
+</p>
+<p>
+    Although you can design your own system for doing data transfers in your app, you should
+    consider using Android's sync adapter framework. This framework helps manage and automate data
+    transfers, and coordinates synchronization operations across different apps. When you use
+    this framework, you can take advantage of several features that aren't available to data
+    transfer schemes you design yourself:
+</p>
+<dl>
+    <dt>
+        Plug-in architecture
+    </dt>
+    <dd>
+        Allows you to add data transfer code to the system in the form of callable components.
+    </dd>
+    <dt>
+        Automated execution
+    </dt>
+    <dd>
+        Allows you to automate data transfer based on a variety of criteria, including data changes,
+        elapsed time, or time of day. In addition, the system adds transfers that are unable to
+        run to a queue, and runs them when possible.
+    </dd>
+    <dt>
+        Automated network checking
+    </dt>
+    <dd>
+        The system only runs your data transfer when the device has network connectivity.
+    </dd>
+    <dt>
+        Improved battery performance
+    </dt>
+    <dd>
+        Allows you to centralize all of your app's data transfer tasks in one place, so that they
+        all run at the same time. Your data transfer is also scheduled in conjunction with data
+        transfers from other apps. These factors reduce the number of times the system has to
+        switch on the network, which reduces battery usage.
+    </dd>
+    <dt>
+        Account management and authentication
+    </dt>
+    <dd>
+        If your app requires user credentials or server login, you can optionally
+        integrate account management and authentication into your data transfer.
+    </dd>
+</dl>
+<p>
+    This class shows you how to create a sync adapter and the bound {@link android.app.Service} that
+    wraps it, how to provide the other components that help you plug the sync adapter into the
+    framework, and how to run the sync adapter to run in various ways.
+</p>
+<p class="note">
+    <strong>Note:</strong> Sync adapters run asynchronously, so you should use them with the
+    expectation that they transfer data regularly and efficiently, but not instantaneously. If
+    you need to do real-time data transfer, you should do it in an {@link android.os.AsyncTask} or
+    an {@link android.app.IntentService}.
+</p>
+<h2>Lessons</h2>
+<dl>
+    <dt>
+        <b><a href="creating-authenticator.html">Creating a Stub Authenticator</a></b>
+    </dt>
+    <dd>
+        Learn how to add an account-handling component that the sync adapter framework expects to be
+        part of your app. This lesson shows you how to create a stub authentication component for
+        simplicity.
+    </dd>
+    <dt>
+        <b><a href="creating-stub-provider.html">Creating a Stub Content Provider</a></b>
+    </dt>
+    <dd>
+        Learn how to add a content provider component that the sync adapter framework expects to be
+        part of your app. This lesson assumes that your app doesn't use a content provider, so it
+        shows you how to add a stub component. If you have a content provider already in your app,
+        you can skip this lesson.
+    </dd>
+    <dt>
+        <b><a href="creating-sync-adapter.html">Creating a Sync Adapter</a></b>
+    </dt>
+    <dd>
+        Learn how to encapsulate your data transfer code in a component that the sync
+        adapter framework can run automatically.
+    </dd>
+    <dt>
+        <b><a href="running-sync-adapter.html">Running a Sync Adapter</a></b>
+    </dt>
+    <dd>
+        Learn how to trigger and schedule data transfers using the sync adapter framework.
+    </dd>
+</dl>
diff --git a/docs/html/training/sync-adapters/running-sync-adapter.jd b/docs/html/training/sync-adapters/running-sync-adapter.jd
new file mode 100644
index 0000000..8fb7e80c
--- /dev/null
+++ b/docs/html/training/sync-adapters/running-sync-adapter.jd
@@ -0,0 +1,524 @@
+page.title=Running a Sync Adapter
+
+trainingnavtop=true
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you how to:</h2>
+<ol>
+    <li><a href="#RunByMessage">Run the Sync Adapter When Server Data Changes</a>
+    <li><a href="#RunDataChange">Run the Sync Adapter When Content Provider Data Changes</a></li>
+    <li><a href="#RunByNetwork">Run the Sync Adapter After a Network Message</a></li>
+    <li><a href="#RunPeriodic">Run the Sync Adapter Periodically</a></li>
+    <li><a href="#RunOnDemand">Run the Sync Adapter On Demand</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+    </li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a>
+ <p class="filename">BasicSyncAdapter.zip</p>
+</div>
+
+</div>
+</div>
+<p>
+    In the previous lessons in this class, you learned how to create a sync adapter component that
+    encapsulates data transfer code, and how to add the additional components that allow you to
+    plug the sync adapter into the system. You now have everything you need to install an app that
+    includes a sync adapter, but none of the code you've seen actually runs the sync adapter.
+</p>
+<p>
+    You should try to run your sync adapter based on a schedule or as the indirect result of some
+    event. For example, you may want your sync adapter to run on a regular schedule, either after a
+    certain period of time or at a particular time of the day. You may also want to run your sync
+    adapter when there are changes to data stored on the device. You should avoid running your
+    sync adapter as the direct result of a user action, because by doing this you don't get the full
+    benefit of the sync adapter framework's scheduling ability. For example, you should avoid
+    providing a refresh button in your user interface.
+</p>
+<p>
+    You have the following options for running your sync adapter:
+</p>
+<dl>
+    <dt>
+        When server data changes
+    </dt>
+    <dd>
+        Run the sync adapter in response to a message from a server, indicating that server-based
+        data has changed. This option allows you to refresh data from the server to the device
+        without degrading performance or wasting battery life by polling the server.
+    </dd>
+    <dt>When device data changes</dt>
+    <dd>
+        Run a sync adapter when data changes on the device. This option allows you to send
+        modified data from the device to a server, and is especially useful if you need to ensure
+        that the server always has the latest device data. This option is straightforward to
+        implement if you actually store data in your content provider. If you're using a stub
+        content provider, detecting data changes may be more difficult.
+    </dd>
+    <dt>
+        When the system sends out a network message
+    </dt>
+    <dd>
+        Run a sync adapter when the Android system sends out a network message that keeps the
+        TCP/IP connection open; this message is a basic part of the networking framework. Using
+        this option is one way to run the sync adapter automatically. Consider using it in
+        conjunction with interval-based sync adapter runs.
+    </dd>
+    <dt>
+        At regular intervals
+    </dt>
+    <dd>
+        Run a sync adapter after the expiration of an interval you choose, or run it at a certain
+        time every day.
+    </dd>
+    <dt>On demand</dt>
+    <dd>
+        Run the sync adapter in response to a user action. However, to provide the best user
+        experience you should rely primarily on one of the more automated options. By using
+        automated options, you conserve battery and network resources.
+    </dd>
+</dl>
+<p>
+    The rest of this lesson describes each of the options in more detail.
+</p>
+<h2 id="RunByMessage">Run the Sync Adapter When Server Data Changes</h2>
+<p>
+    If your app transfers data from a server and the server data changes frequently, you can use
+    a sync adapter to do downloads in response to data changes. To run the sync adapter, have
+    the server send a special message to a {@link android.content.BroadcastReceiver} in your app.
+    In response to this message, call {@link android.content.ContentResolver#requestSync
+    ContentResolver.requestSync()} to signal the sync adapter framework to run your
+    sync adapter.
+</p>
+<p>
+    <a href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> (GCM) provides both the
+    server and device components you need to make this messaging system work. Using GCM to trigger
+    transfers is more reliable and more efficient than polling servers for status. While polling
+    requires a {@link android.app.Service} that is always active, GCM uses a
+    {@link android.content.BroadcastReceiver} that's activated when a message arrives. While polling
+    at regular intervals uses battery power even if no updates are available, GCM only sends
+    messages when needed.
+</p>
+<p class="note">
+    <strong>Note:</strong> If you use GCM to trigger your sync adapter via a broadcast to all
+    devices where your app is installed, remember that they receive your message at
+    roughly the same time. This situation can cause multiple instance of your sync adapter to run
+    at the same time, causing server and network overload. To avoid this situation for a broadcast
+    to all devices, you should consider deferring the start of the sync adapter for a period
+    that's unique for each device.
+<p>
+    The following code snippet shows you how to run
+    {@link android.content.ContentResolver#requestSync requestSync()} in response to an
+    incoming GCM message:
+</p>
+<pre>
+public class GcmBroadcastReceiver extends BroadcastReceiver {
+    ...
+    // Constants
+    // Content provider authority
+    public static final String AUTHORITY = "com.example.android.datasync.provider"
+    // Account type
+    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
+    // Account
+    public static final String ACCOUNT = "default_account";
+    // Incoming Intent key for extended data
+    public static final String KEY_SYNC_REQUEST =
+            "com.example.android.datasync.KEY_SYNC_REQUEST";
+    ...
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+        // Get a GCM object instance
+        GoogleCloudMessaging gcm =
+                GoogleCloudMessaging.getInstance(context);
+        // Get the type of GCM message
+        String messageType = gcm.getMessageType(intent);
+        /*
+         * Test the message type and examine the message contents.
+         * Since GCM is a general-purpose messaging system, you
+         * may receive normal messages that don't require a sync
+         * adapter run.
+         * The following code tests for a a boolean flag indicating
+         * that the message is requesting a transfer from the device.
+         */
+        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)
+            &amp;&amp;
+            intent.getBooleanExtra(KEY_SYNC_REQUEST)) {
+            /*
+             * Signal the framework to run your sync adapter. Assume that
+             * app initialization has already created the account.
+             */
+            ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
+            ...
+        }
+        ...
+    }
+    ...
+}
+</pre>
+<h2 id="RunDataChange">Run the Sync Adapter When Content Provider Data Changes</h2>
+<p>
+    If your app collects data in a content provider, and you want to update the server whenever
+    you update the provider, you can set up your app to run your sync adapter automatically. To do
+    this, you register an observer for the content provider. When data in your content provider
+    changes, the content provider framework calls the observer. In the observer, call
+    {@link android.content.ContentResolver#requestSync requestSync()} to tell the framework to run
+    your sync adapter.
+</p>
+<p class="note">
+    <strong>Note:</strong> If you're using a stub content provider, you don't have any data in
+    the content provider and {@link android.database.ContentObserver#onChange onChange()} is
+    never called. In this case, you have to provide your own mechanism for detecting changes to
+    device data. This mechanism is also responsible for calling
+    {@link android.content.ContentResolver#requestSync requestSync()} when the data changes.
+</p>
+<p>
+   To create an observer for your content provider, extend the class
+   {@link android.database.ContentObserver} and implement both forms of its
+   {@link android.database.ContentObserver#onChange onChange()} method.  In
+   {@link android.database.ContentObserver#onChange onChange()}, call
+   {@link android.content.ContentResolver#requestSync requestSync()} to start the sync adapter.
+</p>
+<p>
+   To register the observer, pass it as an argument in a call to
+   {@link android.content.ContentResolver#registerContentObserver registerContentObserver()}. In
+   this call, you also have to pass in a content URI for the data you want to watch. The content
+   provider framework compares this watch URI to content URIs passed in as arguments to
+   {@link android.content.ContentResolver} methods that modify your provider, such as
+   {@link android.content.ContentResolver#insert ContentResolver.insert()}. If there's a match, your
+   implementation of {@link android.database.ContentObserver#onChange ContentObserver.onChange()}
+   is called.
+</p>
+
+<p>
+    The following code snippet shows you how to define a {@link android.database.ContentObserver}
+    that calls {@link android.content.ContentResolver#requestSync requestSync()} when a table
+    changes:
+</p>
+<pre>
+public class MainActivity extends FragmentActivity {
+    ...
+    // Constants
+    // Content provider scheme
+    public static final String SCHEME = "content://";
+    // Content provider authority
+    public static final String AUTHORITY = "com.example.android.datasync.provider";
+    // Path for the content provider table
+    public static final String TABLE_PATH = "data_table";
+    // Account
+    public static final String ACCOUNT = "default_account";
+    // Global variables
+    // A content URI for the content provider's data table
+    Uri mUri;
+    // A content resolver for accessing the provider
+    ContentResolver mResolver;
+    ...
+    public class TableObserver extends ContentObserver {
+        /*
+         * Define a method that's called when data in the
+         * observed content provider changes.
+         * This method signature is provided for compatibility with
+         * older platforms.
+         */
+        &#64;Override
+        public void onChange(boolean selfChange) {
+            /*
+             * Invoke the method signature available as of
+             * Android platform version 4.1, with a null URI.
+             */
+            onChange(selfChange, null);
+        }
+        /*
+         * Define a method that's called when data in the
+         * observed content provider changes.
+         */
+        &#64;Override
+        public void onChange(boolean selfChange, Uri changeUri) {
+            /*
+             * Ask the framework to run your sync adapter.
+             * To maintain backward compatibility, assume that
+             * changeUri is null.
+            ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
+        }
+        ...
+    }
+    ...
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ...
+        // Get the content resolver object for your app
+        mResolver = getContentResolver();
+        // Construct a URI that points to the content provider data table
+        mUri = new Uri.Builder()
+                  .scheme(SCHEME)
+                  .authority(AUTHORITY)
+                  .path(TABLE_PATH)
+                  .build();
+        /*
+         * Create a content observer object.
+         * Its code does not mutate the provider, so set
+         * selfChange to "false"
+         */
+        TableObserver observer = new TableObserver(false);
+        /*
+         * Register the observer for the data table. The table's path
+         * and any of its subpaths trigger the observer.
+         */
+        mResolver.registerContentObserver(mUri, true, observer);
+        ...
+    }
+    ...
+}
+</pre>
+<h2 id="RunByNetwork">Run the Sync Adapter After a Network Message</h2>
+<p>
+    When a network connection is available, the Android system sends out a message
+    every few seconds to keep the device's TCP/IP connection open. This message also goes to
+    the {@link android.content.ContentResolver} of each app. By calling
+    {@link android.content.ContentResolver#setSyncAutomatically setSyncAutomatically()},
+    you can run the sync adapter whenever the {@link android.content.ContentResolver}
+    receives the message.
+</p>
+<p>
+    By scheduling your sync adapter to run when the network message is sent, you ensure that your
+    sync adapter is always scheduled to run while the network is available. Use this option if you
+    don't have to force a data transfer in response to data changes, but you do want to ensure
+    your data is regularly updated. Similarly, you can use this option if you don't want a fixed
+    schedule for your sync adapter, but you do want it to run frequently.
+</p>
+<p>
+    Since the method
+    {@link android.content.ContentResolver#setSyncAutomatically setSyncAutomatically()}
+    doesn't disable {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()}, your
+    sync adapter may be triggered repeatedly in a short period of time. If you do want to run
+    your sync adapter periodically on a regular schedule, you should disable
+    {@link android.content.ContentResolver#setSyncAutomatically setSyncAutomatically()}.
+</p>
+<p>
+    The following code snippet shows you how to configure your
+    {@link android.content.ContentResolver} to run your sync adapter in response to a network
+    message:
+</p>
+<pre>
+public class MainActivity extends FragmentActivity {
+    ...
+    // Constants
+    // Content provider authority
+    public static final String AUTHORITY = "com.example.android.datasync.provider";
+    // Account
+    public static final String ACCOUNT = "default_account";
+    // Global variables
+    // A content resolver for accessing the provider
+    ContentResolver mResolver;
+    ...
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ...
+        // Get the content resolver for your app
+        mResolver = getContentResolver();
+        // Turn on automatic syncing for the default account and authority
+        mResolver.setSyncAutomatically(ACCOUNT, AUTHORITY, true);
+        ...
+    }
+    ...
+}
+</pre>
+<h2 id="RunPeriodic">Run the Sync Adapter Periodically</h2>
+<p>
+    You can run your sync adapter periodically by setting a period of time to wait between runs,
+    or by running it at certain times of the day, or both. Running your sync adapter
+    periodically allows you to roughly match the update interval of your server.
+</p>
+<p>
+    Similarly, you can upload data from the device when your server is relatively idle, by
+    scheduling your sync adapter to run at night. Most users leave their powered on and plugged in
+    at night, so this time is usually available. Moreover, the device is not running other tasks at
+    the same time as your sync adapter. If you take this approach, however, you need to ensure that
+    each device triggers a data transfer at a slightly different time. If all devices run your
+    sync adapter at the same time, you are likely to overload your server and cell provider data
+    networks.
+</p>
+<p>
+    In general, periodic runs make sense if your users don't need instant updates, but expect to
+    have regular updates. Periodic runs also make sense if you want to balance the availability of
+    up-to-date data with the efficiency of smaller sync adapter runs that don't over-use device
+    resources.
+</p>
+<p>
+    To run your sync adapter at regular intervals, call
+    {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()}. This schedules your
+    sync adapter to run after a certain amount of time has elapsed. Since the sync adapter framework
+    has to account for other sync adapter executions and tries to maximize battery efficiency, the
+    elapsed time may vary by a few seconds. Also, the framework won't run your sync adapter if the
+    network is not available.
+</p>
+<p>
+    Notice that {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()} doesn't
+    run the sync adapter at a particular time of day. To run your sync adapter at roughly the
+    same time every day, use a repeating alarm as a trigger. Repeating alarms are described in more
+    detail in the reference documentation for {@link android.app.AlarmManager}. If you use the
+    method {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()} to set
+    time-of-day triggers that have some variation, you should still randomize the start time to
+    ensure that sync adapter runs from different devices are staggered.
+</p>
+<p>
+    The method {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()} doesn't
+    disable {@link android.content.ContentResolver#setSyncAutomatically setSyncAutomatically()},
+    so you may get multiple sync runs in a relatively short period of time. Also, only a few
+    sync adapter control flags are allowed in a call to
+    {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()}; the flags that are
+    not allowed are described in the referenced documentation for
+    {@link android.content.ContentResolver#addPeriodicSync addPeriodicSync()}.
+</p>
+<p>
+    The following code snippet shows you how to schedule periodic sync adapter runs:
+</p>
+<pre>
+public class MainActivity extends FragmentActivity {
+    ...
+    // Constants
+    // Content provider authority
+    public static final String AUTHORITY = "com.example.android.datasync.provider";
+    // Account
+    public static final String ACCOUNT = "default_account";
+    // Sync interval constants
+    public static final long MILLISECONDS_PER_SECOND = 1000L;
+    public static final long SECONDS_PER_MINUTE = 60L;
+    public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
+    public static final long SYNC_INTERVAL =
+            SYNC_INTERVAL_IN_MINUTES *
+            SECONDS_PER_MINUTE *
+            MILLISECONDS_PER_SECOND;
+    // Global variables
+    // A content resolver for accessing the provider
+    ContentResolver mResolver;
+    ...
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ...
+        // Get the content resolver for your app
+        mResolver = getContentResolver();
+        /*
+         * Turn on periodic syncing
+         */
+        ContentResolver.addPeriodicSync(
+                ACCOUNT,
+                AUTHORITY,
+                null,
+                SYNC_INTERVAL);
+        ...
+    }
+    ...
+}
+</pre>
+<h2 id="RunOnDemand">Run the Sync Adapter On Demand</h2>
+<p>
+    Running your sync adapter in response to a user request is the least preferable strategy
+    for running a sync adapter. The framework is specifically designed to conserve battery power
+    when it runs sync adapters according to a schedule. Options that run a sync in response to data
+    changes use battery power effectively, since the power is used to provide new data.
+</p>
+<p>
+    In comparison, allowing users to run a sync on demand means that the sync runs by itself, which
+    is inefficient use of network and power resources. Also, providing sync on demand leads users to
+    request a sync even if there's no evidence that the data has changed, and running a sync that
+    doesn't refresh data is an ineffective use of battery power. In general, your app should either
+    use other signals to trigger a sync or schedule them at regular intervals, without user input.
+</p>
+<p>
+    However, if you still want to run the sync adapter on demand, set the sync adapter flags for a
+    manual sync adapter run, then call
+    {@link android.content.ContentResolver#requestSync ContentResolver.requestSync()}.
+</p>
+<p>
+    Run on demand transfers with the following flags:
+</p>
+<dl>
+    <dt>
+        {@link android.content.ContentResolver#SYNC_EXTRAS_MANUAL SYNC_EXTRAS_MANUAL}
+    </dt>
+    <dd>
+        Forces a manual sync. The sync adapter framework ignores the existing settings,
+        such as the flag set by {@link android.content.ContentResolver#setSyncAutomatically
+        setSyncAutomatically()}.
+    </dd>
+    <dt>
+        {@link android.content.ContentResolver#SYNC_EXTRAS_EXPEDITED SYNC_EXTRAS_EXPEDITED}
+    </dt>
+    <dd>
+        Forces the sync to start immediately. If you don't set this, the system may wait several
+        seconds before running the sync request, because it tries to optimize battery use by
+        scheduling many requests in a short period of time.
+    </dd>
+</dl>
+<p>
+    The following code snippet shows you how to call
+    {@link android.content.ContentResolver#requestSync requestSync()} in response to a button
+    click:
+</p>
+<pre>
+public class MainActivity extends FragmentActivity {
+    ...
+    // Constants
+    // Content provider authority
+    public static final String AUTHORITY =
+            "com.example.android.datasync.provider"
+    // Account type
+    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
+    // Account
+    public static final String ACCOUNT = "default_account";
+    // Instance fields
+    Account mAccount;
+    ...
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ...
+        /*
+         * Create the dummy account. The code for CreateSyncAccount
+         * is listed in the lesson Creating a Sync Adapter
+         */
+
+        mAccount = CreateSyncAccount(this);
+        ...
+    }
+    /**
+     * Respond to a button click by calling requestSync(). This is an
+     * asynchronous operation.
+     *
+     * This method is attached to the refresh button in the layout
+     * XML file
+     *
+     * @param v The View associated with the method call,
+     * in this case a Button
+     */
+    public void onRefreshButtonClick(View v) {
+        ...
+        // Pass the settings flags by inserting them in a bundle
+        Bundle settingsBundle = new Bundle();
+        settingsBundle.putBoolean(
+                ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        settingsBundle.putBoolean(
+                ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        /*
+         * Request the sync for the default account, authority, and
+         * manual sync settings
+         */
+        ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);
+    }
+</pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 58db404..cb57752 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -475,6 +475,37 @@
           </a>
           </li>
       </li>
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>training/sync-adapters/index.html"
+             description="How to transfer data between the cloud and the device using the Android
+             sync adapter framework"
+             >Transferring Data Using Sync Adapters</a>
+        </div>
+        <ul>
+            <li>
+                <a href="<?cs var:toroot ?>training/sync-adapters/creating-authenticator.html">
+                Creating a Stub Authenticator
+                </a>
+            </li>
+            <li>
+                <a href="<?cs var:toroot ?>training/sync-adapters/creating-stub-provider.html">
+                Creating a Stub Content Provider
+                </a>
+            </li>
+            <li>
+                <a href="<?cs var:toroot ?>training/sync-adapters/creating-sync-adapter.html">
+                Creating a Sync Adapter
+                </a>
+            </li>
+            <li>
+                <a href="<?cs var:toroot ?>training/sync-adapters/running-sync-adapter.html">
+                Running a Sync Adapter
+                </a>
+            </li>
+        </ul>
+      </li>
+
     </ul>
   </li>
   <!-- End connectivity and cloud -->
diff --git a/include/android_runtime/android_view_InputQueue.h b/include/android_runtime/android_view_InputQueue.h
index ba2d02d..ed37b0a 100644
--- a/include/android_runtime/android_view_InputQueue.h
+++ b/include/android_runtime/android_view_InputQueue.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_VIEW_INPUTQUEUE_H
 #define _ANDROID_VIEW_INPUTQUEUE_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/Looper.h>
 #include <utils/TypeHelpers.h>
 #include <utils/Vector.h>
diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h
deleted file mode 100644
index 37ab279..0000000
--- a/include/androidfw/Input.h
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 2010 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 _ANDROIDFW_INPUT_H
-#define _ANDROIDFW_INPUT_H
-
-/**
- * Native input event structures.
- */
-
-#include <android/input.h>
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#ifdef HAVE_ANDROID_OS
-class SkMatrix;
-#endif
-
-/*
- * Additional private constants not defined in ndk/ui/input.h.
- */
-enum {
-    /* Signifies that the key is being predispatched */
-    AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,
-
-    /* Private control to determine when an app is tracking a key sequence. */
-    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,
-
-    /* Key event is inconsistent with previously sent key events. */
-    AKEY_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
-    /* Motion event is inconsistent with previously sent motion events. */
-    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
-    /* Used when a motion event is not associated with any display.
-     * Typically used for non-pointer events. */
-    ADISPLAY_ID_NONE = -1,
-
-    /* The default display id. */
-    ADISPLAY_ID_DEFAULT = 0,
-};
-
-enum {
-    /*
-     * Indicates that an input device has switches.
-     * This input source flag is hidden from the API because switches are only used by the system
-     * and applications have no way to interact with them.
-     */
-    AINPUT_SOURCE_SWITCH = 0x80000000,
-};
-
-/*
- * SystemUiVisibility constants from View.
- */
-enum {
-    ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
-    ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
-};
-
-/*
- * Maximum number of pointers supported per motion event.
- * Smallest number of pointers is 1.
- * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
- * will occasionally emit 11.  There is not much harm making this constant bigger.)
- */
-#define MAX_POINTERS 16
-
-/*
- * Maximum pointer id value supported in a motion event.
- * Smallest pointer id is 0.
- * (This is limited by our use of BitSet32 to track pointer assignments.)
- */
-#define MAX_POINTER_ID 31
-
-/*
- * Declare a concrete type for the NDK's input event forward declaration.
- */
-struct AInputEvent {
-    virtual ~AInputEvent() { }
-};
-
-/*
- * Declare a concrete type for the NDK's input device forward declaration.
- */
-struct AInputDevice {
-    virtual ~AInputDevice() { }
-};
-
-
-namespace android {
-
-#ifdef HAVE_ANDROID_OS
-class Parcel;
-#endif
-
-/*
- * Flags that flow alongside events in the input dispatch system to help with certain
- * policy decisions such as waking from device sleep.
- *
- * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
- */
-enum {
-    /* These flags originate in RawEvents and are generally set in the key map.
-     * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */
-
-    POLICY_FLAG_WAKE = 0x00000001,
-    POLICY_FLAG_WAKE_DROPPED = 0x00000002,
-    POLICY_FLAG_SHIFT = 0x00000004,
-    POLICY_FLAG_CAPS_LOCK = 0x00000008,
-    POLICY_FLAG_ALT = 0x00000010,
-    POLICY_FLAG_ALT_GR = 0x00000020,
-    POLICY_FLAG_MENU = 0x00000040,
-    POLICY_FLAG_LAUNCHER = 0x00000080,
-    POLICY_FLAG_VIRTUAL = 0x00000100,
-    POLICY_FLAG_FUNCTION = 0x00000200,
-
-    POLICY_FLAG_RAW_MASK = 0x0000ffff,
-
-    /* These flags are set by the input dispatcher. */
-
-    // Indicates that the input event was injected.
-    POLICY_FLAG_INJECTED = 0x01000000,
-
-    // Indicates that the input event is from a trusted source such as a directly attached
-    // input device or an application with system-wide event injection permission.
-    POLICY_FLAG_TRUSTED = 0x02000000,
-
-    // Indicates that the input event has passed through an input filter.
-    POLICY_FLAG_FILTERED = 0x04000000,
-
-    // Disables automatic key repeating behavior.
-    POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,
-
-    /* These flags are set by the input reader policy as it intercepts each event. */
-
-    // Indicates that the screen was off when the event was received and the event
-    // should wake the device.
-    POLICY_FLAG_WOKE_HERE = 0x10000000,
-
-    // Indicates that the screen was dim when the event was received and the event
-    // should brighten the device.
-    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
-
-    // Indicates that the event should be dispatched to applications.
-    // The input event should still be sent to the InputDispatcher so that it can see all
-    // input events received include those that it will not deliver.
-    POLICY_FLAG_PASS_TO_USER = 0x40000000,
-};
-
-/*
- * Pointer coordinate data.
- */
-struct PointerCoords {
-    enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
-
-    // Bitfield of axes that are present in this structure.
-    uint64_t bits;
-
-    // Values of axes that are stored in this structure packed in order by axis id
-    // for each axis that is present in the structure according to 'bits'.
-    float values[MAX_AXES];
-
-    inline void clear() {
-        bits = 0;
-    }
-
-    float getAxisValue(int32_t axis) const;
-    status_t setAxisValue(int32_t axis, float value);
-
-    void scale(float scale);
-
-    inline float getX() const {
-        return getAxisValue(AMOTION_EVENT_AXIS_X);
-    }
-
-    inline float getY() const {
-        return getAxisValue(AMOTION_EVENT_AXIS_Y);
-    }
-
-#ifdef HAVE_ANDROID_OS
-    status_t readFromParcel(Parcel* parcel);
-    status_t writeToParcel(Parcel* parcel) const;
-#endif
-
-    bool operator==(const PointerCoords& other) const;
-    inline bool operator!=(const PointerCoords& other) const {
-        return !(*this == other);
-    }
-
-    void copyFrom(const PointerCoords& other);
-
-private:
-    void tooManyAxes(int axis);
-};
-
-/*
- * Pointer property data.
- */
-struct PointerProperties {
-    // The id of the pointer.
-    int32_t id;
-
-    // The pointer tool type.
-    int32_t toolType;
-
-    inline void clear() {
-        id = -1;
-        toolType = 0;
-    }
-
-    bool operator==(const PointerProperties& other) const;
-    inline bool operator!=(const PointerProperties& other) const {
-        return !(*this == other);
-    }
-
-    void copyFrom(const PointerProperties& other);
-};
-
-/*
- * Input events.
- */
-class InputEvent : public AInputEvent {
-public:
-    virtual ~InputEvent() { }
-
-    virtual int32_t getType() const = 0;
-
-    inline int32_t getDeviceId() const { return mDeviceId; }
-
-    inline int32_t getSource() const { return mSource; }
-
-    inline void setSource(int32_t source) { mSource = source; }
-
-protected:
-    void initialize(int32_t deviceId, int32_t source);
-    void initialize(const InputEvent& from);
-
-    int32_t mDeviceId;
-    int32_t mSource;
-};
-
-/*
- * Key events.
- */
-class KeyEvent : public InputEvent {
-public:
-    virtual ~KeyEvent() { }
-
-    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
-
-    inline int32_t getAction() const { return mAction; }
-
-    inline int32_t getFlags() const { return mFlags; }
-
-    inline void setFlags(int32_t flags) { mFlags = flags; }
-
-    inline int32_t getKeyCode() const { return mKeyCode; }
-
-    inline int32_t getScanCode() const { return mScanCode; }
-
-    inline int32_t getMetaState() const { return mMetaState; }
-
-    inline int32_t getRepeatCount() const { return mRepeatCount; }
-
-    inline nsecs_t getDownTime() const { return mDownTime; }
-
-    inline nsecs_t getEventTime() const { return mEventTime; }
-
-    // Return true if this event may have a default action implementation.
-    static bool hasDefaultAction(int32_t keyCode);
-    bool hasDefaultAction() const;
-
-    // Return true if this event represents a system key.
-    static bool isSystemKey(int32_t keyCode);
-    bool isSystemKey() const;
-    
-    void initialize(
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
-    void initialize(const KeyEvent& from);
-
-protected:
-    int32_t mAction;
-    int32_t mFlags;
-    int32_t mKeyCode;
-    int32_t mScanCode;
-    int32_t mMetaState;
-    int32_t mRepeatCount;
-    nsecs_t mDownTime;
-    nsecs_t mEventTime;
-};
-
-/*
- * Motion events.
- */
-class MotionEvent : public InputEvent {
-public:
-    virtual ~MotionEvent() { }
-
-    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
-
-    inline int32_t getAction() const { return mAction; }
-
-    inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
-
-    inline int32_t getActionIndex() const {
-        return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-    }
-
-    inline void setAction(int32_t action) { mAction = action; }
-
-    inline int32_t getFlags() const { return mFlags; }
-
-    inline void setFlags(int32_t flags) { mFlags = flags; }
-
-    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
-
-    inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
-
-    inline int32_t getMetaState() const { return mMetaState; }
-
-    inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
-
-    inline int32_t getButtonState() const { return mButtonState; }
-
-    inline float getXOffset() const { return mXOffset; }
-
-    inline float getYOffset() const { return mYOffset; }
-
-    inline float getXPrecision() const { return mXPrecision; }
-
-    inline float getYPrecision() const { return mYPrecision; }
-
-    inline nsecs_t getDownTime() const { return mDownTime; }
-
-    inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
-
-    inline size_t getPointerCount() const { return mPointerProperties.size(); }
-
-    inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
-        return &mPointerProperties[pointerIndex];
-    }
-
-    inline int32_t getPointerId(size_t pointerIndex) const {
-        return mPointerProperties[pointerIndex].id;
-    }
-
-    inline int32_t getToolType(size_t pointerIndex) const {
-        return mPointerProperties[pointerIndex].toolType;
-    }
-
-    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
-
-    const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
-
-    float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
-
-    inline float getRawX(size_t pointerIndex) const {
-        return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
-    }
-
-    inline float getRawY(size_t pointerIndex) const {
-        return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
-    }
-
-    float getAxisValue(int32_t axis, size_t pointerIndex) const;
-
-    inline float getX(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
-    }
-
-    inline float getY(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
-    }
-
-    inline float getPressure(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
-    }
-
-    inline float getSize(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
-    }
-
-    inline float getTouchMajor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
-    }
-
-    inline float getTouchMinor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
-    }
-
-    inline float getToolMajor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
-    }
-
-    inline float getToolMinor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
-    }
-
-    inline float getOrientation(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
-    }
-
-    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
-
-    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
-        return mSampleEventTimes[historicalIndex];
-    }
-
-    const PointerCoords* getHistoricalRawPointerCoords(
-            size_t pointerIndex, size_t historicalIndex) const;
-
-    float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
-            size_t historicalIndex) const;
-
-    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawAxisValue(
-                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawAxisValue(
-                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
-    }
-
-    float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
-
-    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
-    }
-
-    ssize_t findPointerIndex(int32_t pointerId) const;
-
-    void initialize(
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t edgeFlags,
-            int32_t metaState,
-            int32_t buttonState,
-            float xOffset,
-            float yOffset,
-            float xPrecision,
-            float yPrecision,
-            nsecs_t downTime,
-            nsecs_t eventTime,
-            size_t pointerCount,
-            const PointerProperties* pointerProperties,
-            const PointerCoords* pointerCoords);
-
-    void copyFrom(const MotionEvent* other, bool keepHistory);
-
-    void addSample(
-            nsecs_t eventTime,
-            const PointerCoords* pointerCoords);
-
-    void offsetLocation(float xOffset, float yOffset);
-
-    void scale(float scaleFactor);
-
-#ifdef HAVE_ANDROID_OS
-    void transform(const SkMatrix* matrix);
-
-    status_t readFromParcel(Parcel* parcel);
-    status_t writeToParcel(Parcel* parcel) const;
-#endif
-
-    static bool isTouchEvent(int32_t source, int32_t action);
-    inline bool isTouchEvent() const {
-        return isTouchEvent(mSource, mAction);
-    }
-
-    // Low-level accessors.
-    inline const PointerProperties* getPointerProperties() const {
-        return mPointerProperties.array();
-    }
-    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
-    inline const PointerCoords* getSamplePointerCoords() const {
-            return mSamplePointerCoords.array();
-    }
-
-protected:
-    int32_t mAction;
-    int32_t mFlags;
-    int32_t mEdgeFlags;
-    int32_t mMetaState;
-    int32_t mButtonState;
-    float mXOffset;
-    float mYOffset;
-    float mXPrecision;
-    float mYPrecision;
-    nsecs_t mDownTime;
-    Vector<PointerProperties> mPointerProperties;
-    Vector<nsecs_t> mSampleEventTimes;
-    Vector<PointerCoords> mSamplePointerCoords;
-};
-
-/*
- * Input event factory.
- */
-class InputEventFactoryInterface {
-protected:
-    virtual ~InputEventFactoryInterface() { }
-
-public:
-    InputEventFactoryInterface() { }
-
-    virtual KeyEvent* createKeyEvent() = 0;
-    virtual MotionEvent* createMotionEvent() = 0;
-};
-
-/*
- * A simple input event factory implementation that uses a single preallocated instance
- * of each type of input event that are reused for each request.
- */
-class PreallocatedInputEventFactory : public InputEventFactoryInterface {
-public:
-    PreallocatedInputEventFactory() { }
-    virtual ~PreallocatedInputEventFactory() { }
-
-    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
-    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
-
-private:
-    KeyEvent mKeyEvent;
-    MotionEvent mMotionEvent;
-};
-
-/*
- * An input event factory implementation that maintains a pool of input events.
- */
-class PooledInputEventFactory : public InputEventFactoryInterface {
-public:
-    PooledInputEventFactory(size_t maxPoolSize = 20);
-    virtual ~PooledInputEventFactory();
-
-    virtual KeyEvent* createKeyEvent();
-    virtual MotionEvent* createMotionEvent();
-
-    void recycle(InputEvent* event);
-
-private:
-    const size_t mMaxPoolSize;
-
-    Vector<KeyEvent*> mKeyEventPool;
-    Vector<MotionEvent*> mMotionEventPool;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_H
diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h
deleted file mode 100644
index 45dc2db..0000000
--- a/include/androidfw/InputDevice.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2012 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 _ANDROIDFW_INPUT_DEVICE_H
-#define _ANDROIDFW_INPUT_DEVICE_H
-
-#include <androidfw/Input.h>
-#include <androidfw/KeyCharacterMap.h>
-
-namespace android {
-
-/*
- * Identifies a device.
- */
-struct InputDeviceIdentifier {
-    inline InputDeviceIdentifier() :
-            bus(0), vendor(0), product(0), version(0) {
-    }
-
-    // Information provided by the kernel.
-    String8 name;
-    String8 location;
-    String8 uniqueId;
-    uint16_t bus;
-    uint16_t vendor;
-    uint16_t product;
-    uint16_t version;
-
-    // A composite input device descriptor string that uniquely identifies the device
-    // even across reboots or reconnections.  The value of this field is used by
-    // upper layers of the input system to associate settings with individual devices.
-    // It is hashed from whatever kernel provided information is available.
-    // Ideally, the way this value is computed should not change between Android releases
-    // because that would invalidate persistent settings that rely on it.
-    String8 descriptor;
-};
-
-/*
- * Describes the characteristics and capabilities of an input device.
- */
-class InputDeviceInfo {
-public:
-    InputDeviceInfo();
-    InputDeviceInfo(const InputDeviceInfo& other);
-    ~InputDeviceInfo();
-
-    struct MotionRange {
-        int32_t axis;
-        uint32_t source;
-        float min;
-        float max;
-        float flat;
-        float fuzz;
-        float resolution;
-    };
-
-    void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
-            const String8& alias, bool isExternal);
-
-    inline int32_t getId() const { return mId; }
-    inline int32_t getGeneration() const { return mGeneration; }
-    inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
-    inline const String8& getAlias() const { return mAlias; }
-    inline const String8& getDisplayName() const {
-        return mAlias.isEmpty() ? mIdentifier.name : mAlias;
-    }
-    inline bool isExternal() const { return mIsExternal; }
-    inline uint32_t getSources() const { return mSources; }
-
-    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
-
-    void addSource(uint32_t source);
-    void addMotionRange(int32_t axis, uint32_t source,
-            float min, float max, float flat, float fuzz, float resolution);
-    void addMotionRange(const MotionRange& range);
-
-    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
-    inline int32_t getKeyboardType() const { return mKeyboardType; }
-
-    inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) {
-        mKeyCharacterMap = value;
-    }
-
-    inline sp<KeyCharacterMap> getKeyCharacterMap() const {
-        return mKeyCharacterMap;
-    }
-
-    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
-    inline bool hasVibrator() const { return mHasVibrator; }
-
-    inline const Vector<MotionRange>& getMotionRanges() const {
-        return mMotionRanges;
-    }
-
-private:
-    int32_t mId;
-    int32_t mGeneration;
-    InputDeviceIdentifier mIdentifier;
-    String8 mAlias;
-    bool mIsExternal;
-    uint32_t mSources;
-    int32_t mKeyboardType;
-    sp<KeyCharacterMap> mKeyCharacterMap;
-    bool mHasVibrator;
-
-    Vector<MotionRange> mMotionRanges;
-};
-
-/* Types of input device configuration files. */
-enum InputDeviceConfigurationFileType {
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file */
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
-};
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The device identifier is used to construct several default configuration file
- * names to try based on the device name, vendor, product, and version.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
-        const InputDeviceIdentifier& deviceIdentifier,
-        InputDeviceConfigurationFileType type);
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The name is case-sensitive and is used to construct the filename to resolve.
- * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type);
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_DEVICE_H
diff --git a/include/androidfw/InputTransport.h b/include/androidfw/InputTransport.h
deleted file mode 100644
index 8712995..0000000
--- a/include/androidfw/InputTransport.h
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2010 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 _ANDROIDFW_INPUT_TRANSPORT_H
-#define _ANDROIDFW_INPUT_TRANSPORT_H
-
-/**
- * Native input transport.
- *
- * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.
- *
- * The InputPublisher and InputConsumer each handle one end-point of an input channel.
- * The InputPublisher is used by the input dispatcher to send events to the application.
- * The InputConsumer is used by the application to receive events from the input dispatcher.
- */
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-/*
- * Intermediate representation used to send input events and related signals.
- */
-struct InputMessage {
-    enum {
-        TYPE_KEY = 1,
-        TYPE_MOTION = 2,
-        TYPE_FINISHED = 3,
-    };
-
-    struct Header {
-        uint32_t type;
-        uint32_t padding; // 8 byte alignment for the body that follows
-    } header;
-
-    union Body {
-        struct Key {
-            uint32_t seq;
-            nsecs_t eventTime;
-            int32_t deviceId;
-            int32_t source;
-            int32_t action;
-            int32_t flags;
-            int32_t keyCode;
-            int32_t scanCode;
-            int32_t metaState;
-            int32_t repeatCount;
-            nsecs_t downTime;
-
-            inline size_t size() const {
-                return sizeof(Key);
-            }
-        } key;
-
-        struct Motion {
-            uint32_t seq;
-            nsecs_t eventTime;
-            int32_t deviceId;
-            int32_t source;
-            int32_t action;
-            int32_t flags;
-            int32_t metaState;
-            int32_t buttonState;
-            int32_t edgeFlags;
-            nsecs_t downTime;
-            float xOffset;
-            float yOffset;
-            float xPrecision;
-            float yPrecision;
-            size_t pointerCount;
-            struct Pointer {
-                PointerProperties properties;
-                PointerCoords coords;
-            } pointers[MAX_POINTERS];
-
-            int32_t getActionId() const {
-                uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-                        >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                return pointers[index].properties.id;
-            }
-
-            inline size_t size() const {
-                return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
-                        + sizeof(Pointer) * pointerCount;
-            }
-        } motion;
-
-        struct Finished {
-            uint32_t seq;
-            bool handled;
-
-            inline size_t size() const {
-                return sizeof(Finished);
-            }
-        } finished;
-    } body;
-
-    bool isValid(size_t actualSize) const;
-    size_t size() const;
-};
-
-/*
- * An input channel consists of a local unix domain socket used to send and receive
- * input messages across processes.  Each channel has a descriptive name for debugging purposes.
- *
- * Each endpoint has its own InputChannel object that specifies its file descriptor.
- *
- * The input channel is closed when all references to it are released.
- */
-class InputChannel : public RefBase {
-protected:
-    virtual ~InputChannel();
-
-public:
-    InputChannel(const String8& name, int fd);
-
-    /* Creates a pair of input channels.
-     *
-     * Returns OK on success.
-     */
-    static status_t openInputChannelPair(const String8& name,
-            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
-
-    inline String8 getName() const { return mName; }
-    inline int getFd() const { return mFd; }
-
-    /* Sends a message to the other endpoint.
-     *
-     * If the channel is full then the message is guaranteed not to have been sent at all.
-     * Try again after the consumer has sent a finished signal indicating that it has
-     * consumed some of the pending messages from the channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t sendMessage(const InputMessage* msg);
-
-    /* Receives a message sent by the other endpoint.
-     *
-     * If there is no message present, try again after poll() indicates that the fd
-     * is readable.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no message present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t receiveMessage(InputMessage* msg);
-
-    /* Returns a new object that has a duplicate of this channel's fd. */
-    sp<InputChannel> dup() const;
-
-private:
-    String8 mName;
-    int mFd;
-};
-
-/*
- * Publishes input events to an input channel.
- */
-class InputPublisher {
-public:
-    /* Creates a publisher associated with an input channel. */
-    explicit InputPublisher(const sp<InputChannel>& channel);
-
-    /* Destroys the publisher and releases its input channel. */
-    ~InputPublisher();
-
-    /* Gets the underlying input channel. */
-    inline sp<InputChannel> getChannel() { return mChannel; }
-
-    /* Publishes a key event to the input channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns BAD_VALUE if seq is 0.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t publishKeyEvent(
-            uint32_t seq,
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
-
-    /* Publishes a motion event to the input channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t publishMotionEvent(
-            uint32_t seq,
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t edgeFlags,
-            int32_t metaState,
-            int32_t buttonState,
-            float xOffset,
-            float yOffset,
-            float xPrecision,
-            float yPrecision,
-            nsecs_t downTime,
-            nsecs_t eventTime,
-            size_t pointerCount,
-            const PointerProperties* pointerProperties,
-            const PointerCoords* pointerCoords);
-
-    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
-     * If a signal was received, returns the message sequence number,
-     * and whether the consumer handled the message.
-     *
-     * The returned sequence number is never 0 unless the operation failed.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no signal present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
-
-private:
-    sp<InputChannel> mChannel;
-};
-
-/*
- * Consumes input events from an input channel.
- */
-class InputConsumer {
-public:
-    /* Creates a consumer associated with an input channel. */
-    explicit InputConsumer(const sp<InputChannel>& channel);
-
-    /* Destroys the consumer and releases its input channel. */
-    ~InputConsumer();
-
-    /* Gets the underlying input channel. */
-    inline sp<InputChannel> getChannel() { return mChannel; }
-
-    /* Consumes an input event from the input channel and copies its contents into
-     * an InputEvent object created using the specified factory.
-     *
-     * Tries to combine a series of move events into larger batches whenever possible.
-     *
-     * If consumeBatches is false, then defers consuming pending batched events if it
-     * is possible for additional samples to be added to them later.  Call hasPendingBatch()
-     * to determine whether a pending batch is available to be consumed.
-     *
-     * If consumeBatches is true, then events are still batched but they are consumed
-     * immediately as soon as the input channel is exhausted.
-     *
-     * The frameTime parameter specifies the time when the current display frame started
-     * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
-     *
-     * The returned sequence number is never 0 unless the operation failed.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no event present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns NO_MEMORY if the event could not be created.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
-            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
-
-    /* Sends a finished signal to the publisher to inform it that the message
-     * with the specified sequence number has finished being process and whether
-     * the message was handled by the consumer.
-     *
-     * Returns OK on success.
-     * Returns BAD_VALUE if seq is 0.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t sendFinishedSignal(uint32_t seq, bool handled);
-
-    /* Returns true if there is a deferred event waiting.
-     *
-     * Should be called after calling consume() to determine whether the consumer
-     * has a deferred event to be processed.  Deferred events are somewhat special in
-     * that they have already been removed from the input channel.  If the input channel
-     * becomes empty, the client may need to do extra work to ensure that it processes
-     * the deferred event despite the fact that the input channel's file descriptor
-     * is not readable.
-     *
-     * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
-     * This guarantees that all deferred events will be processed.
-     *
-     * Alternately, the caller can call hasDeferredEvent() to determine whether there is
-     * a deferred event waiting and then ensure that its event loop wakes up at least
-     * one more time to consume the deferred event.
-     */
-    bool hasDeferredEvent() const;
-
-    /* Returns true if there is a pending batch.
-     *
-     * Should be called after calling consume() with consumeBatches == false to determine
-     * whether consume() should be called again later on with consumeBatches == true.
-     */
-    bool hasPendingBatch() const;
-
-private:
-    // True if touch resampling is enabled.
-    const bool mResampleTouch;
-
-    // The input channel.
-    sp<InputChannel> mChannel;
-
-    // The current input message.
-    InputMessage mMsg;
-
-    // True if mMsg contains a valid input message that was deferred from the previous
-    // call to consume and that still needs to be handled.
-    bool mMsgDeferred;
-
-    // Batched motion events per device and source.
-    struct Batch {
-        Vector<InputMessage> samples;
-    };
-    Vector<Batch> mBatches;
-
-    // Touch state per device and source, only for sources of class pointer.
-    struct History {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        int32_t idToIndex[MAX_POINTER_ID + 1];
-        PointerCoords pointers[MAX_POINTERS];
-
-        void initializeFrom(const InputMessage* msg) {
-            eventTime = msg->body.motion.eventTime;
-            idBits.clear();
-            for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
-                uint32_t id = msg->body.motion.pointers[i].properties.id;
-                idBits.markBit(id);
-                idToIndex[id] = i;
-                pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
-            }
-        }
-
-        const PointerCoords& getPointerById(uint32_t id) const {
-            return pointers[idToIndex[id]];
-        }
-    };
-    struct TouchState {
-        int32_t deviceId;
-        int32_t source;
-        size_t historyCurrent;
-        size_t historySize;
-        History history[2];
-        History lastResample;
-
-        void initialize(int32_t deviceId, int32_t source) {
-            this->deviceId = deviceId;
-            this->source = source;
-            historyCurrent = 0;
-            historySize = 0;
-            lastResample.eventTime = 0;
-            lastResample.idBits.clear();
-        }
-
-        void addHistory(const InputMessage* msg) {
-            historyCurrent ^= 1;
-            if (historySize < 2) {
-                historySize += 1;
-            }
-            history[historyCurrent].initializeFrom(msg);
-        }
-
-        const History* getHistory(size_t index) const {
-            return &history[(historyCurrent + index) & 1];
-        }
-    };
-    Vector<TouchState> mTouchStates;
-
-    // Chain of batched sequence numbers.  When multiple input messages are combined into
-    // a batch, we append a record here that associates the last sequence number in the
-    // batch with the previous one.  When the finished signal is sent, we traverse the
-    // chain to individually finish all input messages that were part of the batch.
-    struct SeqChain {
-        uint32_t seq;   // sequence number of batched input message
-        uint32_t chain; // sequence number of previous batched input message
-    };
-    Vector<SeqChain> mSeqChains;
-
-    status_t consumeBatch(InputEventFactoryInterface* factory,
-            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
-    status_t consumeSamples(InputEventFactoryInterface* factory,
-            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
-
-    void updateTouchState(InputMessage* msg);
-    void rewriteMessage(const TouchState& state, InputMessage* msg);
-    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
-            const InputMessage *next);
-
-    ssize_t findBatch(int32_t deviceId, int32_t source) const;
-    ssize_t findTouchState(int32_t deviceId, int32_t source) const;
-
-    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
-
-    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
-    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
-    static void addSample(MotionEvent* event, const InputMessage* msg);
-    static bool canAddSample(const Batch& batch, const InputMessage* msg);
-    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
-    static bool shouldResampleTool(int32_t toolType);
-
-    static bool isTouchResamplingEnabled();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_TRANSPORT_H
diff --git a/include/androidfw/KeyCharacterMap.h b/include/androidfw/KeyCharacterMap.h
deleted file mode 100644
index 06799f9..0000000
--- a/include/androidfw/KeyCharacterMap.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2008 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 _ANDROIDFW_KEY_CHARACTER_MAP_H
-#define _ANDROIDFW_KEY_CHARACTER_MAP_H
-
-#include <stdint.h>
-
-#if HAVE_ANDROID_OS
-#include <binder/IBinder.h>
-#endif
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-/**
- * Describes a mapping from Android key codes to characters.
- * Also specifies other functions of the keyboard such as the keyboard type
- * and key modifier semantics.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyCharacterMap : public RefBase {
-public:
-    enum KeyboardType {
-        KEYBOARD_TYPE_UNKNOWN = 0,
-        KEYBOARD_TYPE_NUMERIC = 1,
-        KEYBOARD_TYPE_PREDICTIVE = 2,
-        KEYBOARD_TYPE_ALPHA = 3,
-        KEYBOARD_TYPE_FULL = 4,
-        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
-        KEYBOARD_TYPE_OVERLAY = 6,
-    };
-
-    enum Format {
-        // Base keyboard layout, may contain device-specific options, such as "type" declaration.
-        FORMAT_BASE = 0,
-        // Overlay keyboard layout, more restrictive, may be published by applications,
-        // cannot override device-specific options.
-        FORMAT_OVERLAY = 1,
-        // Either base or overlay layout ok.
-        FORMAT_ANY = 2,
-    };
-
-    // Substitute key code and meta state for fallback action.
-    struct FallbackAction {
-        int32_t keyCode;
-        int32_t metaState;
-    };
-
-    /* Loads a key character map from a file. */
-    static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
-
-    /* Loads a key character map from its string contents. */
-    static status_t loadContents(const String8& filename,
-            const char* contents, Format format, sp<KeyCharacterMap>* outMap);
-
-    /* Combines a base key character map and an overlay. */
-    static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,
-            const sp<KeyCharacterMap>& overlay);
-
-    /* Returns an empty key character map. */
-    static sp<KeyCharacterMap> empty();
-
-    /* Gets the keyboard type. */
-    int32_t getKeyboardType() const;
-
-    /* Gets the primary character for this key as in the label physically printed on it.
-     * Returns 0 if none (eg. for non-printing keys). */
-    char16_t getDisplayLabel(int32_t keyCode) const;
-
-    /* Gets the Unicode character for the number or symbol generated by the key
-     * when the keyboard is used as a dialing pad.
-     * Returns 0 if no number or symbol is generated.
-     */
-    char16_t getNumber(int32_t keyCode) const;
-
-    /* Gets the Unicode character generated by the key and meta key modifiers.
-     * Returns 0 if no character is generated.
-     */
-    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
-
-    /* Gets the fallback action to use by default if the application does not
-     * handle the specified key.
-     * Returns true if an action was available, false if none.
-     */
-    bool getFallbackAction(int32_t keyCode, int32_t metaState,
-            FallbackAction* outFallbackAction) const;
-
-    /* Gets the first matching Unicode character that can be generated by the key,
-     * preferring the one with the specified meta key modifiers.
-     * Returns 0 if no matching character is generated.
-     */
-    char16_t getMatch(int32_t keyCode, const char16_t* chars,
-            size_t numChars, int32_t metaState) const;
-
-    /* Gets a sequence of key events that could plausibly generate the specified
-     * character sequence.  Returns false if some of the characters cannot be generated.
-     */
-    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
-            Vector<KeyEvent>& outEvents) const;
-
-    /* Maps a scan code and usage code to a key code, in case this key map overrides
-     * the mapping in some way. */
-    status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
-
-#if HAVE_ANDROID_OS
-    /* Reads a key map from a parcel. */
-    static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
-
-    /* Writes a key map to a parcel. */
-    void writeToParcel(Parcel* parcel) const;
-#endif
-
-protected:
-    virtual ~KeyCharacterMap();
-
-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;
-
-        /* The character to insert. */
-        char16_t character;
-
-        /* The fallback keycode if the key is not handled. */
-        int32_t fallbackKeyCode;
-    };
-
-    struct Key {
-        Key();
-        Key(const Key& other);
-        ~Key();
-
-        /* The single character label printed on the key, or 0 if none. */
-        char16_t label;
-
-        /* The number or symbol character generated by the key, or 0 if none. */
-        char16_t number;
-
-        /* The list of key behaviors sorted from most specific to least specific
-         * meta key binding. */
-        Behavior* firstBehavior;
-    };
-
-    class Parser {
-        enum State {
-            STATE_TOP = 0,
-            STATE_KEY = 1,
-        };
-
-        enum {
-            PROPERTY_LABEL = 1,
-            PROPERTY_NUMBER = 2,
-            PROPERTY_META = 3,
-        };
-
-        struct Property {
-            inline Property(int32_t property = 0, int32_t metaState = 0) :
-                    property(property), metaState(metaState) { }
-
-            int32_t property;
-            int32_t metaState;
-        };
-
-        KeyCharacterMap* mMap;
-        Tokenizer* mTokenizer;
-        Format mFormat;
-        State mState;
-        int32_t mKeyCode;
-
-    public:
-        Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);
-        ~Parser();
-        status_t parse();
-
-    private:
-        status_t parseType();
-        status_t parseMap();
-        status_t parseMapKey();
-        status_t parseKey();
-        status_t parseKeyProperty();
-        status_t finishKey(Key* key);
-        status_t parseModifier(const String8& token, int32_t* outMetaState);
-        status_t parseCharacterLiteral(char16_t* outCharacter);
-    };
-
-    static sp<KeyCharacterMap> sEmpty;
-
-    KeyedVector<int32_t, Key*> mKeys;
-    int mType;
-
-    KeyedVector<int32_t, int32_t> mKeysByScanCode;
-    KeyedVector<int32_t, int32_t> mKeysByUsageCode;
-
-    KeyCharacterMap();
-    KeyCharacterMap(const KeyCharacterMap& other);
-
-    bool getKey(int32_t keyCode, const Key** outKey) const;
-    bool getKeyBehavior(int32_t keyCode, int32_t metaState,
-            const Key** outKey, const Behavior** outBehavior) const;
-    static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);
-
-    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
-
-    static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);
-
-    static void addKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
-    static void addMetaKeys(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t* currentMetaState);
-    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t keyCode, int32_t keyMetaState,
-            int32_t* currentMetaState);
-    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t leftKeyCode, int32_t leftKeyMetaState,
-            int32_t rightKeyCode, int32_t rightKeyMetaState,
-            int32_t eitherKeyMetaState,
-            int32_t* currentMetaState);
-    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, nsecs_t time,
-            int32_t keyCode, int32_t keyMetaState,
-            int32_t* currentMetaState);
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/include/androidfw/KeyLayoutMap.h b/include/androidfw/KeyLayoutMap.h
deleted file mode 100644
index e7f22a2..0000000
--- a/include/androidfw/KeyLayoutMap.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 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 _ANDROIDFW_KEY_LAYOUT_MAP_H
-#define _ANDROIDFW_KEY_LAYOUT_MAP_H
-
-#include <stdint.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct AxisInfo {
-    enum Mode {
-        // Axis value is reported directly.
-        MODE_NORMAL = 0,
-        // Axis value should be inverted before reporting.
-        MODE_INVERT = 1,
-        // Axis value should be split into two axes
-        MODE_SPLIT = 2,
-    };
-
-    // Axis mode.
-    Mode mode;
-
-    // Axis id.
-    // When split, this is the axis used for values smaller than the split position.
-    int32_t axis;
-
-    // When split, this is the axis used for values after higher than the split position.
-    int32_t highAxis;
-
-    // The split value, or 0 if not split.
-    int32_t splitValue;
-
-    // The flat value, or -1 if none.
-    int32_t flatOverride;
-
-    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
-    }
-};
-
-/**
- * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyLayoutMap : public RefBase {
-public:
-    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);
-
-    status_t mapKey(int32_t scanCode, int32_t usageCode,
-            int32_t* outKeyCode, uint32_t* outFlags) const;
-    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
-
-    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
-
-protected:
-    virtual ~KeyLayoutMap();
-
-private:
-    struct Key {
-        int32_t keyCode;
-        uint32_t flags;
-    };
-
-    KeyedVector<int32_t, Key> mKeysByScanCode;
-    KeyedVector<int32_t, Key> mKeysByUsageCode;
-    KeyedVector<int32_t, AxisInfo> mAxes;
-
-    KeyLayoutMap();
-
-    const Key* getKey(int32_t scanCode, int32_t usageCode) const;
-
-    class Parser {
-        KeyLayoutMap* mMap;
-        Tokenizer* mTokenizer;
-
-    public:
-        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
-        ~Parser();
-        status_t parse();
-
-    private:
-        status_t parseKey();
-        status_t parseAxis();
-    };
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_LAYOUT_MAP_H
diff --git a/include/androidfw/Keyboard.h b/include/androidfw/Keyboard.h
deleted file mode 100644
index 6537a8f..0000000
--- a/include/androidfw/Keyboard.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2010 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 _ANDROIDFW_KEYBOARD_H
-#define _ANDROIDFW_KEYBOARD_H
-
-#include <androidfw/Input.h>
-#include <androidfw/InputDevice.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/PropertyMap.h>
-
-namespace android {
-
-enum {
-    /* Device id of the built in keyboard. */
-    DEVICE_ID_BUILT_IN_KEYBOARD = 0,
-
-    /* Device id of a generic virtual keyboard with a full layout that can be used
-     * to synthesize key events. */
-    DEVICE_ID_VIRTUAL_KEYBOARD = -1,
-};
-
-class KeyLayoutMap;
-class KeyCharacterMap;
-
-/**
- * Loads the key layout map and key character map for a keyboard device.
- */
-class KeyMap {
-public:
-    String8 keyLayoutFile;
-    sp<KeyLayoutMap> keyLayoutMap;
-
-    String8 keyCharacterMapFile;
-    sp<KeyCharacterMap> keyCharacterMap;
-
-    KeyMap();
-    ~KeyMap();
-
-    status_t load(const InputDeviceIdentifier& deviceIdenfier,
-            const PropertyMap* deviceConfiguration);
-
-    inline bool haveKeyLayout() const {
-        return !keyLayoutFile.isEmpty();
-    }
-
-    inline bool haveKeyCharacterMap() const {
-        return !keyCharacterMapFile.isEmpty();
-    }
-
-    inline bool isComplete() const {
-        return haveKeyLayout() && haveKeyCharacterMap();
-    }
-
-private:
-    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
-    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
-    status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name);
-    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name, InputDeviceConfigurationFileType type);
-};
-
-/**
- * Returns true if the keyboard is eligible for use as a built-in keyboard.
- */
-extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
-        const PropertyMap* deviceConfiguration, const KeyMap* keyMap);
-
-/**
- * Gets a key code by its short form label, eg. "HOME".
- * Returns 0 if unknown.
- */
-extern int32_t getKeyCodeByLabel(const char* label);
-
-/**
- * Gets a key flag by its short form label, eg. "WAKE".
- * Returns 0 if unknown.
- */
-extern uint32_t getKeyFlagByLabel(const char* label);
-
-/**
- * Gets a axis by its short form label, eg. "X".
- * Returns -1 if unknown.
- */
-extern int32_t getAxisByLabel(const char* label);
-
-/**
- * Gets a axis label by its id.
- * Returns NULL if unknown.
- */
-extern const char* getAxisLabel(int32_t axisId);
-
-/**
- * Updates a meta state field when a key is pressed or released.
- */
-extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
-
-/**
- * Returns true if a key is a meta key like ALT or CAPS_LOCK.
- */
-extern bool isMetaKey(int32_t keyCode);
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEYBOARD_H
diff --git a/include/androidfw/KeycodeLabels.h b/include/androidfw/KeycodeLabels.h
deleted file mode 100644
index 3e12f26..0000000
--- a/include/androidfw/KeycodeLabels.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2008 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 _ANDROIDFW_KEYCODE_LABELS_H
-#define _ANDROIDFW_KEYCODE_LABELS_H
-
-#include <android/keycodes.h>
-
-struct KeycodeLabel {
-    const char *literal;
-    int value;
-};
-
-static const KeycodeLabel KEYCODES[] = {
-    { "SOFT_LEFT", 1 },
-    { "SOFT_RIGHT", 2 },
-    { "HOME", 3 },
-    { "BACK", 4 },
-    { "CALL", 5 },
-    { "ENDCALL", 6 },
-    { "0", 7 },
-    { "1", 8 },
-    { "2", 9 },
-    { "3", 10 },
-    { "4", 11 },
-    { "5", 12 },
-    { "6", 13 },
-    { "7", 14 },
-    { "8", 15 },
-    { "9", 16 },
-    { "STAR", 17 },
-    { "POUND", 18 },
-    { "DPAD_UP", 19 },
-    { "DPAD_DOWN", 20 },
-    { "DPAD_LEFT", 21 },
-    { "DPAD_RIGHT", 22 },
-    { "DPAD_CENTER", 23 },
-    { "VOLUME_UP", 24 },
-    { "VOLUME_DOWN", 25 },
-    { "POWER", 26 },
-    { "CAMERA", 27 },
-    { "CLEAR", 28 },
-    { "A", 29 },
-    { "B", 30 },
-    { "C", 31 },
-    { "D", 32 },
-    { "E", 33 },
-    { "F", 34 },
-    { "G", 35 },
-    { "H", 36 },
-    { "I", 37 },
-    { "J", 38 },
-    { "K", 39 },
-    { "L", 40 },
-    { "M", 41 },
-    { "N", 42 },
-    { "O", 43 },
-    { "P", 44 },
-    { "Q", 45 },
-    { "R", 46 },
-    { "S", 47 },
-    { "T", 48 },
-    { "U", 49 },
-    { "V", 50 },
-    { "W", 51 },
-    { "X", 52 },
-    { "Y", 53 },
-    { "Z", 54 },
-    { "COMMA", 55 },
-    { "PERIOD", 56 },
-    { "ALT_LEFT", 57 },
-    { "ALT_RIGHT", 58 },
-    { "SHIFT_LEFT", 59 },
-    { "SHIFT_RIGHT", 60 },
-    { "TAB", 61 },
-    { "SPACE", 62 },
-    { "SYM", 63 },
-    { "EXPLORER", 64 },
-    { "ENVELOPE", 65 },
-    { "ENTER", 66 },
-    { "DEL", 67 },
-    { "GRAVE", 68 },
-    { "MINUS", 69 },
-    { "EQUALS", 70 },
-    { "LEFT_BRACKET", 71 },
-    { "RIGHT_BRACKET", 72 },
-    { "BACKSLASH", 73 },
-    { "SEMICOLON", 74 },
-    { "APOSTROPHE", 75 },
-    { "SLASH", 76 },
-    { "AT", 77 },
-    { "NUM", 78 },
-    { "HEADSETHOOK", 79 },
-    { "FOCUS", 80 },
-    { "PLUS", 81 },
-    { "MENU", 82 },
-    { "NOTIFICATION", 83 },
-    { "SEARCH", 84 },
-    { "MEDIA_PLAY_PAUSE", 85 },
-    { "MEDIA_STOP", 86 },
-    { "MEDIA_NEXT", 87 },
-    { "MEDIA_PREVIOUS", 88 },
-    { "MEDIA_REWIND", 89 },
-    { "MEDIA_FAST_FORWARD", 90 },
-    { "MUTE", 91 },
-    { "PAGE_UP", 92 },
-    { "PAGE_DOWN", 93 },
-    { "PICTSYMBOLS", 94 },
-    { "SWITCH_CHARSET", 95 },
-    { "BUTTON_A", 96 },
-    { "BUTTON_B", 97 },
-    { "BUTTON_C", 98 },
-    { "BUTTON_X", 99 },
-    { "BUTTON_Y", 100 },
-    { "BUTTON_Z", 101 },
-    { "BUTTON_L1", 102 },
-    { "BUTTON_R1", 103 },
-    { "BUTTON_L2", 104 },
-    { "BUTTON_R2", 105 },
-    { "BUTTON_THUMBL", 106 },
-    { "BUTTON_THUMBR", 107 },
-    { "BUTTON_START", 108 },
-    { "BUTTON_SELECT", 109 },
-    { "BUTTON_MODE", 110 },
-    { "ESCAPE", 111 },
-    { "FORWARD_DEL", 112 },
-    { "CTRL_LEFT", 113 },
-    { "CTRL_RIGHT", 114 },
-    { "CAPS_LOCK", 115 },
-    { "SCROLL_LOCK", 116 },
-    { "META_LEFT", 117 },
-    { "META_RIGHT", 118 },
-    { "FUNCTION", 119 },
-    { "SYSRQ", 120 },
-    { "BREAK", 121 },
-    { "MOVE_HOME", 122 },
-    { "MOVE_END", 123 },
-    { "INSERT", 124 },
-    { "FORWARD", 125 },
-    { "MEDIA_PLAY", 126 },
-    { "MEDIA_PAUSE", 127 },
-    { "MEDIA_CLOSE", 128 },
-    { "MEDIA_EJECT", 129 },
-    { "MEDIA_RECORD", 130 },
-    { "F1", 131 },
-    { "F2", 132 },
-    { "F3", 133 },
-    { "F4", 134 },
-    { "F5", 135 },
-    { "F6", 136 },
-    { "F7", 137 },
-    { "F8", 138 },
-    { "F9", 139 },
-    { "F10", 140 },
-    { "F11", 141 },
-    { "F12", 142 },
-    { "NUM_LOCK", 143 },
-    { "NUMPAD_0", 144 },
-    { "NUMPAD_1", 145 },
-    { "NUMPAD_2", 146 },
-    { "NUMPAD_3", 147 },
-    { "NUMPAD_4", 148 },
-    { "NUMPAD_5", 149 },
-    { "NUMPAD_6", 150 },
-    { "NUMPAD_7", 151 },
-    { "NUMPAD_8", 152 },
-    { "NUMPAD_9", 153 },
-    { "NUMPAD_DIVIDE", 154 },
-    { "NUMPAD_MULTIPLY", 155 },
-    { "NUMPAD_SUBTRACT", 156 },
-    { "NUMPAD_ADD", 157 },
-    { "NUMPAD_DOT", 158 },
-    { "NUMPAD_COMMA", 159 },
-    { "NUMPAD_ENTER", 160 },
-    { "NUMPAD_EQUALS", 161 },
-    { "NUMPAD_LEFT_PAREN", 162 },
-    { "NUMPAD_RIGHT_PAREN", 163 },
-    { "VOLUME_MUTE", 164 },
-    { "INFO", 165 },
-    { "CHANNEL_UP", 166 },
-    { "CHANNEL_DOWN", 167 },
-    { "ZOOM_IN", 168 },
-    { "ZOOM_OUT", 169 },
-    { "TV", 170 },
-    { "WINDOW", 171 },
-    { "GUIDE", 172 },
-    { "DVR", 173 },
-    { "BOOKMARK", 174 },
-    { "CAPTIONS", 175 },
-    { "SETTINGS", 176 },
-    { "TV_POWER", 177 },
-    { "TV_INPUT", 178 },
-    { "STB_POWER", 179 },
-    { "STB_INPUT", 180 },
-    { "AVR_POWER", 181 },
-    { "AVR_INPUT", 182 },
-    { "PROG_RED", 183 },
-    { "PROG_GREEN", 184 },
-    { "PROG_YELLOW", 185 },
-    { "PROG_BLUE", 186 },
-    { "APP_SWITCH", 187 },
-    { "BUTTON_1", 188 },
-    { "BUTTON_2", 189 },
-    { "BUTTON_3", 190 },
-    { "BUTTON_4", 191 },
-    { "BUTTON_5", 192 },
-    { "BUTTON_6", 193 },
-    { "BUTTON_7", 194 },
-    { "BUTTON_8", 195 },
-    { "BUTTON_9", 196 },
-    { "BUTTON_10", 197 },
-    { "BUTTON_11", 198 },
-    { "BUTTON_12", 199 },
-    { "BUTTON_13", 200 },
-    { "BUTTON_14", 201 },
-    { "BUTTON_15", 202 },
-    { "BUTTON_16", 203 },
-    { "LANGUAGE_SWITCH", 204 },
-    { "MANNER_MODE", 205 },
-    { "3D_MODE", 206 },
-    { "CONTACTS", 207 },
-    { "CALENDAR", 208 },
-    { "MUSIC", 209 },
-    { "CALCULATOR", 210 },
-    { "ZENKAKU_HANKAKU", 211 },
-    { "EISU", 212 },
-    { "MUHENKAN", 213 },
-    { "HENKAN", 214 },
-    { "KATAKANA_HIRAGANA", 215 },
-    { "YEN", 216 },
-    { "RO", 217 },
-    { "KANA", 218 },
-    { "ASSIST", 219 },
-    { "BRIGHTNESS_DOWN", 220 },
-    { "BRIGHTNESS_UP", 221 },
-
-    // NOTE: If you add a new keycode here you must also add it to several other files.
-    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-
-    { NULL, 0 }
-};
-
-// NOTE: If you edit these flags, also edit policy flags in Input.h.
-static const KeycodeLabel FLAGS[] = {
-    { "WAKE", 0x00000001 },
-    { "WAKE_DROPPED", 0x00000002 },
-    { "SHIFT", 0x00000004 },
-    { "CAPS_LOCK", 0x00000008 },
-    { "ALT", 0x00000010 },
-    { "ALT_GR", 0x00000020 },
-    { "MENU", 0x00000040 },
-    { "LAUNCHER", 0x00000080 },
-    { "VIRTUAL", 0x00000100 },
-    { "FUNCTION", 0x00000200 },
-    { NULL, 0 }
-};
-
-static const KeycodeLabel AXES[] = {
-    { "X", 0 },
-    { "Y", 1 },
-    { "PRESSURE", 2 },
-    { "SIZE", 3 },
-    { "TOUCH_MAJOR", 4 },
-    { "TOUCH_MINOR", 5 },
-    { "TOOL_MAJOR", 6 },
-    { "TOOL_MINOR", 7 },
-    { "ORIENTATION", 8 },
-    { "VSCROLL", 9 },
-    { "HSCROLL", 10 },
-    { "Z", 11 },
-    { "RX", 12 },
-    { "RY", 13 },
-    { "RZ", 14 },
-    { "HAT_X", 15 },
-    { "HAT_Y", 16 },
-    { "LTRIGGER", 17 },
-    { "RTRIGGER", 18 },
-    { "THROTTLE", 19 },
-    { "RUDDER", 20 },
-    { "WHEEL", 21 },
-    { "GAS", 22 },
-    { "BRAKE", 23 },
-    { "DISTANCE", 24 },
-    { "TILT", 25 },
-    { "GENERIC_1", 32 },
-    { "GENERIC_2", 33 },
-    { "GENERIC_3", 34 },
-    { "GENERIC_4", 35 },
-    { "GENERIC_5", 36 },
-    { "GENERIC_6", 37 },
-    { "GENERIC_7", 38 },
-    { "GENERIC_8", 39 },
-    { "GENERIC_9", 40 },
-    { "GENERIC_10", 41 },
-    { "GENERIC_11", 42 },
-    { "GENERIC_12", 43 },
-    { "GENERIC_13", 44 },
-    { "GENERIC_14", 45 },
-    { "GENERIC_15", 46 },
-    { "GENERIC_16", 47 },
-
-    // NOTE: If you add a new axis here you must also add it to several other files.
-    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
-
-    { NULL, -1 }
-};
-
-#endif // _ANDROIDFW_KEYCODE_LABELS_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index ccccc2e..a305fc3 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1553,10 +1553,8 @@
     static bool getIdmapInfo(const void* idmap, size_t size,
                              uint32_t* pOriginalCrc, uint32_t* pOverlayCrc);
 
-#ifdef STATIC_ANDROIDFW_FOR_TOOLS
     void print(bool inclValues) const;
     static String8 normalizeForOutput(const char* input);
-#endif
 
 private:
     struct Header;
diff --git a/include/androidfw/VelocityControl.h b/include/androidfw/VelocityControl.h
deleted file mode 100644
index 84e0444..0000000
--- a/include/androidfw/VelocityControl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 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 _ANDROIDFW_VELOCITY_CONTROL_H
-#define _ANDROIDFW_VELOCITY_CONTROL_H
-
-#include <androidfw/Input.h>
-#include <androidfw/VelocityTracker.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-/*
- * Specifies parameters that govern pointer or wheel acceleration.
- */
-struct VelocityControlParameters {
-    // A scale factor that is multiplied with the raw velocity deltas
-    // prior to applying any other velocity control factors.  The scale
-    // factor should be used to adapt the input device resolution
-    // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
-    //
-    // Must be a positive value.
-    // Default is 1.0 (no scaling).
-    float scale;
-
-    // The scaled speed at which acceleration begins to be applied.
-    // This value establishes the upper bound of a low speed regime for
-    // small precise motions that are performed without any acceleration.
-    //
-    // Must be a non-negative value.
-    // Default is 0.0 (no low threshold).
-    float lowThreshold;
-
-    // The scaled speed at which maximum acceleration is applied.
-    // The difference between highThreshold and lowThreshold controls
-    // the range of speeds over which the acceleration factor is interpolated.
-    // The wider the range, the smoother the acceleration.
-    //
-    // Must be a non-negative value greater than or equal to lowThreshold.
-    // Default is 0.0 (no high threshold).
-    float highThreshold;
-
-    // The acceleration factor.
-    // When the speed is above the low speed threshold, the velocity will scaled
-    // by an interpolated value between 1.0 and this amount.
-    //
-    // Must be a positive greater than or equal to 1.0.
-    // Default is 1.0 (no acceleration).
-    float acceleration;
-
-    VelocityControlParameters() :
-            scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
-    }
-
-    VelocityControlParameters(float scale, float lowThreshold,
-            float highThreshold, float acceleration) :
-            scale(scale), lowThreshold(lowThreshold),
-            highThreshold(highThreshold), acceleration(acceleration) {
-    }
-};
-
-/*
- * Implements mouse pointer and wheel speed control and acceleration.
- */
-class VelocityControl {
-public:
-    VelocityControl();
-
-    /* Sets the various parameters. */
-    void setParameters(const VelocityControlParameters& parameters);
-
-    /* Resets the current movement counters to zero.
-     * This has the effect of nullifying any acceleration. */
-    void reset();
-
-    /* Translates a raw movement delta into an appropriately
-     * scaled / accelerated delta based on the current velocity. */
-    void move(nsecs_t eventTime, float* deltaX, float* deltaY);
-
-private:
-    // If no movements are received within this amount of time,
-    // we assume the movement has stopped and reset the movement counters.
-    static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms
-
-    VelocityControlParameters mParameters;
-
-    nsecs_t mLastMovementTime;
-    VelocityTracker::Position mRawPosition;
-    VelocityTracker mVelocityTracker;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_CONTROL_H
diff --git a/include/androidfw/VelocityTracker.h b/include/androidfw/VelocityTracker.h
deleted file mode 100644
index 8c24219..0000000
--- a/include/androidfw/VelocityTracker.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2012 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 _ANDROIDFW_VELOCITY_TRACKER_H
-#define _ANDROIDFW_VELOCITY_TRACKER_H
-
-#include <androidfw/Input.h>
-#include <utils/Timers.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-class VelocityTrackerStrategy;
-
-/*
- * Calculates the velocity of pointer movements over time.
- */
-class VelocityTracker {
-public:
-    struct Position {
-        float x, y;
-    };
-
-    struct Estimator {
-        static const size_t MAX_DEGREE = 4;
-
-        // Estimator time base.
-        nsecs_t time;
-
-        // Polynomial coefficients describing motion in X and Y.
-        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
-
-        // Polynomial degree (number of coefficients), or zero if no information is
-        // available.
-        uint32_t degree;
-
-        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
-        float confidence;
-
-        inline void clear() {
-            time = 0;
-            degree = 0;
-            confidence = 0;
-            for (size_t i = 0; i <= MAX_DEGREE; i++) {
-                xCoeff[i] = 0;
-                yCoeff[i] = 0;
-            }
-        }
-    };
-
-    // Creates a velocity tracker using the specified strategy.
-    // If strategy is NULL, uses the default strategy for the platform.
-    VelocityTracker(const char* strategy = NULL);
-
-    ~VelocityTracker();
-
-    // Resets the velocity tracker state.
-    void clear();
-
-    // Resets the velocity tracker state for specific pointers.
-    // Call this method when some pointers have changed and may be reusing
-    // an id that was assigned to a different pointer earlier.
-    void clearPointers(BitSet32 idBits);
-
-    // Adds movement information for a set of pointers.
-    // The idBits bitfield specifies the pointer ids of the pointers whose positions
-    // are included in the movement.
-    // The positions array contains position information for each pointer in order by
-    // increasing id.  Its size should be equal to the number of one bits in idBits.
-    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
-
-    // Adds movement information for all pointers in a MotionEvent, including historical samples.
-    void addMovement(const MotionEvent* event);
-
-    // Gets the velocity of the specified pointer id in position units per second.
-    // Returns false and sets the velocity components to zero if there is
-    // insufficient movement information for the pointer.
-    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
-
-    // Gets an estimator for the recent movements of the specified pointer id.
-    // Returns false and clears the estimator if there is no information available
-    // about the pointer.
-    bool getEstimator(uint32_t id, Estimator* outEstimator) const;
-
-    // Gets the active pointer id, or -1 if none.
-    inline int32_t getActivePointerId() const { return mActivePointerId; }
-
-    // Gets a bitset containing all pointer ids from the most recent movement.
-    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
-
-private:
-    static const char* DEFAULT_STRATEGY;
-
-    nsecs_t mLastEventTime;
-    BitSet32 mCurrentPointerIdBits;
-    int32_t mActivePointerId;
-    VelocityTrackerStrategy* mStrategy;
-
-    bool configureStrategy(const char* strategy);
-
-    static VelocityTrackerStrategy* createStrategy(const char* strategy);
-};
-
-
-/*
- * Implements a particular velocity tracker algorithm.
- */
-class VelocityTrackerStrategy {
-protected:
-    VelocityTrackerStrategy() { }
-
-public:
-    virtual ~VelocityTrackerStrategy() { }
-
-    virtual void clear() = 0;
-    virtual void clearPointers(BitSet32 idBits) = 0;
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions) = 0;
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
-};
-
-
-/*
- * Velocity tracker algorithm based on least-squares linear regression.
- */
-class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    enum Weighting {
-        // No weights applied.  All data points are equally reliable.
-        WEIGHTING_NONE,
-
-        // Weight by time delta.  Data points clustered together are weighted less.
-        WEIGHTING_DELTA,
-
-        // Weight such that points within a certain horizon are weighed more than those
-        // outside of that horizon.
-        WEIGHTING_CENTRAL,
-
-        // Weight such that points older than a certain amount are weighed less.
-        WEIGHTING_RECENT,
-    };
-
-    // Degree must be no greater than Estimator::MAX_DEGREE.
-    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
-    virtual ~LeastSquaresVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Sample horizon.
-    // We don't use too much history by default since we want to react to quick
-    // changes in direction.
-    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
-
-    // Number of samples to keep.
-    static const uint32_t HISTORY_SIZE = 20;
-
-    struct Movement {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        VelocityTracker::Position positions[MAX_POINTERS];
-
-        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
-            return positions[idBits.getIndexOfBit(id)];
-        }
-    };
-
-    float chooseWeight(uint32_t index) const;
-
-    const uint32_t mDegree;
-    const Weighting mWeighting;
-    uint32_t mIndex;
-    Movement mMovements[HISTORY_SIZE];
-};
-
-
-/*
- * Velocity tracker algorithm that uses an IIR filter.
- */
-class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    // Degree must be 1 or 2.
-    IntegratingVelocityTrackerStrategy(uint32_t degree);
-    ~IntegratingVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Current state estimate for a particular pointer.
-    struct State {
-        nsecs_t updateTime;
-        uint32_t degree;
-
-        float xpos, xvel, xaccel;
-        float ypos, yvel, yaccel;
-    };
-
-    const uint32_t mDegree;
-    BitSet32 mPointerIdBits;
-    State mPointerState[MAX_POINTER_ID + 1];
-
-    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
-    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
-    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
-};
-
-
-/*
- * Velocity tracker strategy used prior to ICS.
- */
-class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    LegacyVelocityTrackerStrategy();
-    virtual ~LegacyVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Oldest sample to consider when calculating the velocity.
-    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
-
-    // Number of samples to keep.
-    static const uint32_t HISTORY_SIZE = 20;
-
-    // The minimum duration between samples when estimating velocity.
-    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
-
-    struct Movement {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        VelocityTracker::Position positions[MAX_POINTERS];
-
-        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
-            return positions[idBits.getIndexOfBit(id)];
-        }
-    };
-
-    uint32_t mIndex;
-    Movement mMovements[HISTORY_SIZE];
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_TRACKER_H
diff --git a/include/androidfw/VirtualKeyMap.h b/include/androidfw/VirtualKeyMap.h
deleted file mode 100644
index dd3ad1e9..0000000
--- a/include/androidfw/VirtualKeyMap.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 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 _ANDROIDFW_VIRTUAL_KEY_MAP_H
-#define _ANDROIDFW_VIRTUAL_KEY_MAP_H
-
-#include <stdint.h>
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-
-namespace android {
-
-/* Describes a virtual key. */
-struct VirtualKeyDefinition {
-    int32_t scanCode;
-
-    // configured position data, specified in display coords
-    int32_t centerX;
-    int32_t centerY;
-    int32_t width;
-    int32_t height;
-};
-
-
-/**
- * Describes a collection of virtual keys on a touch screen in terms of
- * virtual scan codes and hit rectangles.
- *
- * This object is immutable after it has been loaded.
- */
-class VirtualKeyMap {
-public:
-    ~VirtualKeyMap();
-
-    static status_t load(const String8& filename, VirtualKeyMap** outMap);
-
-    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
-        return mVirtualKeys;
-    }
-
-private:
-    class Parser {
-        VirtualKeyMap* mMap;
-        Tokenizer* mTokenizer;
-
-    public:
-        Parser(VirtualKeyMap* map, Tokenizer* tokenizer);
-        ~Parser();
-        status_t parse();
-
-    private:
-        bool consumeFieldDelimiterAndSkipWhitespace();
-        bool parseNextIntField(int32_t* outValue);
-    };
-
-    Vector<VirtualKeyDefinition> mVirtualKeys;
-
-    VirtualKeyMap();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index c06b144..4e126b8 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -14,11 +14,10 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# libandroidfw is partially built for the host (used by build time keymap validation tool)
+# libandroidfw is partially built for the host (used by obbtool and others)
 # These files are common to host and target builds.
 
-# formerly in libutils
-commonUtilsSources:= \
+commonSources := \
     Asset.cpp \
     AssetDir.cpp \
     AssetManager.cpp \
@@ -30,26 +29,21 @@
     ZipFileRO.cpp \
     ZipUtils.cpp
 
-# formerly in libui
-commonUiSources:= \
-    Input.cpp \
-    InputDevice.cpp \
-    Keyboard.cpp \
-    KeyCharacterMap.cpp \
-    KeyLayoutMap.cpp \
-    VelocityControl.cpp \
-    VirtualKeyMap.cpp
+deviceSources := \
+    $(commonSources) \
+    BackupData.cpp \
+    BackupHelpers.cpp \
+    CursorWindow.cpp
 
-commonSources:= \
-	$(commonUtilsSources) \
-	$(commonUiSources)
+hostSources := \
+    $(commonSources)
 
 # For the host
 # =====================================================
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= $(commonSources)
+LOCAL_SRC_FILES:= $(hostSources)
 
 LOCAL_MODULE:= libandroidfw
 
@@ -68,24 +62,16 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	$(commonSources) \
-	BackupData.cpp \
-	BackupHelpers.cpp \
-    CursorWindow.cpp \
-	InputTransport.cpp \
-	VelocityTracker.cpp
+LOCAL_SRC_FILES:= $(deviceSources)
 
 LOCAL_SHARED_LIBRARIES := \
+	libbinder \
 	liblog \
 	libcutils \
 	libutils \
-	libbinder \
-	libskia \
 	libz
 
 LOCAL_C_INCLUDES := \
-    external/skia/include/core \
     external/icu4c/common \
 	external/zlib
 
@@ -96,21 +82,6 @@
 include $(BUILD_SHARED_LIBRARY)
 
 
-ifeq ($(TARGET_OS),linux)
-include $(CLEAR_VARS)
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-LOCAL_C_INCLUDES += \
-	external/skia/include/core \
-	external/zlib \
-	external/icu4c/common \
-	bionic/libc/private
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-LOCAL_MODULE := libandroidfw
-LOCAL_SRC_FILES := $(commonUtilsSources) BackupData.cpp BackupHelpers.cpp
-include $(BUILD_STATIC_LIBRARY)
-endif
-
-
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 047a4c8..0f54edb 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -17,8 +17,9 @@
 #undef LOG_TAG
 #define LOG_TAG "CursorWindow"
 
-#include <utils/Log.h>
 #include <androidfw/CursorWindow.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
 
 #include <cutils/ashmem.h>
 #include <sys/mman.h>
diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp
deleted file mode 100644
index eca692a..0000000
--- a/libs/androidfw/Input.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "Input"
-//#define LOG_NDEBUG 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/Input.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-
-#include "SkPoint.h"
-#include "SkMatrix.h"
-#include "SkScalar.h"
-#endif
-
-namespace android {
-
-// --- InputEvent ---
-
-void InputEvent::initialize(int32_t deviceId, int32_t source) {
-    mDeviceId = deviceId;
-    mSource = source;
-}
-
-void InputEvent::initialize(const InputEvent& from) {
-    mDeviceId = from.mDeviceId;
-    mSource = from.mSource;
-}
-
-// --- KeyEvent ---
-
-bool KeyEvent::hasDefaultAction(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MENU:
-        case AKEYCODE_NOTIFICATION:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_MUTE:
-        case AKEYCODE_BRIGHTNESS_DOWN:
-        case AKEYCODE_BRIGHTNESS_UP:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::hasDefaultAction() const {
-    return hasDefaultAction(getKeyCode());
-}
-
-bool KeyEvent::isSystemKey(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_MENU:
-        case AKEYCODE_SOFT_RIGHT:
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-        case AKEYCODE_BRIGHTNESS_DOWN:
-        case AKEYCODE_BRIGHTNESS_UP:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::isSystemKey() const {
-    return isSystemKey(getKeyCode());
-}
-
-void KeyEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mKeyCode = keyCode;
-    mScanCode = scanCode;
-    mMetaState = metaState;
-    mRepeatCount = repeatCount;
-    mDownTime = downTime;
-    mEventTime = eventTime;
-}
-
-void KeyEvent::initialize(const KeyEvent& from) {
-    InputEvent::initialize(from);
-    mAction = from.mAction;
-    mFlags = from.mFlags;
-    mKeyCode = from.mKeyCode;
-    mScanCode = from.mScanCode;
-    mMetaState = from.mMetaState;
-    mRepeatCount = from.mRepeatCount;
-    mDownTime = from.mDownTime;
-    mEventTime = from.mEventTime;
-}
-
-
-// --- PointerCoords ---
-
-float PointerCoords::getAxisValue(int32_t axis) const {
-    if (axis < 0 || axis > 63) {
-        return 0;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    if (!(bits & axisBit)) {
-        return 0;
-    }
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    return values[index];
-}
-
-status_t PointerCoords::setAxisValue(int32_t axis, float value) {
-    if (axis < 0 || axis > 63) {
-        return NAME_NOT_FOUND;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    if (!(bits & axisBit)) {
-        if (value == 0) {
-            return OK; // axes with value 0 do not need to be stored
-        }
-        uint32_t count = __builtin_popcountll(bits);
-        if (count >= MAX_AXES) {
-            tooManyAxes(axis);
-            return NO_MEMORY;
-        }
-        bits |= axisBit;
-        for (uint32_t i = count; i > index; i--) {
-            values[i] = values[i - 1];
-        }
-    }
-    values[index] = value;
-    return OK;
-}
-
-static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
-    float value = c.getAxisValue(axis);
-    if (value != 0) {
-        c.setAxisValue(axis, value * scaleFactor);
-    }
-}
-
-void PointerCoords::scale(float scaleFactor) {
-    // No need to scale pressure or size since they are normalized.
-    // No need to scale orientation since it is meaningless to do so.
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
-}
-
-#ifdef HAVE_ANDROID_OS
-status_t PointerCoords::readFromParcel(Parcel* parcel) {
-    bits = parcel->readInt64();
-
-    uint32_t count = __builtin_popcountll(bits);
-    if (count > MAX_AXES) {
-        return BAD_VALUE;
-    }
-
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = parcel->readFloat();
-    }
-    return OK;
-}
-
-status_t PointerCoords::writeToParcel(Parcel* parcel) const {
-    parcel->writeInt64(bits);
-
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        parcel->writeFloat(values[i]);
-    }
-    return OK;
-}
-#endif
-
-void PointerCoords::tooManyAxes(int axis) {
-    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
-            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
-}
-
-bool PointerCoords::operator==(const PointerCoords& other) const {
-    if (bits != other.bits) {
-        return false;
-    }
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        if (values[i] != other.values[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void PointerCoords::copyFrom(const PointerCoords& other) {
-    bits = other.bits;
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = other.values[i];
-    }
-}
-
-
-// --- PointerProperties ---
-
-bool PointerProperties::operator==(const PointerProperties& other) const {
-    return id == other.id
-            && toolType == other.toolType;
-}
-
-void PointerProperties::copyFrom(const PointerProperties& other) {
-    id = other.id;
-    toolType = other.toolType;
-}
-
-
-// --- MotionEvent ---
-
-void MotionEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mEdgeFlags = edgeFlags;
-    mMetaState = metaState;
-    mButtonState = buttonState;
-    mXOffset = xOffset;
-    mYOffset = yOffset;
-    mXPrecision = xPrecision;
-    mYPrecision = yPrecision;
-    mDownTime = downTime;
-    mPointerProperties.clear();
-    mPointerProperties.appendArray(pointerProperties, pointerCount);
-    mSampleEventTimes.clear();
-    mSamplePointerCoords.clear();
-    addSample(eventTime, pointerCoords);
-}
-
-void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
-    InputEvent::initialize(other->mDeviceId, other->mSource);
-    mAction = other->mAction;
-    mFlags = other->mFlags;
-    mEdgeFlags = other->mEdgeFlags;
-    mMetaState = other->mMetaState;
-    mButtonState = other->mButtonState;
-    mXOffset = other->mXOffset;
-    mYOffset = other->mYOffset;
-    mXPrecision = other->mXPrecision;
-    mYPrecision = other->mYPrecision;
-    mDownTime = other->mDownTime;
-    mPointerProperties = other->mPointerProperties;
-
-    if (keepHistory) {
-        mSampleEventTimes = other->mSampleEventTimes;
-        mSamplePointerCoords = other->mSamplePointerCoords;
-    } else {
-        mSampleEventTimes.clear();
-        mSampleEventTimes.push(other->getEventTime());
-        mSamplePointerCoords.clear();
-        size_t pointerCount = other->getPointerCount();
-        size_t historySize = other->getHistorySize();
-        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
-                + (historySize * pointerCount), pointerCount);
-    }
-}
-
-void MotionEvent::addSample(
-        int64_t eventTime,
-        const PointerCoords* pointerCoords) {
-    mSampleEventTimes.push(eventTime);
-    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
-}
-
-const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
-    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
-    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
-    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
-        size_t pointerIndex, size_t historicalIndex) const {
-    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
-    size_t pointerCount = mPointerProperties.size();
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (mPointerProperties.itemAt(i).id == pointerId) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void MotionEvent::offsetLocation(float xOffset, float yOffset) {
-    mXOffset += xOffset;
-    mYOffset += yOffset;
-}
-
-void MotionEvent::scale(float scaleFactor) {
-    mXOffset *= scaleFactor;
-    mYOffset *= scaleFactor;
-    mXPrecision *= scaleFactor;
-    mYPrecision *= scaleFactor;
-
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
-    }
-}
-
-#ifdef HAVE_ANDROID_OS
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
-    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    SkPoint vector;
-    vector.fX = SkFloatToScalar(sinf(angleRadians));
-    vector.fY = SkFloatToScalar(-cosf(angleRadians));
-    matrix->mapVectors(& vector, 1);
-
-    // Derive the transformed vector's clockwise angle from vertical.
-    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
-    if (result < - M_PI_2) {
-        result += M_PI;
-    } else if (result > M_PI_2) {
-        result -= M_PI;
-    }
-    return result;
-}
-
-void MotionEvent::transform(const SkMatrix* matrix) {
-    float oldXOffset = mXOffset;
-    float oldYOffset = mYOffset;
-
-    // The tricky part of this implementation is to preserve the value of
-    // rawX and rawY.  So we apply the transformation to the first point
-    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
-    SkPoint point;
-    float rawX = getRawX(0);
-    float rawY = getRawY(0);
-    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
-            & point);
-    float newX = SkScalarToFloat(point.fX);
-    float newY = SkScalarToFloat(point.fY);
-    float newXOffset = newX - rawX;
-    float newYOffset = newY - rawY;
-
-    mXOffset = newXOffset;
-    mYOffset = newYOffset;
-
-    // Apply the transformation to all samples.
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
-        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
-        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
-        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
-        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
-        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
-
-        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
-        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
-    }
-}
-
-status_t MotionEvent::readFromParcel(Parcel* parcel) {
-    size_t pointerCount = parcel->readInt32();
-    size_t sampleCount = parcel->readInt32();
-    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
-        return BAD_VALUE;
-    }
-
-    mDeviceId = parcel->readInt32();
-    mSource = parcel->readInt32();
-    mAction = parcel->readInt32();
-    mFlags = parcel->readInt32();
-    mEdgeFlags = parcel->readInt32();
-    mMetaState = parcel->readInt32();
-    mButtonState = parcel->readInt32();
-    mXOffset = parcel->readFloat();
-    mYOffset = parcel->readFloat();
-    mXPrecision = parcel->readFloat();
-    mYPrecision = parcel->readFloat();
-    mDownTime = parcel->readInt64();
-
-    mPointerProperties.clear();
-    mPointerProperties.setCapacity(pointerCount);
-    mSampleEventTimes.clear();
-    mSampleEventTimes.setCapacity(sampleCount);
-    mSamplePointerCoords.clear();
-    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        mPointerProperties.push();
-        PointerProperties& properties = mPointerProperties.editTop();
-        properties.id = parcel->readInt32();
-        properties.toolType = parcel->readInt32();
-    }
-
-    while (sampleCount-- > 0) {
-        mSampleEventTimes.push(parcel->readInt64());
-        for (size_t i = 0; i < pointerCount; i++) {
-            mSamplePointerCoords.push();
-            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-
-status_t MotionEvent::writeToParcel(Parcel* parcel) const {
-    size_t pointerCount = mPointerProperties.size();
-    size_t sampleCount = mSampleEventTimes.size();
-
-    parcel->writeInt32(pointerCount);
-    parcel->writeInt32(sampleCount);
-
-    parcel->writeInt32(mDeviceId);
-    parcel->writeInt32(mSource);
-    parcel->writeInt32(mAction);
-    parcel->writeInt32(mFlags);
-    parcel->writeInt32(mEdgeFlags);
-    parcel->writeInt32(mMetaState);
-    parcel->writeInt32(mButtonState);
-    parcel->writeFloat(mXOffset);
-    parcel->writeFloat(mYOffset);
-    parcel->writeFloat(mXPrecision);
-    parcel->writeFloat(mYPrecision);
-    parcel->writeInt64(mDownTime);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        const PointerProperties& properties = mPointerProperties.itemAt(i);
-        parcel->writeInt32(properties.id);
-        parcel->writeInt32(properties.toolType);
-    }
-
-    const PointerCoords* pc = mSamplePointerCoords.array();
-    for (size_t h = 0; h < sampleCount; h++) {
-        parcel->writeInt64(mSampleEventTimes.itemAt(h));
-        for (size_t i = 0; i < pointerCount; i++) {
-            status_t status = (pc++)->writeToParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-#endif
-
-bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
-    if (source & AINPUT_SOURCE_CLASS_POINTER) {
-        // Specifically excludes HOVER_MOVE and SCROLL.
-        switch (action & AMOTION_EVENT_ACTION_MASK) {
-        case AMOTION_EVENT_ACTION_DOWN:
-        case AMOTION_EVENT_ACTION_MOVE:
-        case AMOTION_EVENT_ACTION_UP:
-        case AMOTION_EVENT_ACTION_POINTER_DOWN:
-        case AMOTION_EVENT_ACTION_POINTER_UP:
-        case AMOTION_EVENT_ACTION_CANCEL:
-        case AMOTION_EVENT_ACTION_OUTSIDE:
-            return true;
-        }
-    }
-    return false;
-}
-
-
-// --- PooledInputEventFactory ---
-
-PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
-        mMaxPoolSize(maxPoolSize) {
-}
-
-PooledInputEventFactory::~PooledInputEventFactory() {
-    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
-        delete mKeyEventPool.itemAt(i);
-    }
-    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
-        delete mMotionEventPool.itemAt(i);
-    }
-}
-
-KeyEvent* PooledInputEventFactory::createKeyEvent() {
-    if (!mKeyEventPool.isEmpty()) {
-        KeyEvent* event = mKeyEventPool.top();
-        mKeyEventPool.pop();
-        return event;
-    }
-    return new KeyEvent();
-}
-
-MotionEvent* PooledInputEventFactory::createMotionEvent() {
-    if (!mMotionEventPool.isEmpty()) {
-        MotionEvent* event = mMotionEventPool.top();
-        mMotionEventPool.pop();
-        return event;
-    }
-    return new MotionEvent();
-}
-
-void PooledInputEventFactory::recycle(InputEvent* event) {
-    switch (event->getType()) {
-    case AINPUT_EVENT_TYPE_KEY:
-        if (mKeyEventPool.size() < mMaxPoolSize) {
-            mKeyEventPool.push(static_cast<KeyEvent*>(event));
-            return;
-        }
-        break;
-    case AINPUT_EVENT_TYPE_MOTION:
-        if (mMotionEventPool.size() < mMaxPoolSize) {
-            mMotionEventPool.push(static_cast<MotionEvent*>(event));
-            return;
-        }
-        break;
-    }
-    delete event;
-}
-
-} // namespace android
diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp
deleted file mode 100644
index f742052..0000000
--- a/libs/androidfw/InputDevice.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#define LOG_TAG "InputDevice"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include <androidfw/InputDevice.h>
-
-namespace android {
-
-static const char* CONFIGURATION_FILE_DIR[] = {
-        "idc/",
-        "keylayout/",
-        "keychars/",
-};
-
-static const char* CONFIGURATION_FILE_EXTENSION[] = {
-        ".idc",
-        ".kl",
-        ".kcm",
-};
-
-static bool isValidNameChar(char ch) {
-    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
-}
-
-static void appendInputDeviceConfigurationFileRelativePath(String8& path,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    path.append(CONFIGURATION_FILE_DIR[type]);
-    for (size_t i = 0; i < name.length(); i++) {
-        char ch = name[i];
-        if (!isValidNameChar(ch)) {
-            ch = '_';
-        }
-        path.append(&ch, 1);
-    }
-    path.append(CONFIGURATION_FILE_EXTENSION[type]);
-}
-
-String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
-        const InputDeviceIdentifier& deviceIdentifier,
-        InputDeviceConfigurationFileType type) {
-    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
-        if (deviceIdentifier.version != 0) {
-            // Try vendor product version.
-            String8 versionPath(getInputDeviceConfigurationFilePathByName(
-                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
-                            deviceIdentifier.vendor, deviceIdentifier.product,
-                            deviceIdentifier.version),
-                    type));
-            if (!versionPath.isEmpty()) {
-                return versionPath;
-            }
-        }
-
-        // Try vendor product.
-        String8 productPath(getInputDeviceConfigurationFilePathByName(
-                String8::format("Vendor_%04x_Product_%04x",
-                        deviceIdentifier.vendor, deviceIdentifier.product),
-                type));
-        if (!productPath.isEmpty()) {
-            return productPath;
-        }
-    }
-
-    // Try device name.
-    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
-}
-
-String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type) {
-    // Search system repository.
-    String8 path;
-    path.setTo(getenv("ANDROID_ROOT"));
-    path.append("/usr/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Search user repository.
-    // TODO Should only look here if not in safe mode.
-    path.setTo(getenv("ANDROID_DATA"));
-    path.append("/system/devices/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Not found.
-#if DEBUG_PROBE
-    ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
-            name.string(), type);
-#endif
-    return String8();
-}
-
-
-// --- InputDeviceInfo ---
-
-InputDeviceInfo::InputDeviceInfo() {
-    initialize(-1, -1, InputDeviceIdentifier(), String8(), false);
-}
-
-InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
-        mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier),
-        mAlias(other.mAlias), mIsExternal(other.mIsExternal), mSources(other.mSources),
-        mKeyboardType(other.mKeyboardType),
-        mKeyCharacterMap(other.mKeyCharacterMap),
-        mHasVibrator(other.mHasVibrator),
-        mMotionRanges(other.mMotionRanges) {
-}
-
-InputDeviceInfo::~InputDeviceInfo() {
-}
-
-void InputDeviceInfo::initialize(int32_t id, int32_t generation,
-        const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) {
-    mId = id;
-    mGeneration = generation;
-    mIdentifier = identifier;
-    mAlias = alias;
-    mIsExternal = isExternal;
-    mSources = 0;
-    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
-    mHasVibrator = false;
-    mMotionRanges.clear();
-}
-
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
-        int32_t axis, uint32_t source) const {
-    size_t numRanges = mMotionRanges.size();
-    for (size_t i = 0; i < numRanges; i++) {
-        const MotionRange& range = mMotionRanges.itemAt(i);
-        if (range.axis == axis && range.source == source) {
-            return &range;
-        }
-    }
-    return NULL;
-}
-
-void InputDeviceInfo::addSource(uint32_t source) {
-    mSources |= source;
-}
-
-void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
-        float flat, float fuzz, float resolution) {
-    MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
-    mMotionRanges.add(range);
-}
-
-void InputDeviceInfo::addMotionRange(const MotionRange& range) {
-    mMotionRanges.add(range);
-}
-
-} // namespace android
diff --git a/libs/androidfw/InputTransport.cpp b/libs/androidfw/InputTransport.cpp
deleted file mode 100644
index cfbc923..0000000
--- a/libs/androidfw/InputTransport.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// Provides a shared memory transport for input events.
-//
-#define LOG_TAG "InputTransport"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about channel messages (send message, receive message)
-#define DEBUG_CHANNEL_MESSAGES 0
-
-// Log debug messages whenever InputChannel objects are created/destroyed
-#define DEBUG_CHANNEL_LIFECYCLE 0
-
-// Log debug messages about transport actions
-#define DEBUG_TRANSPORT_ACTIONS 0
-
-// Log debug messages about touch event resampling
-#define DEBUG_RESAMPLING 0
-
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <androidfw/InputTransport.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <math.h>
-
-
-namespace android {
-
-// Socket buffer size.  The default is typically about 128KB, which is much larger than
-// we really need.  So we make it smaller.  It just needs to be big enough to hold
-// a few dozen large multi-finger motion events in the case where an application gets
-// behind processing touches.
-static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Latency added during resampling.  A few milliseconds doesn't hurt much but
-// reduces the impact of mispredicted touch positions.
-static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
-
-// Minimum time difference between consecutive samples before attempting to resample.
-static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
-
-// Maximum time to predict forward from the last known state, to avoid predicting too
-// far into the future.  This time is further bounded by 50% of the last time delta.
-static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
-    return a < b ? a : b;
-}
-
-inline static float lerp(float a, float b, float alpha) {
-    return a + alpha * (b - a);
-}
-
-// --- InputMessage ---
-
-bool InputMessage::isValid(size_t actualSize) const {
-    if (size() == actualSize) {
-        switch (header.type) {
-        case TYPE_KEY:
-            return true;
-        case TYPE_MOTION:
-            return body.motion.pointerCount > 0
-                    && body.motion.pointerCount <= MAX_POINTERS;
-        case TYPE_FINISHED:
-            return true;
-        }
-    }
-    return false;
-}
-
-size_t InputMessage::size() const {
-    switch (header.type) {
-    case TYPE_KEY:
-        return sizeof(Header) + body.key.size();
-    case TYPE_MOTION:
-        return sizeof(Header) + body.motion.size();
-    case TYPE_FINISHED:
-        return sizeof(Header) + body.finished.size();
-    }
-    return sizeof(Header);
-}
-
-
-// --- InputChannel ---
-
-InputChannel::InputChannel(const String8& name, int fd) :
-        mName(name), mFd(fd) {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel constructed: name='%s', fd=%d",
-            mName.string(), fd);
-#endif
-
-    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
-            "non-blocking.  errno=%d", mName.string(), errno);
-}
-
-InputChannel::~InputChannel() {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel destroyed: name='%s', fd=%d",
-            mName.string(), mFd);
-#endif
-
-    ::close(mFd);
-}
-
-status_t InputChannel::openInputChannelPair(const String8& name,
-        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
-    int sockets[2];
-    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
-        status_t result = -errno;
-        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
-                name.string(), errno);
-        outServerChannel.clear();
-        outClientChannel.clear();
-        return result;
-    }
-
-    int bufferSize = SOCKET_BUFFER_SIZE;
-    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-
-    String8 serverChannelName = name;
-    serverChannelName.append(" (server)");
-    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
-
-    String8 clientChannelName = name;
-    clientChannelName.append(" (client)");
-    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
-    return OK;
-}
-
-status_t InputChannel::sendMessage(const InputMessage* msg) {
-    size_t msgLength = msg->size();
-    ssize_t nWrite;
-    do {
-        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
-    } while (nWrite == -1 && errno == EINTR);
-
-    if (nWrite < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
-                msg->header.type, error);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (size_t(nWrite) != msgLength) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
-                mName.string(), msg->header.type);
-#endif
-        return DEAD_OBJECT;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-status_t InputChannel::receiveMessage(InputMessage* msg) {
-    ssize_t nRead;
-    do {
-        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
-    } while (nRead == -1 && errno == EINTR);
-
-    if (nRead < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (nRead == 0) { // check for EOF
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
-#endif
-        return DEAD_OBJECT;
-    }
-
-    if (!msg->isValid(nRead)) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ received invalid message", mName.string());
-#endif
-        return BAD_VALUE;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-sp<InputChannel> InputChannel::dup() const {
-    int fd = ::dup(getFd());
-    return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
-}
-
-
-// --- InputPublisher ---
-
-InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
-        mChannel(channel) {
-}
-
-InputPublisher::~InputPublisher() {
-}
-
-status_t InputPublisher::publishKeyEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
-            "downTime=%lld, eventTime=%lld",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
-            downTime, eventTime);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a key event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    msg.body.key.seq = seq;
-    msg.body.key.deviceId = deviceId;
-    msg.body.key.source = source;
-    msg.body.key.action = action;
-    msg.body.key.flags = flags;
-    msg.body.key.keyCode = keyCode;
-    msg.body.key.scanCode = scanCode;
-    msg.body.key.metaState = metaState;
-    msg.body.key.repeatCount = repeatCount;
-    msg.body.key.downTime = downTime;
-    msg.body.key.eventTime = eventTime;
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::publishMotionEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
-            "xOffset=%f, yOffset=%f, "
-            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
-            "pointerCount=%d",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, edgeFlags, metaState, buttonState,
-            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a motion event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
-        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
-                mChannel->getName().string(), pointerCount);
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_MOTION;
-    msg.body.motion.seq = seq;
-    msg.body.motion.deviceId = deviceId;
-    msg.body.motion.source = source;
-    msg.body.motion.action = action;
-    msg.body.motion.flags = flags;
-    msg.body.motion.edgeFlags = edgeFlags;
-    msg.body.motion.metaState = metaState;
-    msg.body.motion.buttonState = buttonState;
-    msg.body.motion.xOffset = xOffset;
-    msg.body.motion.yOffset = yOffset;
-    msg.body.motion.xPrecision = xPrecision;
-    msg.body.motion.yPrecision = yPrecision;
-    msg.body.motion.downTime = downTime;
-    msg.body.motion.eventTime = eventTime;
-    msg.body.motion.pointerCount = pointerCount;
-    for (size_t i = 0; i < pointerCount; i++) {
-        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
-        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
-    }
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
-            mChannel->getName().string());
-#endif
-
-    InputMessage msg;
-    status_t result = mChannel->receiveMessage(&msg);
-    if (result) {
-        *outSeq = 0;
-        *outHandled = false;
-        return result;
-    }
-    if (msg.header.type != InputMessage::TYPE_FINISHED) {
-        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
-                mChannel->getName().string(), msg.header.type);
-        return UNKNOWN_ERROR;
-    }
-    *outSeq = msg.body.finished.seq;
-    *outHandled = msg.body.finished.handled;
-    return OK;
-}
-
-// --- InputConsumer ---
-
-InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
-        mResampleTouch(isTouchResamplingEnabled()),
-        mChannel(channel), mMsgDeferred(false) {
-}
-
-InputConsumer::~InputConsumer() {
-}
-
-bool InputConsumer::isTouchResamplingEnabled() {
-    char value[PROPERTY_VALUE_MAX];
-    int length = property_get("debug.inputconsumer.resample", value, NULL);
-    if (length > 0) {
-        if (!strcmp("0", value)) {
-            return false;
-        }
-        if (strcmp("1", value)) {
-            ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'.  "
-                    "Use '1' or '0'.");
-        }
-    }
-    return true;
-}
-
-status_t InputConsumer::consume(InputEventFactoryInterface* factory,
-        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
-            mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
-#endif
-
-    *outSeq = 0;
-    *outEvent = NULL;
-
-    // Fetch the next input message.
-    // Loop until an event can be returned or no additional events are received.
-    while (!*outEvent) {
-        if (mMsgDeferred) {
-            // mMsg contains a valid input message from the previous call to consume
-            // that has not yet been processed.
-            mMsgDeferred = false;
-        } else {
-            // Receive a fresh message.
-            status_t result = mChannel->receiveMessage(&mMsg);
-            if (result) {
-                // Consume the next batched event unless batches are being held for later.
-                if (consumeBatches || result != WOULD_BLOCK) {
-                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
-                    if (*outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
-                        ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
-                                mChannel->getName().string(), *outSeq);
-#endif
-                        break;
-                    }
-                }
-                return result;
-            }
-        }
-
-        switch (mMsg.header.type) {
-        case InputMessage::TYPE_KEY: {
-            KeyEvent* keyEvent = factory->createKeyEvent();
-            if (!keyEvent) return NO_MEMORY;
-
-            initializeKeyEvent(keyEvent, &mMsg);
-            *outSeq = mMsg.body.key.seq;
-            *outEvent = keyEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        case AINPUT_EVENT_TYPE_MOTION: {
-            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
-            if (batchIndex >= 0) {
-                Batch& batch = mBatches.editItemAt(batchIndex);
-                if (canAddSample(batch, &mMsg)) {
-                    batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ appended to batch event",
-                            mChannel->getName().string());
-#endif
-                    break;
-                } else {
-                    // We cannot append to the batch in progress, so we need to consume
-                    // the previous batch right now and defer the new message until later.
-                    mMsgDeferred = true;
-                    status_t result = consumeSamples(factory,
-                            batch, batch.samples.size(), outSeq, outEvent);
-                    mBatches.removeAt(batchIndex);
-                    if (result) {
-                        return result;
-                    }
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ consumed batch event and "
-                            "deferred current event, seq=%u",
-                            mChannel->getName().string(), *outSeq);
-#endif
-                    break;
-                }
-            }
-
-            // Start a new batch if needed.
-            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
-                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
-                mBatches.push();
-                Batch& batch = mBatches.editTop();
-                batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
-                ALOGD("channel '%s' consumer ~ started batch event",
-                        mChannel->getName().string());
-#endif
-                break;
-            }
-
-            MotionEvent* motionEvent = factory->createMotionEvent();
-            if (! motionEvent) return NO_MEMORY;
-
-            updateTouchState(&mMsg);
-            initializeMotionEvent(motionEvent, &mMsg);
-            *outSeq = mMsg.body.motion.seq;
-            *outEvent = motionEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        default:
-            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
-                    mChannel->getName().string(), mMsg.header.type);
-            return UNKNOWN_ERROR;
-        }
-    }
-    return OK;
-}
-
-status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
-        nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
-    status_t result;
-    for (size_t i = mBatches.size(); i-- > 0; ) {
-        Batch& batch = mBatches.editItemAt(i);
-        if (frameTime < 0) {
-            result = consumeSamples(factory, batch, batch.samples.size(),
-                    outSeq, outEvent);
-            mBatches.removeAt(i);
-            return result;
-        }
-
-        nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
-        ssize_t split = findSampleNoLaterThan(batch, sampleTime);
-        if (split < 0) {
-            continue;
-        }
-
-        result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
-        const InputMessage* next;
-        if (batch.samples.isEmpty()) {
-            mBatches.removeAt(i);
-            next = NULL;
-        } else {
-            next = &batch.samples.itemAt(0);
-        }
-        if (!result) {
-            resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
-        }
-        return result;
-    }
-
-    return WOULD_BLOCK;
-}
-
-status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
-        Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
-    MotionEvent* motionEvent = factory->createMotionEvent();
-    if (! motionEvent) return NO_MEMORY;
-
-    uint32_t chain = 0;
-    for (size_t i = 0; i < count; i++) {
-        InputMessage& msg = batch.samples.editItemAt(i);
-        updateTouchState(&msg);
-        if (i) {
-            SeqChain seqChain;
-            seqChain.seq = msg.body.motion.seq;
-            seqChain.chain = chain;
-            mSeqChains.push(seqChain);
-            addSample(motionEvent, &msg);
-        } else {
-            initializeMotionEvent(motionEvent, &msg);
-        }
-        chain = msg.body.motion.seq;
-    }
-    batch.samples.removeItemsAt(0, count);
-
-    *outSeq = chain;
-    *outEvent = motionEvent;
-    return OK;
-}
-
-void InputConsumer::updateTouchState(InputMessage* msg) {
-    if (!mResampleTouch ||
-            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
-        return;
-    }
-
-    int32_t deviceId = msg->body.motion.deviceId;
-    int32_t source = msg->body.motion.source;
-    nsecs_t eventTime = msg->body.motion.eventTime;
-
-    // Update the touch state history to incorporate the new input message.
-    // If the message is in the past relative to the most recently produced resampled
-    // touch, then use the resampled time and coordinates instead.
-    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
-    case AMOTION_EVENT_ACTION_DOWN: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index < 0) {
-            mTouchStates.push();
-            index = mTouchStates.size() - 1;
-        }
-        TouchState& touchState = mTouchStates.editItemAt(index);
-        touchState.initialize(deviceId, source);
-        touchState.addHistory(msg);
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_MOVE: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            touchState.addHistory(msg);
-            if (eventTime < touchState.lastResample.eventTime) {
-                rewriteMessage(touchState, msg);
-            } else {
-                touchState.lastResample.idBits.clear();
-            }
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
-            rewriteMessage(touchState, msg);
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_POINTER_UP: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            rewriteMessage(touchState, msg);
-            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_SCROLL: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            const TouchState& touchState = mTouchStates.itemAt(index);
-            rewriteMessage(touchState, msg);
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_UP:
-    case AMOTION_EVENT_ACTION_CANCEL: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            const TouchState& touchState = mTouchStates.itemAt(index);
-            rewriteMessage(touchState, msg);
-            mTouchStates.removeAt(index);
-        }
-        break;
-    }
-    }
-}
-
-void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
-    for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
-        uint32_t id = msg->body.motion.pointers[i].properties.id;
-        if (state.lastResample.idBits.hasBit(id)) {
-            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
-            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
-                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
-                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
-#endif
-            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
-            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
-        }
-    }
-}
-
-void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
-    const InputMessage* next) {
-    if (!mResampleTouch
-            || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
-            || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
-        return;
-    }
-
-    ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
-    if (index < 0) {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, no touch state for device.");
-#endif
-        return;
-    }
-
-    TouchState& touchState = mTouchStates.editItemAt(index);
-    if (touchState.historySize < 1) {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, no history for device.");
-#endif
-        return;
-    }
-
-    // Ensure that the current sample has all of the pointers that need to be reported.
-    const History* current = touchState.getHistory(0);
-    size_t pointerCount = event->getPointerCount();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t id = event->getPointerId(i);
-        if (!current->idBits.hasBit(id)) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, missing id %d", id);
-#endif
-            return;
-        }
-    }
-
-    // Find the data to use for resampling.
-    const History* other;
-    History future;
-    float alpha;
-    if (next) {
-        // Interpolate between current sample and future sample.
-        // So current->eventTime <= sampleTime <= future.eventTime.
-        future.initializeFrom(next);
-        other = &future;
-        nsecs_t delta = future.eventTime - current->eventTime;
-        if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
-            return;
-        }
-        alpha = float(sampleTime - current->eventTime) / delta;
-    } else if (touchState.historySize >= 2) {
-        // Extrapolate future sample using current sample and past sample.
-        // So other->eventTime <= current->eventTime <= sampleTime.
-        other = touchState.getHistory(1);
-        nsecs_t delta = current->eventTime - other->eventTime;
-        if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
-            return;
-        }
-        nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
-        if (sampleTime > maxPredict) {
-#if DEBUG_RESAMPLING
-            ALOGD("Sample time is too far in the future, adjusting prediction "
-                    "from %lld to %lld ns.",
-                    sampleTime - current->eventTime, maxPredict - current->eventTime);
-#endif
-            sampleTime = maxPredict;
-        }
-        alpha = float(current->eventTime - sampleTime) / delta;
-    } else {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, insufficient data.");
-#endif
-        return;
-    }
-
-    // Resample touch coordinates.
-    touchState.lastResample.eventTime = sampleTime;
-    touchState.lastResample.idBits.clear();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t id = event->getPointerId(i);
-        touchState.lastResample.idToIndex[id] = i;
-        touchState.lastResample.idBits.markBit(id);
-        PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
-        const PointerCoords& currentCoords = current->getPointerById(id);
-        if (other->idBits.hasBit(id)
-                && shouldResampleTool(event->getToolType(i))) {
-            const PointerCoords& otherCoords = other->getPointerById(id);
-            resampledCoords.copyFrom(currentCoords);
-            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
-                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
-            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
-                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
-                    "other (%0.3f, %0.3f), alpha %0.3f",
-                    id, resampledCoords.getX(), resampledCoords.getY(),
-                    currentCoords.getX(), currentCoords.getY(),
-                    otherCoords.getX(), otherCoords.getY(),
-                    alpha);
-#endif
-        } else {
-            resampledCoords.copyFrom(currentCoords);
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
-                    id, resampledCoords.getX(), resampledCoords.getY(),
-                    currentCoords.getX(), currentCoords.getY());
-#endif
-        }
-    }
-
-    event->addSample(sampleTime, touchState.lastResample.pointers);
-}
-
-bool InputConsumer::shouldResampleTool(int32_t toolType) {
-    return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
-            || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
-            mChannel->getName().string(), seq, handled ? "true" : "false");
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to send a finished signal with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    // Send finished signals for the batch sequence chain first.
-    size_t seqChainCount = mSeqChains.size();
-    if (seqChainCount) {
-        uint32_t currentSeq = seq;
-        uint32_t chainSeqs[seqChainCount];
-        size_t chainIndex = 0;
-        for (size_t i = seqChainCount; i-- > 0; ) {
-             const SeqChain& seqChain = mSeqChains.itemAt(i);
-             if (seqChain.seq == currentSeq) {
-                 currentSeq = seqChain.chain;
-                 chainSeqs[chainIndex++] = currentSeq;
-                 mSeqChains.removeAt(i);
-             }
-        }
-        status_t status = OK;
-        while (!status && chainIndex-- > 0) {
-            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
-        }
-        if (status) {
-            // An error occurred so at least one signal was not sent, reconstruct the chain.
-            do {
-                SeqChain seqChain;
-                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
-                seqChain.chain = chainSeqs[chainIndex];
-                mSeqChains.push(seqChain);
-            } while (chainIndex-- > 0);
-            return status;
-        }
-    }
-
-    // Send finished signal for the last message in the batch.
-    return sendUnchainedFinishedSignal(seq, handled);
-}
-
-status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_FINISHED;
-    msg.body.finished.seq = seq;
-    msg.body.finished.handled = handled;
-    return mChannel->sendMessage(&msg);
-}
-
-bool InputConsumer::hasDeferredEvent() const {
-    return mMsgDeferred;
-}
-
-bool InputConsumer::hasPendingBatch() const {
-    return !mBatches.isEmpty();
-}
-
-ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
-    for (size_t i = 0; i < mBatches.size(); i++) {
-        const Batch& batch = mBatches.itemAt(i);
-        const InputMessage& head = batch.samples.itemAt(0);
-        if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
-    for (size_t i = 0; i < mTouchStates.size(); i++) {
-        const TouchState& touchState = mTouchStates.itemAt(i);
-        if (touchState.deviceId == deviceId && touchState.source == source) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
-    event->initialize(
-            msg->body.key.deviceId,
-            msg->body.key.source,
-            msg->body.key.action,
-            msg->body.key.flags,
-            msg->body.key.keyCode,
-            msg->body.key.scanCode,
-            msg->body.key.metaState,
-            msg->body.key.repeatCount,
-            msg->body.key.downTime,
-            msg->body.key.eventTime);
-}
-
-void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->initialize(
-            msg->body.motion.deviceId,
-            msg->body.motion.source,
-            msg->body.motion.action,
-            msg->body.motion.flags,
-            msg->body.motion.edgeFlags,
-            msg->body.motion.metaState,
-            msg->body.motion.buttonState,
-            msg->body.motion.xOffset,
-            msg->body.motion.yOffset,
-            msg->body.motion.xPrecision,
-            msg->body.motion.yPrecision,
-            msg->body.motion.downTime,
-            msg->body.motion.eventTime,
-            pointerCount,
-            pointerProperties,
-            pointerCoords);
-}
-
-void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
-    event->addSample(msg->body.motion.eventTime, pointerCoords);
-}
-
-bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
-    const InputMessage& head = batch.samples.itemAt(0);
-    size_t pointerCount = msg->body.motion.pointerCount;
-    if (head.body.motion.pointerCount != pointerCount
-            || head.body.motion.action != msg->body.motion.action) {
-        return false;
-    }
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (head.body.motion.pointers[i].properties
-                != msg->body.motion.pointers[i].properties) {
-            return false;
-        }
-    }
-    return true;
-}
-
-ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
-    size_t numSamples = batch.samples.size();
-    size_t index = 0;
-    while (index < numSamples
-            && batch.samples.itemAt(index).body.motion.eventTime <= time) {
-        index += 1;
-    }
-    return ssize_t(index) - 1;
-}
-
-} // namespace android
diff --git a/libs/androidfw/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp
deleted file mode 100644
index 36cb6e1..0000000
--- a/libs/androidfw/KeyCharacterMap.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#define LOG_TAG "KeyCharacterMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyCharacterMap.h>
-
-#if HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-#endif
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
-
-struct Modifier {
-    const char* label;
-    int32_t metaState;
-};
-static const Modifier modifiers[] = {
-        { "shift", AMETA_SHIFT_ON },
-        { "lshift", AMETA_SHIFT_LEFT_ON },
-        { "rshift", AMETA_SHIFT_RIGHT_ON },
-        { "alt", AMETA_ALT_ON },
-        { "lalt", AMETA_ALT_LEFT_ON },
-        { "ralt", AMETA_ALT_RIGHT_ON },
-        { "ctrl", AMETA_CTRL_ON },
-        { "lctrl", AMETA_CTRL_LEFT_ON },
-        { "rctrl", AMETA_CTRL_RIGHT_ON },
-        { "meta", AMETA_META_ON },
-        { "lmeta", AMETA_META_LEFT_ON },
-        { "rmeta", AMETA_META_RIGHT_ON },
-        { "sym", AMETA_SYM_ON },
-        { "fn", AMETA_FUNCTION_ON },
-        { "capslock", AMETA_CAPS_LOCK_ON },
-        { "numlock", AMETA_NUM_LOCK_ON },
-        { "scrolllock", AMETA_SCROLL_LOCK_ON },
-};
-
-#if DEBUG_MAPPING
-static String8 toString(const char16_t* chars, size_t numChars) {
-    String8 result;
-    for (size_t i = 0; i < numChars; i++) {
-        result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
-    }
-    return result;
-}
-#endif
-
-
-// --- KeyCharacterMap ---
-
-sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap();
-
-KeyCharacterMap::KeyCharacterMap() :
-    mType(KEYBOARD_TYPE_UNKNOWN) {
-}
-
-KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
-    RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
-    mKeysByUsageCode(other.mKeysByUsageCode) {
-    for (size_t i = 0; i < other.mKeys.size(); i++) {
-        mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
-    }
-}
-
-KeyCharacterMap::~KeyCharacterMap() {
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        Key* key = mKeys.editValueAt(i);
-        delete key;
-    }
-}
-
-status_t KeyCharacterMap::load(const String8& filename,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key character map file %s.", status, filename.string());
-    } else {
-        status = load(tokenizer, format, outMap);
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key character map.", status);
-    } else {
-        status = load(tokenizer, format, outMap);
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyCharacterMap::load(Tokenizer* tokenizer,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    status_t status = OK;
-    sp<KeyCharacterMap> map = new KeyCharacterMap();
-    if (!map.get()) {
-        ALOGE("Error allocating key character map.");
-        status = NO_MEMORY;
-    } else {
-#if DEBUG_PARSER_PERFORMANCE
-        nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-        Parser parser(map.get(), tokenizer, format);
-        status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-        nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-        ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                elapsedTime / 1000000.0);
-#endif
-        if (!status) {
-            *outMap = map;
-        }
-    }
-    return status;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
-        const sp<KeyCharacterMap>& overlay) {
-    if (overlay == NULL) {
-        return base;
-    }
-    if (base == NULL) {
-        return overlay;
-    }
-
-    sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
-    for (size_t i = 0; i < overlay->mKeys.size(); i++) {
-        int32_t keyCode = overlay->mKeys.keyAt(i);
-        Key* key = overlay->mKeys.valueAt(i);
-        ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
-        if (oldIndex >= 0) {
-            delete map->mKeys.valueAt(oldIndex);
-            map->mKeys.editValueAt(oldIndex) = new Key(*key);
-        } else {
-            map->mKeys.add(keyCode, new Key(*key));
-        }
-    }
-
-    for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
-        map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
-                overlay->mKeysByScanCode.valueAt(i));
-    }
-
-    for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
-        map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
-                overlay->mKeysByUsageCode.valueAt(i));
-    }
-    return map;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::empty() {
-    return sEmpty;
-}
-
-int32_t KeyCharacterMap::getKeyboardType() const {
-    return mType;
-}
-
-char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->label;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->number;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        result = behavior->character;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
-        FallbackAction* outFallbackAction) const {
-    outFallbackAction->keyCode = 0;
-    outFallbackAction->metaState = 0;
-
-    bool result = false;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        if (behavior->fallbackKeyCode) {
-            outFallbackAction->keyCode = behavior->fallbackKeyCode;
-            outFallbackAction->metaState = metaState & ~behavior->metaState;
-            result = true;
-        }
-    }
-#if DEBUG_MAPPING
-    ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
-            "fallback keyCode=%d, fallback metaState=0x%08x.",
-            keyCode, metaState, result ? "true" : "false",
-            outFallbackAction->keyCode, outFallbackAction->metaState);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
-        int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        // 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 (size_t i = 0; i < numChars; i++) {
-                    if (behavior->character == chars[i]) {
-                        result = behavior->character;
-                        if ((behavior->metaState & metaState) == behavior->metaState) {
-                            goto ExactMatch;
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-    ExactMatch: ;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
-            keyCode, toString(chars, numChars).string(), metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
-        Vector<KeyEvent>& outEvents) const {
-    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
-    for (size_t i = 0; i < numChars; i++) {
-        int32_t keyCode, metaState;
-        char16_t ch = chars[i];
-        if (!findKey(ch, &keyCode, &metaState)) {
-#if DEBUG_MAPPING
-            ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
-                    deviceId, toString(chars, numChars).string(), ch);
-#endif
-            return false;
-        }
-
-        int32_t currentMetaState = 0;
-        addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
-        addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
-    }
-#if DEBUG_MAPPING
-    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
-            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
-    for (size_t i = 0; i < outEvents.size(); i++) {
-        ALOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
-                outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
-                outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
-    }
-#endif
-    return true;
-}
-
-status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
-    if (usageCode) {
-        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
-        if (index >= 0) {
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
-            scanCode, usageCode, *outKeyCode);
-#endif
-            *outKeyCode = mKeysByUsageCode.valueAt(index);
-            return OK;
-        }
-    }
-    if (scanCode) {
-        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
-        if (index >= 0) {
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
-            scanCode, usageCode, *outKeyCode);
-#endif
-            *outKeyCode = mKeysByScanCode.valueAt(index);
-            return OK;
-        }
-    }
-
-#if DEBUG_MAPPING
-        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
-    *outKeyCode = AKEYCODE_UNKNOWN;
-    return NAME_NOT_FOUND;
-}
-
-bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
-    ssize_t index = mKeys.indexOfKey(keyCode);
-    if (index >= 0) {
-        *outKey = mKeys.valueAt(index);
-        return true;
-    }
-    return false;
-}
-
-bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
-        const Key** outKey, const Behavior** outBehavior) const {
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        const Behavior* behavior = key->firstBehavior;
-        while (behavior) {
-            if (matchesMetaState(metaState, behavior->metaState)) {
-                *outKey = key;
-                *outBehavior = behavior;
-                return true;
-            }
-            behavior = behavior->next;
-        }
-    }
-    return false;
-}
-
-bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
-    // Behavior must have at least the set of meta states specified.
-    // And if the key event has CTRL, ALT or META then the behavior must exactly
-    // match those, taking into account that a behavior can specify that it handles
-    // one, both or either of a left/right modifier pair.
-    if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
-        const int32_t EXACT_META_STATES =
-                AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
-                | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
-                | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
-        int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
-        if (behaviorMetaState & AMETA_CTRL_ON) {
-            unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_CTRL_ON;
-        }
-        if (behaviorMetaState & AMETA_ALT_ON) {
-            unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_ALT_ON;
-        }
-        if (behaviorMetaState & AMETA_META_ON) {
-            unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_META_ON;
-        }
-        return !unmatchedMetaState;
-    }
-    return false;
-}
-
-bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
-    if (!ch) {
-        return false;
-    }
-
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        const Key* key = mKeys.valueAt(i);
-
-        // 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 = NULL;
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character == ch) {
-                found = behavior;
-            }
-        }
-        if (found) {
-            *outKeyCode = mKeys.keyAt(i);
-            *outMetaState = found->metaState;
-            return true;
-        }
-    }
-    return false;
-}
-
-void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
-    outEvents.push();
-    KeyEvent& event = outEvents.editTop();
-    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            0, keyCode, 0, metaState, 0, time, time);
-}
-
-void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t* currentMetaState) {
-    // Add and remove meta keys symmetrically.
-    if (down) {
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-    } else {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-    }
-}
-
-bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
-        return true;
-    }
-    return false;
-}
-
-void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t leftKeyCode, int32_t leftKeyMetaState,
-        int32_t rightKeyCode, int32_t rightKeyMetaState,
-        int32_t eitherKeyMetaState,
-        int32_t* currentMetaState) {
-    bool specific = false;
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            leftKeyCode, leftKeyMetaState, currentMetaState);
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            rightKeyCode, rightKeyMetaState, currentMetaState);
-
-    if (!specific) {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-                leftKeyCode, eitherKeyMetaState, currentMetaState);
-    }
-}
-
-void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
-        *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
-    }
-}
-
-#if HAVE_ANDROID_OS
-sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
-    sp<KeyCharacterMap> map = new KeyCharacterMap();
-    map->mType = parcel->readInt32();
-    size_t numKeys = parcel->readInt32();
-    if (parcel->errorCheck()) {
-        return NULL;
-    }
-
-    for (size_t i = 0; i < numKeys; i++) {
-        int32_t keyCode = parcel->readInt32();
-        char16_t label = parcel->readInt32();
-        char16_t number = parcel->readInt32();
-        if (parcel->errorCheck()) {
-            return NULL;
-        }
-
-        Key* key = new Key();
-        key->label = label;
-        key->number = number;
-        map->mKeys.add(keyCode, key);
-
-        Behavior* lastBehavior = NULL;
-        while (parcel->readInt32()) {
-            int32_t metaState = parcel->readInt32();
-            char16_t character = parcel->readInt32();
-            int32_t fallbackKeyCode = parcel->readInt32();
-            if (parcel->errorCheck()) {
-                return NULL;
-            }
-
-            Behavior* behavior = new Behavior();
-            behavior->metaState = metaState;
-            behavior->character = character;
-            behavior->fallbackKeyCode = fallbackKeyCode;
-            if (lastBehavior) {
-                lastBehavior->next = behavior;
-            } else {
-                key->firstBehavior = behavior;
-            }
-            lastBehavior = behavior;
-        }
-
-        if (parcel->errorCheck()) {
-            return NULL;
-        }
-    }
-    return map;
-}
-
-void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
-    parcel->writeInt32(mType);
-
-    size_t numKeys = mKeys.size();
-    parcel->writeInt32(numKeys);
-    for (size_t i = 0; i < numKeys; i++) {
-        int32_t keyCode = mKeys.keyAt(i);
-        const Key* key = mKeys.valueAt(i);
-        parcel->writeInt32(keyCode);
-        parcel->writeInt32(key->label);
-        parcel->writeInt32(key->number);
-        for (const Behavior* behavior = key->firstBehavior; behavior != NULL;
-                behavior = behavior->next) {
-            parcel->writeInt32(1);
-            parcel->writeInt32(behavior->metaState);
-            parcel->writeInt32(behavior->character);
-            parcel->writeInt32(behavior->fallbackKeyCode);
-        }
-        parcel->writeInt32(0);
-    }
-}
-#endif
-
-
-// --- KeyCharacterMap::Key ---
-
-KeyCharacterMap::Key::Key() :
-        label(0), number(0), firstBehavior(NULL) {
-}
-
-KeyCharacterMap::Key::Key(const Key& other) :
-        label(other.label), number(other.number),
-        firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
-}
-
-KeyCharacterMap::Key::~Key() {
-    Behavior* behavior = firstBehavior;
-    while (behavior) {
-        Behavior* next = behavior->next;
-        delete behavior;
-        behavior = next;
-    }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
-        next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
-}
-
-KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
-        next(other.next ? new Behavior(*other.next) : NULL),
-        metaState(other.metaState), character(other.character),
-        fallbackKeyCode(other.fallbackKeyCode) {
-}
-
-
-// --- KeyCharacterMap::Parser ---
-
-KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
-        mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
-}
-
-KeyCharacterMap::Parser::~Parser() {
-}
-
-status_t KeyCharacterMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            switch (mState) {
-            case STATE_TOP: {
-                String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-                if (keywordToken == "type") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseType();
-                    if (status) return status;
-                } else if (keywordToken == "map") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseMap();
-                    if (status) return status;
-                } else if (keywordToken == "key") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseKey();
-                    if (status) return status;
-                } else {
-                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                            keywordToken.string());
-                    return BAD_VALUE;
-                }
-                break;
-            }
-
-            case STATE_KEY: {
-                status_t status = parseKeyProperty();
-                if (status) return status;
-                break;
-            }
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    if (mState != STATE_TOP) {
-        ALOGE("%s: Unterminated key description at end of file.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    if (mFormat == FORMAT_BASE) {
-        if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
-            ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
-                    mTokenizer->getLocation().string());
-            return BAD_VALUE;
-        }
-    } else if (mFormat == FORMAT_OVERLAY) {
-        if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
-            ALOGE("%s: Overlay keyboard layout missing required keyboard "
-                    "'type OVERLAY' declaration.",
-                    mTokenizer->getLocation().string());
-            return BAD_VALUE;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseType() {
-    if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Duplicate keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    KeyboardType type;
-    String8 typeToken = mTokenizer->nextToken(WHITESPACE);
-    if (typeToken == "NUMERIC") {
-        type = KEYBOARD_TYPE_NUMERIC;
-    } else if (typeToken == "PREDICTIVE") {
-        type = KEYBOARD_TYPE_PREDICTIVE;
-    } else if (typeToken == "ALPHA") {
-        type = KEYBOARD_TYPE_ALPHA;
-    } else if (typeToken == "FULL") {
-        type = KEYBOARD_TYPE_FULL;
-    } else if (typeToken == "SPECIAL_FUNCTION") {
-        type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
-    } else if (typeToken == "OVERLAY") {
-        type = KEYBOARD_TYPE_OVERLAY;
-    } else {
-        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
-                typeToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed type: type=%d.", type);
-#endif
-    mMap->mType = type;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseMap() {
-    String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-    if (keywordToken == "key") {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        return parseMapKey();
-    }
-    ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
-            keywordToken.string());
-    return BAD_VALUE;
-}
-
-status_t KeyCharacterMap::Parser::parseMapKey() {
-    String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    bool mapUsage = false;
-    if (codeToken == "usage") {
-        mapUsage = true;
-        mTokenizer->skipDelimiters(WHITESPACE);
-        codeToken = mTokenizer->nextToken(WHITESPACE);
-    }
-
-    char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-    KeyedVector<int32_t, int32_t>& map =
-            mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
-    if (map.indexOfKey(code) >= 0) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
-            mapUsage ? "usage" : "scan code", code, keyCode);
-#endif
-    map.add(code, keyCode);
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKey() {
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
-        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
-    if (openBraceToken != "{") {
-        ALOGE("%s: Expected '{' after key code label, got '%s'.",
-                mTokenizer->getLocation().string(), openBraceToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
-#endif
-    mKeyCode = keyCode;
-    mMap->mKeys.add(keyCode, new Key());
-    mState = STATE_KEY;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKeyProperty() {
-    Key* key = mMap->mKeys.valueFor(mKeyCode);
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-    if (token == "}") {
-        mState = STATE_TOP;
-        return finishKey(key);
-    }
-
-    Vector<Property> properties;
-
-    // Parse all comma-delimited property names up to the first colon.
-    for (;;) {
-        if (token == "label") {
-            properties.add(Property(PROPERTY_LABEL));
-        } else if (token == "number") {
-            properties.add(Property(PROPERTY_NUMBER));
-        } else {
-            int32_t metaState;
-            status_t status = parseModifier(token, &metaState);
-            if (status) {
-                ALOGE("%s: Expected a property name or modifier, got '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return status;
-            }
-            properties.add(Property(PROPERTY_META, metaState));
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (!mTokenizer->isEol()) {
-            char ch = mTokenizer->nextChar();
-            if (ch == ':') {
-                break;
-            } else if (ch == ',') {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-                continue;
-            }
-        }
-
-        ALOGE("%s: Expected ',' or ':' after property name.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    // Parse behavior after the colon.
-    mTokenizer->skipDelimiters(WHITESPACE);
-
-    Behavior behavior;
-    bool haveCharacter = false;
-    bool haveFallback = false;
-
-    do {
-        char ch = mTokenizer->peekChar();
-        if (ch == '\'') {
-            char16_t character;
-            status_t status = parseCharacterLiteral(&character);
-            if (status || !character) {
-                ALOGE("%s: Invalid character literal for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            if (haveCharacter) {
-                ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            behavior.character = character;
-            haveCharacter = true;
-        } else {
-            token = mTokenizer->nextToken(WHITESPACE);
-            if (token == "none") {
-                if (haveCharacter) {
-                    ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                haveCharacter = true;
-            } else if (token == "fallback") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE);
-                int32_t keyCode = getKeyCodeByLabel(token.string());
-                if (!keyCode) {
-                    ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
-                            mTokenizer->getLocation().string(),
-                            token.string());
-                    return BAD_VALUE;
-                }
-                if (haveFallback) {
-                    ALOGE("%s: Cannot combine multiple fallback key codes.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                behavior.fallbackKeyCode = keyCode;
-                haveFallback = true;
-            } else {
-                ALOGE("%s: Expected a key behavior after ':'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-    } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
-
-    // Add the behavior.
-    for (size_t i = 0; i < properties.size(); i++) {
-        const Property& property = properties.itemAt(i);
-        switch (property.property) {
-        case PROPERTY_LABEL:
-            if (key->label) {
-                ALOGE("%s: Duplicate label for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->label = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
-#endif
-            break;
-        case PROPERTY_NUMBER:
-            if (key->number) {
-                ALOGE("%s: Duplicate number for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->number = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
-#endif
-            break;
-        case PROPERTY_META: {
-            for (Behavior* b = key->firstBehavior; b; b = b->next) {
-                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.", mKeyCode,
-                    newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
-#endif
-            break;
-        }
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::finishKey(Key* key) {
-    // Fill in default number property.
-    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;
-            if (ch) {
-                if (ch >= '0' && ch <= '9') {
-                    digit = ch;
-                } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
-                        || ch == '-' || ch == '+' || ch == ',' || ch == '.'
-                        || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
-                    symbol = ch;
-                }
-            }
-        }
-        key->number = digit ? digit : symbol;
-    }
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
-    if (token == "base") {
-        *outMetaState = 0;
-        return NO_ERROR;
-    }
-
-    int32_t combinedMeta = 0;
-
-    const char* str = token.string();
-    const char* start = str;
-    for (const char* cur = str; ; cur++) {
-        char ch = *cur;
-        if (ch == '+' || ch == '\0') {
-            size_t len = cur - start;
-            int32_t metaState = 0;
-            for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
-                if (strlen(modifiers[i].label) == len
-                        && strncmp(modifiers[i].label, start, len) == 0) {
-                    metaState = modifiers[i].metaState;
-                    break;
-                }
-            }
-            if (!metaState) {
-                return BAD_VALUE;
-            }
-            if (combinedMeta & metaState) {
-                ALOGE("%s: Duplicate modifier combination '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return BAD_VALUE;
-            }
-
-            combinedMeta |= metaState;
-            start = cur + 1;
-
-            if (ch == '\0') {
-                break;
-            }
-        }
-    }
-    *outMetaState = combinedMeta;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
-    char ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch == '\\') {
-        // Escape sequence.
-        ch = mTokenizer->nextChar();
-        if (ch == 'n') {
-            *outCharacter = '\n';
-        } else if (ch == 't') {
-            *outCharacter = '\t';
-        } else if (ch == '\\') {
-            *outCharacter = '\\';
-        } else if (ch == '\'') {
-            *outCharacter = '\'';
-        } else if (ch == '"') {
-            *outCharacter = '"';
-        } else if (ch == 'u') {
-            *outCharacter = 0;
-            for (int i = 0; i < 4; i++) {
-                ch = mTokenizer->nextChar();
-                int digit;
-                if (ch >= '0' && ch <= '9') {
-                    digit = ch - '0';
-                } else if (ch >= 'A' && ch <= 'F') {
-                    digit = ch - 'A' + 10;
-                } else if (ch >= 'a' && ch <= 'f') {
-                    digit = ch - 'a' + 10;
-                } else {
-                    goto Error;
-                }
-                *outCharacter = (*outCharacter << 4) | digit;
-            }
-        } else {
-            goto Error;
-        }
-    } else if (ch >= 32 && ch <= 126 && ch != '\'') {
-        // ASCII literal character.
-        *outCharacter = ch;
-    } else {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    // Ensure that we consumed the entire token.
-    if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
-        return NO_ERROR;
-    }
-
-Error:
-    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
-    return BAD_VALUE;
-}
-
-} // namespace android
diff --git a/libs/androidfw/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp
deleted file mode 100644
index ae14f23..0000000
--- a/libs/androidfw/KeyLayoutMap.cpp
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#define LOG_TAG "KeyLayoutMap"
-
-#include <stdlib.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-
-// --- KeyLayoutMap ---
-
-KeyLayoutMap::KeyLayoutMap() {
-}
-
-KeyLayoutMap::~KeyLayoutMap() {
-}
-
-status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key layout map file %s.", status, filename.string());
-    } else {
-        sp<KeyLayoutMap> map = new KeyLayoutMap();
-        if (!map.get()) {
-            ALOGE("Error allocating key layout map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map.get(), tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (!status) {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode,
-        int32_t* outKeyCode, uint32_t* outFlags) const {
-    const Key* key = getKey(scanCode, usageCode);
-    if (!key) {
-#if DEBUG_MAPPING
-        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
-        *outKeyCode = AKEYCODE_UNKNOWN;
-        *outFlags = 0;
-        return NAME_NOT_FOUND;
-    }
-
-    *outKeyCode = key->keyCode;
-    *outFlags = key->flags;
-
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d, outFlags=0x%08x.",
-            scanCode, usageCode, *outKeyCode, *outFlags);
-#endif
-    return NO_ERROR;
-}
-
-const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
-    if (usageCode) {
-        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
-        if (index >= 0) {
-            return &mKeysByUsageCode.valueAt(index);
-        }
-    }
-    if (scanCode) {
-        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
-        if (index >= 0) {
-            return &mKeysByScanCode.valueAt(index);
-        }
-    }
-    return NULL;
-}
-
-status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
-    const size_t N = mKeysByScanCode.size();
-    for (size_t i=0; i<N; i++) {
-        if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
-            outScanCodes->add(mKeysByScanCode.keyAt(i));
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
-    ssize_t index = mAxes.indexOfKey(scanCode);
-    if (index < 0) {
-#if DEBUG_MAPPING
-        ALOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
-#endif
-        return NAME_NOT_FOUND;
-    }
-
-    *outAxisInfo = mAxes.valueAt(index);
-
-#if DEBUG_MAPPING
-    ALOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
-            outAxisInfo->splitValue, outAxisInfo->flatOverride);
-#endif
-    return NO_ERROR;
-}
-
-
-// --- KeyLayoutMap::Parser ---
-
-KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-KeyLayoutMap::Parser::~Parser() {
-}
-
-status_t KeyLayoutMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-            if (keywordToken == "key") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseKey();
-                if (status) return status;
-            } else if (keywordToken == "axis") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseAxis();
-                if (status) return status;
-            } else {
-                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                        keywordToken.string());
-                return BAD_VALUE;
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseKey() {
-    String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    bool mapUsage = false;
-    if (codeToken == "usage") {
-        mapUsage = true;
-        mTokenizer->skipDelimiters(WHITESPACE);
-        codeToken = mTokenizer->nextToken(WHITESPACE);
-    }
-
-    char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-    KeyedVector<int32_t, Key>& map =
-            mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
-    if (map.indexOfKey(code) >= 0) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    uint32_t flags = 0;
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
-
-        String8 flagToken = mTokenizer->nextToken(WHITESPACE);
-        uint32_t flag = getKeyFlagByLabel(flagToken.string());
-        if (!flag) {
-            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        if (flags & flag) {
-            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        flags |= flag;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
-            mapUsage ? "usage" : "scan code", code, keyCode, flags);
-#endif
-    Key key;
-    key.keyCode = keyCode;
-    key.flags = flags;
-    map.add(code, key);
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseAxis() {
-    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
-    char* end;
-    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
-        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    AxisInfo axisInfo;
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 token = mTokenizer->nextToken(WHITESPACE);
-    if (token == "invert") {
-        axisInfo.mode = AxisInfo::MODE_INVERT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 axisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(axisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected inverted axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), axisToken.string());
-            return BAD_VALUE;
-        }
-    } else if (token == "split") {
-        axisInfo.mode = AxisInfo::MODE_SPLIT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 splitToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
-        if (*end) {
-            ALOGE("%s: Expected split value, got '%s'.",
-                    mTokenizer->getLocation().string(), splitToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(lowAxisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected low axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), lowAxisToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
-        if (axisInfo.highAxis < 0) {
-            ALOGE("%s: Expected high axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), highAxisToken.string());
-            return BAD_VALUE;
-        }
-    } else {
-        axisInfo.axis = getAxisByLabel(token.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
-                    mTokenizer->getLocation().string(), token.string());
-            return BAD_VALUE;
-        }
-    }
-
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') {
-            break;
-        }
-        String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-        if (keywordToken == "flat") {
-            mTokenizer->skipDelimiters(WHITESPACE);
-            String8 flatToken = mTokenizer->nextToken(WHITESPACE);
-            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
-            if (*end) {
-                ALOGE("%s: Expected flat value, got '%s'.",
-                        mTokenizer->getLocation().string(), flatToken.string());
-                return BAD_VALUE;
-            }
-        } else {
-            ALOGE("%s: Expected keyword 'flat', got '%s'.",
-                    mTokenizer->getLocation().string(), keywordToken.string());
-            return BAD_VALUE;
-        }
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
-            axisInfo.splitValue, axisInfo.flatOverride);
-#endif
-    mMap->mAxes.add(scanCode, axisInfo);
-    return NO_ERROR;
-}
-
-};
diff --git a/libs/androidfw/Keyboard.cpp b/libs/androidfw/Keyboard.cpp
deleted file mode 100644
index 26a4e6a..0000000
--- a/libs/androidfw/Keyboard.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "Keyboard"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeycodeLabels.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/InputDevice.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-namespace android {
-
-// --- KeyMap ---
-
-KeyMap::KeyMap() {
-}
-
-KeyMap::~KeyMap() {
-}
-
-status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
-        const PropertyMap* deviceConfiguration) {
-    // Use the configured key layout if available.
-    if (deviceConfiguration) {
-        String8 keyLayoutName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
-                keyLayoutName)) {
-            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
-                        "it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        String8 keyCharacterMapName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
-                keyCharacterMapName)) {
-            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard character "
-                        "map '%s' but it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        if (isComplete()) {
-            return OK;
-        }
-    }
-
-    // Try searching by device identifier.
-    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
-        return OK;
-    }
-
-    // Fall back on the Generic key map.
-    // TODO Apply some additional heuristics here to figure out what kind of
-    //      generic key map to use (US English, etc.) for typical external keyboards.
-    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
-        return OK;
-    }
-
-    // Try the Virtual key map as a last resort.
-    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
-        return OK;
-    }
-
-    // Give up!
-    ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
-            deviceIdenfifier.name.string());
-    return NAME_NOT_FOUND;
-}
-
-bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& keyMapName) {
-    if (!haveKeyLayout()) {
-        loadKeyLayout(deviceIdentifier, keyMapName);
-    }
-    if (!haveKeyCharacterMap()) {
-        loadKeyCharacterMap(deviceIdentifier, keyMapName);
-    }
-    return isComplete();
-}
-
-status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    status_t status = KeyLayoutMap::load(path, &keyLayoutMap);
-    if (status) {
-        return status;
-    }
-
-    keyLayoutFile.setTo(path);
-    return OK;
-}
-
-status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    status_t status = KeyCharacterMap::load(path,
-            KeyCharacterMap::FORMAT_BASE, &keyCharacterMap);
-    if (status) {
-        return status;
-    }
-
-    keyCharacterMapFile.setTo(path);
-    return OK;
-}
-
-String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    return name.isEmpty()
-            ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
-            : getInputDeviceConfigurationFilePathByName(name, type);
-}
-
-
-// --- Global functions ---
-
-bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
-        const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
-    if (!keyMap->haveKeyCharacterMap()
-            || keyMap->keyCharacterMap->getKeyboardType()
-                    == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
-        return false;
-    }
-
-    if (deviceConfiguration) {
-        bool builtIn = false;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
-                && builtIn) {
-            return true;
-        }
-    }
-
-    return strstr(deviceIdentifier.name.string(), "-keypad");
-}
-
-static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (strcmp(literal, list->literal) == 0) {
-            return list->value;
-        }
-        list++;
-    }
-    return list->value;
-}
-
-static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (list->value == value) {
-            return list->literal;
-        }
-        list++;
-    }
-    return NULL;
-}
-
-int32_t getKeyCodeByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, KEYCODES));
-}
-
-uint32_t getKeyFlagByLabel(const char* label) {
-    return uint32_t(lookupValueByLabel(label, FLAGS));
-}
-
-int32_t getAxisByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, AXES));
-}
-
-const char* getAxisLabel(int32_t axisId) {
-    return lookupLabelByValue(axisId, AXES);
-}
-
-static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    int32_t newMetaState;
-    if (down) {
-        newMetaState = oldMetaState | mask;
-    } else {
-        newMetaState = oldMetaState &
-                ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
-    }
-
-    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-        newMetaState |= AMETA_ALT_ON;
-    }
-
-    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
-        newMetaState |= AMETA_SHIFT_ON;
-    }
-
-    if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
-        newMetaState |= AMETA_CTRL_ON;
-    }
-
-    if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
-        newMetaState |= AMETA_META_ON;
-    }
-    return newMetaState;
-}
-
-static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    if (down) {
-        return oldMetaState;
-    } else {
-        return oldMetaState ^ mask;
-    }
-}
-
-int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
-    int32_t mask;
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-        return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_ALT_RIGHT:
-        return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_LEFT:
-        return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_RIGHT:
-        return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SYM:
-        return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
-    case AKEYCODE_FUNCTION:
-        return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_LEFT:
-        return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_RIGHT:
-        return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_META_LEFT:
-        return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_META_RIGHT:
-        return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_CAPS_LOCK:
-        return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_NUM_LOCK:
-        return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_SCROLL_LOCK:
-        return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
-    default:
-        return oldMetaState;
-    }
-}
-
-bool isMetaKey(int32_t keyCode) {
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-    case AKEYCODE_ALT_RIGHT:
-    case AKEYCODE_SHIFT_LEFT:
-    case AKEYCODE_SHIFT_RIGHT:
-    case AKEYCODE_SYM:
-    case AKEYCODE_FUNCTION:
-    case AKEYCODE_CTRL_LEFT:
-    case AKEYCODE_CTRL_RIGHT:
-    case AKEYCODE_META_LEFT:
-    case AKEYCODE_META_RIGHT:
-    case AKEYCODE_CAPS_LOCK:
-    case AKEYCODE_NUM_LOCK:
-    case AKEYCODE_SCROLL_LOCK:
-        return true;
-    default:
-        return false;
-    }
-}
-
-
-} // namespace android
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index e31246f..1128e02 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -5323,13 +5323,12 @@
 }
 
 
-#ifdef STATIC_ANDROIDFW_FOR_TOOLS
 #define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
 
 #define CHAR16_ARRAY_EQ(constant, var, len) \
         ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
 
-void print_complex(uint32_t complex, bool isFraction)
+static void print_complex(uint32_t complex, bool isFraction)
 {
     const float MANTISSA_MULT =
         1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
@@ -5620,6 +5619,4 @@
     }
 }
 
-#endif // STATIC_ANDROIDFW_FOR_TOOLS
-
 }   // namespace android
diff --git a/libs/androidfw/VelocityControl.cpp b/libs/androidfw/VelocityControl.cpp
deleted file mode 100644
index cde2b76..0000000
--- a/libs/androidfw/VelocityControl.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#define LOG_TAG "VelocityControl"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/VelocityControl.h>
-#include <utils/BitSet.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-// --- VelocityControl ---
-
-const nsecs_t VelocityControl::STOP_TIME;
-
-VelocityControl::VelocityControl() {
-    reset();
-}
-
-void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
-    mParameters = parameters;
-    reset();
-}
-
-void VelocityControl::reset() {
-    mLastMovementTime = LLONG_MIN;
-    mRawPosition.x = 0;
-    mRawPosition.y = 0;
-    mVelocityTracker.clear();
-}
-
-void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
-    if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
-        if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
-                    (eventTime - mLastMovementTime) * 0.000001f);
-#endif
-            reset();
-        }
-
-        mLastMovementTime = eventTime;
-        if (deltaX) {
-            mRawPosition.x += *deltaX;
-        }
-        if (deltaY) {
-            mRawPosition.y += *deltaY;
-        }
-        mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
-
-        float vx, vy;
-        float scale = mParameters.scale;
-        if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
-            float speed = hypotf(vx, vy) * scale;
-            if (speed >= mParameters.highThreshold) {
-                // Apply full acceleration above the high speed threshold.
-                scale *= mParameters.acceleration;
-            } else if (speed > mParameters.lowThreshold) {
-                // Linearly interpolate the acceleration to apply between the low and high
-                // speed thresholds.
-                scale *= 1 + (speed - mParameters.lowThreshold)
-                        / (mParameters.highThreshold - mParameters.lowThreshold)
-                        * (mParameters.acceleration - 1);
-            }
-
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
-                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration,
-                    vx, vy, speed, scale / mParameters.scale);
-#endif
-        } else {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration);
-#endif
-        }
-
-        if (deltaX) {
-            *deltaX *= scale;
-        }
-        if (deltaY) {
-            *deltaY *= scale;
-        }
-    }
-}
-
-} // namespace android
diff --git a/libs/androidfw/VelocityTracker.cpp b/libs/androidfw/VelocityTracker.cpp
deleted file mode 100644
index f48ec62..0000000
--- a/libs/androidfw/VelocityTracker.cpp
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#define LOG_TAG "VelocityTracker"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about velocity tracking.
-#define DEBUG_VELOCITY 0
-
-// Log debug messages about the progress of the algorithm itself.
-#define DEBUG_STRATEGY 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/VelocityTracker.h>
-#include <utils/BitSet.h>
-#include <utils/String8.h>
-#include <utils/Timers.h>
-
-#include <cutils/properties.h>
-
-namespace android {
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Threshold for determining that a pointer has stopped moving.
-// Some input devices do not send ACTION_MOVE events in the case where a pointer has
-// stopped.  We need to detect this case so that we can accurately predict the
-// velocity after the pointer starts moving again.
-static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;
-
-
-static float vectorDot(const float* a, const float* b, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        r += *(a++) * *(b++);
-    }
-    return r;
-}
-
-static float vectorNorm(const float* a, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        float t = *(a++);
-        r += t * t;
-    }
-    return sqrtf(r);
-}
-
-#if DEBUG_STRATEGY || DEBUG_VELOCITY
-static String8 vectorToString(const float* a, uint32_t m) {
-    String8 str;
-    str.append("[");
-    while (m--) {
-        str.appendFormat(" %f", *(a++));
-        if (m) {
-            str.append(",");
-        }
-    }
-    str.append(" ]");
-    return str;
-}
-
-static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
-    String8 str;
-    str.append("[");
-    for (size_t i = 0; i < m; i++) {
-        if (i) {
-            str.append(",");
-        }
-        str.append(" [");
-        for (size_t j = 0; j < n; j++) {
-            if (j) {
-                str.append(",");
-            }
-            str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]);
-        }
-        str.append(" ]");
-    }
-    str.append(" ]");
-    return str;
-}
-#endif
-
-
-// --- VelocityTracker ---
-
-// The default velocity tracker strategy.
-// Although other strategies are available for testing and comparison purposes,
-// this is the strategy that applications will actually use.  Be very careful
-// when adjusting the default strategy because it can dramatically affect
-// (often in a bad way) the user experience.
-const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
-
-VelocityTracker::VelocityTracker(const char* strategy) :
-        mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
-    char value[PROPERTY_VALUE_MAX];
-
-    // Allow the default strategy to be overridden using a system property for debugging.
-    if (!strategy) {
-        int length = property_get("debug.velocitytracker.strategy", value, NULL);
-        if (length > 0) {
-            strategy = value;
-        } else {
-            strategy = DEFAULT_STRATEGY;
-        }
-    }
-
-    // Configure the strategy.
-    if (!configureStrategy(strategy)) {
-        ALOGD("Unrecognized velocity tracker strategy name '%s'.", strategy);
-        if (!configureStrategy(DEFAULT_STRATEGY)) {
-            LOG_ALWAYS_FATAL("Could not create the default velocity tracker strategy '%s'!",
-                    strategy);
-        }
-    }
-}
-
-VelocityTracker::~VelocityTracker() {
-    delete mStrategy;
-}
-
-bool VelocityTracker::configureStrategy(const char* strategy) {
-    mStrategy = createStrategy(strategy);
-    return mStrategy != NULL;
-}
-
-VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
-    if (!strcmp("lsq1", strategy)) {
-        // 1st order least squares.  Quality: POOR.
-        // Frequently underfits the touch data especially when the finger accelerates
-        // or changes direction.  Often underestimates velocity.  The direction
-        // is overly influenced by historical touch points.
-        return new LeastSquaresVelocityTrackerStrategy(1);
-    }
-    if (!strcmp("lsq2", strategy)) {
-        // 2nd order least squares.  Quality: VERY GOOD.
-        // Pretty much ideal, but can be confused by certain kinds of touch data,
-        // particularly if the panel has a tendency to generate delayed,
-        // duplicate or jittery touch coordinates when the finger is released.
-        return new LeastSquaresVelocityTrackerStrategy(2);
-    }
-    if (!strcmp("lsq3", strategy)) {
-        // 3rd order least squares.  Quality: UNUSABLE.
-        // Frequently overfits the touch data yielding wildly divergent estimates
-        // of the velocity when the finger is released.
-        return new LeastSquaresVelocityTrackerStrategy(3);
-    }
-    if (!strcmp("wlsq2-delta", strategy)) {
-        // 2nd order weighted least squares, delta weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_DELTA);
-    }
-    if (!strcmp("wlsq2-central", strategy)) {
-        // 2nd order weighted least squares, central weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_CENTRAL);
-    }
-    if (!strcmp("wlsq2-recent", strategy)) {
-        // 2nd order weighted least squares, recent weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_RECENT);
-    }
-    if (!strcmp("int1", strategy)) {
-        // 1st order integrating filter.  Quality: GOOD.
-        // Not as good as 'lsq2' because it cannot estimate acceleration but it is
-        // more tolerant of errors.  Like 'lsq1', this strategy tends to underestimate
-        // the velocity of a fling but this strategy tends to respond to changes in
-        // direction more quickly and accurately.
-        return new IntegratingVelocityTrackerStrategy(1);
-    }
-    if (!strcmp("int2", strategy)) {
-        // 2nd order integrating filter.  Quality: EXPERIMENTAL.
-        // For comparison purposes only.  Unlike 'int1' this strategy can compensate
-        // for acceleration but it typically overestimates the effect.
-        return new IntegratingVelocityTrackerStrategy(2);
-    }
-    if (!strcmp("legacy", strategy)) {
-        // Legacy velocity tracker algorithm.  Quality: POOR.
-        // For comparison purposes only.  This algorithm is strongly influenced by
-        // old data points, consistently underestimates velocity and takes a very long
-        // time to adjust to changes in direction.
-        return new LegacyVelocityTrackerStrategy();
-    }
-    return NULL;
-}
-
-void VelocityTracker::clear() {
-    mCurrentPointerIdBits.clear();
-    mActivePointerId = -1;
-
-    mStrategy->clear();
-}
-
-void VelocityTracker::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
-    mCurrentPointerIdBits = remainingIdBits;
-
-    if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
-    }
-
-    mStrategy->clearPointers(idBits);
-}
-
-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
-    while (idBits.count() > MAX_POINTERS) {
-        idBits.clearLastMarkedBit();
-    }
-
-    if ((mCurrentPointerIdBits.value & idBits.value)
-            && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
-#if DEBUG_VELOCITY
-        ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
-                (eventTime - mLastEventTime) * 0.000001f);
-#endif
-        // We have not received any movements for too long.  Assume that all pointers
-        // have stopped.
-        mStrategy->clear();
-    }
-    mLastEventTime = eventTime;
-
-    mCurrentPointerIdBits = idBits;
-    if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
-    }
-
-    mStrategy->addMovement(eventTime, idBits, positions);
-
-#if DEBUG_VELOCITY
-    ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
-            eventTime, idBits.value, mActivePointerId);
-    for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
-        uint32_t id = iterBits.firstMarkedBit();
-        uint32_t index = idBits.getIndexOfBit(id);
-        iterBits.clearBit(id);
-        Estimator estimator;
-        getEstimator(id, &estimator);
-        ALOGD("  %d: position (%0.3f, %0.3f), "
-                "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
-                id, positions[index].x, positions[index].y,
-                int(estimator.degree),
-                vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
-                vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
-                estimator.confidence);
-    }
-#endif
-}
-
-void VelocityTracker::addMovement(const MotionEvent* event) {
-    int32_t actionMasked = event->getActionMasked();
-
-    switch (actionMasked) {
-    case AMOTION_EVENT_ACTION_DOWN:
-    case AMOTION_EVENT_ACTION_HOVER_ENTER:
-        // Clear all pointers on down before adding the new movement.
-        clear();
-        break;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
-        // Start a new movement trace for a pointer that just went down.
-        // We do this on down instead of on up because the client may want to query the
-        // final velocity for a pointer that just went up.
-        BitSet32 downIdBits;
-        downIdBits.markBit(event->getPointerId(event->getActionIndex()));
-        clearPointers(downIdBits);
-        break;
-    }
-    case AMOTION_EVENT_ACTION_MOVE:
-    case AMOTION_EVENT_ACTION_HOVER_MOVE:
-        break;
-    default:
-        // Ignore all other actions because they do not convey any new information about
-        // pointer movement.  We also want to preserve the last known velocity of the pointers.
-        // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
-        // of the pointers that went up.  ACTION_POINTER_UP does include the new position of
-        // pointers that remained down but we will also receive an ACTION_MOVE with this
-        // information if any of them actually moved.  Since we don't know how many pointers
-        // will be going up at once it makes sense to just wait for the following ACTION_MOVE
-        // before adding the movement.
-        return;
-    }
-
-    size_t pointerCount = event->getPointerCount();
-    if (pointerCount > MAX_POINTERS) {
-        pointerCount = MAX_POINTERS;
-    }
-
-    BitSet32 idBits;
-    for (size_t i = 0; i < pointerCount; i++) {
-        idBits.markBit(event->getPointerId(i));
-    }
-
-    uint32_t pointerIndex[MAX_POINTERS];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
-    }
-
-    nsecs_t eventTime;
-    Position positions[pointerCount];
-
-    size_t historySize = event->getHistorySize();
-    for (size_t h = 0; h < historySize; h++) {
-        eventTime = event->getHistoricalEventTime(h);
-        for (size_t i = 0; i < pointerCount; i++) {
-            uint32_t index = pointerIndex[i];
-            positions[index].x = event->getHistoricalX(i, h);
-            positions[index].y = event->getHistoricalY(i, h);
-        }
-        addMovement(eventTime, idBits, positions);
-    }
-
-    eventTime = event->getEventTime();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t index = pointerIndex[i];
-        positions[index].x = event->getX(i);
-        positions[index].y = event->getY(i);
-    }
-    addMovement(eventTime, idBits, positions);
-}
-
-bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
-    Estimator estimator;
-    if (getEstimator(id, &estimator) && estimator.degree >= 1) {
-        *outVx = estimator.xCoeff[1];
-        *outVy = estimator.yCoeff[1];
-        return true;
-    }
-    *outVx = 0;
-    *outVy = 0;
-    return false;
-}
-
-bool VelocityTracker::getEstimator(uint32_t id, Estimator* outEstimator) const {
-    return mStrategy->getEstimator(id, outEstimator);
-}
-
-
-// --- LeastSquaresVelocityTrackerStrategy ---
-
-const nsecs_t LeastSquaresVelocityTrackerStrategy::HORIZON;
-const uint32_t LeastSquaresVelocityTrackerStrategy::HISTORY_SIZE;
-
-LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
-        uint32_t degree, Weighting weighting) :
-        mDegree(degree), mWeighting(weighting) {
-    clear();
-}
-
-LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {
-}
-
-void LeastSquaresVelocityTrackerStrategy::clear() {
-    mIndex = 0;
-    mMovements[0].idBits.clear();
-}
-
-void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
-    mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    if (++mIndex == HISTORY_SIZE) {
-        mIndex = 0;
-    }
-
-    Movement& movement = mMovements[mIndex];
-    movement.eventTime = eventTime;
-    movement.idBits = idBits;
-    uint32_t count = idBits.count();
-    for (uint32_t i = 0; i < count; i++) {
-        movement.positions[i] = positions[i];
-    }
-}
-
-/**
- * Solves a linear least squares problem to obtain a N degree polynomial that fits
- * the specified input data as nearly as possible.
- *
- * Returns true if a solution is found, false otherwise.
- *
- * The input consists of two vectors of data points X and Y with indices 0..m-1
- * along with a weight vector W of the same size.
- *
- * The output is a vector B with indices 0..n that describes a polynomial
- * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1] X[i]
- * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is minimized.
- *
- * Accordingly, the weight vector W should be initialized by the caller with the
- * reciprocal square root of the variance of the error in each input data point.
- * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 / stddev(Y[i]).
- * The weights express the relative importance of each data point.  If the weights are
- * all 1, then the data points are considered to be of equal importance when fitting
- * the polynomial.  It is a good idea to choose weights that diminish the importance
- * of data points that may have higher than usual error margins.
- *
- * Errors among data points are assumed to be independent.  W is represented here
- * as a vector although in the literature it is typically taken to be a diagonal matrix.
- *
- * That is to say, the function that generated the input data can be approximated
- * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
- *
- * The coefficient of determination (R^2) is also returned to describe the goodness
- * of fit of the model for the given data.  It is a value between 0 and 1, where 1
- * indicates perfect correspondence.
- *
- * This function first expands the X vector to a m by n matrix A such that
- * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then
- * multiplies it by w[i]./
- *
- * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
- * and an m by n upper triangular matrix R.  Because R is upper triangular (lower
- * part is all zeroes), we can simplify the decomposition into an m by n matrix
- * Q1 and a n by n matrix R1 such that A = Q1 R1.
- *
- * Finally we solve the system of linear equations given by R1 B = (Qtranspose W Y)
- * to find B.
- *
- * For efficiency, we lay out A and Q column-wise in memory because we frequently
- * operate on the column vectors.  Conversely, we lay out R row-wise.
- *
- * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
- * http://en.wikipedia.org/wiki/Gram-Schmidt
- */
-static bool solveLeastSquares(const float* x, const float* y,
-        const float* w, uint32_t m, uint32_t n, float* outB, float* outDet) {
-#if DEBUG_STRATEGY
-    ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
-            vectorToString(x, m).string(), vectorToString(y, m).string(),
-            vectorToString(w, m).string());
-#endif
-
-    // Expand the X vector to a matrix A, pre-multiplied by the weights.
-    float a[n][m]; // column-major order
-    for (uint32_t h = 0; h < m; h++) {
-        a[0][h] = w[h];
-        for (uint32_t i = 1; i < n; i++) {
-            a[i][h] = a[i - 1][h] * x[h];
-        }
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
-    float q[n][m]; // orthonormal basis, column-major order
-    float r[n][n]; // upper triangular matrix, row-major order
-    for (uint32_t j = 0; j < n; j++) {
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] = a[j][h];
-        }
-        for (uint32_t i = 0; i < j; i++) {
-            float dot = vectorDot(&q[j][0], &q[i][0], m);
-            for (uint32_t h = 0; h < m; h++) {
-                q[j][h] -= dot * q[i][h];
-            }
-        }
-
-        float norm = vectorNorm(&q[j][0], m);
-        if (norm < 0.000001f) {
-            // vectors are linearly dependent or zero so no solution
-#if DEBUG_STRATEGY
-            ALOGD("  - no solution, norm=%f", norm);
-#endif
-            return false;
-        }
-
-        float invNorm = 1.0f / norm;
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] *= invNorm;
-        }
-        for (uint32_t i = 0; i < n; i++) {
-            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
-        }
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
-    ALOGD("  - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
-
-    // calculate QR, if we factored A correctly then QR should equal A
-    float qr[n][m];
-    for (uint32_t h = 0; h < m; h++) {
-        for (uint32_t i = 0; i < n; i++) {
-            qr[i][h] = 0;
-            for (uint32_t j = 0; j < n; j++) {
-                qr[i][h] += q[j][h] * r[j][i];
-            }
-        }
-    }
-    ALOGD("  - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
-    // We just work from bottom-right to top-left calculating B's coefficients.
-    float wy[m];
-    for (uint32_t h = 0; h < m; h++) {
-        wy[h] = y[h] * w[h];
-    }
-    for (uint32_t i = n; i-- != 0; ) {
-        outB[i] = vectorDot(&q[i][0], wy, m);
-        for (uint32_t j = n - 1; j > i; j--) {
-            outB[i] -= r[i][j] * outB[j];
-        }
-        outB[i] /= r[i][i];
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - b=%s", vectorToString(outB, n).string());
-#endif
-
-    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
-    // SSerr is the residual sum of squares (variance of the error),
-    // and SStot is the total sum of squares (variance of the data) where each
-    // has been weighted.
-    float ymean = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        ymean += y[h];
-    }
-    ymean /= m;
-
-    float sserr = 0;
-    float sstot = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        float err = y[h] - outB[0];
-        float term = 1;
-        for (uint32_t i = 1; i < n; i++) {
-            term *= x[h];
-            err -= term * outB[i];
-        }
-        sserr += w[h] * w[h] * err * err;
-        float var = y[h] - ymean;
-        sstot += w[h] * w[h] * var * var;
-    }
-    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
-#if DEBUG_STRATEGY
-    ALOGD("  - sserr=%f", sserr);
-    ALOGD("  - sstot=%f", sstot);
-    ALOGD("  - det=%f", *outDet);
-#endif
-    return true;
-}
-
-bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    // Iterate over movement samples in reverse time order and collect samples.
-    float x[HISTORY_SIZE];
-    float y[HISTORY_SIZE];
-    float w[HISTORY_SIZE];
-    float time[HISTORY_SIZE];
-    uint32_t m = 0;
-    uint32_t index = mIndex;
-    const Movement& newestMovement = mMovements[mIndex];
-    do {
-        const Movement& movement = mMovements[index];
-        if (!movement.idBits.hasBit(id)) {
-            break;
-        }
-
-        nsecs_t age = newestMovement.eventTime - movement.eventTime;
-        if (age > HORIZON) {
-            break;
-        }
-
-        const VelocityTracker::Position& position = movement.getPosition(id);
-        x[m] = position.x;
-        y[m] = position.y;
-        w[m] = chooseWeight(index);
-        time[m] = -age * 0.000000001f;
-        index = (index == 0 ? HISTORY_SIZE : index) - 1;
-    } while (++m < HISTORY_SIZE);
-
-    if (m == 0) {
-        return false; // no data
-    }
-
-    // Calculate a least squares polynomial fit.
-    uint32_t degree = mDegree;
-    if (degree > m - 1) {
-        degree = m - 1;
-    }
-    if (degree >= 1) {
-        float xdet, ydet;
-        uint32_t n = degree + 1;
-        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
-                && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {
-            outEstimator->time = newestMovement.eventTime;
-            outEstimator->degree = degree;
-            outEstimator->confidence = xdet * ydet;
-#if DEBUG_STRATEGY
-            ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
-                    int(outEstimator->degree),
-                    vectorToString(outEstimator->xCoeff, n).string(),
-                    vectorToString(outEstimator->yCoeff, n).string(),
-                    outEstimator->confidence);
-#endif
-            return true;
-        }
-    }
-
-    // No velocity data available for this pointer, but we do have its current position.
-    outEstimator->xCoeff[0] = x[0];
-    outEstimator->yCoeff[0] = y[0];
-    outEstimator->time = newestMovement.eventTime;
-    outEstimator->degree = 0;
-    outEstimator->confidence = 1;
-    return true;
-}
-
-float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {
-    switch (mWeighting) {
-    case WEIGHTING_DELTA: {
-        // Weight points based on how much time elapsed between them and the next
-        // point so that points that "cover" a shorter time span are weighed less.
-        //   delta  0ms: 0.5
-        //   delta 10ms: 1.0
-        if (index == mIndex) {
-            return 1.0f;
-        }
-        uint32_t nextIndex = (index + 1) % HISTORY_SIZE;
-        float deltaMillis = (mMovements[nextIndex].eventTime- mMovements[index].eventTime)
-                * 0.000001f;
-        if (deltaMillis < 0) {
-            return 0.5f;
-        }
-        if (deltaMillis < 10) {
-            return 0.5f + deltaMillis * 0.05;
-        }
-        return 1.0f;
-    }
-
-    case WEIGHTING_CENTRAL: {
-        // Weight points based on their age, weighing very recent and very old points less.
-        //   age  0ms: 0.5
-        //   age 10ms: 1.0
-        //   age 50ms: 1.0
-        //   age 60ms: 0.5
-        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
-                * 0.000001f;
-        if (ageMillis < 0) {
-            return 0.5f;
-        }
-        if (ageMillis < 10) {
-            return 0.5f + ageMillis * 0.05;
-        }
-        if (ageMillis < 50) {
-            return 1.0f;
-        }
-        if (ageMillis < 60) {
-            return 0.5f + (60 - ageMillis) * 0.05;
-        }
-        return 0.5f;
-    }
-
-    case WEIGHTING_RECENT: {
-        // Weight points based on their age, weighing older points less.
-        //   age   0ms: 1.0
-        //   age  50ms: 1.0
-        //   age 100ms: 0.5
-        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
-                * 0.000001f;
-        if (ageMillis < 50) {
-            return 1.0f;
-        }
-        if (ageMillis < 100) {
-            return 0.5f + (100 - ageMillis) * 0.01f;
-        }
-        return 0.5f;
-    }
-
-    case WEIGHTING_NONE:
-    default:
-        return 1.0f;
-    }
-}
-
-
-// --- IntegratingVelocityTrackerStrategy ---
-
-IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
-        mDegree(degree) {
-}
-
-IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
-}
-
-void IntegratingVelocityTrackerStrategy::clear() {
-    mPointerIdBits.clear();
-}
-
-void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    mPointerIdBits.value &= ~idBits.value;
-}
-
-void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    uint32_t index = 0;
-    for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
-        uint32_t id = iterIdBits.clearFirstMarkedBit();
-        State& state = mPointerState[id];
-        const VelocityTracker::Position& position = positions[index++];
-        if (mPointerIdBits.hasBit(id)) {
-            updateState(state, eventTime, position.x, position.y);
-        } else {
-            initState(state, eventTime, position.x, position.y);
-        }
-    }
-
-    mPointerIdBits = idBits;
-}
-
-bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    if (mPointerIdBits.hasBit(id)) {
-        const State& state = mPointerState[id];
-        populateEstimator(state, outEstimator);
-        return true;
-    }
-
-    return false;
-}
-
-void IntegratingVelocityTrackerStrategy::initState(State& state,
-        nsecs_t eventTime, float xpos, float ypos) const {
-    state.updateTime = eventTime;
-    state.degree = 0;
-
-    state.xpos = xpos;
-    state.xvel = 0;
-    state.xaccel = 0;
-    state.ypos = ypos;
-    state.yvel = 0;
-    state.yaccel = 0;
-}
-
-void IntegratingVelocityTrackerStrategy::updateState(State& state,
-        nsecs_t eventTime, float xpos, float ypos) const {
-    const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
-    const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
-
-    if (eventTime <= state.updateTime + MIN_TIME_DELTA) {
-        return;
-    }
-
-    float dt = (eventTime - state.updateTime) * 0.000000001f;
-    state.updateTime = eventTime;
-
-    float xvel = (xpos - state.xpos) / dt;
-    float yvel = (ypos - state.ypos) / dt;
-    if (state.degree == 0) {
-        state.xvel = xvel;
-        state.yvel = yvel;
-        state.degree = 1;
-    } else {
-        float alpha = dt / (FILTER_TIME_CONSTANT + dt);
-        if (mDegree == 1) {
-            state.xvel += (xvel - state.xvel) * alpha;
-            state.yvel += (yvel - state.yvel) * alpha;
-        } else {
-            float xaccel = (xvel - state.xvel) / dt;
-            float yaccel = (yvel - state.yvel) / dt;
-            if (state.degree == 1) {
-                state.xaccel = xaccel;
-                state.yaccel = yaccel;
-                state.degree = 2;
-            } else {
-                state.xaccel += (xaccel - state.xaccel) * alpha;
-                state.yaccel += (yaccel - state.yaccel) * alpha;
-            }
-            state.xvel += (state.xaccel * dt) * alpha;
-            state.yvel += (state.yaccel * dt) * alpha;
-        }
-    }
-    state.xpos = xpos;
-    state.ypos = ypos;
-}
-
-void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->time = state.updateTime;
-    outEstimator->confidence = 1.0f;
-    outEstimator->degree = state.degree;
-    outEstimator->xCoeff[0] = state.xpos;
-    outEstimator->xCoeff[1] = state.xvel;
-    outEstimator->xCoeff[2] = state.xaccel / 2;
-    outEstimator->yCoeff[0] = state.ypos;
-    outEstimator->yCoeff[1] = state.yvel;
-    outEstimator->yCoeff[2] = state.yaccel / 2;
-}
-
-
-// --- LegacyVelocityTrackerStrategy ---
-
-const nsecs_t LegacyVelocityTrackerStrategy::HORIZON;
-const uint32_t LegacyVelocityTrackerStrategy::HISTORY_SIZE;
-const nsecs_t LegacyVelocityTrackerStrategy::MIN_DURATION;
-
-LegacyVelocityTrackerStrategy::LegacyVelocityTrackerStrategy() {
-    clear();
-}
-
-LegacyVelocityTrackerStrategy::~LegacyVelocityTrackerStrategy() {
-}
-
-void LegacyVelocityTrackerStrategy::clear() {
-    mIndex = 0;
-    mMovements[0].idBits.clear();
-}
-
-void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
-    mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    if (++mIndex == HISTORY_SIZE) {
-        mIndex = 0;
-    }
-
-    Movement& movement = mMovements[mIndex];
-    movement.eventTime = eventTime;
-    movement.idBits = idBits;
-    uint32_t count = idBits.count();
-    for (uint32_t i = 0; i < count; i++) {
-        movement.positions[i] = positions[i];
-    }
-}
-
-bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    const Movement& newestMovement = mMovements[mIndex];
-    if (!newestMovement.idBits.hasBit(id)) {
-        return false; // no data
-    }
-
-    // Find the oldest sample that contains the pointer and that is not older than HORIZON.
-    nsecs_t minTime = newestMovement.eventTime - HORIZON;
-    uint32_t oldestIndex = mIndex;
-    uint32_t numTouches = 1;
-    do {
-        uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
-        const Movement& nextOldestMovement = mMovements[nextOldestIndex];
-        if (!nextOldestMovement.idBits.hasBit(id)
-                || nextOldestMovement.eventTime < minTime) {
-            break;
-        }
-        oldestIndex = nextOldestIndex;
-    } while (++numTouches < HISTORY_SIZE);
-
-    // Calculate an exponentially weighted moving average of the velocity estimate
-    // at different points in time measured relative to the oldest sample.
-    // This is essentially an IIR filter.  Newer samples are weighted more heavily
-    // than older samples.  Samples at equal time points are weighted more or less
-    // equally.
-    //
-    // One tricky problem is that the sample data may be poorly conditioned.
-    // Sometimes samples arrive very close together in time which can cause us to
-    // overestimate the velocity at that time point.  Most samples might be measured
-    // 16ms apart but some consecutive samples could be only 0.5sm apart because
-    // the hardware or driver reports them irregularly or in bursts.
-    float accumVx = 0;
-    float accumVy = 0;
-    uint32_t index = oldestIndex;
-    uint32_t samplesUsed = 0;
-    const Movement& oldestMovement = mMovements[oldestIndex];
-    const VelocityTracker::Position& oldestPosition = oldestMovement.getPosition(id);
-    nsecs_t lastDuration = 0;
-
-    while (numTouches-- > 1) {
-        if (++index == HISTORY_SIZE) {
-            index = 0;
-        }
-        const Movement& movement = mMovements[index];
-        nsecs_t duration = movement.eventTime - oldestMovement.eventTime;
-
-        // If the duration between samples is small, we may significantly overestimate
-        // the velocity.  Consequently, we impose a minimum duration constraint on the
-        // samples that we include in the calculation.
-        if (duration >= MIN_DURATION) {
-            const VelocityTracker::Position& position = movement.getPosition(id);
-            float scale = 1000000000.0f / duration; // one over time delta in seconds
-            float vx = (position.x - oldestPosition.x) * scale;
-            float vy = (position.y - oldestPosition.y) * scale;
-            accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration);
-            accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration);
-            lastDuration = duration;
-            samplesUsed += 1;
-        }
-    }
-
-    // Report velocity.
-    const VelocityTracker::Position& newestPosition = newestMovement.getPosition(id);
-    outEstimator->time = newestMovement.eventTime;
-    outEstimator->confidence = 1;
-    outEstimator->xCoeff[0] = newestPosition.x;
-    outEstimator->yCoeff[0] = newestPosition.y;
-    if (samplesUsed) {
-        outEstimator->xCoeff[1] = accumVx;
-        outEstimator->yCoeff[1] = accumVy;
-        outEstimator->degree = 1;
-    } else {
-        outEstimator->degree = 0;
-    }
-    return true;
-}
-
-} // namespace android
diff --git a/libs/androidfw/VirtualKeyMap.cpp b/libs/androidfw/VirtualKeyMap.cpp
deleted file mode 100644
index 2ba1673..0000000
--- a/libs/androidfw/VirtualKeyMap.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "VirtualKeyMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <androidfw/VirtualKeyMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
-
-
-// --- VirtualKeyMap ---
-
-VirtualKeyMap::VirtualKeyMap() {
-}
-
-VirtualKeyMap::~VirtualKeyMap() {
-}
-
-status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
-    *outMap = NULL;
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
-    } else {
-        VirtualKeyMap* map = new VirtualKeyMap();
-        if (!map) {
-            ALOGE("Error allocating virtual key map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map, tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (status) {
-                delete map;
-            } else {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-
-// --- VirtualKeyMap::Parser ---
-
-VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-VirtualKeyMap::Parser::~Parser() {
-}
-
-status_t VirtualKeyMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            // Multiple keys can appear on one line or they can be broken up across multiple lines.
-            do {
-                String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-                if (token != "0x01") {
-                    ALOGE("%s: Unknown virtual key type, expected 0x01.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-                VirtualKeyDefinition defn;
-                bool success = parseNextIntField(&defn.scanCode)
-                        && parseNextIntField(&defn.centerX)
-                        && parseNextIntField(&defn.centerY)
-                        && parseNextIntField(&defn.width)
-                        && parseNextIntField(&defn.height);
-                if (!success) {
-                    ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-#if DEBUG_PARSER
-                ALOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
-                        "width=%d, height=%d",
-                        defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
-#endif
-                mMap->mVirtualKeys.push(defn);
-            } while (consumeFieldDelimiterAndSkipWhitespace());
-
-            if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    return NO_ERROR;
-}
-
-bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
-    mTokenizer->skipDelimiters(WHITESPACE);
-    if (mTokenizer->peekChar() == ':') {
-        mTokenizer->nextChar();
-        mTokenizer->skipDelimiters(WHITESPACE);
-        return true;
-    }
-    return false;
-}
-
-bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
-    if (!consumeFieldDelimiterAndSkipWhitespace()) {
-        return false;
-    }
-
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-    char* end;
-    *outValue = strtol(token.string(), &end, 0);
-    if (token.isEmpty() || *end != '\0') {
-        ALOGE("Expected an integer, got '%s'.", token.string());
-        return false;
-    }
-    return true;
-}
-
-} // namespace android
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 6be7c5b..0522212 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -4,9 +4,6 @@
 
 # Build the unit tests.
 test_src_files := \
-    InputChannel_test.cpp \
-    InputEvent_test.cpp \
-    InputPublisherAndConsumer_test.cpp \
     ObbFile_test.cpp \
     ZipFileRO_test.cpp
 
@@ -14,10 +11,8 @@
     libandroidfw \
     libcutils \
     libutils \
-    libbinder \
     libui \
-    libstlport \
-    libskia
+    libstlport
 
 static_libraries := \
     libgtest \
diff --git a/libs/androidfw/tests/InputChannel_test.cpp b/libs/androidfw/tests/InputChannel_test.cpp
deleted file mode 100644
index 7fff8af..0000000
--- a/libs/androidfw/tests/InputChannel_test.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2010 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 <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <utils/StrongPointer.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "TestHelpers.h"
-
-namespace android {
-
-class InputChannelTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-
-TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
-    // Our purpose here is to verify that the input channel destructor closes the
-    // file descriptor provided to it.  One easy way is to provide it with one end
-    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
-    Pipe pipe;
-
-    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"), pipe.sendFd);
-
-    EXPECT_STREQ("channel name", inputChannel->getName().string())
-            << "channel should have provided name";
-    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
-            << "channel should have provided fd";
-
-    inputChannel.clear(); // destroys input channel
-
-    EXPECT_EQ(-EPIPE, pipe.readSignal())
-            << "channel should have closed fd when destroyed";
-
-    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
-    pipe.sendFd = -1;
-}
-
-TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    // Name
-    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
-            << "server channel should have suffixed name";
-    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
-            << "client channel should have suffixed name";
-
-    // Server->Client communication
-    InputMessage serverMsg;
-    memset(&serverMsg, 0, sizeof(InputMessage));
-    serverMsg.header.type = InputMessage::TYPE_KEY;
-    serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
-    EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
-            << "server channel should be able to send message to client channel";
-
-    InputMessage clientMsg;
-    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
-            << "client channel should be able to receive message from server channel";
-    EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
-            << "client channel should receive the correct message from server channel";
-    EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
-            << "client channel should receive the correct message from server channel";
-
-    // Client->Server communication
-    InputMessage clientReply;
-    memset(&clientReply, 0, sizeof(InputMessage));
-    clientReply.header.type = InputMessage::TYPE_FINISHED;
-    clientReply.body.finished.seq = 0x11223344;
-    clientReply.body.finished.handled = true;
-    EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
-            << "client channel should be able to send message to server channel";
-
-    InputMessage serverReply;
-    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
-            << "server channel should be able to receive message from client channel";
-    EXPECT_EQ(clientReply.header.type, serverReply.header.type)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
-            << "server channel should receive the correct message from client channel";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    InputMessage msg;
-    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned WOULD_BLOCK";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned DEAD_OBJECT";
-}
-
-TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
-            << "sendMessage should have returned DEAD_OBJECT";
-}
-
-
-} // namespace android
diff --git a/libs/androidfw/tests/InputEvent_test.cpp b/libs/androidfw/tests/InputEvent_test.cpp
deleted file mode 100644
index e9164d1..0000000
--- a/libs/androidfw/tests/InputEvent_test.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2011 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 <androidfw/Input.h>
-#include <gtest/gtest.h>
-#include <binder/Parcel.h>
-
-#include <math.h>
-#include <core/SkMatrix.h>
-
-namespace android {
-
-class BaseTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-// --- PointerCoordsTest ---
-
-class PointerCoordsTest : public BaseTest {
-};
-
-TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
-    PointerCoords coords;
-    coords.clear();
-
-    ASSERT_EQ(0ULL, coords.bits);
-}
-
-TEST_F(PointerCoordsTest, AxisValues) {
-    float* valuePtr;
-    PointerCoords coords;
-    coords.clear();
-
-    // Check invariants when no axes are present.
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(0, coords.getAxisValue(1))
-            << "getAxisValue should return zero because axis is not present";
-
-    // Set first axis.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 5));
-    ASSERT_EQ(0x00000002ULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with a higher id than all others.  (appending value at the end)
-    ASSERT_EQ(OK, coords.setAxisValue(3, 2));
-    ASSERT_EQ(0x0000000aULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-    ASSERT_EQ(2, coords.values[1]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id lower than all others.  (prepending value at beginning)
-    ASSERT_EQ(OK, coords.setAxisValue(0, 4));
-    ASSERT_EQ(0x0000000bULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(2, coords.values[2]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id between the others.  (inserting value in the middle)
-    ASSERT_EQ(OK, coords.setAxisValue(2, 1));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an existing axis value in place.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 6));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(6, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(6, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set maximum number of axes.
-    for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
-        ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
-    }
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-
-    // Try to set one more axis beyond maximum number.
-    // Ensure bits are unchanged.
-    ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-}
-
-TEST_F(PointerCoordsTest, Parcel) {
-    Parcel parcel;
-
-    PointerCoords inCoords;
-    inCoords.clear();
-    PointerCoords outCoords;
-
-    // Round trip with empty coords.
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(0ULL, outCoords.bits);
-
-    // Round trip with some values.
-    parcel.freeData();
-    inCoords.setAxisValue(2, 5);
-    inCoords.setAxisValue(5, 8);
-
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(outCoords.bits, inCoords.bits);
-    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
-    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
-}
-
-
-// --- KeyEventTest ---
-
-class KeyEventTest : public BaseTest {
-};
-
-TEST_F(KeyEventTest, Properties) {
-    KeyEvent event;
-
-    // Initialize and get properties.
-    const nsecs_t ARBITRARY_DOWN_TIME = 1;
-    const nsecs_t ARBITRARY_EVENT_TIME = 2;
-    event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
-            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
-
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
-    ASSERT_EQ(2, event.getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
-    ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
-    ASSERT_EQ(121, event.getScanCode());
-    ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
-    ASSERT_EQ(1, event.getRepeatCount());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-}
-
-
-// --- MotionEventTest ---
-
-class MotionEventTest : public BaseTest {
-protected:
-    static const nsecs_t ARBITRARY_DOWN_TIME;
-    static const nsecs_t ARBITRARY_EVENT_TIME;
-    static const float X_OFFSET;
-    static const float Y_OFFSET;
-
-    void initializeEventWithHistory(MotionEvent* event);
-    void assertEqualsEventWithHistory(const MotionEvent* event);
-};
-
-const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
-const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
-const float MotionEventTest::X_OFFSET = 1.0f;
-const float MotionEventTest::Y_OFFSET = 1.1f;
-
-void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
-    PointerProperties pointerProperties[2];
-    pointerProperties[0].clear();
-    pointerProperties[0].id = 1;
-    pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-    pointerProperties[1].clear();
-    pointerProperties[1].id = 2;
-    pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
-
-    PointerCoords pointerCoords[2];
-    pointerCoords[0].clear();
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
-    pointerCoords[1].clear();
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
-    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
-            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
-            AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
-            X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
-            ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
-            2, pointerProperties, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
-    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
-    event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
-}
-
-void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
-    // Check properties.
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
-    ASSERT_EQ(2, event->getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
-    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
-    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
-    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
-    ASSERT_EQ(X_OFFSET, event->getXOffset());
-    ASSERT_EQ(Y_OFFSET, event->getYOffset());
-    ASSERT_EQ(2.0f, event->getXPrecision());
-    ASSERT_EQ(2.1f, event->getYPrecision());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
-
-    ASSERT_EQ(2U, event->getPointerCount());
-    ASSERT_EQ(1, event->getPointerId(0));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
-    ASSERT_EQ(2, event->getPointerId(1));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
-
-    ASSERT_EQ(2U, event->getHistorySize());
-
-    // Check data.
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
-
-    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(211, event->getRawPointerCoords(0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(221, event->getRawPointerCoords(1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-
-    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
-    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
-    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
-
-    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
-    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
-    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
-    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
-    ASSERT_EQ(210, event->getRawX(0));
-    ASSERT_EQ(220, event->getRawX(1));
-
-    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
-    ASSERT_EQ(211, event->getRawY(0));
-    ASSERT_EQ(221, event->getRawY(1));
-
-    ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
-    ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
-    ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
-    ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
-    ASSERT_EQ(X_OFFSET + 210, event->getX(0));
-    ASSERT_EQ(X_OFFSET + 220, event->getX(1));
-
-    ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
-    ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
-    ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
-    ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
-    ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
-    ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
-
-    ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
-    ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
-    ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
-    ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
-    ASSERT_EQ(212, event->getPressure(0));
-    ASSERT_EQ(222, event->getPressure(1));
-
-    ASSERT_EQ(13, event->getHistoricalSize(0, 0));
-    ASSERT_EQ(23, event->getHistoricalSize(1, 0));
-    ASSERT_EQ(113, event->getHistoricalSize(0, 1));
-    ASSERT_EQ(123, event->getHistoricalSize(1, 1));
-    ASSERT_EQ(213, event->getSize(0));
-    ASSERT_EQ(223, event->getSize(1));
-
-    ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
-    ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
-    ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
-    ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
-    ASSERT_EQ(214, event->getTouchMajor(0));
-    ASSERT_EQ(224, event->getTouchMajor(1));
-
-    ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
-    ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
-    ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
-    ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
-    ASSERT_EQ(215, event->getTouchMinor(0));
-    ASSERT_EQ(225, event->getTouchMinor(1));
-
-    ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
-    ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
-    ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
-    ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
-    ASSERT_EQ(216, event->getToolMajor(0));
-    ASSERT_EQ(226, event->getToolMajor(1));
-
-    ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
-    ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
-    ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
-    ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
-    ASSERT_EQ(217, event->getToolMinor(0));
-    ASSERT_EQ(227, event->getToolMinor(1));
-
-    ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
-    ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
-    ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
-    ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
-    ASSERT_EQ(218, event->getOrientation(0));
-    ASSERT_EQ(228, event->getOrientation(1));
-}
-
-TEST_F(MotionEventTest, Properties) {
-    MotionEvent event;
-
-    // Initialize, add samples and check properties.
-    initializeEventWithHistory(&event);
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-
-    // Set action.
-    event.setAction(AMOTION_EVENT_ACTION_CANCEL);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
-
-    // Set meta state.
-    event.setMetaState(AMETA_CTRL_ON);
-    ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
-}
-
-TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, true /*keepHistory*/);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-}
-
-TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, false /*keepHistory*/);
-
-    ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
-    ASSERT_EQ(0U, copy.getHistorySize());
-
-    ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
-    ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
-
-    ASSERT_EQ(event.getEventTime(), copy.getEventTime());
-
-    ASSERT_EQ(event.getX(0), copy.getX(0));
-}
-
-TEST_F(MotionEventTest, OffsetLocation) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.offsetLocation(5.0f, -2.0f);
-
-    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
-}
-
-TEST_F(MotionEventTest, Scale) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.scale(2.0f);
-
-    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
-
-    ASSERT_EQ(210 * 2, event.getRawX(0));
-    ASSERT_EQ(211 * 2, event.getRawY(0));
-    ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
-    ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
-    ASSERT_EQ(212, event.getPressure(0));
-    ASSERT_EQ(213, event.getSize(0));
-    ASSERT_EQ(214 * 2, event.getTouchMajor(0));
-    ASSERT_EQ(215 * 2, event.getTouchMinor(0));
-    ASSERT_EQ(216 * 2, event.getToolMajor(0));
-    ASSERT_EQ(217 * 2, event.getToolMinor(0));
-    ASSERT_EQ(218, event.getOrientation(0));
-}
-
-TEST_F(MotionEventTest, Parcel) {
-    Parcel parcel;
-
-    MotionEvent inEvent;
-    initializeEventWithHistory(&inEvent);
-    MotionEvent outEvent;
-
-    // Round trip.
-    inEvent.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outEvent.readFromParcel(&parcel);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
-}
-
-TEST_F(MotionEventTest, Transform) {
-    // Generate some points on a circle.
-    // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
-    // of ARC * i degrees clockwise relative to the Y axis.
-    // The geometrical representation is irrelevant to the test, it's just easy to generate
-    // and check rotation.  We set the orientation to the same angle.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    const float PI_180 = float(M_PI / 180);
-    const float RADIUS = 10;
-    const float ARC = 36;
-    const float ROTATION = ARC * 2;
-
-    const size_t pointerCount = 11;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float(i * ARC * PI_180);
-        pointerProperties[i].clear();
-        pointerProperties[i].id = i;
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
-    }
-    MotionEvent event;
-    event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
-    float originalRawX = 0 + 3;
-    float originalRawY = -RADIUS + 2;
-
-    // Check original raw X and Y assumption.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Now translate the motion event so the circle's origin is at (0,0).
-    event.offsetLocation(-3, -2);
-
-    // Offsetting the location should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Apply a rotation about the origin by ROTATION degrees clockwise.
-    SkMatrix matrix;
-    matrix.setRotate(ROTATION);
-    event.transform(&matrix);
-
-    // Check the points.
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float((i * ARC + ROTATION) * PI_180);
-        ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
-        ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
-        ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
-    }
-
-    // Applying the transformation should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-}
-
-} // namespace android
diff --git a/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
deleted file mode 100644
index f45774b..0000000
--- a/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2010 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 <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/mman.h>
-#include <cutils/ashmem.h>
-
-#include "TestHelpers.h"
-
-namespace android {
-
-class InputPublisherAndConsumerTest : public testing::Test {
-protected:
-    sp<InputChannel> serverChannel, clientChannel;
-    InputPublisher* mPublisher;
-    InputConsumer* mConsumer;
-    PreallocatedInputEventFactory mEventFactory;
-
-    virtual void SetUp() {
-        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-                serverChannel, clientChannel);
-
-        mPublisher = new InputPublisher(serverChannel);
-        mConsumer = new InputConsumer(clientChannel);
-    }
-
-    virtual void TearDown() {
-        if (mPublisher) {
-            delete mPublisher;
-            mPublisher = NULL;
-        }
-
-        if (mConsumer) {
-            delete mConsumer;
-            mConsumer = NULL;
-        }
-
-        serverChannel.clear();
-        clientChannel.clear();
-    }
-
-    void PublishAndConsumeKeyEvent();
-    void PublishAndConsumeMotionEvent();
-};
-
-TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
-    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
-    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_KEYBOARD;
-    const int32_t action = AKEY_EVENT_ACTION_DOWN;
-    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
-    const int32_t keyCode = AKEYCODE_ENTER;
-    const int32_t scanCode = 13;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t repeatCount = 1;
-    const nsecs_t downTime = 3;
-    const nsecs_t eventTime = 4;
-
-    status = mPublisher->publishKeyEvent(seq, deviceId, source, action, flags,
-            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
-    ASSERT_EQ(OK, status)
-            << "publisher publishKeyEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
-            << "consumer should have returned a key event";
-
-    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
-    EXPECT_EQ(source, keyEvent->getSource());
-    EXPECT_EQ(action, keyEvent->getAction());
-    EXPECT_EQ(flags, keyEvent->getFlags());
-    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
-    EXPECT_EQ(scanCode, keyEvent->getScanCode());
-    EXPECT_EQ(metaState, keyEvent->getMetaState());
-    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
-    EXPECT_EQ(downTime, keyEvent->getDownTime());
-    EXPECT_EQ(eventTime, keyEvent->getEventTime());
-
-    status = mConsumer->sendFinishedSignal(seq, true);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = false;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_TRUE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
-    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
-    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
-    const float xOffset = -10;
-    const float yOffset = -20;
-    const float xPrecision = 0.25;
-    const float yPrecision = 0.5;
-    const nsecs_t downTime = 3;
-    const size_t pointerCount = 3;
-    const nsecs_t eventTime = 4;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerProperties[i].id = (i + 2) % pointerCount;
-        pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
-    }
-
-    status = mPublisher->publishMotionEvent(seq, deviceId, source, action, flags, edgeFlags,
-            metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
-            downTime, eventTime, pointerCount,
-            pointerProperties, pointerCoords);
-    ASSERT_EQ(OK, status)
-            << "publisher publishMotionEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
-            << "consumer should have returned a motion event";
-
-    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
-    EXPECT_EQ(source, motionEvent->getSource());
-    EXPECT_EQ(action, motionEvent->getAction());
-    EXPECT_EQ(flags, motionEvent->getFlags());
-    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
-    EXPECT_EQ(metaState, motionEvent->getMetaState());
-    EXPECT_EQ(buttonState, motionEvent->getButtonState());
-    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
-    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
-    EXPECT_EQ(downTime, motionEvent->getDownTime());
-    EXPECT_EQ(eventTime, motionEvent->getEventTime());
-    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
-    EXPECT_EQ(0U, motionEvent->getHistorySize());
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        SCOPED_TRACE(i);
-        EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
-        EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
-
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                motionEvent->getRawX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                motionEvent->getRawY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
-                motionEvent->getX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
-                motionEvent->getY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                motionEvent->getPressure(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                motionEvent->getSize(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                motionEvent->getTouchMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                motionEvent->getTouchMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                motionEvent->getToolMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                motionEvent->getToolMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
-                motionEvent->getOrientation(i));
-    }
-
-    status = mConsumer->sendFinishedSignal(seq, false);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = true;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_FALSE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = 0;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = MAX_POINTERS + 1;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerCoords[i].clear();
-    }
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-} // namespace android
diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h
deleted file mode 100644
index d8e985e..0000000
--- a/libs/androidfw/tests/TestHelpers.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 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 TESTHELPERS_H
-#define TESTHELPERS_H
-
-#include <utils/threads.h>
-
-namespace android {
-
-class Pipe {
-public:
-    int sendFd;
-    int receiveFd;
-
-    Pipe() {
-        int fds[2];
-        ::pipe(fds);
-
-        receiveFd = fds[0];
-        sendFd = fds[1];
-    }
-
-    ~Pipe() {
-        if (sendFd != -1) {
-            ::close(sendFd);
-        }
-
-        if (receiveFd != -1) {
-            ::close(receiveFd);
-        }
-    }
-
-    status_t writeSignal() {
-        ssize_t nWritten = ::write(sendFd, "*", 1);
-        return nWritten == 1 ? 0 : -errno;
-    }
-
-    status_t readSignal() {
-        char buf[1];
-        ssize_t nRead = ::read(receiveFd, buf, 1);
-        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
-    }
-};
-
-class DelayedTask : public Thread {
-    int mDelayMillis;
-
-public:
-    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
-
-protected:
-    virtual ~DelayedTask() { }
-
-    virtual void doTask() = 0;
-
-    virtual bool threadLoop() {
-        usleep(mDelayMillis * 1000);
-        doTask();
-        return false;
-    }
-};
-
-} // namespace android
-
-#endif // TESTHELPERS_H
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 01b3174..63a61e2 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -57,6 +57,8 @@
     frameworks/av/media/libstagefright/codecs/amrnb/common/include \
     frameworks/av/media/mtp \
     frameworks/native/include/media/openmax \
+    $(call include-path-for, libhardware)/hardware \
+    system/media/camera/include \
     $(PV_INCLUDES) \
     $(JNI_H_INCLUDE) \
     $(call include-path-for, corecg graphics)
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index bdb07a6..7866df4 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -24,6 +24,7 @@
 
 #include <gui/CpuConsumer.h>
 #include <gui/Surface.h>
+#include <camera3.h>
 
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
@@ -268,6 +269,29 @@
     return format;
 }
 
+static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer)
+{
+    ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
+    uint32_t size = 0;
+    uint32_t width = buffer->width;
+    uint8_t* jpegBuffer = buffer->data;
+
+    // First check for JPEG transport header at the end of the buffer
+    uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
+    struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header);
+    if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
+        size = blob->jpeg_size;
+        ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
+    }
+
+    // failed to find size, default to whole buffer
+    if (size == 0) {
+        size = width;
+    }
+
+    return size;
+}
+
 static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
                                 uint8_t **base, uint32_t *size)
 {
@@ -353,7 +377,7 @@
             ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height);
 
             pData = buffer->data;
-            dataSize = buffer->width;
+            dataSize = Image_getJpegSize(buffer);
             break;
         case HAL_PIXEL_FORMAT_RAW_SENSOR:
             // Single plane 16bpp bayer data.
@@ -624,8 +648,17 @@
 
     // Check if the producer buffer configurations match what ImageReader configured.
     // We want to fail for the very first image because this case is too bad.
-    int outputWidth = buffer->crop.getWidth() + 1;
-    int outputHeight = buffer->crop.getHeight() + 1;
+    int outputWidth = buffer->width;
+    int outputHeight = buffer->height;
+
+    // Correct with/height when crop is set.
+    if (buffer->crop.getWidth() > 0) {
+        outputWidth = buffer->crop.getWidth() + 1;
+    }
+    if (buffer->crop.getHeight() > 0) {
+        outputHeight = buffer->crop.getHeight() + 1;
+    }
+
     int imageReaderWidth = ctx->getBufferWidth();
     int imageReaderHeight = ctx->getBufferHeight();
     if ((imageReaderWidth != outputWidth) ||
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 207cc4b..cda38e0 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -20,6 +20,7 @@
     liblog \
     libcutils \
     libandroidfw \
+    libinput \
     libutils \
     libbinder \
     libui \
diff --git a/native/android/input.cpp b/native/android/input.cpp
index f6ea576..e9d08b4 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -18,8 +18,8 @@
 #include <utils/Log.h>
 
 #include <android/input.h>
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/Looper.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5838526..b65a9a0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2239,14 +2239,11 @@
             // Set default cdma call auto retry
             loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
 
-            // Set the preferred network mode to 0 = Global, CDMA default
+            // Set the preferred network mode to target desired value or Default
+            // value defined in RILConstants
             int type;
-            if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
-                type = Phone.NT_MODE_GLOBAL;
-            } else {
-                type = SystemProperties.getInt("ro.telephony.default_network",
+            type = SystemProperties.getInt("ro.telephony.default_network",
                         RILConstants.PREFERRED_NETWORK_MODE);
-            }
             loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
 
             // --- New global settings start here
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 71855b2..5a95f4c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -646,9 +646,6 @@
             }
         }
 
-        Slog.d(TAG, "openPanel: b9404689 setting isOpen true, st=" + st + " decorView="
-                + st.decorView);
-        st.isOpen = true;
         st.isHandled = false;
 
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -666,8 +663,11 @@
         }
 
         lp.windowAnimations = st.windowAnimations;
-        
+
         wm.addView(st.decorView, lp);
+        Slog.d(TAG, "openPanel: b9404689 setting isOpen true, st=" + st + " decorView="
+                + st.decorView);
+        st.isOpen = true;
         // Log.v(TAG, "Adding main menu to window manager.");
     }
 
@@ -696,7 +696,8 @@
      */
     public final void closePanel(PanelFeatureState st, boolean doCallback) {
         // System.out.println("Close panel: isOpen=" + st.isOpen);
-        Slog.d(TAG, "closePanel: b9404689 entry, st=" + st + " decorView=" + st.decorView);
+        Slog.d(TAG, "closePanel: b9404689 entry, st=" + st + " isOpen=" + st.isOpen
+                + " decorView=" + st.decorView + " Callers=" + Debug.getCallers(4));
         if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
                 mActionBar != null && mActionBar.isOverflowMenuShowing()) {
             checkCloseActionMenu(st.menu);
@@ -717,6 +718,8 @@
             if (doCallback) {
                 callOnPanelClosed(st.featureId, st, null);
             }
+        } else {
+            Slog.d(TAG, "closePanel: b9404689 not removing wm=" + wm);
         }
 
         st.isPrepared = false;
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 5d913f3..6e944ef 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -36,12 +36,13 @@
     libhardware_legacy \
     libskia \
     libgui \
-    libui
+    libui \
+    libinput
 
 LOCAL_C_INCLUDES := \
     external/skia/include/core
 
-LOCAL_MODULE:= libinput
+LOCAL_MODULE:= libinputservice
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 376de96..65749b3 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -36,9 +36,9 @@
 #include <errno.h>
 #include <assert.h>
 
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.h>
 
 #include <string.h>
 #include <stdint.h>
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index c93fc7a..daa1bea 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -18,12 +18,12 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputDevice.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/Input.h>
+#include <input/InputDevice.h>
+#include <input/Keyboard.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Log.h>
diff --git a/services/input/InputApplication.h b/services/input/InputApplication.h
index c04a935..1f5504c 100644
--- a/services/input/InputApplication.h
+++ b/services/input/InputApplication.h
@@ -17,7 +17,7 @@
 #ifndef _UI_INPUT_APPLICATION_H
 #define _UI_INPUT_APPLICATION_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 430721e..63ea781 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -17,8 +17,8 @@
 #ifndef _UI_INPUT_DISPATCHER_H
 #define _UI_INPUT_DISPATCHER_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
index cd7c25a..78ae10f 100644
--- a/services/input/InputListener.h
+++ b/services/input/InputListener.h
@@ -17,7 +17,7 @@
 #ifndef _UI_INPUT_LISTENER_H
 #define _UI_INPUT_LISTENER_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 
diff --git a/services/input/InputManager.h b/services/input/InputManager.h
index 29584c9..a213b2d 100644
--- a/services/input/InputManager.h
+++ b/services/input/InputManager.h
@@ -25,8 +25,8 @@
 #include "InputReader.h"
 #include "InputDispatcher.h"
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/Errors.h>
 #include <utils/Vector.h>
 #include <utils/Timers.h>
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index e229755..5b64d8a 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -42,8 +42,8 @@
 #include "InputReader.h"
 
 #include <cutils/log.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/Keyboard.h>
+#include <input/VirtualKeyMap.h>
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 0189ba7..7e303e4 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -21,9 +21,9 @@
 #include "PointerController.h"
 #include "InputListener.h"
 
-#include <androidfw/Input.h>
-#include <androidfw/VelocityControl.h>
-#include <androidfw/VelocityTracker.h>
+#include <input/Input.h>
+#include <input/VelocityControl.h>
+#include <input/VelocityTracker.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 7bd3af7..136870a 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -17,8 +17,8 @@
 #ifndef _UI_INPUT_WINDOW_H
 #define _UI_INPUT_WINDOW_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
 #include <utils/String8.h>
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index fd68b61..790c0bb 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -20,7 +20,7 @@
 #include "SpriteController.h"
 
 #include <ui/DisplayInfo.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/BitSet.h>
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
diff --git a/services/input/tests/Android.mk b/services/input/tests/Android.mk
index f3e2dee..9278f41 100644
--- a/services/input/tests/Android.mk
+++ b/services/input/tests/Android.mk
@@ -17,7 +17,8 @@
     libui \
     libskia \
     libstlport \
-    libinput
+    libinput \
+    libinputservice
 
 static_libraries := \
     libgtest \
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 54f6118..fc346a2 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -31,6 +31,9 @@
 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.bluetooth.BluetoothTetheringDataTracker;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -52,11 +55,13 @@
 import android.net.INetworkStatsService;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
+import android.net.Uri;
 import android.net.LinkProperties.CompareResult;
 import android.net.MobileDataStateTracker;
 import android.net.NetworkConfig;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkInfo.State;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkState;
 import android.net.NetworkStateTracker;
@@ -66,6 +71,7 @@
 import android.net.RouteInfo;
 import android.net.wifi.WifiStateTracker;
 import android.net.wimax.WimaxManagerConstants;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -79,6 +85,7 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -86,13 +93,16 @@
 import android.provider.Settings;
 import android.security.Credentials;
 import android.security.KeyStore;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseIntArray;
 
+import com.android.internal.R;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
+import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.util.IndentingPrintWriter;
@@ -112,9 +122,11 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
+import java.net.HttpURLConnection;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.URL;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -122,6 +134,8 @@
 import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @hide
@@ -142,6 +156,12 @@
     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
             "android.telephony.apn-restore";
 
+    // Default value if FAIL_FAST_TIME_MS is not set
+    private static final int DEFAULT_FAIL_FAST_TIME_MS = 1 * 60 * 1000;
+    // system property that can override DEFAULT_FAIL_FAST_TIME_MS
+    private static final String FAIL_FAST_TIME_MS =
+            "persist.radio.fail_fast_time_ms";
+
     // used in recursive route setting to add gateways for the host for which
     // a host route was requested.
     private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
@@ -293,6 +313,11 @@
 
     private static final int EVENT_VPN_STATE_CHANGED = 14;
 
+    /**
+     * Used internally to disable fail fast of mobile data
+     */
+    private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 15;
+
     /** Handler used for internal events. */
     private InternalHandler mHandler;
     /** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -348,6 +373,9 @@
     List mProtectedNetworks;
 
     private DataConnectionStats mDataConnectionStats;
+    private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
+
+    TelephonyManager mTelephonyManager;
 
     public ConnectivityService(Context context, INetworkManagementService netd,
             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
@@ -397,6 +425,7 @@
         mNetd = checkNotNull(netManager, "missing INetworkManagementService");
         mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
         mKeyStore = KeyStore.getInstance();
+        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
 
         try {
             mPolicyManager.registerListener(mPolicyListener);
@@ -1414,8 +1443,12 @@
                 netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
                 tracker.isTeardownRequested()) {
             if (VDBG) {
-                log("requestRouteToHostAddress on down network " +
-                           "(" + networkType + ") - dropped");
+                log("requestRouteToHostAddress on down network "
+                        + "(" + networkType + ") - dropped"
+                        + " tracker=" + tracker
+                        + " netState=" + netState
+                        + " isTeardownRequested="
+                            + ((tracker != null) ? tracker.isTeardownRequested() : "tracker:null"));
             }
             return false;
         }
@@ -1423,12 +1456,15 @@
         try {
             InetAddress addr = InetAddress.getByAddress(hostAddress);
             LinkProperties lp = tracker.getLinkProperties();
-            return addRouteToAddress(lp, addr);
+            boolean ok = addRouteToAddress(lp, addr);
+            if (DBG) log("requestRouteToHostAddress ok=" + ok);
+            return ok;
         } catch (UnknownHostException e) {
             if (DBG) log("requestRouteToHostAddress got " + e.toString());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+        if (DBG) log("requestRouteToHostAddress X bottom return false");
         return false;
     }
 
@@ -2830,6 +2866,19 @@
                     }
                     break;
                 }
+                case EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: {
+                    int tag = mEnableFailFastMobileDataTag.get();
+                    if (msg.arg1 == tag) {
+                        MobileDataStateTracker mobileDst =
+                            (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE];
+                        if (mobileDst != null) {
+                            mobileDst.setEnableFailFastMobileData(msg.arg2);
+                        }
+                    } else {
+                        log("EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: stale arg1:" + msg.arg1
+                                + " != tag:" + tag);
+                    }
+                }
             }
         }
     }
@@ -3484,4 +3533,460 @@
         }
         return ConnectivityManager.TYPE_NONE;
     }
+
+    /**
+     * Have mobile data fail fast if enabled.
+     *
+     * @param enabled DctConstants.ENABLED/DISABLED
+     */
+    private void setEnableFailFastMobileData(int enabled) {
+        int tag;
+
+        if (enabled == DctConstants.ENABLED) {
+            tag = mEnableFailFastMobileDataTag.incrementAndGet();
+        } else {
+            tag = mEnableFailFastMobileDataTag.get();
+        }
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_ENABLE_FAIL_FAST_MOBILE_DATA, tag,
+                         enabled));
+    }
+
+    @Override
+    public int checkMobileProvisioning(boolean sendNotification, int suggestedTimeOutMs,
+            final ResultReceiver resultReceiver) {
+        log("checkMobileProvisioning: E sendNotification=" + sendNotification
+                + " suggestedTimeOutMs=" + suggestedTimeOutMs
+                + " resultReceiver=" + resultReceiver);
+        enforceChangePermission();
+
+        int timeOutMs = suggestedTimeOutMs;
+        if (suggestedTimeOutMs > CheckMp.MAX_TIMEOUT_MS) {
+            timeOutMs = CheckMp.MAX_TIMEOUT_MS;
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            CheckMp checkMp = new CheckMp(mContext, this);
+            CheckMp.CallBack cb = new CheckMp.CallBack() {
+                @Override
+                void onComplete(Integer result) {
+                    log("CheckMp.onComplete: result=" + result);
+                    if (resultReceiver != null) {
+                        log("CheckMp.onComplete: send result");
+                        resultReceiver.send(result, null);
+                    }
+                    NetworkInfo ni =
+                            mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI].getNetworkInfo();
+                    switch(result) {
+                        case ConnectivityManager.CMP_RESULT_CODE_CONNECTABLE:
+                        case ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION: {
+                            log("CheckMp.onComplete: ignore, connected or no connection");
+                            break;
+                        }
+                        case ConnectivityManager.CMP_RESULT_CODE_REDIRECTED: {
+                            log("CheckMp.onComplete: warm sim");
+                            String url = getProvisioningUrl();
+                            if (TextUtils.isEmpty(url)) {
+                                url = mContext.getResources()
+                                        .getString(R.string.mobile_redirected_provisioning_url);
+                            }
+                            if (TextUtils.isEmpty(url) == false) {
+                                log("CheckMp.onComplete: warm sim (redirected), url=" + url);
+                                setNotificationVisible(true, ni, url);
+                            } else {
+                                log("CheckMp.onComplete: warm sim (redirected), no url");
+                            }
+                            break;
+                        }
+                        case ConnectivityManager.CMP_RESULT_CODE_NO_DNS:
+                        case ConnectivityManager.CMP_RESULT_CODE_NO_TCP_CONNECTION: {
+                            String url = getProvisioningUrl();
+                            if (TextUtils.isEmpty(url) == false) {
+                                log("CheckMp.onComplete: warm sim (no dns/tcp), url=" + url);
+                                setNotificationVisible(true, ni, url);
+                            } else {
+                                log("CheckMp.onComplete: warm sim (no dns/tcp), no url");
+                            }
+                            break;
+                        }
+                        default: {
+                            loge("CheckMp.onComplete: ignore unexpected result=" + result);
+                            break;
+                        }
+                    }
+                }
+            };
+            CheckMp.Params params =
+                    new CheckMp.Params(checkMp.getDefaultUrl(), timeOutMs, cb);
+            log("checkMobileProvisioning: params=" + params);
+            setNotificationVisible(false, null, null);
+            checkMp.execute(params);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+            log("checkMobileProvisioning: X");
+        }
+        return timeOutMs;
+    }
+
+    static class CheckMp extends
+            AsyncTask<CheckMp.Params, Void, Integer> {
+        private static final String CHECKMP_TAG = "CheckMp";
+        public static final int MAX_TIMEOUT_MS =  60000;
+        private static final int SOCKET_TIMEOUT_MS = 5000;
+        private Context mContext;
+        private ConnectivityService mCs;
+        private TelephonyManager mTm;
+        private Params mParams;
+
+        /**
+         * Parameters for AsyncTask.execute
+         */
+        static class Params {
+            private String mUrl;
+            private long mTimeOutMs;
+            private CallBack mCb;
+
+            Params(String url, long timeOutMs, CallBack cb) {
+                mUrl = url;
+                mTimeOutMs = timeOutMs;
+                mCb = cb;
+            }
+
+            @Override
+            public String toString() {
+                return "{" + " url=" + mUrl + " mTimeOutMs=" + mTimeOutMs + " mCb=" + mCb + "}";
+            }
+        }
+
+        /**
+         * The call back object passed in Params. onComplete will be called
+         * on the main thread.
+         */
+        abstract static class CallBack {
+            // Called on the main thread.
+            abstract void onComplete(Integer result);
+        }
+
+        public CheckMp(Context context, ConnectivityService cs) {
+            mContext = context;
+            mCs = cs;
+
+            // Setup access to TelephonyService we'll be using.
+            mTm = (TelephonyManager) mContext.getSystemService(
+                    Context.TELEPHONY_SERVICE);
+        }
+
+        /**
+         * Get the default url to use for the test.
+         */
+        public String getDefaultUrl() {
+            // See http://go/clientsdns for usage approval
+            String server = Settings.Global.getString(mContext.getContentResolver(),
+                    Settings.Global.CAPTIVE_PORTAL_SERVER);
+            if (server == null) {
+                server = "clients3.google.com";
+            }
+            return "http://" + server + "/generate_204";
+        }
+
+        /**
+         * Detect if its possible to connect to the http url. DNS based detection techniques
+         * do not work at all hotspots. The best way to check is to perform a request to
+         * a known address that fetches the data we expect.
+         */
+        private synchronized Integer isMobileOk(Params params) {
+            Integer result = ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION;
+            Uri orgUri = Uri.parse(params.mUrl);
+            Random rand = new Random();
+            mParams = params;
+
+            try {
+                if (mCs.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
+                    log("isMobileOk: not mobile capable");
+                    result = ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION;
+                    return result;
+                }
+
+                // Enable fail fast as we'll do retries here and use a
+                // hipri connection so the default connection stays active.
+                log("isMobileOk: start hipri url=" + params.mUrl);
+                mCs.setEnableFailFastMobileData(DctConstants.ENABLED);
+                mCs.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                        Phone.FEATURE_ENABLE_HIPRI, new Binder());
+
+                // Continue trying to connect until time has run out
+                long endTime = SystemClock.elapsedRealtime() + params.mTimeOutMs;
+                while(SystemClock.elapsedRealtime() < endTime) {
+                    try {
+                        // Wait for hipri to connect.
+                        // TODO: Don't poll and handle situation where hipri fails
+                        // because default is retrying. See b/9569540
+                        NetworkInfo.State state = mCs
+                                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
+                        if (state != NetworkInfo.State.CONNECTED) {
+                            log("isMobileOk: not connected ni=" +
+                                    mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI));
+                            sleep(1);
+                            result = ConnectivityManager.CMP_RESULT_CODE_NO_CONNECTION;
+                            continue;
+                        }
+
+                        // Get of the addresses associated with the url host. We need to use the
+                        // address otherwise HttpURLConnection object will use the name to get
+                        // the addresses and is will try every address but that will bypass the
+                        // route to host we setup and the connection could succeed as the default
+                        // interface might be connected to the internet via wifi or other interface.
+                        InetAddress[] addresses;
+                        try {
+                            addresses = InetAddress.getAllByName(orgUri.getHost());
+                        } catch (UnknownHostException e) {
+                            log("isMobileOk: UnknownHostException");
+                            result = ConnectivityManager.CMP_RESULT_CODE_NO_DNS;
+                            return result;
+                        }
+                        log("isMobileOk: addresses=" + inetAddressesToString(addresses));
+
+                        // Get the type of addresses supported by this link
+                        LinkProperties lp = mCs.getLinkProperties(
+                                ConnectivityManager.TYPE_MOBILE_HIPRI);
+                        boolean linkHasIpv4 = hasIPv4Address(lp);
+                        boolean linkHasIpv6 = hasIPv6Address(lp);
+                        log("isMobileOk: linkHasIpv4=" + linkHasIpv4
+                                + " linkHasIpv6=" + linkHasIpv6);
+
+                        // Loop through at most 3 valid addresses or all of the address or until
+                        // we run out of time
+                        int loops = Math.min(3, addresses.length);
+                        for(int validAddr=0, addrTried=0;
+                                    (validAddr < loops) && (addrTried < addresses.length)
+                                      && (SystemClock.elapsedRealtime() < endTime);
+                                addrTried ++) {
+
+                            // Choose the address at random but make sure its type is supported
+                            InetAddress hostAddr = addresses[rand.nextInt(addresses.length)];
+                            if (((hostAddr instanceof Inet4Address) && linkHasIpv4)
+                                    || ((hostAddr instanceof Inet6Address) && linkHasIpv6)) {
+                                // Valid address, so use it
+                                validAddr += 1;
+                            } else {
+                                // Invalid address so try next address
+                                continue;
+                            }
+
+                            // Make a route to host so we check the specific interface.
+                            if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
+                                    hostAddr.getAddress())) {
+                                // Wait a short time to be sure the route is established ??
+                                log("isMobileOk:"
+                                        + " wait to establish route to hostAddr=" + hostAddr);
+                                sleep(3);
+                            } else {
+                                log("isMobileOk:"
+                                        + " could not establish route to hostAddr=" + hostAddr);
+                                continue;
+                            }
+
+                            // Rewrite the url to have numeric address to use the specific route.
+                            // I also set the "Connection" to "Close" as by default "Keep-Alive"
+                            // is used which is useless in this case.
+                            URL newUrl = new URL(orgUri.getScheme() + "://"
+                                    + hostAddr.getHostAddress() + orgUri.getPath());
+                            log("isMobileOk: newUrl=" + newUrl);
+
+                            HttpURLConnection urlConn = null;
+                            try {
+                                // Open the connection set the request header and get the response
+                                urlConn = (HttpURLConnection) newUrl.openConnection(
+                                        java.net.Proxy.NO_PROXY);
+                                urlConn.setInstanceFollowRedirects(false);
+                                urlConn.setConnectTimeout(SOCKET_TIMEOUT_MS);
+                                urlConn.setReadTimeout(SOCKET_TIMEOUT_MS);
+                                urlConn.setUseCaches(false);
+                                urlConn.setAllowUserInteraction(false);
+                                urlConn.setRequestProperty("Connection", "close");
+                                int responseCode = urlConn.getResponseCode();
+                                if (responseCode == 204) {
+                                    result = ConnectivityManager.CMP_RESULT_CODE_CONNECTABLE;
+                                } else {
+                                    result = ConnectivityManager.CMP_RESULT_CODE_REDIRECTED;
+                                }
+                                log("isMobileOk: connected responseCode=" + responseCode);
+                                urlConn.disconnect();
+                                urlConn = null;
+                                return result;
+                            } catch (Exception e) {
+                                log("isMobileOk: HttpURLConnection Exception e=" + e);
+                                if (urlConn != null) {
+                                    urlConn.disconnect();
+                                    urlConn = null;
+                                }
+                            }
+                        }
+                        result = ConnectivityManager.CMP_RESULT_CODE_NO_TCP_CONNECTION;
+                        log("isMobileOk: loops|timed out");
+                        return result;
+                    } catch (Exception e) {
+                        log("isMobileOk: Exception e=" + e);
+                        continue;
+                    }
+                }
+                log("isMobileOk: timed out");
+            } finally {
+                log("isMobileOk: F stop hipri");
+                mCs.setEnableFailFastMobileData(DctConstants.DISABLED);
+                mCs.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                        Phone.FEATURE_ENABLE_HIPRI);
+                log("isMobileOk: X result=" + result);
+            }
+            return result;
+        }
+
+        @Override
+        protected Integer doInBackground(Params... params) {
+            return isMobileOk(params[0]);
+        }
+
+        @Override
+        protected void onPostExecute(Integer result) {
+            log("onPostExecute: result=" + result);
+            if ((mParams != null) && (mParams.mCb != null)) {
+                mParams.mCb.onComplete(result);
+            }
+        }
+
+        private String inetAddressesToString(InetAddress[] addresses) {
+            StringBuffer sb = new StringBuffer();
+            boolean firstTime = true;
+            for(InetAddress addr : addresses) {
+                if (firstTime) {
+                    firstTime = false;
+                } else {
+                    sb.append(",");
+                }
+                sb.append(addr);
+            }
+            return sb.toString();
+        }
+
+        private void printNetworkInfo() {
+            boolean hasIccCard = mTm.hasIccCard();
+            int simState = mTm.getSimState();
+            log("hasIccCard=" + hasIccCard
+                    + " simState=" + simState);
+            NetworkInfo[] ni = mCs.getAllNetworkInfo();
+            if (ni != null) {
+                log("ni.length=" + ni.length);
+                for (NetworkInfo netInfo: ni) {
+                    log("netInfo=" + netInfo.toString());
+                }
+            } else {
+                log("no network info ni=null");
+            }
+        }
+
+        /**
+         * Sleep for a few seconds then return.
+         * @param seconds
+         */
+        private static void sleep(int seconds) {
+            try {
+                Thread.sleep(seconds * 1000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        public boolean hasIPv4Address(LinkProperties lp) {
+            return lp.hasIPv4Address();
+        }
+
+        // Not implemented in LinkProperties, do it here.
+        public boolean hasIPv6Address(LinkProperties lp) {
+            for (LinkAddress address : lp.getLinkAddresses()) {
+              if (address.getAddress() instanceof Inet6Address) {
+                return true;
+              }
+            }
+            return false;
+        }
+
+        private void log(String s) {
+            Slog.d(ConnectivityService.TAG, "[" + CHECKMP_TAG + "] " + s);
+        }
+    }
+
+    private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
+
+    private void setNotificationVisible(boolean visible, NetworkInfo networkInfo, String url) {
+        log("setNotificationVisible: E visible=" + visible + " ni=" + networkInfo + " url=" + url);
+
+        Resources r = Resources.getSystem();
+        NotificationManager notificationManager = (NotificationManager) mContext
+            .getSystemService(Context.NOTIFICATION_SERVICE);
+
+        if (visible) {
+            CharSequence title;
+            CharSequence details;
+            int icon;
+            switch (networkInfo.getType()) {
+                case ConnectivityManager.TYPE_WIFI:
+                    log("setNotificationVisible: TYPE_WIFI");
+                    title = r.getString(R.string.wifi_available_sign_in, 0);
+                    details = r.getString(R.string.network_available_sign_in_detailed,
+                            networkInfo.getExtraInfo());
+                    icon = R.drawable.stat_notify_wifi_in_range;
+                    break;
+                case ConnectivityManager.TYPE_MOBILE:
+                case ConnectivityManager.TYPE_MOBILE_HIPRI:
+                    log("setNotificationVisible: TYPE_MOBILE|HIPRI");
+                    title = r.getString(R.string.network_available_sign_in, 0);
+                    // TODO: Change this to pull from NetworkInfo once a printable
+                    // name has been added to it
+                    details = mTelephonyManager.getNetworkOperatorName();
+                    icon = R.drawable.stat_notify_rssi_in_range;
+                    break;
+                default:
+                    log("setNotificationVisible: other type=" + networkInfo.getType());
+                    title = r.getString(R.string.network_available_sign_in, 0);
+                    details = r.getString(R.string.network_available_sign_in_detailed,
+                            networkInfo.getExtraInfo());
+                    icon = R.drawable.stat_notify_rssi_in_range;
+                    break;
+            }
+
+            Notification notification = new Notification();
+            notification.when = 0;
+            notification.icon = icon;
+            notification.flags = Notification.FLAG_AUTO_CANCEL;
+            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+            intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                    Intent.FLAG_ACTIVITY_NEW_TASK);
+            notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+            notification.tickerText = title;
+            notification.setLatestEventInfo(mContext, title, details, notification.contentIntent);
+
+            log("setNotificaitionVisible: notify notificaiton=" + notification);
+            notificationManager.notify(NOTIFICATION_ID, 1, notification);
+        } else {
+            log("setNotificaitionVisible: cancel");
+            notificationManager.cancel(NOTIFICATION_ID, 1);
+        }
+        log("setNotificationVisible: X visible=" + visible + " ni=" + networkInfo + " url=" + url);
+    }
+
+    private String getProvisioningUrl() {
+        String url = mContext.getResources().getString(R.string.mobile_provisioning_url);
+        log("getProvisioningUrl: resource url=" + url);
+
+        // populate the iccid and imei in the provisioning url.
+        if (!TextUtils.isEmpty(url)) {
+            url = String.format(url,
+                    mTelephonyManager.getSimSerialNumber() /* ICCID */,
+                    mTelephonyManager.getDeviceId() /* IMEI */,
+                    mTelephonyManager.getLine1Number() /* Phone numer */);
+        }
+
+        log("getProvisioningUrl: url=" + url);
+        return url;
+    }
 }
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index faa72a2..e0f415b 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -417,7 +417,15 @@
                 int keyId = clientInfo.mClientIds.indexOfValue(id);
                 if (keyId != -1) {
                     clientId = clientInfo.mClientIds.keyAt(keyId);
+                } else {
+                    // This can happen because of race conditions. For example,
+                    // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
+                    // and we may get in this situation.
+                    Slog.d(TAG, "Notification for a listener that is no longer active: " + id);
+                    handled = false;
+                    return handled;
                 }
+
                 switch (code) {
                     case NativeResponseCode.SERVICE_FOUND:
                         /* NNN uniqueId serviceName regType domain */
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9c98848..72be39b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2007,7 +2007,6 @@
                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
                                             st.rel_stime-otherSTime);
                                     ps.addSpeedStepTimes(cpuSpeedTimes);
-                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
                                 } else {
                                     BatteryStatsImpl.Uid.Proc ps =
                                             bstats.getProcessStatsLocked(st.name, st.pid);
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 92a1523..9afac2c 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -259,7 +259,9 @@
         if (prev != null) {
             prev.mLaunchHomeTaskNext = false;
         }
-        if (mHomeStack.topRunningActivityLocked(null) != null) {
+        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
+        if (r != null) {
+            mService.setFocusedActivityLocked(r);
             return resumeTopActivitiesLocked(mHomeStack, prev, null);
         }
         return mService.startHomeActivityLocked(mCurrentUser);
diff --git a/services/java/com/android/server/connectivity/Nat464Xlat.java b/services/java/com/android/server/connectivity/Nat464Xlat.java
index 59403c5..a15d678 100644
--- a/services/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/java/com/android/server/connectivity/Nat464Xlat.java
@@ -147,17 +147,24 @@
                    " added, mIsRunning = " + mIsRunning + " -> true");
             mIsRunning = true;
 
-            // Get the network configuration of the clat interface, store it
-            // in our link properties, and stack it on top of the interface
-            // it's running on.
+            // Create the LinkProperties for the clat interface by fetching the
+            // IPv4 address for the interface and adding an IPv4 default route,
+            // then stack the LinkProperties on top of the link it's running on.
+            // Although the clat interface is a point-to-point tunnel, we don't
+            // point the route directly at the interface because some apps don't
+            // understand routes without gateways (see, e.g., http://b/9597256
+            // http://b/9597516). Instead, set the next hop of the route to the
+            // clat IPv4 address itself (for those apps, it doesn't matter what
+            // the IP of the gateway is, only that there is one).
             try {
                 InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
+                LinkAddress clatAddress = config.getLinkAddress();
                 mLP.clear();
                 mLP.setInterfaceName(iface);
-                RouteInfo ipv4Default = new RouteInfo(new LinkAddress(Inet4Address.ANY, 0), null,
-                                                      iface);
+                RouteInfo ipv4Default = new RouteInfo(new LinkAddress(Inet4Address.ANY, 0),
+                                                      clatAddress.getAddress(), iface);
                 mLP.addRoute(ipv4Default);
-                mLP.addLinkAddress(config.getLinkAddress());
+                mLP.addLinkAddress(clatAddress);
                 mTracker.addStackedLink(mLP);
                 Slog.i(TAG, "Adding stacked link. tracker LP: " +
                        mTracker.getLinkProperties());
diff --git a/services/java/com/android/server/wifi/WifiController.java b/services/java/com/android/server/wifi/WifiController.java
index 87b4394..4594fa67 100644
--- a/services/java/com/android/server/wifi/WifiController.java
+++ b/services/java/com/android/server/wifi/WifiController.java
@@ -379,6 +379,9 @@
 
         @Override
         public void enter() {
+
+            if (DBG) logd("Going to disabled without scan state");
+
             mWifiStateMachine.setSupplicantRunning(false);
             // Supplicant can't restart right away, so not the time we switched off
             mDisabledTimestamp = SystemClock.elapsedRealtime();
@@ -496,6 +499,9 @@
 
         @Override
         public void enter() {
+
+            if (DBG) logd("Enabling disabled with scan state");
+
             mWifiStateMachine.setSupplicantRunning(true);
             mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
             mWifiStateMachine.setDriverStart(true);
diff --git a/services/java/com/android/server/wifi/WifiSettingsStore.java b/services/java/com/android/server/wifi/WifiSettingsStore.java
index 3ff8061..f5c6ec3 100644
--- a/services/java/com/android/server/wifi/WifiSettingsStore.java
+++ b/services/java/com/android/server/wifi/WifiSettingsStore.java
@@ -51,7 +51,7 @@
         mContext = context;
         mAirplaneModeOn = getPersistedAirplaneModeOn();
         mPersistWifiState = getPersistedWifiState();
-        mScanAlwaysAvailable = getPersistedScanAlwaysAvailable();
+        mScanAlwaysAvailable = false; // getPersistedScanAlwaysAvailable();
     }
 
     synchronized boolean isWifiToggleEnabled() {
@@ -124,7 +124,8 @@
     }
 
     synchronized void handleWifiScanAlwaysAvailableToggled() {
-        mScanAlwaysAvailable = getPersistedScanAlwaysAvailable();
+        // mScanAlwaysAvailable = getPersistedScanAlwaysAvailable();
+        mScanAlwaysAvailable = false;
     }
 
     void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index e416676..f332350 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -41,6 +41,7 @@
     libutils \
     libui \
     libinput \
+    libinputservice \
     libskia \
     libgui \
     libusbhost \
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 9d556c0..4d8342c 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -93,6 +93,7 @@
     public static final int EVENT_ICC_CHANGED = BASE + 33;
     public static final int EVENT_DISCONNECT_DC_RETRYING = BASE + 34;
     public static final int EVENT_DATA_SETUP_COMPLETE_ERROR = BASE + 35;
+    public static final int CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA = BASE + 36;
 
     /***** Constants *****/
 
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 3b49819..452c60a 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -83,20 +83,19 @@
 LOCAL_C_INCLUDES += external/libpng
 LOCAL_C_INCLUDES += external/zlib
 
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
 LOCAL_CFLAGS += -Wno-non-virtual-dtor
 
 LOCAL_SHARED_LIBRARIES := \
+        libandroidfw \
+        libutils \
+        libcutils \
         libpng \
+        liblog \
         libz
 
 LOCAL_STATIC_LIBRARIES := \
         libstlport_static \
-        libandroidfw \
-        libutils \
-        libcutils \
-        libexpat_static \
-        liblog
+        libexpat_static
 
 include $(BUILD_EXECUTABLE)
 endif
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
index 90fbc08..9af721d 100644
--- a/tools/validatekeymaps/Android.mk
+++ b/tools/validatekeymaps/Android.mk
@@ -15,10 +15,8 @@
 
 LOCAL_CFLAGS := -Wall -Werror
 
-#LOCAL_C_INCLUDES +=
-
 LOCAL_STATIC_LIBRARIES := \
-	libandroidfw \
+	libinput \
 	libutils \
 	libcutils \
 	liblog
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 91e4fda..5b45c55 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/KeyLayoutMap.h>
+#include <input/VirtualKeyMap.h>
 #include <utils/PropertyMap.h>
 #include <utils/String8.h>