am 92d7c3ee: am b65f32eb: Fix two EGLConfig selection bugs

* commit '92d7c3ee03109cf2d465a103b828b7d7d3ee9848':
  Fix two EGLConfig selection bugs
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index d6ac3d2..e80dbb1 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -73,7 +73,7 @@
         },
     },
 
-    { "3:2 Single Static Window",
+    { "4:3 Single Static Window",
         2048, 1536, { 1536 },
         {
             {   // Window
@@ -117,7 +117,7 @@
         },
     },
 
-    { "3:2 App -> Home Transition",
+    { "4:3 App -> Home Transition",
         2048, 1536, { 1536 },
         {
             {   // Wallpaper
@@ -173,7 +173,7 @@
         },
     },
 
-    { "3:2 SurfaceView -> Home Transition",
+    { "4:3 SurfaceView -> Home Transition",
         2048, 1536, { 1536 },
         {
             {   // Wallpaper
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 3eaf1eb..11120f5 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -32,6 +32,8 @@
     { AID_MEDIA, "media.player" },
     { AID_MEDIA, "media.camera" },
     { AID_MEDIA, "media.audio_policy" },
+    { AID_AUDIO, "audio" },
+    { AID_INPUT, "input" },
     { AID_DRM,   "drm.drmManager" },
     { AID_NFC,   "nfc" },
     { AID_BLUETOOTH, "bluetooth" },
diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index 829061a..a2530b6 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -43,6 +43,13 @@
     BATTERY_HEALTH_COLD = 7, // equals BatteryManager.BATTERY_HEALTH_COLD constant
 };
 
+// must be kept in sync with definitions in BatteryProperty.java
+enum {
+    BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.BATTERY_PROP_CHARGE_COUNTER constant
+    BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.BATTERY_PROP_CURRENT_NOW constant
+    BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.BATTERY_PROP_CURRENT_AVG constant
+};
+
 struct BatteryProperties {
     bool chargerAcOnline;
     bool chargerUsbOnline;
@@ -61,6 +68,18 @@
     status_t readFromParcel(Parcel* parcel);
 };
 
+struct BatteryExtraProperties {
+    int batteryCurrentNow;
+    int batteryChargeCounter;
+};
+
+struct BatteryProperty {
+    int valueInt;
+
+    status_t writeToParcel(Parcel* parcel) const;
+    status_t readFromParcel(Parcel* parcel);
+};
+
 }; // namespace android
 
 #endif // ANDROID_BATTERYSERVICE_H
diff --git a/include/batteryservice/IBatteryPropertiesRegistrar.h b/include/batteryservice/IBatteryPropertiesRegistrar.h
index 8d28b1d..eca075d 100644
--- a/include/batteryservice/IBatteryPropertiesRegistrar.h
+++ b/include/batteryservice/IBatteryPropertiesRegistrar.h
@@ -26,6 +26,7 @@
 enum {
     REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
     UNREGISTER_LISTENER,
+    GET_PROPERTY,
 };
 
 class IBatteryPropertiesRegistrar : public IInterface {
@@ -34,6 +35,7 @@
 
     virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0;
     virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0;
+    virtual status_t getProperty(int id, struct BatteryProperty *val) = 0;
 };
 
 class BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> {
diff --git a/include/binder/IBatteryStats.h b/include/binder/IBatteryStats.h
new file mode 100644
index 0000000..f4a8aa3
--- /dev/null
+++ b/include/binder/IBatteryStats.h
@@ -0,0 +1,55 @@
+/*
+ * 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_IBATTERYSTATS_H
+#define ANDROID_IBATTERYSTATS_H
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IBatteryStats : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(BatteryStats);
+
+    virtual void noteStartSensor(int uid, int sensor) = 0;
+    virtual void noteStopSensor(int uid, int sensor) = 0;
+
+    enum {
+        NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+        NOTE_STOP_SENSOR_TRANSACTION,
+    };
+};
+
+// ----------------------------------------------------------------------
+
+class BnBatteryStats : public BnInterface<IBatteryStats>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IBATTERYSTATS_H
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 8b84951..43b6543 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -81,14 +81,6 @@
                                         Parcel* reply,
                                         uint32_t flags = 0) = 0;
 
-    /**
-     * This method allows you to add data that is transported through
-     * IPC along with your IBinder pointer.  When implementing a Binder
-     * object, override it to write your desired data in to @a outData.
-     * You can then call getConstantData() on your IBinder to retrieve
-     * that data, from any process.  You MUST return the number of bytes
-     * written in to the parcel (including padding).
-     */
     class DeathRecipient : public virtual RefBase
     {
     public:
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 7a782f5..0e20da9 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -124,6 +124,11 @@
     // will be closed once the parcel is destroyed.
     status_t            writeDupFileDescriptor(int fd);
 
+    // Writes a raw fd and optional comm channel fd to the parcel as a ParcelFileDescriptor.
+    // A dup's of the fds are made, which will be closed once the parcel is destroyed.
+    // Null values are passed as -1.
+    status_t            writeParcelFileDescriptor(int fd, int commChannel = -1);
+
     // Writes a blob to the parcel.
     // If the blob is small, then it is stored in-place, otherwise it is
     // transferred by way of an anonymous shared memory region.
@@ -183,6 +188,11 @@
     // in the parcel, which you do not own -- use dup() to get your own copy.
     int                 readFileDescriptor() const;
 
+    // Reads a ParcelFileDescriptor from the parcel.  Returns the raw fd as
+    // the result, and the optional comm channel fd in outCommChannel.
+    // Null values are returned as -1.
+    int                 readParcelFileDescriptor(int& outCommChannel) const;
+
     // Reads a blob from the parcel.
     // The caller should call release() on the blob after reading its contents.
     status_t            readBlob(size_t len, ReadableBlob* outBlob) 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/media/hardware/HDCPAPI.h b/include/media/hardware/HDCPAPI.h
index d4abb3f..3a53e9f 100644
--- a/include/media/hardware/HDCPAPI.h
+++ b/include/media/hardware/HDCPAPI.h
@@ -88,6 +88,11 @@
     // Request to shutdown the active HDCP session.
     virtual status_t shutdownAsync() = 0;
 
+    // Returns the capability bitmask of this HDCP session.
+    virtual uint32_t getCaps() {
+        return HDCP_CAPS_ENCRYPT;
+    }
+
     // ENCRYPTION only:
     // Encrypt data according to the HDCP spec. "size" bytes of data are
     // available at "inData" (virtual address), "size" may not be a multiple
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index f3f8daf..c8147ed 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -21,6 +21,7 @@
     Debug.cpp \
     IAppOpsCallback.cpp \
     IAppOpsService.cpp \
+    IBatteryStats.cpp \
     IInterface.cpp \
     IMemory.cpp \
     IPCThreadState.cpp \
diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp
new file mode 100644
index 0000000..6469b08
--- /dev/null
+++ b/libs/binder/IBatteryStats.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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/IBatteryStats.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/binder/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpBatteryStats : public BpInterface<IBatteryStats>
+{
+public:
+    BpBatteryStats(const sp<IBinder>& impl)
+        : BpInterface<IBatteryStats>(impl)
+    {
+    }
+
+    virtual void noteStartSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_START_SENSOR_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStopSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_STOP_SENSOR_TRANSACTION, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(BatteryStats, "com.android.internal.app.IBatteryStats");
+
+// ----------------------------------------------------------------------
+
+status_t BnBatteryStats::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case NOTE_START_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStartSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_STOP_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStopSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 7a5919f..d130d7c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -750,6 +750,32 @@
     return err;
 }
 
+// WARNING: This method must stay in sync with
+// Parcelable.Creator<ParcelFileDescriptor> CREATOR
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+status_t Parcel::writeParcelFileDescriptor(int fd, int commChannel) {
+    status_t status;
+
+    if (fd < 0) {
+        status = writeInt32(0); // ParcelFileDescriptor is null
+        if (status) return status;
+    } else {
+        status = writeInt32(1); // ParcelFileDescriptor is not null
+        if (status) return status;
+        status = writeDupFileDescriptor(fd);
+        if (status) return status;
+        if (commChannel < 0) {
+            status = writeInt32(0); // commChannel is null
+            if (status) return status;
+        } else {
+            status = writeInt32(1); // commChannel is not null
+            if (status) return status;
+            status = writeDupFileDescriptor(commChannel);
+        }
+    }
+    return status;
+}
+
 status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
 {
     status_t status;
@@ -1148,6 +1174,23 @@
     return BAD_TYPE;
 }
 
+// WARNING: This method must stay in sync with writeToParcel()
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+int Parcel::readParcelFileDescriptor(int& outCommChannel) const {
+    int fd;
+    outCommChannel = -1;
+
+    if (readInt32() == 0) {
+        fd = -1;
+    } else {
+        fd = readFileDescriptor();
+        if (fd >= 0 && readInt32() != 0) {
+            outCommChannel = readFileDescriptor();
+        }
+    }
+    return fd;
+}
+
 status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
 {
     int32_t useAshmem;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 87d66e2..0e6fb5c 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -31,7 +31,6 @@
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
-#include <utils/CallStack.h>
 
 // Macros for including the BufferQueue name in log messages
 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 16e533c..de182ee 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -23,7 +23,6 @@
 
 #include <android/native_window.h>
 
-#include <utils/CallStack.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index e4fba15..28c05a7 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -35,6 +35,7 @@
 #include <GLES2/gl2ext.h>
 
 #include <ui/FramebufferNativeWindow.h>
+#include <UniquePtr.h>
 #include <android/native_window.h>
 
 namespace android {
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index f1921a4..944ac7f 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -27,6 +27,7 @@
 
 deviceSources := \
     $(commonSources) \
+    IInputFlinger.cpp \
     InputTransport.cpp \
     VelocityControl.cpp \
     VelocityTracker.cpp
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/services/batteryservice/Android.mk b/services/batteryservice/Android.mk
index 0a29c36..9354b99 100644
--- a/services/batteryservice/Android.mk
+++ b/services/batteryservice/Android.mk
@@ -3,6 +3,7 @@
 
 LOCAL_SRC_FILES:= \
 	BatteryProperties.cpp \
+	BatteryProperty.cpp \
 	IBatteryPropertiesListener.cpp \
 	IBatteryPropertiesRegistrar.cpp
 
diff --git a/services/batteryservice/BatteryProperty.cpp b/services/batteryservice/BatteryProperty.cpp
new file mode 100644
index 0000000..6cbc896
--- /dev/null
+++ b/services/batteryservice/BatteryProperty.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 <batteryservice/BatteryService.h>
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/*
+ * Parcel read/write code must be kept in sync with
+ * frameworks/base/core/java/android/os/BatteryProperty.java
+ */
+
+status_t BatteryProperty::readFromParcel(Parcel* p) {
+    valueInt = p->readInt32();
+    return OK;
+}
+
+status_t BatteryProperty::writeToParcel(Parcel* p) const {
+    p->writeInt32(valueInt);
+    return OK;
+}
+
+}; // namespace android
diff --git a/services/batteryservice/IBatteryPropertiesRegistrar.cpp b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
index 6c2d2a5..6647122 100644
--- a/services/batteryservice/IBatteryPropertiesRegistrar.cpp
+++ b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
@@ -44,6 +44,18 @@
             data.writeStrongBinder(listener->asBinder());
             remote()->transact(UNREGISTER_LISTENER, data, NULL);
         }
+
+        status_t getProperty(int id, struct BatteryProperty *val) {
+            Parcel data, reply;
+            data.writeInterfaceToken(IBatteryPropertiesRegistrar::getInterfaceDescriptor());
+            data.writeInt32(id);
+            remote()->transact(GET_PROPERTY, data, &reply);
+            status_t ret = reply.readInt32();
+            int parcelpresent = reply.readInt32();
+            if (parcelpresent)
+                val->readFromParcel(&reply);
+            return ret;
+        }
 };
 
 IMPLEMENT_META_INTERFACE(BatteryPropertiesRegistrar, "android.os.IBatteryPropertiesRegistrar");
@@ -69,6 +81,18 @@
             unregisterListener(listener);
             return OK;
         }
+
+        case GET_PROPERTY: {
+            CHECK_INTERFACE(IBatteryPropertiesRegistrar, data, reply);
+            int id = data.readInt32();
+            struct BatteryProperty val;
+            status_t result = getProperty(id, &val);
+            reply->writeNoException();
+            reply->writeInt32(result);
+            reply->writeInt32(1);
+            val.writeToParcel(reply);
+            return OK;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 };
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
new file mode 100644
index 0000000..e32d38a
--- /dev/null
+++ b/services/inputflinger/Android.mk
@@ -0,0 +1,50 @@
+# 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)
+
+########################################################################
+# build input flinger executable
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	libinputflinger \
+	libutils
+
+LOCAL_MODULE := inputflinger
+
+include $(BUILD_EXECUTABLE)
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/inputflinger/main.cpp b/services/inputflinger/main.cpp
new file mode 100644
index 0000000..3209a62
--- /dev/null
+++ b/services/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/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 38dc749..cb962a6 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -34,32 +34,10 @@
     const sp<IServiceManager> sm(defaultServiceManager());
     if (sm != NULL) {
         const String16 name("batterystats");
-        mBatteryStatService = sm->getService(name);
+        mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
     }
 }
 
-status_t BatteryService::noteStartSensor(int uid, int handle) {
-    Parcel data, reply;
-    data.writeInterfaceToken(DESCRIPTOR);
-    data.writeInt32(uid);
-    data.writeInt32(handle);
-    status_t err = mBatteryStatService->transact(
-            TRANSACTION_noteStartSensor, data, &reply, 0);
-    err = reply.readExceptionCode();
-    return err;
-}
-
-status_t BatteryService::noteStopSensor(int uid, int handle) {
-    Parcel data, reply;
-    data.writeInterfaceToken(DESCRIPTOR);
-    data.writeInt32(uid);
-    data.writeInt32(handle);
-    status_t err = mBatteryStatService->transact(
-            TRANSACTION_noteStopSensor, data, &reply, 0);
-    err = reply.readExceptionCode();
-    return err;
-}
-
 bool BatteryService::addSensor(uid_t uid, int handle) {
     Mutex::Autolock _l(mActivationsLock);
     Info key(uid, handle);
@@ -86,7 +64,7 @@
     if (mBatteryStatService != 0) {
         if (addSensor(uid, handle)) {
             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
-            noteStartSensor(uid, handle);
+            mBatteryStatService->noteStartSensor(uid, handle);
             IPCThreadState::self()->restoreCallingIdentity(identity);
         }
     }
@@ -95,7 +73,7 @@
     if (mBatteryStatService != 0) {
         if (removeSensor(uid, handle)) {
             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
-            noteStopSensor(uid, handle);
+            mBatteryStatService->noteStopSensor(uid, handle);
             IPCThreadState::self()->restoreCallingIdentity(identity);
         }
     }
@@ -108,7 +86,7 @@
         for (ssize_t i=0 ; i<mActivations.size() ; i++) {
             const Info& info(mActivations[i]);
             if (info.uid == uid) {
-                noteStopSensor(info.uid, info.handle);
+                mBatteryStatService->noteStopSensor(info.uid, info.handle);
                 mActivations.removeAt(i);
                 i--;
             }
@@ -117,8 +95,6 @@
     }
 }
 
-const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
-
 ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/BatteryService.h b/services/sensorservice/BatteryService.h
index 86cc884..08ba857 100644
--- a/services/sensorservice/BatteryService.h
+++ b/services/sensorservice/BatteryService.h
@@ -17,22 +17,18 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <binder/IBatteryStats.h>
 #include <utils/Singleton.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
 
 class BatteryService : public Singleton<BatteryService> {
-    static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
-    static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
-    static const String16 DESCRIPTOR;
 
     friend class Singleton<BatteryService>;
-    sp<IBinder> mBatteryStatService;
+    sp<IBatteryStats> mBatteryStatService;
 
     BatteryService();
-    status_t noteStartSensor(int uid, int handle);
-    status_t noteStopSensor(int uid, int handle);
 
     void enableSensorImpl(uid_t uid, int handle);
     void disableSensorImpl(uid_t uid, int handle);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c851a2c..ef81ab5 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 #include <math.h>
 
-#include <utils/CallStack.h>
 #include <utils/Errors.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 09b0ddc..38450c2 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -169,7 +169,7 @@
             fs << "gl_FragColor.rgb = gl_FragColor.rgb/gl_FragColor.a;";
         }
         fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2));";
-        fs << "gl_FragColor     = colorMatrix*gl_FragColor;";
+        fs << "gl_FragColor.rgb = mat3(colorMatrix) * gl_FragColor.rgb + vec3(colorMatrix[3]);";
         fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2));";
         if (!needs.isOpaque() && needs.isPremultiplied()) {
             // and re-premultiply if needed after gamma correction
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4f139fe..5c6fc87 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -114,7 +114,8 @@
         mDebugInTransaction(0),
         mLastTransactionTime(0),
         mBootFinished(false),
-        mDaltonize(false)
+        mDaltonize(false),
+        mHasColorMatrix(false)
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -880,7 +881,7 @@
                         for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                             const sp<Layer>& layer(currentLayers[i]);
                             layer->setGeometry(hw, *cur);
-                            if (mDebugDisableHWC || mDebugRegion || mDaltonize) {
+                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
                                 cur->setSkip(true);
                             }
                         }
@@ -1500,11 +1501,17 @@
         }
     }
 
-    if (CC_LIKELY(!mDaltonize)) {
+    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
         doComposeSurfaces(hw, dirtyRegion);
     } else {
         RenderEngine& engine(getRenderEngine());
-        engine.beginGroup(mDaltonizer());
+        mat4 colorMatrix = mColorMatrix;
+        if (mDaltonize) {
+            // preserve last row of color matrix
+            colorMatrix = colorMatrix * mDaltonizer();
+            colorMatrix[3] = mColorMatrix[3];
+        }
+        engine.beginGroup(colorMatrix);
         doComposeSurfaces(hw, dirtyRegion);
         engine.endGroup();
     }
@@ -2388,7 +2395,8 @@
     colorizer.reset(result);
     result.appendFormat("  h/w composer %s and %s\n",
             hwc.initCheck()==NO_ERROR ? "present" : "not present",
-                    (mDebugDisableHWC || mDebugRegion || mDaltonize) ? "disabled" : "enabled");
+                    (mDebugDisableHWC || mDebugRegion || mDaltonize
+                            || mHasColorMatrix) ? "disabled" : "enabled");
     hwc.dump(result);
 
     /*
@@ -2551,8 +2559,33 @@
                 mDaltonize = n > 0;
                 invalidateHwcGeometry();
                 repaintEverything();
+                return NO_ERROR;
             }
-            return NO_ERROR;
+            case 1015: {
+                // apply a color matrix
+                n = data.readInt32();
+                mHasColorMatrix = n ? 1 : 0;
+                if (n) {
+                    // color matrix is sent as mat3 matrix followed by vec3
+                    // offset, then packed into a mat4 where the last row is
+                    // the offset and extra values are 0
+                    for (size_t i = 0 ; i < 3 ; i++) {
+                        for (size_t j = 0; j < 3; j++) {
+                            mColorMatrix[i][j] = data.readFloat();
+                        }
+                        mColorMatrix[i][3] = 0;
+                    }
+                    for (size_t i = 0; i < 3; i++) {
+                        mColorMatrix[3][i] = data.readFloat();
+                    }
+                    mColorMatrix[3][3] = 0;
+                } else {
+                    mColorMatrix = mat4();
+                }
+                invalidateHwcGeometry();
+                repaintEverything();
+                return NO_ERROR;
+            }
         }
     }
     return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0e9955c..3a79c06 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -38,6 +38,7 @@
 #include <binder/IMemory.h>
 
 #include <ui/PixelFormat.h>
+#include <ui/mat4.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
@@ -462,6 +463,9 @@
 
     Daltonizer mDaltonizer;
     bool mDaltonize;
+
+    mat4 mColorMatrix;
+    bool mHasColorMatrix;
 };
 
 // ---------------------------------------------------------------------------