Merge "always pass the BufferQueue explicitely to consumers"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 8e6998f..7710c5b 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -95,6 +95,7 @@
 
     run_command("PROCESSES", 10, "ps", "-P", NULL);
     run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
+    run_command("PROCESSES (SELINUX LABELS)", 10, "ps", "-Z", NULL);
     run_command("LIBRANK", 10, "librank", NULL);
 
     do_dmesg();
diff --git a/cmds/inputflinger/Android.mk b/cmds/inputflinger/Android.mk
new file mode 100644
index 0000000..b44de44
--- /dev/null
+++ b/cmds/inputflinger/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	libinputflinger \
+	libutils
+
+LOCAL_MODULE := inputflinger
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/inputflinger/main.cpp b/cmds/inputflinger/main.cpp
new file mode 100644
index 0000000..6de7b24
--- /dev/null
+++ b/cmds/inputflinger/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 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 <binder/BinderService.h>
+#include <InputFlinger.h>
+
+using namespace android;
+
+int main(int argc, char** argv) {
+    ProcessState::self()->setThreadPoolMaxThreadCount(4);
+    BinderService<InputFlinger>::publishAndJoinThreadPool(true);
+    return 0;
+}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 27580f3..84ad204 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -108,11 +108,11 @@
     return 0;
 }
 
-int uninstall(const char *pkgname, uid_t persona)
+int uninstall(const char *pkgname, userid_t userid)
 {
     char pkgdir[PKG_PATH_MAX];
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
+    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
         return -1;
 
     /* delete contents AND directory, no exceptions */
@@ -173,18 +173,18 @@
     return 0;
 }
 
-int delete_user_data(const char *pkgname, uid_t persona)
+int delete_user_data(const char *pkgname, userid_t userid)
 {
     char pkgdir[PKG_PATH_MAX];
 
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
+    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
         return -1;
 
     /* delete contents, excluding "lib", but not the directory itself */
     return delete_dir_contents(pkgdir, 0, "lib");
 }
 
-int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
+int make_user_data(const char *pkgname, uid_t uid, userid_t userid)
 {
     char pkgdir[PKG_PATH_MAX];
     char applibdir[PKG_PATH_MAX];
@@ -192,10 +192,10 @@
     struct stat libStat;
 
     // Create the data dir for the package
-    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) {
+    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) {
         return -1;
     }
-    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) {
+    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) {
         ALOGE("cannot create package lib symlink origin path\n");
         return -1;
     }
@@ -262,10 +262,10 @@
     return 0;
 }
 
-int delete_persona(uid_t persona)
+int delete_user(userid_t userid)
 {
     char data_path[PKG_PATH_MAX];
-    if (create_persona_path(data_path, persona)) {
+    if (create_user_path(data_path, userid)) {
         return -1;
     }
     if (delete_dir_contents(data_path, 1, NULL)) {
@@ -273,7 +273,7 @@
     }
 
     char media_path[PATH_MAX];
-    if (create_persona_media_path(media_path, (userid_t) persona) == -1) {
+    if (create_user_media_path(media_path, userid) == -1) {
         return -1;
     }
     if (delete_dir_contents(media_path, 1, NULL) == -1) {
@@ -283,11 +283,11 @@
     return 0;
 }
 
-int delete_cache(const char *pkgname, uid_t persona)
+int delete_cache(const char *pkgname, userid_t userid)
 {
     char cachedir[PKG_PATH_MAX];
 
-    if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, persona))
+    if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid))
         return -1;
 
         /* delete contents, not the directory, no exceptions */
@@ -319,7 +319,7 @@
     cache = start_cache_collection();
 
     // Collect cache files for primary user.
-    if (create_persona_path(tmpdir, 0) == 0) {
+    if (create_user_path(tmpdir, 0) == 0) {
         //ALOGI("adding cache files from %s\n", tmpdir);
         add_cache_files(cache, tmpdir, "cache");
     }
@@ -420,7 +420,7 @@
     }
 }
 
-int get_size(const char *pkgname, int persona, const char *apkpath,
+int get_size(const char *pkgname, userid_t userid, const char *apkpath,
              const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
              int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize,
              int64_t* _asecsize)
@@ -477,7 +477,7 @@
         }
     }
 
-    if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, persona)) {
+    if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) {
         goto done;
     }
 
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 87f900a..1904408 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -83,7 +83,7 @@
     int64_t asecsize = 0;
     int res = 0;
 
-        /* pkgdir, persona, apkpath */
+        /* pkgdir, userid, apkpath */
     res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5],
             &codesize, &datasize, &cachesize, &asecsize);
 
@@ -108,7 +108,7 @@
 
 static int do_rm_user(char **arg, char reply[REPLY_MAX])
 {
-    return delete_persona(atoi(arg[0])); /* userid */
+    return delete_user(atoi(arg[0])); /* userid */
 }
 
 static int do_movefiles(char **arg, char reply[REPLY_MAX])
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index fbfc876..635b07c 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -78,9 +78,6 @@
 #define PKG_NAME_MAX  128   /* largest allowed package name */
 #define PKG_PATH_MAX  256   /* max size of any path we use */
 
-#define PER_USER_RANGE ((uid_t)100000)   /* range of uids per user
-                                            uid = persona * PER_USER_RANGE + appid */
-
 /* data structures */
 
 typedef struct {
@@ -138,17 +135,17 @@
 int create_pkg_path(char path[PKG_PATH_MAX],
                     const char *pkgname,
                     const char *postfix,
-                    uid_t persona);
+                    userid_t userid);
 
-int create_persona_path(char path[PKG_PATH_MAX],
-                    uid_t persona);
+int create_user_path(char path[PKG_PATH_MAX],
+                    userid_t userid);
 
-int create_persona_media_path(char path[PKG_PATH_MAX], userid_t userid);
+int create_user_media_path(char path[PKG_PATH_MAX], userid_t userid);
 
 int create_move_path(char path[PKG_PATH_MAX],
                      const char* pkgname,
                      const char* leaf,
-                     uid_t persona);
+                     userid_t userid);
 
 int is_valid_package_name(const char* pkgname);
 
@@ -193,17 +190,17 @@
 /* commands.c */
 
 int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo);
-int uninstall(const char *pkgname, uid_t persona);
+int uninstall(const char *pkgname, userid_t userid);
 int renamepkg(const char *oldpkgname, const char *newpkgname);
 int fix_uid(const char *pkgname, uid_t uid, gid_t gid);
-int delete_user_data(const char *pkgname, uid_t persona);
-int make_user_data(const char *pkgname, uid_t uid, uid_t persona);
-int delete_persona(uid_t persona);
-int delete_cache(const char *pkgname, uid_t persona);
+int delete_user_data(const char *pkgname, userid_t userid);
+int make_user_data(const char *pkgname, uid_t uid, userid_t userid);
+int delete_user(userid_t userid);
+int delete_cache(const char *pkgname, userid_t userid);
 int move_dex(const char *src, const char *dst);
 int rm_dex(const char *path);
 int protect(char *pkgname, gid_t gid);
-int get_size(const char *pkgname, int persona, const char *apkpath, const char *libdirpath,
+int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
              const char *fwdlock_apkpath, const char *asecpath, int64_t *codesize,
              int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
 int free_cache(int64_t free_size);
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 7cb9b37..0b182af 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -340,7 +340,7 @@
 TEST_F(UtilsTest, CreatePersonaPath_Primary) {
     char path[PKG_PATH_MAX];
 
-    EXPECT_EQ(0, create_persona_path(path, 0))
+    EXPECT_EQ(0, create_user_path(path, 0))
             << "Should successfully build primary user path.";
 
     EXPECT_STREQ("/data/data/", path)
@@ -350,7 +350,7 @@
 TEST_F(UtilsTest, CreatePersonaPath_Secondary) {
     char path[PKG_PATH_MAX];
 
-    EXPECT_EQ(0, create_persona_path(path, 1))
+    EXPECT_EQ(0, create_user_path(path, 1))
             << "Should successfully build primary user path.";
 
     EXPECT_STREQ("/data/user/1/", path)
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 625a35e..ef634c6 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -53,38 +53,39 @@
 
 /**
  * Create the package path name for a given package name with a postfix for
- * a certain persona. Returns 0 on success, and -1 on failure.
+ * a certain userid. Returns 0 on success, and -1 on failure.
  */
 int create_pkg_path(char path[PKG_PATH_MAX],
                     const char *pkgname,
                     const char *postfix,
-                    uid_t persona)
+                    userid_t userid)
 {
-    size_t uid_len;
-    char* persona_prefix;
-    if (persona == 0) {
-        persona_prefix = PRIMARY_USER_PREFIX;
-        uid_len = 0;
+    size_t userid_len;
+    char* userid_prefix;
+    if (userid == 0) {
+        userid_prefix = PRIMARY_USER_PREFIX;
+        userid_len = 0;
     } else {
-        persona_prefix = SECONDARY_USER_PREFIX;
-        uid_len = snprintf(NULL, 0, "%d", persona);
+        userid_prefix = SECONDARY_USER_PREFIX;
+        userid_len = snprintf(NULL, 0, "%d", userid);
     }
 
-    const size_t prefix_len = android_data_dir.len + strlen(persona_prefix) + uid_len + 1 /*slash*/;
+    const size_t prefix_len = android_data_dir.len + strlen(userid_prefix)
+            + userid_len + 1 /*slash*/;
     char prefix[prefix_len + 1];
 
     char *dst = prefix;
     size_t dst_size = sizeof(prefix);
 
     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
-            || append_and_increment(&dst, persona_prefix, &dst_size) < 0) {
+            || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
         ALOGE("Error building prefix for APK path");
         return -1;
     }
 
-    if (persona != 0) {
-        int ret = snprintf(dst, dst_size, "%d/", persona);
-        if (ret < 0 || (size_t) ret != uid_len + 1) {
+    if (userid != 0) {
+        int ret = snprintf(dst, dst_size, "%d/", userid);
+        if (ret < 0 || (size_t) ret != userid_len + 1) {
             ALOGW("Error appending UID to APK path");
             return -1;
         }
@@ -98,39 +99,39 @@
 }
 
 /**
- * Create the path name for user data for a certain persona.
+ * Create the path name for user data for a certain userid.
  * Returns 0 on success, and -1 on failure.
  */
-int create_persona_path(char path[PKG_PATH_MAX],
-                    uid_t persona)
+int create_user_path(char path[PKG_PATH_MAX],
+                    userid_t userid)
 {
-    size_t uid_len;
-    char* persona_prefix;
-    if (persona == 0) {
-        persona_prefix = PRIMARY_USER_PREFIX;
-        uid_len = 0;
+    size_t userid_len;
+    char* userid_prefix;
+    if (userid == 0) {
+        userid_prefix = PRIMARY_USER_PREFIX;
+        userid_len = 0;
     } else {
-        persona_prefix = SECONDARY_USER_PREFIX;
-        uid_len = snprintf(NULL, 0, "%d/", persona);
+        userid_prefix = SECONDARY_USER_PREFIX;
+        userid_len = snprintf(NULL, 0, "%d/", userid);
     }
 
     char *dst = path;
     size_t dst_size = PKG_PATH_MAX;
 
     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
-            || append_and_increment(&dst, persona_prefix, &dst_size) < 0) {
+            || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
         ALOGE("Error building prefix for user path");
         return -1;
     }
 
-    if (persona != 0) {
-        if (dst_size < uid_len + 1) {
+    if (userid != 0) {
+        if (dst_size < userid_len + 1) {
             ALOGE("Error building user path");
             return -1;
         }
-        int ret = snprintf(dst, dst_size, "%d/", persona);
-        if (ret < 0 || (size_t) ret != uid_len) {
-            ALOGE("Error appending persona id to path");
+        int ret = snprintf(dst, dst_size, "%d/", userid);
+        if (ret < 0 || (size_t) ret != userid_len) {
+            ALOGE("Error appending userid to path");
             return -1;
         }
     }
@@ -138,10 +139,10 @@
 }
 
 /**
- * Create the path name for media for a certain persona.
+ * Create the path name for media for a certain userid.
  * Returns 0 on success, and -1 on failure.
  */
-int create_persona_media_path(char path[PATH_MAX], userid_t userid) {
+int create_user_media_path(char path[PATH_MAX], userid_t userid) {
     if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
         return -1;
     }
@@ -151,7 +152,7 @@
 int create_move_path(char path[PKG_PATH_MAX],
     const char* pkgname,
     const char* leaf,
-    uid_t persona)
+    userid_t userid)
 {
     if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1)
             >= PKG_PATH_MAX) {
@@ -997,7 +998,7 @@
     char path[PATH_MAX];
 
     // Ensure /data/media/<userid> exists
-    create_persona_media_path(media_user_path, userid);
+    create_user_media_path(media_user_path, userid);
     if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
         return -1;
     }
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index cf38d1a..1ca1332 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -265,6 +265,7 @@
     AKEYCODE_ASSIST          = 219,
     AKEYCODE_BRIGHTNESS_DOWN = 220,
     AKEYCODE_BRIGHTNESS_UP   = 221,
+    AKEYCODE_MEDIA_AUDIO_TRACK = 222,
 
     // 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.
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index ad0daee..5bc123e 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -39,8 +39,8 @@
             
             status_t            clearLastError();
 
-            int                 getCallingPid();
-            int                 getCallingUid();
+            int                 getCallingPid() const;
+            int                 getCallingUid() const;
 
             void                setStrictModePolicy(int32_t policy);
             int32_t             getStrictModePolicy() const;
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
new file mode 100644
index 0000000..79ff12a
--- /dev/null
+++ b/include/input/IInputFlinger.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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 _LIBINPUT_IINPUT_FLINGER_H
+#define _LIBINPUT_IINPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+/*
+ * This class defines the Binder IPC interface for accessing various
+ * InputFlinger features.
+ */
+class IInputFlinger : public IInterface {
+public:
+    DECLARE_META_INTERFACE(InputFlinger);
+
+    virtual status_t doSomething() = 0;
+};
+
+
+/**
+ * Binder implementation.
+ */
+class BnInputFlinger : public BnInterface<IInputFlinger> {
+public:
+    enum {
+        DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+    };
+
+    virtual status_t onTransact(uint32_t code, const Parcel& data,
+            Parcel* reply, uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_IINPUT_FLINGER_H
diff --git a/include/input/Input.h b/include/input/Input.h
index 6d49b18..e778076 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -28,10 +28,6 @@
 #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.
  */
@@ -529,9 +525,11 @@
 
     void scale(float scaleFactor);
 
-#ifdef HAVE_ANDROID_OS
-    void transform(const SkMatrix* matrix);
+    // Apply 3x3 perspective matrix transformation.
+    // Matrix is in row-major form and compatible with SkMatrix.
+    void transform(const float matrix[9]);
 
+#ifdef HAVE_ANDROID_OS
     status_t readFromParcel(Parcel* parcel);
     status_t writeToParcel(Parcel* parcel) const;
 #endif
diff --git a/include/input/KeycodeLabels.h b/include/input/KeycodeLabels.h
index c76ba12..c64c5d8 100644
--- a/include/input/KeycodeLabels.h
+++ b/include/input/KeycodeLabels.h
@@ -246,6 +246,7 @@
     { "ASSIST", 219 },
     { "BRIGHTNESS_DOWN", 220 },
     { "BRIGHTNESS_UP", 221 },
+    { "MEDIA_AUDIO_TRACK", 222 },
 
     // 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.
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 5a38b95..5951a3f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -362,12 +362,12 @@
     return err;
 }
 
-int IPCThreadState::getCallingPid()
+int IPCThreadState::getCallingPid() const
 {
     return mCallingPid;
 }
 
-int IPCThreadState::getCallingUid()
+int IPCThreadState::getCallingUid() const
 {
     return mCallingUid;
 }
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index 2a1e762..944ac7f 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ifneq ($(TARGET_BUILD_PDK),true)
-
 LOCAL_PATH:= $(call my-dir)
 
 # libinput is partially built for the host (used by build time keymap validation tool)
@@ -29,6 +27,7 @@
 
 deviceSources := \
     $(commonSources) \
+    IInputFlinger.cpp \
     InputTransport.cpp \
     VelocityControl.cpp \
     VelocityTracker.cpp
@@ -61,14 +60,7 @@
 	liblog \
 	libcutils \
 	libutils \
-	libbinder \
-	libskia \
-	libz
-
-LOCAL_C_INCLUDES := \
-    external/skia/include/core \
-    external/icu4c/common \
-	external/zlib
+	libbinder
 
 LOCAL_MODULE:= libinput
 
@@ -85,5 +77,3 @@
 ifeq (,$(ONE_SHOT_MAKEFILE))
 include $(call first-makefiles-under,$(LOCAL_PATH))
 endif
-
-endif #!PDK
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
new file mode 100644
index 0000000..e009731
--- /dev/null
+++ b/libs/input/IInputFlinger.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 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 <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <input/IInputFlinger.h>
+
+
+namespace android {
+
+class BpInputFlinger : public BpInterface<IInputFlinger> {
+public:
+    BpInputFlinger(const sp<IBinder>& impl) :
+            BpInterface<IInputFlinger>(impl) { }
+
+    virtual status_t doSomething() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
+        remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger");
+
+
+status_t BnInputFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    switch(code) {
+    case DO_SOMETHING_TRANSACTION: {
+        CHECK_INTERFACE(IInputFlinger, data, reply);
+        reply->writeInt32(0);
+        break;
+    }
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+    return NO_ERROR;
+}
+
+};
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 7a217c3..6f53996 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -24,10 +24,6 @@
 
 #ifdef HAVE_ANDROID_OS
 #include <binder/Parcel.h>
-
-#include "SkPoint.h"
-#include "SkMatrix.h"
-#include "SkScalar.h"
 #endif
 
 namespace android {
@@ -74,6 +70,7 @@
         case AKEYCODE_MUTE:
         case AKEYCODE_BRIGHTNESS_DOWN:
         case AKEYCODE_BRIGHTNESS_UP:
+        case AKEYCODE_MEDIA_AUDIO_TRACK:
             return true;
     }
     
@@ -112,6 +109,7 @@
         case AKEYCODE_SEARCH:
         case AKEYCODE_BRIGHTNESS_DOWN:
         case AKEYCODE_BRIGHTNESS_UP:
+        case AKEYCODE_MEDIA_AUDIO_TRACK:
             return true;
     }
     
@@ -421,17 +419,30 @@
     }
 }
 
-#ifdef HAVE_ANDROID_OS
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
+static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
+    // Apply perspective transform like Skia.
+    float newX = matrix[0] * x + matrix[1] * y + matrix[2];
+    float newY = matrix[3] * x + matrix[4] * y + matrix[5];
+    float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
+    if (newZ) {
+        newZ = 1.0f / newZ;
+    }
+    *outX = newX * newZ;
+    *outY = newY * newZ;
+}
+
+static float transformAngle(const float matrix[9], float angleRadians,
+        float originX, float originY) {
     // 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);
+    float x = sinf(angleRadians);
+    float y = -cosf(angleRadians);
+    transformPoint(matrix, x, y, &x, &y);
+    x -= originX;
+    y -= originY;
 
     // Derive the transformed vector's clockwise angle from vertical.
-    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
+    float result = atan2f(x, -y);
     if (result < - M_PI_2) {
         result += M_PI;
     } else if (result > M_PI_2) {
@@ -440,25 +451,24 @@
     return result;
 }
 
-void MotionEvent::transform(const SkMatrix* matrix) {
-    float oldXOffset = mXOffset;
-    float oldYOffset = mYOffset;
-
+void MotionEvent::transform(const float matrix[9]) {
     // 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;
+    // then derive an appropriate new X/Y offset that will preserve rawX
+     // and rawY for that point.
+    float oldXOffset = mXOffset;
+    float oldYOffset = mYOffset;
+    float newX, newY;
     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;
+    transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
+    mXOffset = newX - rawX;
+    mYOffset = newY - rawY;
 
-    mXOffset = newXOffset;
-    mYOffset = newYOffset;
+    // Determine how the origin is transformed by the matrix so that we
+    // can transform orientation vectors.
+    float originX, originY;
+    transformPoint(matrix, 0, 0, &originX, &originY);
 
     // Apply the transformation to all samples.
     size_t numSamples = mSamplePointerCoords.size();
@@ -466,15 +476,17 @@
         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);
+        transformPoint(matrix, x, y, &x, &y);
+        c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
+        c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
 
         float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
-        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
+        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
+                transformAngle(matrix, orientation, originX, originY));
     }
 }
 
+#ifdef HAVE_ANDROID_OS
 status_t MotionEvent::readFromParcel(Parcel* parcel) {
     size_t pointerCount = parcel->readInt32();
     size_t sampleCount = parcel->readInt32();
diff --git a/libs/input/tests/Android.mk b/libs/input/tests/Android.mk
index 4292741..c62dff1 100644
--- a/libs/input/tests/Android.mk
+++ b/libs/input/tests/Android.mk
@@ -14,8 +14,7 @@
     libutils \
     libbinder \
     libui \
-    libstlport \
-    libskia
+    libstlport
 
 static_libraries := \
     libgtest \
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index ab1feb3..78ea98e 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -17,7 +17,6 @@
 #include <math.h>
 
 #include <binder/Parcel.h>
-#include <core/SkMatrix.h>
 #include <gtest/gtest.h>
 #include <input/Input.h>
 
@@ -519,6 +518,20 @@
     ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
 }
 
+static void setRotationMatrix(float matrix[9], float angle) {
+    float sin = sinf(angle);
+    float cos = cosf(angle);
+    matrix[0] = cos;
+    matrix[1] = -sin;
+    matrix[2] = 0;
+    matrix[3] = sin;
+    matrix[4] = cos;
+    matrix[5] = 0;
+    matrix[6] = 0;
+    matrix[7] = 0;
+    matrix[8] = 1.0f;
+}
+
 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
@@ -561,9 +574,9 @@
     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);
+    float matrix[9];
+    setRotationMatrix(matrix, ROTATION * PI_180);
+    event.transform(matrix);
 
     // Check the points.
     for (size_t i = 0; i < pointerCount; i++) {
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
new file mode 100644
index 0000000..7148db8
--- /dev/null
+++ b/services/inputflinger/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    InputFlinger.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libbinder \
+    libcutils \
+    libinput \
+    liblog \
+    libutils
+
+LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+LOCAL_MODULE := libinputflinger
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/inputflinger/InputFlinger.cpp b/services/inputflinger/InputFlinger.cpp
new file mode 100644
index 0000000..9ea6ce5
--- /dev/null
+++ b/services/inputflinger/InputFlinger.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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 "InputFlinger"
+
+#include "InputFlinger.h"
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+
+namespace android {
+
+const String16 sAccessInputFlingerPermission("android.permission.ACCESS_INPUT_FLINGER");
+const String16 sDumpPermission("android.permission.DUMP");
+
+
+InputFlinger::InputFlinger() :
+        BnInputFlinger() {
+    ALOGI("InputFlinger is starting");
+}
+
+InputFlinger::~InputFlinger() {
+}
+
+status_t InputFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    switch (code) {
+    case DO_SOMETHING_TRANSACTION:
+        const IPCThreadState* ipc = IPCThreadState::self();
+        const int pid = ipc->getCallingPid();
+        const int uid = ipc->getCallingUid();
+        if (!PermissionCache::checkPermission(sAccessInputFlingerPermission, pid, uid)) {
+            ALOGE("Permission Denial: "
+                    "can't access InputFlinger from pid=%d, uid=%d", pid, uid);
+            return PERMISSION_DENIED;
+        }
+        break;
+    }
+
+    return BnInputFlinger::onTransact(code, data, reply, flags);
+}
+
+status_t InputFlinger::dump(int fd, const Vector<String16>& args) {
+    String8 result;
+    const IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    if ((uid != AID_SHELL)
+            && !PermissionCache::checkPermission(sDumpPermission, pid, uid)) {
+        result.appendFormat("Permission Denial: "
+                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
+    } else {
+        dumpInternal(result);
+    }
+    write(fd, result.string(), result.size());
+    return OK;
+}
+
+void InputFlinger::dumpInternal(String8& result) {
+    result.append("INPUT FLINGER (dumpsys inputflinger)\n");
+    result.append("... nothing here yet...\n");
+}
+
+status_t InputFlinger::doSomething() {
+    ALOGI("Did something...");
+    return OK;
+}
+
+}; // namespace android
diff --git a/services/inputflinger/InputFlinger.h b/services/inputflinger/InputFlinger.h
new file mode 100644
index 0000000..731ab17
--- /dev/null
+++ b/services/inputflinger/InputFlinger.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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 ANDROID_INPUT_FLINGER_H
+#define ANDROID_INPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/compiler.h>
+#include <input/IInputFlinger.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+class InputFlinger : public BnInputFlinger {
+public:
+    static char const* getServiceName() ANDROID_API {
+        return "inputflinger";
+    }
+
+    InputFlinger() ANDROID_API;
+
+    // IBinder interface
+    virtual status_t onTransact(uint32_t code,
+            const Parcel& data, Parcel* reply, uint32_t flags);
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+    // IInputFlinger interface
+    virtual status_t doSomething();
+
+private:
+    virtual ~InputFlinger();
+
+    void dumpInternal(String8& result);
+};
+
+} // namespace android
+
+#endif // ANDROID_INPUT_FLINGER_H
diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 70b65ab..38dc749 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -33,7 +33,7 @@
 BatteryService::BatteryService() {
     const sp<IServiceManager> sm(defaultServiceManager());
     if (sm != NULL) {
-        const String16 name("batteryinfo");
+        const String16 name("batterystats");
         mBatteryStatService = sm->getService(name);
     }
 }
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index f6bd676..35ac0c8 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -104,7 +104,7 @@
     // protected by mLock
     SortedVector< wp<Connection> > mDisplayEventConnections;
     Vector< DisplayEventReceiver::Event > mPendingEvents;
-    DisplayEventReceiver::Event mVSyncEvent[HWC_DISPLAY_TYPES_SUPPORTED];
+    DisplayEventReceiver::Event mVSyncEvent[HWC_NUM_DISPLAY_TYPES];
     bool mUseSoftwareVSync;
 
     // for debugging