Merge "Add mutex"
diff --git a/data/etc/android.hardware.camera.external.xml b/data/etc/android.hardware.camera.external.xml
new file mode 100644
index 0000000..a138bcd
--- /dev/null
+++ b/data/etc/android.hardware.camera.external.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- This is the standard set of features for a Android device that can support
+an external camera being connected to it. -->
+<permissions>
+    <feature name="android.hardware.camera.any" />
+    <feature name="android.hardware.camera.external" />
+</permissions>
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index efde5db..8042211 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -113,9 +113,18 @@
      */
     virtual void unblank(const sp<IBinder>& display) = 0;
 
-    /* returns information about a display
+    /* returns information for each configuration of the given display
      * intended to be used to get information about built-in displays */
-    virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
+    virtual status_t getDisplayConfigs(const sp<IBinder>& display,
+            Vector<DisplayInfo>* configs) = 0;
+
+    /* indicates which of the configurations returned by getDisplayInfo is
+     * currently active */
+    virtual int getActiveConfig(const sp<IBinder>& display) = 0;
+
+    /* specifies which configuration (of those returned by getDisplayInfo)
+     * should be used */
+    virtual status_t setActiveConfig(const sp<IBinder>& display, int id) = 0;
 
     /* Capture the specified screen. requires READ_FRAME_BUFFER permission
      * This function will fail if there is a secure window on screen.
@@ -158,7 +167,9 @@
         AUTHENTICATE_SURFACE,
         BLANK,
         UNBLANK,
-        GET_DISPLAY_INFO,
+        GET_DISPLAY_CONFIGS,
+        GET_ACTIVE_CONFIG,
+        SET_ACTIVE_CONFIG,
         CONNECT_DISPLAY,
         CAPTURE_SCREEN,
         CLEAR_ANIMATION_FRAME_STATS,
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 6a53ccb..c2192af 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -66,8 +66,21 @@
     status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
             void* cookie = NULL, uint32_t flags = 0);
 
-    // Get information about a display
-    static status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
+    // Get a list of supported configurations for a given display
+    static status_t getDisplayConfigs(const sp<IBinder>& display,
+            Vector<DisplayInfo>* configs);
+
+    // Get the DisplayInfo for the currently-active configuration
+    static status_t getDisplayInfo(const sp<IBinder>& display,
+            DisplayInfo* info);
+
+    // Get the index of the current active configuration (relative to the list
+    // returned by getDisplayInfo)
+    static int getActiveConfig(const sp<IBinder>& display);
+
+    // Set a new active configuration using an index relative to the list
+    // returned by getDisplayInfo
+    static status_t setActiveConfig(const sp<IBinder>& display, int id);
 
     /* triggers screen off and waits for it to complete */
     static void blankDisplay(const sp<IBinder>& display);
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 609b679..8ffdfca 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -86,7 +86,7 @@
             float yOffset;
             float xPrecision;
             float yPrecision;
-            size_t pointerCount;
+            uint32_t pointerCount;
             struct Pointer {
                 PointerProperties properties;
                 PointerCoords coords;
@@ -234,7 +234,7 @@
             float yPrecision,
             nsecs_t downTime,
             nsecs_t eventTime,
-            size_t pointerCount,
+            uint32_t pointerCount,
             const PointerProperties* pointerProperties,
             const PointerCoords* pointerCoords);
 
@@ -360,7 +360,7 @@
         void initializeFrom(const InputMessage* msg) {
             eventTime = msg->body.motion.eventTime;
             idBits.clear();
-            for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
+            for (uint32_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;
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index c503dcf..7070809 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -72,6 +72,8 @@
     OMX_IndexConfigVideoVp8ReferenceFrame,          /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */
     OMX_IndexConfigVideoVp8ReferenceFrameType,      /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */
     OMX_IndexParamVideoAndroidVp8Encoder,           /**< reference: OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE */
+    OMX_IndexParamVideoHevc,                        /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */
+    OMX_IndexParamSliceSegments,                    /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */
 
     /* Image & Video common configurations */
     OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
diff --git a/include/media/openmax/OMX_Video.h b/include/media/openmax/OMX_Video.h
index 4441a7a..21dc5a6 100644
--- a/include/media/openmax/OMX_Video.h
+++ b/include/media/openmax/OMX_Video.h
@@ -87,6 +87,7 @@
     OMX_VIDEO_CodingMJPEG,      /**< Motion JPEG */
     OMX_VIDEO_CodingVP8,        /**< Google VP8, formerly known as On2 VP8 */
     OMX_VIDEO_CodingVP9,        /**< Google VP9 */
+    OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */
     OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
     OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h
index 3f18b43..fb10cbb 100644
--- a/include/media/openmax/OMX_VideoExt.h
+++ b/include/media/openmax/OMX_VideoExt.h
@@ -145,6 +145,63 @@
     OMX_U32 nMaxQuantizer;
 };
 
+/** HEVC Profile enum type */
+typedef enum OMX_VIDEO_HEVCPROFILETYPE {
+    OMX_VIDEO_HEVCProfileUnknown = 0x0,
+    OMX_VIDEO_HEVCProfileMain    = 0x1,
+    OMX_VIDEO_HEVCProfileMain10  = 0x2,
+    OMX_VIDEO_HEVCProfileMax     = 0x7FFFFFFF
+} OMX_VIDEO_HEVCPROFILETYPE;
+
+/** HEVC Level enum type */
+typedef enum OMX_VIDEO_HEVCLEVELTYPE {
+    OMX_VIDEO_HEVCLevelUnknown    = 0x0,
+    OMX_VIDEO_HEVCMainTierLevel1  = 0x1,
+    OMX_VIDEO_HEVCHighTierLevel1  = 0x2,
+    OMX_VIDEO_HEVCMainTierLevel2  = 0x4,
+    OMX_VIDEO_HEVCHighTierLevel2  = 0x8,
+    OMX_VIDEO_HEVCMainTierLevel21 = 0x10,
+    OMX_VIDEO_HEVCHighTierLevel21 = 0x20,
+    OMX_VIDEO_HEVCMainTierLevel3  = 0x40,
+    OMX_VIDEO_HEVCHighTierLevel3  = 0x80,
+    OMX_VIDEO_HEVCMainTierLevel31 = 0x100,
+    OMX_VIDEO_HEVCHighTierLevel31 = 0x200,
+    OMX_VIDEO_HEVCMainTierLevel4  = 0x400,
+    OMX_VIDEO_HEVCHighTierLevel4  = 0x800,
+    OMX_VIDEO_HEVCMainTierLevel41 = 0x1000,
+    OMX_VIDEO_HEVCHighTierLevel41 = 0x2000,
+    OMX_VIDEO_HEVCMainTierLevel5  = 0x4000,
+    OMX_VIDEO_HEVCHighTierLevel5  = 0x8000,
+    OMX_VIDEO_HEVCMainTierLevel51 = 0x10000,
+    OMX_VIDEO_HEVCHighTierLevel51 = 0x20000,
+    OMX_VIDEO_HEVCMainTierLevel52 = 0x40000,
+    OMX_VIDEO_HEVCHighTierLevel52 = 0x80000,
+    OMX_VIDEO_HEVCMainTierLevel6  = 0x100000,
+    OMX_VIDEO_HEVCHighTierLevel6  = 0x200000,
+    OMX_VIDEO_HEVCMainTierLevel61 = 0x400000,
+    OMX_VIDEO_HEVCHighTierLevel61 = 0x800000,
+    OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000,
+    OMX_VIDEO_HEVCHighTierLevel62 = 0x2000000,
+    OMX_VIDEO_HEVCHighTiermax     = 0x7FFFFFFF
+} OMX_VIDEO_HEVCLEVELTYPE;
+
+/** Structure for controlling HEVC video encoding and decoding */
+typedef struct OMX_VIDEO_PARAM_HEVCTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_HEVCPROFILETYPE eProfile;
+    OMX_VIDEO_HEVCLEVELTYPE eLevel;
+} OMX_VIDEO_PARAM_HEVCTYPE;
+
+/** Structure to define if dependent slice segments should be used */
+typedef struct OMX_VIDEO_SLICESEGMENTSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bDepedentSegments;
+    OMX_BOOL bEnableLoopFilterAcrossSlices;
+} OMX_VIDEO_SLICESEGMENTSTYPE;
 
 #ifdef __cplusplus
 }
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index 2853e06..3b5cd6d 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -33,7 +33,6 @@
     float density;
     uint8_t orientation;
     bool secure;
-    uint8_t reserved[2];
 };
 
 /* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d8ae0aa..c8a1e35 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -39,7 +39,6 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
 LOCAL_MODULE := libbinder
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
 LOCAL_SRC_FILES := $(sources)
@@ -51,7 +50,6 @@
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
 LOCAL_MODULE := libbinder
 LOCAL_STATIC_LIBRARIES += libutils
 LOCAL_SRC_FILES := $(sources)
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4298522..52fff82 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -25,6 +25,7 @@
 #include <binder/ProcessState.h>
 #include <binder/TextOutput.h>
 
+#include <errno.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -1284,7 +1285,11 @@
     status_t err = NO_ERROR;
     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
         fds[i] = dup(this->readFileDescriptor());
-        if (fds[i] < 0) err = BAD_VALUE;
+        if (fds[i] < 0) {
+            err = BAD_VALUE;
+            ALOGE("dup() failed in Parcel::read, i is %d, fds[i] is %d, fd_count is %d, error: %s",
+                i, fds[i], fd_count, strerror(errno));
+        }
     }
 
     if (err == NO_ERROR) {
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index c067244..58a2ae2 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -220,13 +220,43 @@
         remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply);
     }
 
-    virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info)
+    virtual status_t getDisplayConfigs(const sp<IBinder>& display,
+            Vector<DisplayInfo>* configs)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
-        remote()->transact(BnSurfaceComposer::GET_DISPLAY_INFO, data, &reply);
-        memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo));
+        remote()->transact(BnSurfaceComposer::GET_DISPLAY_CONFIGS, data, &reply);
+        status_t result = reply.readInt32();
+        if (result == NO_ERROR) {
+            size_t numConfigs = static_cast<size_t>(reply.readInt32());
+            configs->clear();
+            configs->resize(numConfigs);
+            for (size_t c = 0; c < numConfigs; ++c) {
+                memcpy(&(configs->editItemAt(c)),
+                        reply.readInplace(sizeof(DisplayInfo)),
+                        sizeof(DisplayInfo));
+            }
+        }
+        return result;
+    }
+
+    virtual int getActiveConfig(const sp<IBinder>& display)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeStrongBinder(display);
+        remote()->transact(BnSurfaceComposer::GET_ACTIVE_CONFIG, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setActiveConfig(const sp<IBinder>& display, int id)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeStrongBinder(display);
+        data.writeInt32(id);
+        remote()->transact(BnSurfaceComposer::SET_ACTIVE_CONFIG, data, &reply);
         return reply.readInt32();
     }
 
@@ -357,12 +387,33 @@
             unblank(display);
             return NO_ERROR;
         }
-        case GET_DISPLAY_INFO: {
+        case GET_DISPLAY_CONFIGS: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            DisplayInfo info;
+            Vector<DisplayInfo> configs;
             sp<IBinder> display = data.readStrongBinder();
-            status_t result = getDisplayInfo(display, &info);
-            memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo));
+            status_t result = getDisplayConfigs(display, &configs);
+            reply->writeInt32(result);
+            if (result == NO_ERROR) {
+                reply->writeInt32(static_cast<int32_t>(configs.size()));
+                for (size_t c = 0; c < configs.size(); ++c) {
+                    memcpy(reply->writeInplace(sizeof(DisplayInfo)),
+                            &configs[c], sizeof(DisplayInfo));
+                }
+            }
+            return NO_ERROR;
+        }
+        case GET_ACTIVE_CONFIG: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> display = data.readStrongBinder();
+            int id = getActiveConfig(display);
+            reply->writeInt32(id);
+            return NO_ERROR;
+        }
+        case SET_ACTIVE_CONFIG: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> display = data.readStrongBinder();
+            int id = data.readInt32();
+            status_t result = setActiveConfig(display, id);
             reply->writeInt32(result);
             return NO_ERROR;
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index b7af415..1dffdb2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -623,10 +623,36 @@
 
 // ----------------------------------------------------------------------------
 
-status_t SurfaceComposerClient::getDisplayInfo(
-        const sp<IBinder>& display, DisplayInfo* info)
+status_t SurfaceComposerClient::getDisplayConfigs(
+        const sp<IBinder>& display, Vector<DisplayInfo>* configs)
 {
-    return ComposerService::getComposerService()->getDisplayInfo(display, info);
+    return ComposerService::getComposerService()->getDisplayConfigs(display, configs);
+}
+
+status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display,
+        DisplayInfo* info) {
+    Vector<DisplayInfo> configs;
+    status_t result = getDisplayConfigs(display, &configs);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    int activeId = getActiveConfig(display);
+    if (activeId < 0) {
+        ALOGE("No active configuration found");
+        return NAME_NOT_FOUND;
+    }
+
+    *info = configs[activeId];
+    return NO_ERROR;
+}
+
+int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) {
+    return ComposerService::getComposerService()->getActiveConfig(display);
+}
+
+status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int id) {
+    return ComposerService::getComposerService()->setActiveConfig(display, id);
 }
 
 void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index a73780d..5bad2e6 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -292,7 +292,7 @@
         float yPrecision,
         nsecs_t downTime,
         nsecs_t eventTime,
-        size_t pointerCount,
+        uint32_t pointerCount,
         const PointerProperties* pointerProperties,
         const PointerCoords* pointerCoords) {
 #if DEBUG_TRANSPORT_ACTIONS
@@ -334,7 +334,7 @@
     msg.body.motion.downTime = downTime;
     msg.body.motion.eventTime = eventTime;
     msg.body.motion.pointerCount = pointerCount;
-    for (size_t i = 0; i < pointerCount; i++) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
         msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
         msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
     }
@@ -654,7 +654,7 @@
 }
 
 void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
-    for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
+    for (uint32_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;
@@ -894,10 +894,10 @@
 }
 
 void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
+    uint32_t pointerCount = msg->body.motion.pointerCount;
     PointerProperties pointerProperties[pointerCount];
     PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
         pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
         pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
     }
@@ -922,9 +922,9 @@
 }
 
 void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
+    uint32_t pointerCount = msg->body.motion.pointerCount;
     PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
         pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
     }
 
@@ -934,7 +934,7 @@
 
 bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
     const InputMessage& head = batch.samples.itemAt(0);
-    size_t pointerCount = msg->body.motion.pointerCount;
+    uint32_t pointerCount = msg->body.motion.pointerCount;
     if (head.body.motion.pointerCount != pointerCount
             || head.body.motion.action != msg->body.motion.action) {
         return false;
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 78ea98e..9105ae5 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -53,8 +53,8 @@
 
     // Set first axis.
     ASSERT_EQ(OK, coords.setAxisValue(1, 5));
-    ASSERT_EQ(0x00000002ULL, coords.bits);
     ASSERT_EQ(5, coords.values[0]);
+    ASSERT_EQ(0x4000000000000000ULL, coords.bits);
 
     ASSERT_EQ(0, coords.getAxisValue(0))
             << "getAxisValue should return zero because axis is not present";
@@ -63,7 +63,7 @@
 
     // 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(0x5000000000000000ULL, coords.bits);
     ASSERT_EQ(5, coords.values[0]);
     ASSERT_EQ(2, coords.values[1]);
 
@@ -78,7 +78,7 @@
 
     // 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(0xd000000000000000ULL, coords.bits);
     ASSERT_EQ(4, coords.values[0]);
     ASSERT_EQ(5, coords.values[1]);
     ASSERT_EQ(2, coords.values[2]);
@@ -94,7 +94,7 @@
 
     // 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(0xf000000000000000ULL, coords.bits);
     ASSERT_EQ(4, coords.values[0]);
     ASSERT_EQ(5, coords.values[1]);
     ASSERT_EQ(1, coords.values[2]);
@@ -111,7 +111,7 @@
 
     // Set an existing axis value in place.
     ASSERT_EQ(OK, coords.setAxisValue(1, 6));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
+    ASSERT_EQ(0xf000000000000000ULL, coords.bits);
     ASSERT_EQ(4, coords.values[0]);
     ASSERT_EQ(6, coords.values[1]);
     ASSERT_EQ(1, coords.values[2]);
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 32bc5d9..64320cf 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -27,7 +27,6 @@
 LOCAL_CFLAGS += -fvisibility=hidden
 
 LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils liblog libpixelflinger libETC1 libui
-LOCAL_LDLIBS := -lpthread -ldl
 
 LOCAL_SRC_FILES_arm += fixed_asm.S iterators.S
 LOCAL_CFLAGS_arm += -fstrict-aliasing
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 7328a1d..35feb61 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -33,7 +33,6 @@
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libGLES_trace
-LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libEGL
 LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
 LOCAL_SHARED_LIBRARIES += libdl
@@ -79,7 +78,6 @@
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils liblog libEGL
-LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libGLESv1_CM
 
 LOCAL_SHARED_LIBRARIES += libdl
@@ -104,7 +102,6 @@
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
-LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libGLESv2
 
 LOCAL_SHARED_LIBRARIES += libdl
@@ -141,7 +138,6 @@
 	ETC1/etc1.cpp 	\
 #
 
-LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libETC1
 
 include $(BUILD_HOST_STATIC_LIBRARY)
@@ -156,7 +152,6 @@
 	ETC1/etc1.cpp 	\
 #
 
-LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libETC1
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 0bae399..a750a3d 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -1965,7 +1965,7 @@
                 xOffset = dispatchEntry->xOffset * scaleFactor;
                 yOffset = dispatchEntry->yOffset * scaleFactor;
                 if (scaleFactor != 1.0f) {
-                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+                    for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                         scaledCoords[i] = motionEntry->pointerCoords[i];
                         scaledCoords[i].scale(scaleFactor);
                     }
@@ -1978,7 +1978,7 @@
 
                 // We don't want the dispatch target to know.
                 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
-                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+                    for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                         scaledCoords[i].clear();
                     }
                     usingCoords = scaledCoords;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2d63bde..51c7059 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -170,20 +170,15 @@
 
         DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
         disp.connected = true;
-        disp.width = mFbDev->width;
-        disp.height = mFbDev->height;
         disp.format = mFbDev->format;
-        disp.xdpi = mFbDev->xdpi;
-        disp.ydpi = mFbDev->ydpi;
-        if (disp.refresh == 0) {
-            disp.refresh = nsecs_t(1e9 / mFbDev->fps);
-            ALOGW("getting VSYNC period from fb HAL: %lld", disp.refresh);
-        }
-        if (disp.refresh == 0) {
-            disp.refresh = nsecs_t(1e9 / 60.0);
-            ALOGW("getting VSYNC period from thin air: %lld",
-                    mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
-        }
+        DisplayConfig config = DisplayConfig();
+        config.width = mFbDev->width;
+        config.height = mFbDev->height;
+        config.xdpi = mFbDev->xdpi;
+        config.ydpi = mFbDev->ydpi;
+        config.refresh = nsecs_t(1e9 / mFbDev->fps);
+        disp.configs.push_back(config);
+        disp.currentConfig = 0;
     } else if (mHwc) {
         // here we're guaranteed to have at least HWC 1.1
         for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
@@ -342,55 +337,63 @@
     int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
     memset(values, 0, sizeof(values));
 
-    uint32_t config;
-    size_t numConfigs = 1;
-    status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
+    const size_t MAX_NUM_CONFIGS = 128;
+    uint32_t configs[MAX_NUM_CONFIGS] = {0};
+    size_t numConfigs = MAX_NUM_CONFIGS;
+    status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);
     if (err != NO_ERROR) {
         // this can happen if an unpluggable display is not connected
         mDisplayData[disp].connected = false;
         return err;
     }
 
-    err = mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES, values);
-    if (err != NO_ERROR) {
-        // we can't get this display's info. turn it off.
-        mDisplayData[disp].connected = false;
-        return err;
-    }
-
-    int32_t w = 0, h = 0;
-    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
-        switch (DISPLAY_ATTRIBUTES[i]) {
-        case HWC_DISPLAY_VSYNC_PERIOD:
-            mDisplayData[disp].refresh = nsecs_t(values[i]);
-            break;
-        case HWC_DISPLAY_WIDTH:
-            mDisplayData[disp].width = values[i];
-            break;
-        case HWC_DISPLAY_HEIGHT:
-            mDisplayData[disp].height = values[i];
-            break;
-        case HWC_DISPLAY_DPI_X:
-            mDisplayData[disp].xdpi = values[i] / 1000.0f;
-            break;
-        case HWC_DISPLAY_DPI_Y:
-            mDisplayData[disp].ydpi = values[i] / 1000.0f;
-            break;
-        default:
-            ALOG_ASSERT(false, "unknown display attribute[%d] %#x",
-                    i, DISPLAY_ATTRIBUTES[i]);
-            break;
+    mDisplayData[disp].currentConfig = 0;
+    for (size_t c = 0; c < numConfigs; ++c) {
+        err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
+                DISPLAY_ATTRIBUTES, values);
+        if (err != NO_ERROR) {
+            // we can't get this display's info. turn it off.
+            mDisplayData[disp].connected = false;
+            return err;
         }
+
+        DisplayConfig config = DisplayConfig();
+        for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
+            switch (DISPLAY_ATTRIBUTES[i]) {
+                case HWC_DISPLAY_VSYNC_PERIOD:
+                    config.refresh = nsecs_t(values[i]);
+                    break;
+                case HWC_DISPLAY_WIDTH:
+                    config.width = values[i];
+                    break;
+                case HWC_DISPLAY_HEIGHT:
+                    config.height = values[i];
+                    break;
+                case HWC_DISPLAY_DPI_X:
+                    config.xdpi = values[i] / 1000.0f;
+                    break;
+                case HWC_DISPLAY_DPI_Y:
+                    config.ydpi = values[i] / 1000.0f;
+                    break;
+                default:
+                    ALOG_ASSERT(false, "unknown display attribute[%d] %#x",
+                            i, DISPLAY_ATTRIBUTES[i]);
+                    break;
+            }
+        }
+
+        if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
+            float dpi = getDefaultDensity(config.height);
+            config.xdpi = dpi;
+            config.ydpi = dpi;
+        }
+
+        mDisplayData[disp].configs.push_back(config);
     }
 
     // FIXME: what should we set the format to?
     mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
     mDisplayData[disp].connected = true;
-    if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) {
-        float dpi = getDefaultDensity(h);
-        mDisplayData[disp].xdpi = dpi;
-        mDisplayData[disp].ydpi = dpi;
-    }
     return NO_ERROR;
 }
 
@@ -400,10 +403,12 @@
             !mAllocatedDisplayIDs.hasBit(id)) {
         return BAD_INDEX;
     }
-    mDisplayData[id].width = w;
-    mDisplayData[id].height = h;
+    size_t configId = mDisplayData[id].currentConfig;
     mDisplayData[id].format = format;
-    mDisplayData[id].xdpi = mDisplayData[id].ydpi = getDefaultDensity(h);
+    DisplayConfig& config = mDisplayData[id].configs.editItemAt(configId);
+    config.width = w;
+    config.height = h;
+    config.xdpi = config.ydpi = getDefaultDensity(h);
     return NO_ERROR;
 }
 
@@ -414,6 +419,8 @@
     int32_t id = mAllocatedDisplayIDs.firstUnmarkedBit();
     mAllocatedDisplayIDs.markBit(id);
     mDisplayData[id].connected = true;
+    mDisplayData[id].configs.resize(1);
+    mDisplayData[id].currentConfig = 0;
     return id;
 }
 
@@ -430,31 +437,21 @@
     return NO_ERROR;
 }
 
-nsecs_t HWComposer::getRefreshPeriod(int disp) const {
-    return mDisplayData[disp].refresh;
-}
-
 nsecs_t HWComposer::getRefreshTimestamp(int disp) const {
     // this returns the last refresh timestamp.
     // if the last one is not available, we estimate it based on
     // the refresh period and whatever closest timestamp we have.
     Mutex::Autolock _l(mLock);
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
-    return now - ((now - mLastHwVSync[disp]) %  mDisplayData[disp].refresh);
+    size_t configId = mDisplayData[disp].currentConfig;
+    return now - ((now - mLastHwVSync[disp]) %
+            mDisplayData[disp].configs[configId].refresh);
 }
 
 sp<Fence> HWComposer::getDisplayFence(int disp) const {
     return mDisplayData[disp].lastDisplayFence;
 }
 
-uint32_t HWComposer::getWidth(int disp) const {
-    return mDisplayData[disp].width;
-}
-
-uint32_t HWComposer::getHeight(int disp) const {
-    return mDisplayData[disp].height;
-}
-
 uint32_t HWComposer::getFormat(int disp) const {
     if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) {
         return HAL_PIXEL_FORMAT_RGBA_8888;
@@ -463,16 +460,41 @@
     }
 }
 
+bool HWComposer::isConnected(int disp) const {
+    return mDisplayData[disp].connected;
+}
+
+uint32_t HWComposer::getWidth(int disp) const {
+    size_t currentConfig = mDisplayData[disp].currentConfig;
+    return mDisplayData[disp].configs[currentConfig].width;
+}
+
+uint32_t HWComposer::getHeight(int disp) const {
+    size_t currentConfig = mDisplayData[disp].currentConfig;
+    return mDisplayData[disp].configs[currentConfig].height;
+}
+
 float HWComposer::getDpiX(int disp) const {
-    return mDisplayData[disp].xdpi;
+    size_t currentConfig = mDisplayData[disp].currentConfig;
+    return mDisplayData[disp].configs[currentConfig].xdpi;
 }
 
 float HWComposer::getDpiY(int disp) const {
-    return mDisplayData[disp].ydpi;
+    size_t currentConfig = mDisplayData[disp].currentConfig;
+    return mDisplayData[disp].configs[currentConfig].ydpi;
 }
 
-bool HWComposer::isConnected(int disp) const {
-    return mDisplayData[disp].connected;
+nsecs_t HWComposer::getRefreshPeriod(int disp) const {
+    size_t currentConfig = mDisplayData[disp].currentConfig;
+    return mDisplayData[disp].configs[currentConfig].refresh;
+}
+
+const Vector<HWComposer::DisplayConfig>& HWComposer::getConfigs(int disp) const {
+    return mDisplayData[disp].configs;
+}
+
+size_t HWComposer::getCurrentConfig(int disp) const {
+    return mDisplayData[disp].currentConfig;
 }
 
 void HWComposer::eventControl(int disp, int event, int enabled) {
@@ -536,7 +558,10 @@
         if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
             disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];
             memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));
-            const hwc_rect_t r = { 0, 0, (int) disp.width, (int) disp.height };
+            const DisplayConfig& currentConfig =
+                    disp.configs[disp.currentConfig];
+            const hwc_rect_t r = { 0, 0,
+                    (int) currentConfig.width, (int) currentConfig.height };
             disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
             disp.framebufferTarget->hints = 0;
             disp.framebufferTarget->flags = 0;
@@ -546,8 +571,10 @@
             if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
                 disp.framebufferTarget->sourceCropf.left = 0;
                 disp.framebufferTarget->sourceCropf.top = 0;
-                disp.framebufferTarget->sourceCropf.right = disp.width;
-                disp.framebufferTarget->sourceCropf.bottom = disp.height;
+                disp.framebufferTarget->sourceCropf.right =
+                        currentConfig.width;
+                disp.framebufferTarget->sourceCropf.bottom =
+                        currentConfig.height;
             } else {
                 disp.framebufferTarget->sourceCrop = r;
             }
@@ -1050,9 +1077,14 @@
             const Vector< sp<Layer> >& visibleLayersSortedByZ =
                     mFlinger->getLayerSortedByZForHwcDisplay(i);
 
-            result.appendFormat(
-                    "  Display[%zd] : %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n",
-                    i, disp.width, disp.height, disp.xdpi, disp.ydpi, disp.refresh);
+
+            result.appendFormat("  Display[%zd] configurations (* current):\n", i);
+            for (size_t c = 0; c < disp.configs.size(); ++c) {
+                const DisplayConfig& config(disp.configs[c]);
+                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n",
+                        c == disp.currentConfig ? "* " : "", c, config.width, config.height,
+                        config.xdpi, config.ydpi, config.refresh);
+            }
 
             if (disp.list) {
                 result.appendFormat(
@@ -1181,9 +1213,9 @@
 }
 
 HWComposer::DisplayData::DisplayData()
-:   width(0), height(0), format(HAL_PIXEL_FORMAT_RGBA_8888),
-    xdpi(0.0f), ydpi(0.0f),
-    refresh(0),
+:   configs(),
+    currentConfig(0),
+    format(HAL_PIXEL_FORMAT_RGBA_8888),
     connected(false),
     hasFbComp(false), hasOvComp(false),
     capacity(0), list(NULL),
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index e93bb7e..2f92672 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -247,17 +247,31 @@
 
     void eventControl(int disp, int event, int enabled);
 
+    struct DisplayConfig {
+        uint32_t width;
+        uint32_t height;
+        float xdpi;
+        float ydpi;
+        nsecs_t refresh;
+    };
+
     // Query display parameters.  Pass in a display index (e.g.
     // HWC_DISPLAY_PRIMARY).
-    nsecs_t getRefreshPeriod(int disp) const;
     nsecs_t getRefreshTimestamp(int disp) const;
     sp<Fence> getDisplayFence(int disp) const;
+    uint32_t getFormat(int disp) const;
+    bool isConnected(int disp) const;
+
+    // These return the values for the current config of a given display index.
+    // To get the values for all configs, use getConfigs below.
     uint32_t getWidth(int disp) const;
     uint32_t getHeight(int disp) const;
-    uint32_t getFormat(int disp) const;
     float getDpiX(int disp) const;
     float getDpiY(int disp) const;
-    bool isConnected(int disp) const;
+    nsecs_t getRefreshPeriod(int disp) const;
+
+    const Vector<DisplayConfig>& getConfigs(int disp) const;
+    size_t getCurrentConfig(int disp) const;
 
     status_t setVirtualDisplayProperties(int32_t id, uint32_t w, uint32_t h,
             uint32_t format);
@@ -306,16 +320,12 @@
     status_t setFramebufferTarget(int32_t id,
             const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
 
-
     struct DisplayData {
         DisplayData();
         ~DisplayData();
-        uint32_t width;
-        uint32_t height;
+        Vector<DisplayConfig> configs;
+        size_t currentConfig;
         uint32_t format;    // pixel format from FB hal, for pre-hwc-1.1
-        float xdpi;
-        float ydpi;
-        nsecs_t refresh;
         bool connected;
         bool hasFbComp;
         bool hasOvComp;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7bd8d38..32d173d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -502,7 +502,12 @@
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
 
-status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
+status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
+        Vector<DisplayInfo>* configs) {
+    if (configs == NULL) {
+        return BAD_VALUE;
+    }
+
     int32_t type = NAME_NOT_FOUND;
     for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
         if (display == mBuiltinDisplays[i]) {
@@ -515,10 +520,6 @@
         return type;
     }
 
-    const HWComposer& hwc(getHwComposer());
-    float xdpi = hwc.getDpiX(type);
-    float ydpi = hwc.getDpiY(type);
-
     // TODO: Not sure if display density should handled by SF any longer
     class Density {
         static int getDensityFromProperty(char const* propName) {
@@ -536,41 +537,63 @@
             return getDensityFromProperty("ro.sf.lcd_density"); }
     };
 
-    if (type == DisplayDevice::DISPLAY_PRIMARY) {
-        // The density of the device is provided by a build property
-        float density = Density::getBuildDensity() / 160.0f;
-        if (density == 0) {
-            // the build doesn't provide a density -- this is wrong!
-            // use xdpi instead
-            ALOGE("ro.sf.lcd_density must be defined as a build property");
-            density = xdpi / 160.0f;
-        }
-        if (Density::getEmuDensity()) {
-            // if "qemu.sf.lcd_density" is specified, it overrides everything
-            xdpi = ydpi = density = Density::getEmuDensity();
-            density /= 160.0f;
-        }
-        info->density = density;
+    configs->clear();
 
-        // TODO: this needs to go away (currently needed only by webkit)
-        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-        info->orientation = hw->getOrientation();
-    } else {
-        // TODO: where should this value come from?
-        static const int TV_DENSITY = 213;
-        info->density = TV_DENSITY / 160.0f;
-        info->orientation = 0;
+    const Vector<HWComposer::DisplayConfig>& hwConfigs =
+            getHwComposer().getConfigs(type);
+    for (size_t c = 0; c < hwConfigs.size(); ++c) {
+        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
+        DisplayInfo info = DisplayInfo();
+
+        float xdpi = hwConfig.xdpi;
+        float ydpi = hwConfig.ydpi;
+
+        if (type == DisplayDevice::DISPLAY_PRIMARY) {
+            // The density of the device is provided by a build property
+            float density = Density::getBuildDensity() / 160.0f;
+            if (density == 0) {
+                // the build doesn't provide a density -- this is wrong!
+                // use xdpi instead
+                ALOGE("ro.sf.lcd_density must be defined as a build property");
+                density = xdpi / 160.0f;
+            }
+            if (Density::getEmuDensity()) {
+                // if "qemu.sf.lcd_density" is specified, it overrides everything
+                xdpi = ydpi = density = Density::getEmuDensity();
+                density /= 160.0f;
+            }
+            info.density = density;
+
+            // TODO: this needs to go away (currently needed only by webkit)
+            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+            info.orientation = hw->getOrientation();
+        } else {
+            // TODO: where should this value come from?
+            static const int TV_DENSITY = 213;
+            info.density = TV_DENSITY / 160.0f;
+            info.orientation = 0;
+        }
+
+        info.w = hwConfig.width;
+        info.h = hwConfig.height;
+        info.xdpi = xdpi;
+        info.ydpi = ydpi;
+        info.fps = float(1e9 / hwConfig.refresh);
+
+        // All non-virtual displays are currently considered secure.
+        info.secure = true;
+
+        configs->push_back(info);
     }
 
-    info->w = hwc.getWidth(type);
-    info->h = hwc.getHeight(type);
-    info->xdpi = xdpi;
-    info->ydpi = ydpi;
-    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
+    return NO_ERROR;
+}
 
-    // All non-virtual displays are currently considered secure.
-    info->secure = true;
+int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
+    return 0;
+}
 
+status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int id) {
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 717ee66..0b868e2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -209,7 +209,10 @@
     virtual void blank(const sp<IBinder>& display);
     // called when screen is turning back on
     virtual void unblank(const sp<IBinder>& display);
-    virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
+    virtual status_t getDisplayConfigs(const sp<IBinder>& display,
+            Vector<DisplayInfo>* configs);
+    virtual int getActiveConfig(const sp<IBinder>& display);
+    virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
     virtual status_t clearAnimationFrameStats();
     virtual status_t getAnimationFrameStats(FrameStats* outStats) const;