diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index f1075b1..05e599b 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -298,7 +298,9 @@
 
         Mutex::Autolock autoLock(mLock);
 
-        if (err == ERROR_UNSUPPORTED) {
+        if (err == ERROR_UNSUPPORTED || err == -EPIPE) {
+            // These are errors that are not likely to go away even if we
+            // retry, i.e. the server doesn't support range requests or similar.
             mNumRetriesLeft = 0;
             return;
         } else if (err != OK) {
@@ -317,8 +319,14 @@
     Mutex::Autolock autoLock(mLock);
 
     if (n < 0) {
-        ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
         mFinalStatus = n;
+        if (n == ERROR_UNSUPPORTED || n == -EPIPE) {
+            // These are errors that are not likely to go away even if we
+            // retry, i.e. the server doesn't support range requests or similar.
+            mNumRetriesLeft = 0;
+        }
+
+        ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
         mCache->releasePage(page);
     } else if (n == 0) {
         ALOGI("ERROR_END_OF_STREAM");
diff --git a/media/libstagefright/wifi-display/ANetworkSession.cpp b/media/libstagefright/wifi-display/ANetworkSession.cpp
new file mode 100644
index 0000000..ee0600c
--- /dev/null
+++ b/media/libstagefright/wifi-display/ANetworkSession.cpp
@@ -0,0 +1,994 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NetworkSession"
+#include <utils/Log.h>
+
+#include "ANetworkSession.h"
+#include "ParsedMessage.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+static const size_t kMaxUDPSize = 1500;
+
+struct ANetworkSession::NetworkThread : public Thread {
+    NetworkThread(ANetworkSession *session);
+
+protected:
+    virtual ~NetworkThread();
+
+private:
+    ANetworkSession *mSession;
+
+    virtual bool threadLoop();
+
+    DISALLOW_EVIL_CONSTRUCTORS(NetworkThread);
+};
+
+struct ANetworkSession::Session : public RefBase {
+    enum State {
+        CONNECTING,
+        CONNECTED,
+        LISTENING,
+        DATAGRAM,
+    };
+
+    Session(int32_t sessionID,
+            State state,
+            int s,
+            const sp<AMessage> &notify);
+
+    int32_t sessionID() const;
+    int socket() const;
+    sp<AMessage> getNotificationMessage() const;
+
+    bool isListening() const;
+
+    bool wantsToRead();
+    bool wantsToWrite();
+
+    status_t readMore();
+    status_t writeMore();
+
+    status_t sendRequest(const void *data, ssize_t size);
+
+protected:
+    virtual ~Session();
+
+private:
+    int32_t mSessionID;
+    State mState;
+    int mSocket;
+    sp<AMessage> mNotify;
+    bool mSawReceiveFailure, mSawSendFailure;
+
+    AString mOutBuffer;
+    List<size_t> mOutBufferSizes;
+
+    AString mInBuffer;
+
+    void notifyError(bool send, status_t err, const char *detail);
+    void notify(NotificationReason reason);
+
+    DISALLOW_EVIL_CONSTRUCTORS(Session);
+};
+////////////////////////////////////////////////////////////////////////////////
+
+ANetworkSession::NetworkThread::NetworkThread(ANetworkSession *session)
+    : mSession(session) {
+}
+
+ANetworkSession::NetworkThread::~NetworkThread() {
+}
+
+bool ANetworkSession::NetworkThread::threadLoop() {
+    mSession->threadLoop();
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+ANetworkSession::Session::Session(
+        int32_t sessionID,
+        State state,
+        int s,
+        const sp<AMessage> &notify)
+    : mSessionID(sessionID),
+      mState(state),
+      mSocket(s),
+      mNotify(notify),
+      mSawReceiveFailure(false),
+      mSawSendFailure(false) {
+    if (mState == CONNECTED) {
+        struct sockaddr_in localAddr;
+        socklen_t localAddrLen = sizeof(localAddr);
+
+        int res = getsockname(
+                mSocket, (struct sockaddr *)&localAddr, &localAddrLen);
+        CHECK_GE(res, 0);
+
+        struct sockaddr_in remoteAddr;
+        socklen_t remoteAddrLen = sizeof(remoteAddr);
+
+        res = getpeername(
+                mSocket, (struct sockaddr *)&remoteAddr, &remoteAddrLen);
+        CHECK_GE(res, 0);
+
+        in_addr_t addr = ntohl(localAddr.sin_addr.s_addr);
+        AString localAddrString = StringPrintf(
+                "%d.%d.%d.%d",
+                (addr >> 24),
+                (addr >> 16) & 0xff,
+                (addr >> 8) & 0xff,
+                addr & 0xff);
+
+        addr = ntohl(remoteAddr.sin_addr.s_addr);
+        AString remoteAddrString = StringPrintf(
+                "%d.%d.%d.%d",
+                (addr >> 24),
+                (addr >> 16) & 0xff,
+                (addr >> 8) & 0xff,
+                addr & 0xff);
+
+        sp<AMessage> msg = mNotify->dup();
+        msg->setInt32("sessionID", mSessionID);
+        msg->setInt32("reason", kWhatClientConnected);
+        msg->setString("server-ip", localAddrString.c_str());
+        msg->setInt32("server-port", ntohs(localAddr.sin_port));
+        msg->setString("client-ip", remoteAddrString.c_str());
+        msg->setInt32("client-port", ntohs(remoteAddr.sin_port));
+        msg->post();
+    }
+}
+
+ANetworkSession::Session::~Session() {
+    ALOGI("Session %d gone", mSessionID);
+
+    close(mSocket);
+    mSocket = -1;
+}
+
+int32_t ANetworkSession::Session::sessionID() const {
+    return mSessionID;
+}
+
+int ANetworkSession::Session::socket() const {
+    return mSocket;
+}
+
+sp<AMessage> ANetworkSession::Session::getNotificationMessage() const {
+    return mNotify;
+}
+
+bool ANetworkSession::Session::isListening() const {
+    return mState == LISTENING;
+}
+
+bool ANetworkSession::Session::wantsToRead() {
+    return !mSawReceiveFailure && mState != CONNECTING;
+}
+
+bool ANetworkSession::Session::wantsToWrite() {
+    return !mSawSendFailure
+        && (mState == CONNECTING
+            || ((mState == CONNECTED || mState == DATAGRAM)
+                    && !mOutBuffer.empty()));
+}
+
+status_t ANetworkSession::Session::readMore() {
+    if (mState == DATAGRAM) {
+        status_t err;
+        do {
+            sp<ABuffer> buf = new ABuffer(kMaxUDPSize);
+
+            struct sockaddr_in remoteAddr;
+            socklen_t remoteAddrLen = sizeof(remoteAddr);
+
+            ssize_t n;
+            do {
+                n = recvfrom(
+                        mSocket, buf->data(), buf->capacity(), 0,
+                        (struct sockaddr *)&remoteAddr, &remoteAddrLen);
+            } while (n < 0 && errno == EINTR);
+
+            err = OK;
+            if (n < 0) {
+                err = -errno;
+            } else if (n == 0) {
+                err = -ECONNRESET;
+            } else {
+                buf->setRange(0, n);
+
+                int64_t nowUs = ALooper::GetNowUs();
+                buf->meta()->setInt64("arrivalTimeUs", nowUs);
+
+                sp<AMessage> notify = mNotify->dup();
+                notify->setInt32("sessionID", mSessionID);
+                notify->setInt32("reason", kWhatDatagram);
+
+                uint32_t ip = ntohl(remoteAddr.sin_addr.s_addr);
+                notify->setString(
+                        "fromAddr",
+                        StringPrintf(
+                            "%u.%u.%u.%u",
+                            ip >> 24,
+                            (ip >> 16) & 0xff,
+                            (ip >> 8) & 0xff,
+                            ip & 0xff).c_str());
+
+                notify->setInt32("fromPort", ntohs(remoteAddr.sin_port));
+
+                notify->setBuffer("data", buf);
+                notify->post();
+            }
+        } while (err == OK);
+
+        if (err == -EAGAIN) {
+            err = OK;
+        }
+
+        if (err != OK) {
+            notifyError(false /* send */, err, "Recvfrom failed.");
+            mSawReceiveFailure = true;
+        }
+
+        return err;
+    }
+
+    char tmp[512];
+    ssize_t n;
+    do {
+        n = recv(mSocket, tmp, sizeof(tmp), 0);
+    } while (n < 0 && errno == EINTR);
+
+    status_t err = OK;
+
+    if (n > 0) {
+        mInBuffer.append(tmp, n);
+
+#if 0
+        ALOGI("in:");
+        hexdump(tmp, n);
+#endif
+    } else if (n < 0) {
+        err = -errno;
+    } else {
+        err = -ECONNRESET;
+    }
+
+    for (;;) {
+        size_t length;
+
+        if (mInBuffer.size() > 0 && mInBuffer.c_str()[0] == '$') {
+            if (mInBuffer.size() < 4) {
+                break;
+            }
+
+            length = U16_AT((const uint8_t *)mInBuffer.c_str() + 2);
+
+            if (mInBuffer.size() < 4 + length) {
+                break;
+            }
+
+            sp<AMessage> notify = mNotify->dup();
+            notify->setInt32("sessionID", mSessionID);
+            notify->setInt32("reason", kWhatBinaryData);
+            notify->setInt32("channel", mInBuffer.c_str()[1]);
+
+            sp<ABuffer> data = new ABuffer(length);
+            memcpy(data->data(), mInBuffer.c_str() + 4, length);
+
+            int64_t nowUs = ALooper::GetNowUs();
+            data->meta()->setInt64("arrivalTimeUs", nowUs);
+
+            notify->setBuffer("data", data);
+            notify->post();
+
+            mInBuffer.erase(0, 4 + length);
+            continue;
+        }
+
+        sp<ParsedMessage> msg =
+            ParsedMessage::Parse(
+                    mInBuffer.c_str(), mInBuffer.size(), err != OK, &length);
+
+        if (msg == NULL) {
+            break;
+        }
+
+        sp<AMessage> notify = mNotify->dup();
+        notify->setInt32("sessionID", mSessionID);
+        notify->setInt32("reason", kWhatData);
+        notify->setObject("data", msg);
+        notify->post();
+
+#if 1
+        // XXX The dongle sends the wrong content length header on a
+        // SET_PARAMETER request that signals a "wfd_idr_request".
+        // (17 instead of 19).
+        const char *content = msg->getContent();
+        if (content && !memcmp(content, "wfd_idr_request\r\n", 17)) {
+            length += 2;
+        }
+#endif
+
+        mInBuffer.erase(0, length);
+
+        if (err != OK) {
+            break;
+        }
+    }
+
+    if (err != OK) {
+        notifyError(false /* send */, err, "Recv failed.");
+        mSawReceiveFailure = true;
+    }
+
+    return err;
+}
+
+status_t ANetworkSession::Session::writeMore() {
+    if (mState == DATAGRAM) {
+        CHECK(!mOutBufferSizes.empty());
+
+        status_t err;
+        do {
+            size_t size = *mOutBufferSizes.begin();
+
+            CHECK_GE(mOutBuffer.size(), size);
+
+            int n;
+            do {
+                n = send(mSocket, mOutBuffer.c_str(), size, 0);
+            } while (n < 0 && errno == EINTR);
+
+            err = OK;
+
+            if (n > 0) {
+                mOutBufferSizes.erase(mOutBufferSizes.begin());
+                mOutBuffer.erase(0, n);
+            } else if (n < 0) {
+                err = -errno;
+            } else if (n == 0) {
+                err = -ECONNRESET;
+            }
+        } while (err == OK && !mOutBufferSizes.empty());
+
+        if (err == -EAGAIN) {
+            err = OK;
+        }
+
+        if (err != OK) {
+            notifyError(true /* send */, err, "Send datagram failed.");
+            mSawSendFailure = true;
+        }
+
+        return err;
+    }
+
+    if (mState == CONNECTING) {
+        int err;
+        socklen_t optionLen = sizeof(err);
+        CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0);
+        CHECK_EQ(optionLen, (socklen_t)sizeof(err));
+
+        if (err != 0) {
+            notifyError(kWhatError, -err, "Connection failed");
+            mSawSendFailure = true;
+
+            return UNKNOWN_ERROR;
+        }
+
+        mState = CONNECTED;
+        notify(kWhatConnected);
+
+        return OK;
+    }
+
+    CHECK_EQ(mState, CONNECTED);
+    CHECK(!mOutBuffer.empty());
+
+    ssize_t n;
+    do {
+        n = send(mSocket, mOutBuffer.c_str(), mOutBuffer.size(), 0);
+    } while (n < 0 && errno == EINTR);
+
+    status_t err = OK;
+
+    if (n > 0) {
+        ALOGI("out:");
+        hexdump(mOutBuffer.c_str(), n);
+
+        mOutBuffer.erase(0, n);
+    } else if (n < 0) {
+        err = -errno;
+    } else if (n == 0) {
+        err = -ECONNRESET;
+    }
+
+    if (err != OK) {
+        notifyError(true /* send */, err, "Send failed.");
+        mSawSendFailure = true;
+    }
+
+    return err;
+}
+
+status_t ANetworkSession::Session::sendRequest(const void *data, ssize_t size) {
+    CHECK(mState == CONNECTED || mState == DATAGRAM);
+
+    mOutBuffer.append(
+            (const char *)data,
+            (size >= 0) ? size : strlen((const char *)data));
+
+    if (mState == DATAGRAM) {
+        CHECK_GE(size, 0);
+        mOutBufferSizes.push_back(size);
+    }
+
+    return OK;
+}
+
+void ANetworkSession::Session::notifyError(
+        bool send, status_t err, const char *detail) {
+    sp<AMessage> msg = mNotify->dup();
+    msg->setInt32("sessionID", mSessionID);
+    msg->setInt32("reason", kWhatError);
+    msg->setInt32("send", send);
+    msg->setInt32("err", err);
+    msg->setString("detail", detail);
+    msg->post();
+}
+
+void ANetworkSession::Session::notify(NotificationReason reason) {
+    sp<AMessage> msg = mNotify->dup();
+    msg->setInt32("sessionID", mSessionID);
+    msg->setInt32("reason", reason);
+    msg->post();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+ANetworkSession::ANetworkSession()
+    : mNextSessionID(1) {
+    mPipeFd[0] = mPipeFd[1] = -1;
+}
+
+ANetworkSession::~ANetworkSession() {
+    stop();
+}
+
+status_t ANetworkSession::start() {
+    if (mThread != NULL) {
+        return INVALID_OPERATION;
+    }
+
+    int res = pipe(mPipeFd);
+    if (res != 0) {
+        mPipeFd[0] = mPipeFd[1] = -1;
+        return -errno;
+    }
+
+    mThread = new NetworkThread(this);
+
+    status_t err = mThread->run("ANetworkSession", ANDROID_PRIORITY_AUDIO);
+
+    if (err != OK) {
+        mThread.clear();
+
+        close(mPipeFd[0]);
+        close(mPipeFd[1]);
+        mPipeFd[0] = mPipeFd[1] = -1;
+
+        return err;
+    }
+
+    return OK;
+}
+
+status_t ANetworkSession::stop() {
+    if (mThread == NULL) {
+        return INVALID_OPERATION;
+    }
+
+    mThread->requestExit();
+    interrupt();
+    mThread->requestExitAndWait();
+
+    mThread.clear();
+
+    close(mPipeFd[0]);
+    close(mPipeFd[1]);
+    mPipeFd[0] = mPipeFd[1] = -1;
+
+    return OK;
+}
+
+status_t ANetworkSession::createRTSPClient(
+        const char *host, unsigned port, const sp<AMessage> &notify,
+        int32_t *sessionID) {
+    return createClientOrServer(
+            kModeCreateRTSPClient,
+            0 /* port */,
+            host,
+            port,
+            notify,
+            sessionID);
+}
+
+status_t ANetworkSession::createRTSPServer(
+        unsigned port, const sp<AMessage> &notify, int32_t *sessionID) {
+    return createClientOrServer(
+            kModeCreateRTSPServer,
+            port,
+            NULL /* remoteHost */,
+            0 /* remotePort */,
+            notify,
+            sessionID);
+}
+
+status_t ANetworkSession::createUDPSession(
+        unsigned localPort, const sp<AMessage> &notify, int32_t *sessionID) {
+    return createUDPSession(localPort, NULL, 0, notify, sessionID);
+}
+
+status_t ANetworkSession::createUDPSession(
+        unsigned localPort,
+        const char *remoteHost,
+        unsigned remotePort,
+        const sp<AMessage> &notify,
+        int32_t *sessionID) {
+    return createClientOrServer(
+            kModeCreateUDPSession,
+            localPort,
+            remoteHost,
+            remotePort,
+            notify,
+            sessionID);
+}
+
+status_t ANetworkSession::destroySession(int32_t sessionID) {
+    Mutex::Autolock autoLock(mLock);
+
+    ssize_t index = mSessions.indexOfKey(sessionID);
+
+    if (index < 0) {
+        return -ENOENT;
+    }
+
+    mSessions.removeItemsAt(index);
+
+    interrupt();
+
+    return OK;
+}
+
+// static
+status_t ANetworkSession::MakeSocketNonBlocking(int s) {
+    int flags = fcntl(s, F_GETFL, 0);
+    if (flags < 0) {
+        flags = 0;
+    }
+
+    int res = fcntl(s, F_SETFL, flags | O_NONBLOCK);
+    if (res < 0) {
+        return -errno;
+    }
+
+    return OK;
+}
+
+status_t ANetworkSession::createClientOrServer(
+        Mode mode,
+        unsigned port,
+        const char *remoteHost,
+        unsigned remotePort,
+        const sp<AMessage> &notify,
+        int32_t *sessionID) {
+    Mutex::Autolock autoLock(mLock);
+
+    *sessionID = 0;
+    status_t err = OK;
+    int s, res;
+    sp<Session> session;
+
+    s = socket(
+            AF_INET,
+            (mode == kModeCreateUDPSession) ? SOCK_DGRAM : SOCK_STREAM,
+            0);
+
+    if (s < 0) {
+        err = -errno;
+        goto bail;
+    }
+
+    if (mode == kModeCreateRTSPServer) {
+        const int yes = 1;
+        res = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
+
+        if (res < 0) {
+            err = -errno;
+            goto bail2;
+        }
+    }
+
+    if (mode == kModeCreateUDPSession) {
+        int size = 256 * 1024;
+
+        res = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+
+        if (res < 0) {
+            err = -errno;
+            goto bail2;
+        }
+
+        res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+
+        if (res < 0) {
+            err = -errno;
+            goto bail2;
+        }
+    }
+
+    err = MakeSocketNonBlocking(s);
+
+    if (err != OK) {
+        goto bail2;
+    }
+
+    struct sockaddr_in addr;
+    memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+    addr.sin_family = AF_INET;
+
+    if (mode == kModeCreateRTSPClient) {
+        struct hostent *ent= gethostbyname(remoteHost);
+        if (ent == NULL) {
+            err = -h_errno;
+            goto bail2;
+        }
+
+        addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
+        addr.sin_port = htons(remotePort);
+    } else {
+        addr.sin_addr.s_addr = INADDR_ANY;
+        addr.sin_port = htons(port);
+    }
+
+    if (mode == kModeCreateRTSPClient) {
+        res = connect(s, (const struct sockaddr *)&addr, sizeof(addr));
+
+        CHECK_LT(res, 0);
+        if (errno == EINPROGRESS) {
+            res = 0;
+        }
+    } else {
+        res = bind(s, (const struct sockaddr *)&addr, sizeof(addr));
+
+        if (res == 0) {
+            if (mode == kModeCreateRTSPServer) {
+                res = listen(s, 4);
+            } else {
+                CHECK_EQ(mode, kModeCreateUDPSession);
+
+                if (remoteHost != NULL) {
+                    struct sockaddr_in remoteAddr;
+                    memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero));
+                    remoteAddr.sin_family = AF_INET;
+                    remoteAddr.sin_port = htons(remotePort);
+
+                    struct hostent *ent= gethostbyname(remoteHost);
+                    if (ent == NULL) {
+                        err = -h_errno;
+                        goto bail2;
+                    }
+
+                    remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
+
+                    res = connect(
+                            s,
+                            (const struct sockaddr *)&remoteAddr,
+                            sizeof(remoteAddr));
+                }
+            }
+        }
+    }
+
+    if (res < 0) {
+        err = -errno;
+        goto bail2;
+    }
+
+    Session::State state;
+    switch (mode) {
+        case kModeCreateRTSPClient:
+            state = Session::CONNECTING;
+            break;
+
+        case kModeCreateRTSPServer:
+            state = Session::LISTENING;
+            break;
+
+        default:
+            CHECK_EQ(mode, kModeCreateUDPSession);
+            state = Session::DATAGRAM;
+            break;
+    }
+
+    session = new Session(
+            mNextSessionID++,
+            state,
+            s,
+            notify);
+
+    mSessions.add(session->sessionID(), session);
+
+    interrupt();
+
+    *sessionID = session->sessionID();
+
+    goto bail;
+
+bail2:
+    close(s);
+    s = -1;
+
+bail:
+    return err;
+}
+
+status_t ANetworkSession::connectUDPSession(
+        int32_t sessionID, const char *remoteHost, unsigned remotePort) {
+    Mutex::Autolock autoLock(mLock);
+
+    ssize_t index = mSessions.indexOfKey(sessionID);
+
+    if (index < 0) {
+        return -ENOENT;
+    }
+
+    const sp<Session> session = mSessions.valueAt(index);
+    int s = session->socket();
+
+    struct sockaddr_in remoteAddr;
+    memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero));
+    remoteAddr.sin_family = AF_INET;
+    remoteAddr.sin_port = htons(remotePort);
+
+    status_t err = OK;
+    struct hostent *ent= gethostbyname(remoteHost);
+    if (ent == NULL) {
+        err = -h_errno;
+    } else {
+        remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
+
+        int res = connect(
+                s,
+                (const struct sockaddr *)&remoteAddr,
+                sizeof(remoteAddr));
+
+        if (res < 0) {
+            err = -errno;
+        }
+    }
+
+    return err;
+}
+
+status_t ANetworkSession::sendRequest(
+        int32_t sessionID, const void *data, ssize_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    ssize_t index = mSessions.indexOfKey(sessionID);
+
+    if (index < 0) {
+        return -ENOENT;
+    }
+
+    const sp<Session> session = mSessions.valueAt(index);
+
+    status_t err = session->sendRequest(data, size);
+
+    interrupt();
+
+    return err;
+}
+
+void ANetworkSession::interrupt() {
+    static const char dummy = 0;
+
+    ssize_t n;
+    do {
+        n = write(mPipeFd[1], &dummy, 1);
+    } while (n < 0 && errno == EINTR);
+
+    if (n < 0) {
+        ALOGW("Error writing to pipe (%s)", strerror(errno));
+    }
+}
+
+void ANetworkSession::threadLoop() {
+    fd_set rs, ws;
+    FD_ZERO(&rs);
+    FD_ZERO(&ws);
+
+    FD_SET(mPipeFd[0], &rs);
+    int maxFd = mPipeFd[0];
+
+    {
+        Mutex::Autolock autoLock(mLock);
+
+        for (size_t i = 0; i < mSessions.size(); ++i) {
+            const sp<Session> &session = mSessions.valueAt(i);
+
+            int s = session->socket();
+
+            if (s < 0) {
+                continue;
+            }
+
+            if (session->wantsToRead()) {
+                FD_SET(s, &rs);
+                if (s > maxFd) {
+                    maxFd = s;
+                }
+            }
+
+            if (session->wantsToWrite()) {
+                FD_SET(s, &ws);
+                if (s > maxFd) {
+                    maxFd = s;
+                }
+            }
+        }
+    }
+
+    int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */);
+
+    if (res == 0) {
+        return;
+    }
+
+    if (res < 0) {
+        if (errno == EINTR) {
+            return;
+        }
+
+        ALOGE("select failed w/ error %d (%s)", errno, strerror(errno));
+        return;
+    }
+
+    if (FD_ISSET(mPipeFd[0], &rs)) {
+        char c;
+        ssize_t n;
+        do {
+            n = read(mPipeFd[0], &c, 1);
+        } while (n < 0 && errno == EINTR);
+
+        if (n < 0) {
+            ALOGW("Error reading from pipe (%s)", strerror(errno));
+        }
+
+        --res;
+    }
+
+    {
+        Mutex::Autolock autoLock(mLock);
+
+        List<sp<Session> > sessionsToAdd;
+
+        for (size_t i = mSessions.size(); res > 0 && i-- > 0;) {
+            const sp<Session> &session = mSessions.valueAt(i);
+
+            int s = session->socket();
+
+            if (s < 0) {
+                continue;
+            }
+
+            if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
+                --res;
+            }
+
+            if (FD_ISSET(s, &rs)) {
+                if (session->isListening()) {
+                    struct sockaddr_in remoteAddr;
+                    socklen_t remoteAddrLen = sizeof(remoteAddr);
+
+                    int clientSocket = accept(
+                            s, (struct sockaddr *)&remoteAddr, &remoteAddrLen);
+
+                    if (clientSocket >= 0) {
+                        status_t err = MakeSocketNonBlocking(clientSocket);
+
+                        if (err != OK) {
+                            ALOGE("Unable to make client socket non blocking, "
+                                  "failed w/ error %d (%s)",
+                                  err, strerror(-err));
+
+                            close(clientSocket);
+                            clientSocket = -1;
+                        } else {
+                            in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr);
+
+                            ALOGI("incoming connection from %d.%d.%d.%d:%d "
+                                  "(socket %d)",
+                                  (addr >> 24),
+                                  (addr >> 16) & 0xff,
+                                  (addr >> 8) & 0xff,
+                                  addr & 0xff,
+                                  ntohs(remoteAddr.sin_port),
+                                  clientSocket);
+
+                            sp<Session> clientSession =
+                                // using socket sd as sessionID
+                                new Session(
+                                        mNextSessionID++,
+                                        Session::CONNECTED,
+                                        clientSocket,
+                                        session->getNotificationMessage());
+
+                            sessionsToAdd.push_back(clientSession);
+                        }
+                    } else {
+                        ALOGE("accept returned error %d (%s)",
+                              errno, strerror(errno));
+                    }
+                } else {
+                    status_t err = session->readMore();
+                    if (err != OK) {
+                        ALOGI("readMore on socket %d failed w/ error %d (%s)",
+                              s, err, strerror(-err));
+                    }
+                }
+            }
+
+            if (FD_ISSET(s, &ws)) {
+                status_t err = session->writeMore();
+                if (err != OK) {
+                    ALOGI("writeMore on socket %d failed w/ error %d (%s)",
+                          s, err, strerror(-err));
+                }
+            }
+        }
+
+        while (!sessionsToAdd.empty()) {
+            sp<Session> session = *sessionsToAdd.begin();
+            sessionsToAdd.erase(sessionsToAdd.begin());
+
+            mSessions.add(session->sessionID(), session);
+
+            ALOGI("added clientSession %d", session->sessionID());
+        }
+    }
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/ANetworkSession.h b/media/libstagefright/wifi-display/ANetworkSession.h
new file mode 100644
index 0000000..0402317
--- /dev/null
+++ b/media/libstagefright/wifi-display/ANetworkSession.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_NETWORK_SESSION_H_
+
+#define A_NETWORK_SESSION_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/Thread.h>
+
+namespace android {
+
+struct AMessage;
+
+struct ANetworkSession : public RefBase {
+    ANetworkSession();
+
+    status_t start();
+    status_t stop();
+
+    status_t createRTSPClient(
+            const char *host, unsigned port, const sp<AMessage> &notify,
+            int32_t *sessionID);
+
+    status_t createRTSPServer(
+            unsigned port, const sp<AMessage> &notify, int32_t *sessionID);
+
+    status_t createUDPSession(
+            unsigned localPort, const sp<AMessage> &notify, int32_t *sessionID);
+
+    status_t createUDPSession(
+            unsigned localPort,
+            const char *remoteHost,
+            unsigned remotePort,
+            const sp<AMessage> &notify,
+            int32_t *sessionID);
+
+    status_t connectUDPSession(
+            int32_t sessionID, const char *remoteHost, unsigned remotePort);
+
+    status_t destroySession(int32_t sessionID);
+
+    status_t sendRequest(
+            int32_t sessionID, const void *data, ssize_t size = -1);
+
+    enum NotificationReason {
+        kWhatError,
+        kWhatConnected,
+        kWhatClientConnected,
+        kWhatData,
+        kWhatDatagram,
+        kWhatBinaryData,
+    };
+
+protected:
+    virtual ~ANetworkSession();
+
+private:
+    struct NetworkThread;
+    struct Session;
+
+    Mutex mLock;
+    sp<Thread> mThread;
+
+    int32_t mNextSessionID;
+
+    int mPipeFd[2];
+
+    KeyedVector<int32_t, sp<Session> > mSessions;
+
+    enum Mode {
+        kModeCreateUDPSession,
+        kModeCreateRTSPServer,
+        kModeCreateRTSPClient,
+    };
+    status_t createClientOrServer(
+            Mode mode,
+            unsigned port,
+            const char *remoteHost,
+            unsigned remotePort,
+            const sp<AMessage> &notify,
+            int32_t *sessionID);
+
+    void threadLoop();
+    void interrupt();
+
+    static status_t MakeSocketNonBlocking(int s);
+
+    DISALLOW_EVIL_CONSTRUCTORS(ANetworkSession);
+};
+
+}  // namespace android
+
+#endif  // A_NETWORK_SESSION_H_
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
new file mode 100644
index 0000000..114ff62
--- /dev/null
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+        udptest.cpp                 \
+        ANetworkSession.cpp         \
+        ParsedMessage.cpp           \
+
+LOCAL_SHARED_LIBRARIES:= \
+        libbinder                       \
+        libgui                          \
+        libmedia                        \
+        libstagefright                  \
+        libstagefright_foundation       \
+        libutils                        \
+
+LOCAL_MODULE:= udptest
+
+LOCAL_MODULE_TAGS := debug
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/wifi-display/ParsedMessage.cpp b/media/libstagefright/wifi-display/ParsedMessage.cpp
new file mode 100644
index 0000000..c0e60c3
--- /dev/null
+++ b/media/libstagefright/wifi-display/ParsedMessage.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ParsedMessage.h"
+
+#include <ctype.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+// static
+sp<ParsedMessage> ParsedMessage::Parse(
+        const char *data, size_t size, bool noMoreData, size_t *length) {
+    sp<ParsedMessage> msg = new ParsedMessage;
+    ssize_t res = msg->parse(data, size, noMoreData);
+
+    if (res < 0) {
+        *length = 0;
+        return NULL;
+    }
+
+    *length = res;
+    return msg;
+}
+
+ParsedMessage::ParsedMessage() {
+}
+
+ParsedMessage::~ParsedMessage() {
+}
+
+bool ParsedMessage::findString(const char *name, AString *value) const {
+    AString key = name;
+    key.tolower();
+
+    ssize_t index = mDict.indexOfKey(key);
+
+    if (index < 0) {
+        value->clear();
+
+        return false;
+    }
+
+    *value = mDict.valueAt(index);
+    return true;
+}
+
+bool ParsedMessage::findInt32(const char *name, int32_t *value) const {
+    AString stringValue;
+
+    if (!findString(name, &stringValue)) {
+        return false;
+    }
+
+    char *end;
+    *value = strtol(stringValue.c_str(), &end, 10);
+
+    if (end == stringValue.c_str() || *end != '\0') {
+        *value = 0;
+        return false;
+    }
+
+    return true;
+}
+
+const char *ParsedMessage::getContent() const {
+    return mContent.c_str();
+}
+
+ssize_t ParsedMessage::parse(const char *data, size_t size, bool noMoreData) {
+    if (size == 0) {
+        return -1;
+    }
+
+    ssize_t lastDictIndex = -1;
+
+    size_t offset = 0;
+    while (offset < size) {
+        size_t lineEndOffset = offset;
+        while (lineEndOffset + 1 < size
+                && (data[lineEndOffset] != '\r'
+                        || data[lineEndOffset + 1] != '\n')) {
+            ++lineEndOffset;
+        }
+
+        if (lineEndOffset + 1 >= size) {
+            return -1;
+        }
+
+        AString line(&data[offset], lineEndOffset - offset);
+
+        if (offset == 0) {
+            // Special handling for the request/status line.
+
+            mDict.add(AString("_"), line);
+            offset = lineEndOffset + 2;
+
+            continue;
+        }
+
+        if (lineEndOffset == offset) {
+            offset += 2;
+            break;
+        }
+
+        if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {
+            // Support for folded header values.
+
+            if (lastDictIndex >= 0) {
+                // Otherwise it's malformed since the first header line
+                // cannot continue anything...
+
+                AString &value = mDict.editValueAt(lastDictIndex);
+                value.append(line);
+            }
+
+            offset = lineEndOffset + 2;
+            continue;
+        }
+
+        ssize_t colonPos = line.find(":");
+        if (colonPos >= 0) {
+            AString key(line, 0, colonPos);
+            key.trim();
+            key.tolower();
+
+            line.erase(0, colonPos + 1);
+
+            lastDictIndex = mDict.add(key, line);
+        }
+
+        offset = lineEndOffset + 2;
+    }
+
+    for (size_t i = 0; i < mDict.size(); ++i) {
+        mDict.editValueAt(i).trim();
+    }
+
+    // Found the end of headers.
+
+    int32_t contentLength;
+    if (!findInt32("content-length", &contentLength) || contentLength < 0) {
+        contentLength = 0;
+    }
+
+    size_t totalLength = offset + contentLength;
+
+    if (size < totalLength) {
+        return -1;
+    }
+
+    mContent.setTo(&data[offset], contentLength);
+
+    return totalLength;
+}
+
+void ParsedMessage::getRequestField(size_t index, AString *field) const {
+    AString line;
+    CHECK(findString("_", &line));
+
+    size_t prevOffset = 0;
+    size_t offset = 0;
+    for (size_t i = 0; i <= index; ++i) {
+        ssize_t spacePos = line.find(" ", offset);
+
+        if (spacePos < 0) {
+            spacePos = line.size();
+        }
+
+        prevOffset = offset;
+        offset = spacePos + 1;
+    }
+
+    field->setTo(line, prevOffset, offset - prevOffset - 1);
+}
+
+bool ParsedMessage::getStatusCode(int32_t *statusCode) const {
+    AString statusCodeString;
+    getRequestField(1, &statusCodeString);
+
+    char *end;
+    *statusCode = strtol(statusCodeString.c_str(), &end, 10);
+
+    if (*end != '\0' || end == statusCodeString.c_str()
+            || (*statusCode) < 100 || (*statusCode) > 999) {
+        *statusCode = 0;
+        return false;
+    }
+
+    return true;
+}
+
+AString ParsedMessage::debugString() const {
+    AString line;
+    CHECK(findString("_", &line));
+
+    line.append("\n");
+
+    for (size_t i = 0; i < mDict.size(); ++i) {
+        const AString &key = mDict.keyAt(i);
+        const AString &value = mDict.valueAt(i);
+
+        if (key == AString("_")) {
+            continue;
+        }
+
+        line.append(key);
+        line.append(": ");
+        line.append(value);
+        line.append("\n");
+    }
+
+    line.append("\n");
+    line.append(mContent);
+
+    return line;
+}
+
+// static
+bool ParsedMessage::GetAttribute(
+        const char *s, const char *key, AString *value) {
+    value->clear();
+
+    size_t keyLen = strlen(key);
+
+    for (;;) {
+        while (isspace(*s)) {
+            ++s;
+        }
+
+        const char *colonPos = strchr(s, ';');
+
+        size_t len =
+            (colonPos == NULL) ? strlen(s) : colonPos - s;
+
+        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
+            value->setTo(&s[keyLen + 1], len - keyLen - 1);
+            return true;
+        }
+
+        if (colonPos == NULL) {
+            return false;
+        }
+
+        s = colonPos + 1;
+    }
+}
+
+// static
+bool ParsedMessage::GetInt32Attribute(
+        const char *s, const char *key, int32_t *value) {
+    AString stringValue;
+    if (!GetAttribute(s, key, &stringValue)) {
+        *value = 0;
+        return false;
+    }
+
+    char *end;
+    *value = strtol(stringValue.c_str(), &end, 10);
+
+    if (end == stringValue.c_str() || *end != '\0') {
+        *value = 0;
+        return false;
+    }
+
+    return true;
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/ParsedMessage.h b/media/libstagefright/wifi-display/ParsedMessage.h
new file mode 100644
index 0000000..00f578f
--- /dev/null
+++ b/media/libstagefright/wifi-display/ParsedMessage.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ParsedMessage : public RefBase {
+    static sp<ParsedMessage> Parse(
+            const char *data, size_t size, bool noMoreData, size_t *length);
+
+    bool findString(const char *name, AString *value) const;
+    bool findInt32(const char *name, int32_t *value) const;
+
+    const char *getContent() const;
+
+    void getRequestField(size_t index, AString *field) const;
+    bool getStatusCode(int32_t *statusCode) const;
+
+    AString debugString() const;
+
+    static bool GetAttribute(const char *s, const char *key, AString *value);
+
+    static bool GetInt32Attribute(
+            const char *s, const char *key, int32_t *value);
+
+
+protected:
+    virtual ~ParsedMessage();
+
+private:
+    KeyedVector<AString, AString> mDict;
+    AString mContent;
+
+    ParsedMessage();
+
+    ssize_t parse(const char *data, size_t size, bool noMoreData);
+
+    DISALLOW_EVIL_CONSTRUCTORS(ParsedMessage);
+};
+
+}  // namespace android
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 079599a..391c319 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -11,7 +11,8 @@
     CameraClient.cpp \
     Camera2Client.cpp \
     Camera2Device.cpp \
-    CameraMetadata.cpp
+    camera2/CameraMetadata.cpp \
+    camera2/Parameters.cpp
 
 LOCAL_SHARED_LIBRARIES:= \
     libui \
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 3f12ed0..9b6401b 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -26,15 +26,15 @@
 #include <gui/Surface.h>
 #include <media/hardware/MetadataBufferType.h>
 
-#include <math.h>
-
 #include "Camera2Client.h"
 
-namespace android {
-
 #define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
 #define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
 
+namespace android {
+
+using namespace camera2;
+
 static int getCallingPid() {
     return IPCThreadState::self()->getCallingPid();
 }
@@ -52,7 +52,7 @@
         int clientPid):
         Client(cameraService, cameraClient,
                 cameraId, cameraFacing, clientPid),
-        mDeviceInfo(NULL),
+        mParameters(cameraId, cameraFacing),
         mPreviewStreamId(NO_STREAM),
         mCallbackStreamId(NO_STREAM),
         mCallbackHeapId(0),
@@ -65,8 +65,8 @@
 
     mDevice = new Camera2Device(cameraId);
 
-    LockedParameters::Key k(mParameters);
-    k.mParameters.state = DISCONNECTED;
+    SharedParameters::Lock l(mParameters);
+    l.mParameters.state = Parameters::DISCONNECTED;
 }
 
 status_t Camera2Client::checkPid(const char* checkLocation) const {
@@ -98,8 +98,9 @@
 
     res = mDevice->setNotifyCallback(this);
 
-    res = buildDeviceInfo();
-    res = buildDefaultParameters();
+    SharedParameters::Lock l(mParameters);
+
+    res = l.mParameters.initialize(&(mDevice->info()));
     if (res != OK) {
         ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
                 __FUNCTION__, mCameraId, strerror(-res), res);
@@ -107,10 +108,9 @@
     }
 
     if (gLogLevel >= 1) {
-        LockedParameters::Key k(mParameters);
         ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
               mCameraId);
-        ALOGD("%s", k.mParameters.paramsFlattened.string());
+        ALOGD("%s", l.mParameters.paramsFlattened.string());
     }
 
     return OK;
@@ -139,9 +139,9 @@
     result.append("  State: ");
 #define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
 
-    const Parameters& p = mParameters.unsafeUnlock();
+    const Parameters& p = mParameters.unsafeAccess();
 
-    result.append(getStateName(p.state));
+    result.append(Parameters::getStateName(p.state));
 
     result.append("\n  Current parameters:\n");
     result.appendFormat("    Preview size: %d x %d\n",
@@ -339,23 +339,6 @@
     return NO_ERROR;
 }
 
-const char* Camera2Client::getStateName(State state) {
-#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
-    switch(state) {
-        CASE_ENUM_TO_CHAR(DISCONNECTED)
-        CASE_ENUM_TO_CHAR(STOPPED)
-        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
-        CASE_ENUM_TO_CHAR(PREVIEW)
-        CASE_ENUM_TO_CHAR(RECORD)
-        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
-        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
-        default:
-            return "Unknown state!";
-            break;
-    }
-#undef CASE_ENUM_TO_CHAR
-}
-
 // ICamera interface
 
 void Camera2Client::disconnect() {
@@ -390,13 +373,8 @@
     }
 
     mDevice.clear();
-    LockedParameters::Key k(mParameters);
-    k.mParameters.state = DISCONNECTED;
-
-    if (mDeviceInfo != NULL) {
-        delete mDeviceInfo;
-        mDeviceInfo = NULL;
-    }
+    SharedParameters::Lock l(mParameters);
+    l.mParameters.state = Parameters::DISCONNECTED;
 
     CameraService::Client::disconnect();
 }
@@ -418,8 +396,8 @@
     Mutex::Autolock iccl(mICameraClientLock);
     mCameraClient = client;
 
-    LockedParameters::Key k(mParameters);
-    k.mParameters.state = STOPPED;
+    SharedParameters::Lock l(mParameters);
+    l.mParameters.state = Parameters::STOPPED;
 
     return OK;
 }
@@ -513,25 +491,26 @@
         return NO_ERROR;
     }
 
-    LockedParameters::Key k(mParameters);
-    switch (k.mParameters.state) {
-        case DISCONNECTED:
-        case RECORD:
-        case STILL_CAPTURE:
-        case VIDEO_SNAPSHOT:
+    SharedParameters::Lock l(mParameters);
+    switch (l.mParameters.state) {
+        case Parameters::DISCONNECTED:
+        case Parameters::RECORD:
+        case Parameters::STILL_CAPTURE:
+        case Parameters::VIDEO_SNAPSHOT:
             ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
-                    __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
+                    __FUNCTION__, mCameraId,
+                    Parameters::getStateName(l.mParameters.state));
             return INVALID_OPERATION;
-        case STOPPED:
-        case WAITING_FOR_PREVIEW_WINDOW:
+        case Parameters::STOPPED:
+        case Parameters::WAITING_FOR_PREVIEW_WINDOW:
             // OK
             break;
-        case PREVIEW:
+        case Parameters::PREVIEW:
             // Already running preview - need to stop and create a new stream
             // TODO: Optimize this so that we don't wait for old stream to drain
             // before spinning up new stream
             mDevice->clearStreamingRequest();
-            k.mParameters.state = WAITING_FOR_PREVIEW_WINDOW;
+            l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
             break;
     }
 
@@ -554,8 +533,8 @@
     mPreviewSurface = binder;
     mPreviewWindow = window;
 
-    if (k.mParameters.state == WAITING_FOR_PREVIEW_WINDOW) {
-        return startPreviewL(k.mParameters, false);
+    if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) {
+        return startPreviewL(l.mParameters, false);
     }
 
     return OK;
@@ -568,8 +547,8 @@
     status_t res;
     if ( checkPid(__FUNCTION__) != OK) return;
 
-    LockedParameters::Key k(mParameters);
-    setPreviewCallbackFlagL(k.mParameters, flag);
+    SharedParameters::Lock l(mParameters);
+    setPreviewCallbackFlagL(l.mParameters, flag);
 }
 
 void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
@@ -581,11 +560,11 @@
     if (params.previewCallbackFlags != (uint32_t)flag) {
         params.previewCallbackFlags = flag;
         switch(params.state) {
-        case PREVIEW:
+        case Parameters::PREVIEW:
             res = startPreviewL(params, true);
             break;
-        case RECORD:
-        case VIDEO_SNAPSHOT:
+        case Parameters::RECORD:
+        case Parameters::VIDEO_SNAPSHOT:
             res = startRecordingL(params, true);
             break;
         default:
@@ -593,7 +572,8 @@
         }
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to refresh request in state %s",
-                    __FUNCTION__, mCameraId, getStateName(params.state));
+                    __FUNCTION__, mCameraId,
+                    Parameters::getStateName(params.state));
         }
     }
 
@@ -605,24 +585,25 @@
     Mutex::Autolock icl(mICameraLock);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
-    LockedParameters::Key k(mParameters);
-    return startPreviewL(k.mParameters, false);
+    SharedParameters::Lock l(mParameters);
+    return startPreviewL(l.mParameters, false);
 }
 
 status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
     ATRACE_CALL();
     status_t res;
-    if (params.state >= PREVIEW && !restart) {
+    if (params.state >= Parameters::PREVIEW && !restart) {
         ALOGE("%s: Can't start preview in state %s",
-                __FUNCTION__, getStateName(params.state));
+                __FUNCTION__,
+                Parameters::getStateName(params.state));
         return INVALID_OPERATION;
     }
 
     if (mPreviewWindow == 0) {
-        params.state = WAITING_FOR_PREVIEW_WINDOW;
+        params.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
         return OK;
     }
-    params.state = STOPPED;
+    params.state = Parameters::STOPPED;
 
     res = updatePreviewStream(params);
     if (res != OK) {
@@ -681,7 +662,7 @@
                 __FUNCTION__, mCameraId, strerror(-res), res);
         return res;
     }
-    params.state = PREVIEW;
+    params.state = Parameters::PREVIEW;
 
     return OK;
 }
@@ -697,33 +678,33 @@
 
 void Camera2Client::stopPreviewL() {
     ATRACE_CALL();
-    State state;
+    Parameters::State state;
     {
-        LockedParameters::Key k(mParameters);
-        state = k.mParameters.state;
+        SharedParameters::Lock l(mParameters);
+        state = l.mParameters.state;
     }
 
     switch (state) {
-        case DISCONNECTED:
+        case Parameters::DISCONNECTED:
             ALOGE("%s: Camera %d: Call before initialized",
                     __FUNCTION__, mCameraId);
             break;
-        case STOPPED:
+        case Parameters::STOPPED:
             break;
-        case STILL_CAPTURE:
+        case Parameters::STILL_CAPTURE:
             ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
                     __FUNCTION__, mCameraId);
             break;
-        case RECORD:
+        case Parameters::RECORD:
             // no break - identical to preview
-        case PREVIEW:
+        case Parameters::PREVIEW:
             mDevice->clearStreamingRequest();
             mDevice->waitUntilDrained();
             // no break
-        case WAITING_FOR_PREVIEW_WINDOW: {
-            LockedParameters::Key k(mParameters);
-            k.mParameters.state = STOPPED;
-            commandStopFaceDetectionL(k.mParameters);
+        case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
+            SharedParameters::Lock l(mParameters);
+            l.mParameters.state = Parameters::STOPPED;
+            commandStopFaceDetectionL(l.mParameters);
             break;
         }
         default:
@@ -738,8 +719,8 @@
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
 
-    LockedParameters::Key k(mParameters);
-    return k.mParameters.state == PREVIEW;
+    SharedParameters::Lock l(mParameters);
+    return l.mParameters.state == Parameters::PREVIEW;
 }
 
 status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
@@ -748,19 +729,20 @@
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
-    LockedParameters::Key k(mParameters);
-    switch (k.mParameters.state) {
-        case RECORD:
-        case VIDEO_SNAPSHOT:
+    SharedParameters::Lock l(mParameters);
+    switch (l.mParameters.state) {
+        case Parameters::RECORD:
+        case Parameters::VIDEO_SNAPSHOT:
             ALOGE("%s: Camera %d: Can't be called in state %s",
-                    __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
+                    __FUNCTION__, mCameraId,
+                    Parameters::getStateName(l.mParameters.state));
             return INVALID_OPERATION;
         default:
             // OK
             break;
     }
 
-    k.mParameters.storeMetadataInBuffers = enabled;
+    l.mParameters.storeMetadataInBuffers = enabled;
 
     return OK;
 }
@@ -771,30 +753,31 @@
     Mutex::Autolock icl(mICameraLock);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
 
-    return startRecordingL(k.mParameters, false);
+    return startRecordingL(l.mParameters, false);
 }
 
 status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
     status_t res;
     switch (params.state) {
-        case STOPPED:
+        case Parameters::STOPPED:
             res = startPreviewL(params, false);
             if (res != OK) return res;
             break;
-        case PREVIEW:
+        case Parameters::PREVIEW:
             // Ready to go
             break;
-        case RECORD:
-        case VIDEO_SNAPSHOT:
+        case Parameters::RECORD:
+        case Parameters::VIDEO_SNAPSHOT:
             // OK to call this when recording is already on, just skip unless
             // we're looking to restart
             if (!restart) return OK;
             break;
         default:
             ALOGE("%s: Camera %d: Can't start recording in state %s",
-                    __FUNCTION__, mCameraId, getStateName(params.state));
+                    __FUNCTION__, mCameraId,
+                    Parameters::getStateName(params.state));
             return INVALID_OPERATION;
     };
 
@@ -862,8 +845,8 @@
                 strerror(-res), res);
         return res;
     }
-    if (params.state < RECORD) {
-        params.state = RECORD;
+    if (params.state < Parameters::RECORD) {
+        params.state = Parameters::RECORD;
     }
 
     return OK;
@@ -873,22 +856,23 @@
     ATRACE_CALL();
     ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mICameraLock);
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
 
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return;
 
-    switch (k.mParameters.state) {
-        case RECORD:
+    switch (l.mParameters.state) {
+        case Parameters::RECORD:
             // OK to stop
             break;
-        case STOPPED:
-        case PREVIEW:
-        case STILL_CAPTURE:
-        case VIDEO_SNAPSHOT:
+        case Parameters::STOPPED:
+        case Parameters::PREVIEW:
+        case Parameters::STILL_CAPTURE:
+        case Parameters::VIDEO_SNAPSHOT:
         default:
             ALOGE("%s: Camera %d: Can't stop recording in state %s",
-                    __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
+                    __FUNCTION__, mCameraId,
+                    Parameters::getStateName(l.mParameters.state));
             return;
     };
 
@@ -904,7 +888,7 @@
     // TODO: Should recording heap be freed? Can't do it yet since requests
     // could still be in flight.
 
-    k.mParameters.state = PREVIEW;
+    l.mParameters.state = Parameters::PREVIEW;
 }
 
 bool Camera2Client::recordingEnabled() {
@@ -918,9 +902,10 @@
 
 bool Camera2Client::recordingEnabledL() {
     ATRACE_CALL();
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
 
-    return (k.mParameters.state == RECORD || k.mParameters.state == VIDEO_SNAPSHOT);
+    return (l.mParameters.state == Parameters::RECORD
+            || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
 }
 
 void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
@@ -929,7 +914,7 @@
     status_t res;
     if ( checkPid(__FUNCTION__) != OK) return;
 
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
 
     // Make sure this is for the current heap
     ssize_t offset;
@@ -990,9 +975,9 @@
 
     int triggerId;
     {
-        LockedParameters::Key k(mParameters);
-        k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
-        triggerId = k.mParameters.currentAfTriggerId;
+        SharedParameters::Lock l(mParameters);
+        l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
+        triggerId = l.mParameters.currentAfTriggerId;
     }
 
     mDevice->triggerAutofocus(triggerId);
@@ -1008,8 +993,8 @@
 
     int triggerId;
     {
-        LockedParameters::Key k(mParameters);
-        triggerId = ++k.mParameters.afTriggerCounter;
+        SharedParameters::Lock l(mParameters);
+        triggerId = ++l.mParameters.afTriggerCounter;
     }
 
     mDevice->triggerCancelAutofocus(triggerId);
@@ -1023,20 +1008,20 @@
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
-    LockedParameters::Key k(mParameters);
-    switch (k.mParameters.state) {
-        case DISCONNECTED:
-        case STOPPED:
-        case WAITING_FOR_PREVIEW_WINDOW:
+    SharedParameters::Lock l(mParameters);
+    switch (l.mParameters.state) {
+        case Parameters::DISCONNECTED:
+        case Parameters::STOPPED:
+        case Parameters::WAITING_FOR_PREVIEW_WINDOW:
             ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
                     __FUNCTION__, mCameraId);
             return INVALID_OPERATION;
-        case PREVIEW:
-        case RECORD:
+        case Parameters::PREVIEW:
+        case Parameters::RECORD:
             // Good to go for takePicture
             break;
-        case STILL_CAPTURE:
-        case VIDEO_SNAPSHOT:
+        case Parameters::STILL_CAPTURE:
+        case Parameters::VIDEO_SNAPSHOT:
             ALOGE("%s: Camera %d: Already taking a picture",
                     __FUNCTION__, mCameraId);
             return INVALID_OPERATION;
@@ -1044,7 +1029,7 @@
 
     ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
 
-    res = updateCaptureStream(k.mParameters);
+    res = updateCaptureStream(l.mParameters);
     if (res != OK) {
         ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
                 __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1052,7 +1037,7 @@
     }
 
     if (mCaptureRequest.entryCount() == 0) {
-        res = updateCaptureRequest(k.mParameters);
+        res = updateCaptureRequest(l.mParameters);
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create still image capture request: "
                     "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1060,9 +1045,9 @@
         }
     }
 
-    bool callbacksEnabled = k.mParameters.previewCallbackFlags &
+    bool callbacksEnabled = l.mParameters.previewCallbackFlags &
             CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
-    bool recordingEnabled = (k.mParameters.state == RECORD);
+    bool recordingEnabled = (l.mParameters.state == Parameters::RECORD);
 
     int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
             (recordingEnabled ? 0x1 : 0x0);
@@ -1115,7 +1100,7 @@
         return NO_MEMORY;
     }
 
-    if (k.mParameters.state == PREVIEW) {
+    if (l.mParameters.state == Parameters::PREVIEW) {
         res = mDevice->clearStreamingRequest();
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
@@ -1133,18 +1118,18 @@
         return res;
     }
 
-    switch (k.mParameters.state) {
-        case PREVIEW:
-            k.mParameters.state = STILL_CAPTURE;
-            res = commandStopFaceDetectionL(k.mParameters);
+    switch (l.mParameters.state) {
+        case Parameters::PREVIEW:
+            l.mParameters.state = Parameters::STILL_CAPTURE;
+            res = commandStopFaceDetectionL(l.mParameters);
             if (res != OK) {
                 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
                         __FUNCTION__, mCameraId);
                 return res;
             }
             break;
-        case RECORD:
-            k.mParameters.state = VIDEO_SNAPSHOT;
+        case Parameters::RECORD:
+            l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
             break;
         default:
             ALOGE("%s: Camera %d: Unknown state for still capture!",
@@ -1162,508 +1147,12 @@
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
 
-    CameraParameters newParams(params);
+    res = l.mParameters.set(params);
+    if (res != OK) return res;
 
-    // TODO: Currently ignoring any changes to supposedly read-only
-    // parameters such as supported preview sizes, etc. Should probably
-    // produce an error if they're changed.
-
-    /** Extract and verify new parameters */
-
-    size_t i;
-
-    // PREVIEW_SIZE
-    int previewWidth, previewHeight;
-    newParams.getPreviewSize(&previewWidth, &previewHeight);
-
-    if (previewWidth != k.mParameters.previewWidth ||
-            previewHeight != k.mParameters.previewHeight) {
-        if (k.mParameters.state >= PREVIEW) {
-            ALOGE("%s: Preview size cannot be updated when preview "
-                    "is active! (Currently %d x %d, requested %d x %d",
-                    __FUNCTION__,
-                    k.mParameters.previewWidth, k.mParameters.previewHeight,
-                    previewWidth, previewHeight);
-            return BAD_VALUE;
-        }
-        camera_metadata_ro_entry_t availablePreviewSizes =
-            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
-            if (availablePreviewSizes.data.i32[i] == previewWidth &&
-                    availablePreviewSizes.data.i32[i+1] == previewHeight) break;
-        }
-        if (i == availablePreviewSizes.count) {
-            ALOGE("%s: Requested preview size %d x %d is not supported",
-                    __FUNCTION__, previewWidth, previewHeight);
-            return BAD_VALUE;
-        }
-    }
-
-    // PREVIEW_FPS_RANGE
-    int previewFpsRange[2];
-    int previewFps = 0;
-    bool fpsRangeChanged = false;
-    newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
-    if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
-            previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
-        fpsRangeChanged = true;
-        camera_metadata_ro_entry_t availablePreviewFpsRanges =
-            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
-        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
-            if ((availablePreviewFpsRanges.data.i32[i] ==
-                    previewFpsRange[0]) &&
-                (availablePreviewFpsRanges.data.i32[i+1] ==
-                    previewFpsRange[1]) ) {
-                break;
-            }
-        }
-        if (i == availablePreviewFpsRanges.count) {
-            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
-                __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
-            return BAD_VALUE;
-        }
-        previewFps = previewFpsRange[0];
-    }
-
-    // PREVIEW_FORMAT
-    int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
-    if (previewFormat != k.mParameters.previewFormat) {
-        if (k.mParameters.state >= PREVIEW) {
-            ALOGE("%s: Preview format cannot be updated when preview "
-                    "is active!", __FUNCTION__);
-            return BAD_VALUE;
-        }
-        camera_metadata_ro_entry_t availableFormats =
-            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
-        for (i = 0; i < availableFormats.count; i++) {
-            if (availableFormats.data.i32[i] == previewFormat) break;
-        }
-        if (i == availableFormats.count) {
-            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
-                    __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
-            return BAD_VALUE;
-        }
-    }
-
-    // PREVIEW_FRAME_RATE
-    // Deprecated, only use if the preview fps range is unchanged this time.
-    // The single-value FPS is the same as the minimum of the range.
-    if (!fpsRangeChanged) {
-        previewFps = newParams.getPreviewFrameRate();
-        if (previewFps != k.mParameters.previewFps) {
-            camera_metadata_ro_entry_t availableFrameRates =
-                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
-            for (i = 0; i < availableFrameRates.count; i+=2) {
-                if (availableFrameRates.data.i32[i] == previewFps) break;
-            }
-            if (i == availableFrameRates.count) {
-                ALOGE("%s: Requested preview frame rate %d is not supported",
-                        __FUNCTION__, previewFps);
-                return BAD_VALUE;
-            }
-            previewFpsRange[0] = availableFrameRates.data.i32[i];
-            previewFpsRange[1] = availableFrameRates.data.i32[i+1];
-        }
-    }
-
-    // PICTURE_SIZE
-    int pictureWidth, pictureHeight;
-    newParams.getPictureSize(&pictureWidth, &pictureHeight);
-    if (pictureWidth == k.mParameters.pictureWidth ||
-            pictureHeight == k.mParameters.pictureHeight) {
-        camera_metadata_ro_entry_t availablePictureSizes =
-            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-        for (i = 0; i < availablePictureSizes.count; i+=2) {
-            if (availablePictureSizes.data.i32[i] == pictureWidth &&
-                    availablePictureSizes.data.i32[i+1] == pictureHeight) break;
-        }
-        if (i == availablePictureSizes.count) {
-            ALOGE("%s: Requested picture size %d x %d is not supported",
-                    __FUNCTION__, pictureWidth, pictureHeight);
-            return BAD_VALUE;
-        }
-    }
-
-    // JPEG_THUMBNAIL_WIDTH/HEIGHT
-    int jpegThumbSize[2];
-    jpegThumbSize[0] =
-            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
-    jpegThumbSize[1] =
-            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
-    if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
-            jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
-        camera_metadata_ro_entry_t availableJpegThumbSizes =
-            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
-        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
-            if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
-                    availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
-                break;
-            }
-        }
-        if (i == availableJpegThumbSizes.count) {
-            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
-                    __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
-            return BAD_VALUE;
-        }
-    }
-
-    // JPEG_THUMBNAIL_QUALITY
-    int jpegThumbQuality =
-            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
-    if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
-        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
-                __FUNCTION__, jpegThumbQuality);
-        return BAD_VALUE;
-    }
-
-    // JPEG_QUALITY
-    int jpegQuality =
-            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
-    if (jpegQuality < 0 || jpegQuality > 100) {
-        ALOGE("%s: Requested JPEG quality %d is not supported",
-                __FUNCTION__, jpegQuality);
-        return BAD_VALUE;
-    }
-
-    // ROTATION
-    int jpegRotation =
-            newParams.getInt(CameraParameters::KEY_ROTATION);
-    if (jpegRotation != 0 &&
-            jpegRotation != 90 &&
-            jpegRotation != 180 &&
-            jpegRotation != 270) {
-        ALOGE("%s: Requested picture rotation angle %d is not supported",
-                __FUNCTION__, jpegRotation);
-        return BAD_VALUE;
-    }
-
-    // GPS
-    bool gpsEnabled = false;
-    double gpsCoordinates[3] = {0,0,0};
-    int64_t gpsTimestamp = 0;
-    String8 gpsProcessingMethod;
-    const char *gpsLatStr =
-            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
-    if (gpsLatStr != NULL) {
-        const char *gpsLongStr =
-                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
-        const char *gpsAltitudeStr =
-                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
-        const char *gpsTimeStr =
-                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
-        const char *gpsProcMethodStr =
-                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
-        if (gpsLongStr == NULL ||
-                gpsAltitudeStr == NULL ||
-                gpsTimeStr == NULL ||
-                gpsProcMethodStr == NULL) {
-            ALOGE("%s: Incomplete set of GPS parameters provided",
-                    __FUNCTION__);
-            return BAD_VALUE;
-        }
-        char *endPtr;
-        errno = 0;
-        gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
-        if (errno || endPtr == gpsLatStr) {
-            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
-            return BAD_VALUE;
-        }
-        errno = 0;
-        gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
-        if (errno || endPtr == gpsLongStr) {
-            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
-            return BAD_VALUE;
-        }
-        errno = 0;
-        gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
-        if (errno || endPtr == gpsAltitudeStr) {
-            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
-                    gpsAltitudeStr);
-            return BAD_VALUE;
-        }
-        errno = 0;
-        gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
-        if (errno || endPtr == gpsTimeStr) {
-            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
-            return BAD_VALUE;
-        }
-        gpsProcessingMethod = gpsProcMethodStr;
-
-        gpsEnabled = true;
-    }
-
-    // WHITE_BALANCE
-    int wbMode = wbModeStringToEnum(
-        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
-    if (wbMode != k.mParameters.wbMode) {
-        camera_metadata_ro_entry_t availableWbModes =
-            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
-        for (i = 0; i < availableWbModes.count; i++) {
-            if (wbMode == availableWbModes.data.u8[i]) break;
-        }
-        if (i == availableWbModes.count) {
-            ALOGE("%s: Requested white balance mode %s is not supported",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
-            return BAD_VALUE;
-        }
-    }
-
-    // EFFECT
-    int effectMode = effectModeStringToEnum(
-        newParams.get(CameraParameters::KEY_EFFECT) );
-    if (effectMode != k.mParameters.effectMode) {
-        camera_metadata_ro_entry_t availableEffectModes =
-            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
-        for (i = 0; i < availableEffectModes.count; i++) {
-            if (effectMode == availableEffectModes.data.u8[i]) break;
-        }
-        if (i == availableEffectModes.count) {
-            ALOGE("%s: Requested effect mode \"%s\" is not supported",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_EFFECT) );
-            return BAD_VALUE;
-        }
-    }
-
-    // ANTIBANDING
-    int antibandingMode = abModeStringToEnum(
-        newParams.get(CameraParameters::KEY_ANTIBANDING) );
-    if (antibandingMode != k.mParameters.antibandingMode) {
-        camera_metadata_ro_entry_t availableAbModes =
-            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
-        for (i = 0; i < availableAbModes.count; i++) {
-            if (antibandingMode == availableAbModes.data.u8[i]) break;
-        }
-        if (i == availableAbModes.count) {
-            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_ANTIBANDING));
-            return BAD_VALUE;
-        }
-    }
-
-    // SCENE_MODE
-    int sceneMode = sceneModeStringToEnum(
-        newParams.get(CameraParameters::KEY_SCENE_MODE) );
-    if (sceneMode != k.mParameters.sceneMode &&
-            sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
-        camera_metadata_ro_entry_t availableSceneModes =
-            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
-        for (i = 0; i < availableSceneModes.count; i++) {
-            if (sceneMode == availableSceneModes.data.u8[i]) break;
-        }
-        if (i == availableSceneModes.count) {
-            ALOGE("%s: Requested scene mode \"%s\" is not supported",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_SCENE_MODE));
-            return BAD_VALUE;
-        }
-    }
-
-    // FLASH_MODE
-    Parameters::flashMode_t flashMode = flashModeStringToEnum(
-        newParams.get(CameraParameters::KEY_FLASH_MODE) );
-    if (flashMode != k.mParameters.flashMode) {
-        camera_metadata_ro_entry_t flashAvailable =
-            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
-        if (!flashAvailable.data.u8[0] &&
-                flashMode != Parameters::FLASH_MODE_OFF) {
-            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
-                    "No flash on device", __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_FLASH_MODE));
-            return BAD_VALUE;
-        } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
-            camera_metadata_ro_entry_t availableAeModes =
-                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
-            for (i = 0; i < availableAeModes.count; i++) {
-                if (flashMode == availableAeModes.data.u8[i]) break;
-            }
-            if (i == availableAeModes.count) {
-                ALOGE("%s: Requested flash mode \"%s\" is not supported",
-                        __FUNCTION__,
-                        newParams.get(CameraParameters::KEY_FLASH_MODE));
-                return BAD_VALUE;
-            }
-        } else if (flashMode == -1) {
-            ALOGE("%s: Requested flash mode \"%s\" is unknown",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_FLASH_MODE));
-            return BAD_VALUE;
-        }
-    }
-
-    // FOCUS_MODE
-    Parameters::focusMode_t focusMode = focusModeStringToEnum(
-        newParams.get(CameraParameters::KEY_FOCUS_MODE));
-    if (focusMode != k.mParameters.focusMode) {
-        if (focusMode != Parameters::FOCUS_MODE_FIXED) {
-            camera_metadata_ro_entry_t minFocusDistance =
-                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
-            if (minFocusDistance.data.f[0] == 0) {
-                ALOGE("%s: Requested focus mode \"%s\" is not available: "
-                        "fixed focus lens",
-                        __FUNCTION__,
-                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
-                return BAD_VALUE;
-            } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
-                camera_metadata_ro_entry_t availableFocusModes =
-                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
-                for (i = 0; i < availableFocusModes.count; i++) {
-                    if (focusMode == availableFocusModes.data.u8[i]) break;
-                }
-                if (i == availableFocusModes.count) {
-                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
-                            __FUNCTION__,
-                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
-                    return BAD_VALUE;
-                }
-            }
-        }
-    }
-
-    // FOCUS_AREAS
-    Vector<Parameters::Area> focusingAreas;
-    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
-            &focusingAreas);
-    size_t max3aRegions =
-        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
-    if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
-    if (res != OK) {
-        ALOGE("%s: Requested focus areas are malformed: %s",
-                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
-        return BAD_VALUE;
-    }
-
-    // EXPOSURE_COMPENSATION
-    int exposureCompensation =
-        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
-    camera_metadata_ro_entry_t exposureCompensationRange =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
-    if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
-            exposureCompensation > exposureCompensationRange.data.i32[1]) {
-        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
-                __FUNCTION__, exposureCompensation);
-        return BAD_VALUE;
-    }
-
-    // AUTO_EXPOSURE_LOCK (always supported)
-    bool autoExposureLock = boolFromString(
-        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
-
-    // AUTO_WHITEBALANCE_LOCK (always supported)
-    bool autoWhiteBalanceLock = boolFromString(
-        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
-
-    // METERING_AREAS
-    Vector<Parameters::Area> meteringAreas;
-    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
-            &meteringAreas);
-    if (res == OK) res = validateAreas(meteringAreas, max3aRegions);
-    if (res != OK) {
-        ALOGE("%s: Requested metering areas are malformed: %s",
-                __FUNCTION__,
-                newParams.get(CameraParameters::KEY_METERING_AREAS));
-        return BAD_VALUE;
-    }
-
-    // ZOOM
-    int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
-    if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
-        ALOGE("%s: Requested zoom level %d is not supported",
-                __FUNCTION__, zoom);
-        return BAD_VALUE;
-    }
-
-    // VIDEO_SIZE
-    int videoWidth, videoHeight;
-    newParams.getVideoSize(&videoWidth, &videoHeight);
-    if (videoWidth != k.mParameters.videoWidth ||
-            videoHeight != k.mParameters.videoHeight) {
-        if (k.mParameters.state == RECORD) {
-            ALOGE("%s: Video size cannot be updated when recording is active!",
-                    __FUNCTION__);
-            return BAD_VALUE;
-        }
-        camera_metadata_ro_entry_t availableVideoSizes =
-            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
-            if (availableVideoSizes.data.i32[i] == videoWidth &&
-                    availableVideoSizes.data.i32[i+1] == videoHeight)  break;
-        }
-        if (i == availableVideoSizes.count) {
-            ALOGE("%s: Requested video size %d x %d is not supported",
-                    __FUNCTION__, videoWidth, videoHeight);
-            return BAD_VALUE;
-        }
-    }
-
-    // RECORDING_HINT (always supported)
-    bool recordingHint = boolFromString(
-        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
-
-    // VIDEO_STABILIZATION
-    bool videoStabilization = boolFromString(
-        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
-    camera_metadata_ro_entry_t availableVideoStabilizationModes =
-        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
-    if (videoStabilization && availableVideoStabilizationModes.count == 1) {
-        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
-    }
-
-    /** Update internal parameters */
-
-    k.mParameters.previewWidth = previewWidth;
-    k.mParameters.previewHeight = previewHeight;
-    k.mParameters.previewFpsRange[0] = previewFpsRange[0];
-    k.mParameters.previewFpsRange[1] = previewFpsRange[1];
-    k.mParameters.previewFps = previewFps;
-    k.mParameters.previewFormat = previewFormat;
-
-    k.mParameters.pictureWidth = pictureWidth;
-    k.mParameters.pictureHeight = pictureHeight;
-
-    k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
-    k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
-    k.mParameters.jpegQuality = jpegQuality;
-    k.mParameters.jpegThumbQuality = jpegThumbQuality;
-
-    k.mParameters.gpsEnabled = gpsEnabled;
-    k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
-    k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
-    k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
-    k.mParameters.gpsTimestamp = gpsTimestamp;
-    k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
-
-    k.mParameters.wbMode = wbMode;
-    k.mParameters.effectMode = effectMode;
-    k.mParameters.antibandingMode = antibandingMode;
-    k.mParameters.sceneMode = sceneMode;
-
-    k.mParameters.flashMode = flashMode;
-    if (focusMode != k.mParameters.focusMode) {
-        k.mParameters.currentAfTriggerId = -1;
-    }
-    k.mParameters.focusMode = focusMode;
-
-    k.mParameters.focusingAreas = focusingAreas;
-    k.mParameters.exposureCompensation = exposureCompensation;
-    k.mParameters.autoExposureLock = autoExposureLock;
-    k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
-    k.mParameters.meteringAreas = meteringAreas;
-    k.mParameters.zoom = zoom;
-
-    k.mParameters.videoWidth = videoWidth;
-    k.mParameters.videoHeight = videoHeight;
-
-    k.mParameters.recordingHint = recordingHint;
-    k.mParameters.videoStabilization = videoStabilization;
-
-    k.mParameters.paramsFlattened = params;
-
-    res = updateRequests(k.mParameters);
+    res = updateRequests(l.mParameters);
 
     return res;
 }
@@ -1673,10 +1162,10 @@
     Mutex::Autolock icl(mICameraLock);
     if ( checkPid(__FUNCTION__) != OK) return String8();
 
-    LockedParameters::ReadKey k(mParameters);
+    SharedParameters::ReadLock l(mParameters);
 
     // TODO: Deal with focus distances
-    return k.mParameters.paramsFlattened;
+    return l.mParameters.paramsFlattened;
 }
 
 status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
@@ -1702,8 +1191,8 @@
         case CAMERA_CMD_START_FACE_DETECTION:
             return commandStartFaceDetectionL(arg1);
         case CAMERA_CMD_STOP_FACE_DETECTION: {
-            LockedParameters::Key k(mParameters);
-            return commandStopFaceDetectionL(k.mParameters);
+            SharedParameters::Lock l(mParameters);
+            return commandStopFaceDetectionL(l.mParameters);
         }
         case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
             return commandEnableFocusMoveMsgL(arg1 == 1);
@@ -1729,26 +1218,26 @@
 }
 
 status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
-    LockedParameters::Key k(mParameters);
-    int transform = degToTransform(degrees,
+    int transform = Parameters::degToTransform(degrees,
             mCameraFacing == CAMERA_FACING_FRONT);
     if (transform == -1) {
         ALOGE("%s: Camera %d: Error setting %d as display orientation value",
                 __FUNCTION__, mCameraId, degrees);
         return BAD_VALUE;
     }
-    if (transform != k.mParameters.previewTransform &&
+    SharedParameters::Lock l(mParameters);
+    if (transform != l.mParameters.previewTransform &&
             mPreviewStreamId != NO_STREAM) {
         mDevice->setStreamTransform(mPreviewStreamId, transform);
     }
-    k.mParameters.previewTransform = transform;
+    l.mParameters.previewTransform = transform;
     return OK;
 }
 
 status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
     if (enable) {
-        k.mParameters.playShutterSound = true;
+        l.mParameters.playShutterSound = true;
         return OK;
     }
 
@@ -1766,7 +1255,7 @@
         }
     }
 
-    k.mParameters.playShutterSound = false;
+    l.mParameters.playShutterSound = false;
     return OK;
 }
 
@@ -1779,32 +1268,33 @@
     ALOGV("%s: Camera %d: Starting face detection",
           __FUNCTION__, mCameraId);
     status_t res;
-    LockedParameters::Key k(mParameters);
-    switch (k.mParameters.state) {
-        case DISCONNECTED:
-        case STOPPED:
-        case WAITING_FOR_PREVIEW_WINDOW:
-        case STILL_CAPTURE:
+    SharedParameters::Lock l(mParameters);
+    switch (l.mParameters.state) {
+        case Parameters::DISCONNECTED:
+        case Parameters::STOPPED:
+        case Parameters::WAITING_FOR_PREVIEW_WINDOW:
+        case Parameters::STILL_CAPTURE:
             ALOGE("%s: Camera %d: Cannot start face detection without preview active",
                     __FUNCTION__, mCameraId);
             return INVALID_OPERATION;
-        case PREVIEW:
-        case RECORD:
-        case VIDEO_SNAPSHOT:
+        case Parameters::PREVIEW:
+        case Parameters::RECORD:
+        case Parameters::VIDEO_SNAPSHOT:
             // Good to go for starting face detect
             break;
     }
     // Ignoring type
-    if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
+    if (l.mParameters.fastInfo.bestFaceDetectMode ==
+            ANDROID_STATS_FACE_DETECTION_OFF) {
         ALOGE("%s: Camera %d: Face detection not supported",
                 __FUNCTION__, mCameraId);
         return INVALID_OPERATION;
     }
-    if (k.mParameters.enableFaceDetect) return OK;
+    if (l.mParameters.enableFaceDetect) return OK;
 
-    k.mParameters.enableFaceDetect = true;
+    l.mParameters.enableFaceDetect = true;
 
-    res = updateRequests(k.mParameters);
+    res = updateRequests(l.mParameters);
 
     return res;
 }
@@ -1818,8 +1308,9 @@
 
     params.enableFaceDetect = false;
 
-    if (params.state == PREVIEW || params.state == RECORD ||
-            params.state == VIDEO_SNAPSHOT) {
+    if (params.state == Parameters::PREVIEW
+            || params.state == Parameters::RECORD
+            || params.state == Parameters::VIDEO_SNAPSHOT) {
         res = updateRequests(params);
     }
 
@@ -1827,16 +1318,16 @@
 }
 
 status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
-    LockedParameters::Key k(mParameters);
-    k.mParameters.enableFocusMoveMessages = enable;
+    SharedParameters::Lock l(mParameters);
+    l.mParameters.enableFocusMoveMessages = enable;
 
     return OK;
 }
 
 status_t Camera2Client::commandPingL() {
     // Always ping back if access is proper and device is alive
-    LockedParameters::Key k(mParameters);
-    if (k.mParameters.state != DISCONNECTED) {
+    SharedParameters::Lock l(mParameters);
+    if (l.mParameters.state != Parameters::DISCONNECTED) {
         return OK;
     } else {
         return NO_INIT;
@@ -1889,21 +1380,21 @@
     bool success = false;
     bool afInMotion = false;
     {
-        LockedParameters::Key k(mParameters);
-        switch (k.mParameters.focusMode) {
+        SharedParameters::Lock l(mParameters);
+        switch (l.mParameters.focusMode) {
             case Parameters::FOCUS_MODE_AUTO:
             case Parameters::FOCUS_MODE_MACRO:
                 // Don't send notifications upstream if they're not for the current AF
                 // trigger. For example, if cancel was called in between, or if we
                 // already sent a notification about this AF call.
-                if (triggerId != k.mParameters.currentAfTriggerId) break;
+                if (triggerId != l.mParameters.currentAfTriggerId) break;
                 switch (newState) {
                     case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
                         success = true;
                         // no break
                     case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                         sendCompletedMessage = true;
-                        k.mParameters.currentAfTriggerId = -1;
+                        l.mParameters.currentAfTriggerId = -1;
                         break;
                     case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
                         // Just starting focusing, ignore
@@ -1930,21 +1421,21 @@
                         // called in between, or if we already sent a
                         // notification about this AF call.
                         // Send both a 'AF done' callback and a 'AF move' callback
-                        if (triggerId != k.mParameters.currentAfTriggerId) break;
+                        if (triggerId != l.mParameters.currentAfTriggerId) break;
                         sendCompletedMessage = true;
                         afInMotion = false;
-                        if (k.mParameters.enableFocusMoveMessages &&
-                                k.mParameters.afInMotion) {
+                        if (l.mParameters.enableFocusMoveMessages &&
+                                l.mParameters.afInMotion) {
                             sendMovingMessage = true;
                         }
-                        k.mParameters.currentAfTriggerId = -1;
+                        l.mParameters.currentAfTriggerId = -1;
                         break;
                     case ANDROID_CONTROL_AF_STATE_INACTIVE:
                         // Cancel was called, or we switched state; care if
                         // currently moving
                         afInMotion = false;
-                        if (k.mParameters.enableFocusMoveMessages &&
-                                k.mParameters.afInMotion) {
+                        if (l.mParameters.enableFocusMoveMessages &&
+                                l.mParameters.afInMotion) {
                             sendMovingMessage = true;
                         }
                         break;
@@ -1954,12 +1445,12 @@
                         // no break
                     case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
                         // Stop passive scan, inform upstream
-                        if (k.mParameters.enableFocusMoveMessages) {
+                        if (l.mParameters.enableFocusMoveMessages) {
                             sendMovingMessage = true;
                         }
                         break;
                 }
-                k.mParameters.afInMotion = afInMotion;
+                l.mParameters.afInMotion = afInMotion;
                 break;
             case Parameters::FOCUS_MODE_EDOF:
             case Parameters::FOCUS_MODE_INFINITY:
@@ -1967,7 +1458,7 @@
             default:
                 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
                     ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
-                          __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
+                          __FUNCTION__, newState, triggerId, l.mParameters.focusMode);
                 }
         }
     }
@@ -2064,9 +1555,10 @@
     status_t res;
     camera_metadata_ro_entry_t entry;
     bool enableFaceDetect;
+    int maxFaces;
     {
-        LockedParameters::Key k(client->mParameters);
-        enableFaceDetect = k.mParameters.enableFaceDetect;
+        SharedParameters::Lock l(client->mParameters);
+        enableFaceDetect = l.mParameters.enableFaceDetect;
     }
     entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE);
 
@@ -2077,20 +1569,24 @@
 
     uint8_t faceDetectMode = entry.data.u8[0];
 
+    camera_frame_metadata metadata;
+    Vector<camera_face_t> faces;
+    metadata.number_of_faces = 0;
+
     if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
+        SharedParameters::Lock l(client->mParameters);
         entry = frame.find(ANDROID_STATS_FACE_RECTANGLES);
         if (entry.count == 0) {
             ALOGE("%s: Camera %d: Unable to read face rectangles",
                     __FUNCTION__, client->mCameraId);
             return res;
         }
-        camera_frame_metadata metadata;
         metadata.number_of_faces = entry.count / 4;
         if (metadata.number_of_faces >
-                client->mDeviceInfo->maxFaces) {
+                l.mParameters.fastInfo.maxFaces) {
             ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
                     __FUNCTION__, client->mCameraId,
-                    metadata.number_of_faces, client->mDeviceInfo->maxFaces);
+                    metadata.number_of_faces, l.mParameters.fastInfo.maxFaces);
             return res;
         }
         const int32_t *faceRects = entry.data.i32;
@@ -2125,32 +1621,31 @@
             faceIds = entry.data.i32;
         }
 
-        Vector<camera_face_t> faces;
         faces.setCapacity(metadata.number_of_faces);
 
         for (int i = 0; i < metadata.number_of_faces; i++) {
             camera_face_t face;
 
-            face.rect[0] = client->arrayXToNormalized(faceRects[i*4 + 0]);
-            face.rect[1] = client->arrayYToNormalized(faceRects[i*4 + 1]);
-            face.rect[2] = client->arrayXToNormalized(faceRects[i*4 + 2]);
-            face.rect[3] = client->arrayYToNormalized(faceRects[i*4 + 3]);
+            face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]);
+            face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]);
+            face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]);
+            face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]);
 
             face.score = faceScores[i];
             if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
                 face.id = faceIds[i];
                 face.left_eye[0] =
-                        client->arrayXToNormalized(faceLandmarks[i*6 + 0]);
+                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]);
                 face.left_eye[1] =
-                        client->arrayYToNormalized(faceLandmarks[i*6 + 1]);
+                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]);
                 face.right_eye[0] =
-                        client->arrayXToNormalized(faceLandmarks[i*6 + 2]);
+                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]);
                 face.right_eye[1] =
-                        client->arrayYToNormalized(faceLandmarks[i*6 + 3]);
+                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]);
                 face.mouth[0] =
-                        client->arrayXToNormalized(faceLandmarks[i*6 + 4]);
+                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]);
                 face.mouth[1] =
-                        client->arrayYToNormalized(faceLandmarks[i*6 + 5]);
+                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]);
             } else {
                 face.id = 0;
                 face.left_eye[0] = face.left_eye[1] = -2000;
@@ -2161,12 +1656,13 @@
         }
 
         metadata.faces = faces.editArray();
-        {
-            Mutex::Autolock iccl(client->mICameraClientLock);
-            if (client->mCameraClient != NULL) {
-                client->mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
-                        NULL, &metadata);
-            }
+    }
+
+    if (metadata.number_of_faces != 0) {
+        Mutex::Autolock iccl(client->mICameraClientLock);
+        if (client->mCameraClient != NULL) {
+            client->mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
+                    NULL, &metadata);
         }
     }
     return OK;
@@ -2191,34 +1687,35 @@
     }
 
     {
-        LockedParameters::Key k(mParameters);
+        SharedParameters::Lock l(mParameters);
 
-        if ( k.mParameters.state != PREVIEW && k.mParameters.state != RECORD
-                && k.mParameters.state != VIDEO_SNAPSHOT) {
+        if ( l.mParameters.state != Parameters::PREVIEW
+                && l.mParameters.state != Parameters::RECORD
+                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
             ALOGV("%s: Camera %d: No longer streaming",
                     __FUNCTION__, mCameraId);
             mCallbackConsumer->unlockBuffer(imgBuffer);
             return;
         }
 
-        if (! (k.mParameters.previewCallbackFlags &
+        if (! (l.mParameters.previewCallbackFlags &
                 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
             ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
             mCallbackConsumer->unlockBuffer(imgBuffer);
             return;
         }
-        if ((k.mParameters.previewCallbackFlags &
+        if ((l.mParameters.previewCallbackFlags &
                         CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
-                !k.mParameters.previewCallbackOneShot) {
+                !l.mParameters.previewCallbackOneShot) {
             ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
             mCallbackConsumer->unlockBuffer(imgBuffer);
             return;
         }
 
-        if (imgBuffer.format != k.mParameters.previewFormat) {
+        if (imgBuffer.format != l.mParameters.previewFormat) {
             ALOGE("%s: Camera %d: Unexpected format for callback: "
                     "%x, expected %x", __FUNCTION__, mCameraId,
-                    imgBuffer.format, k.mParameters.previewFormat);
+                    imgBuffer.format, l.mParameters.previewFormat);
             mCallbackConsumer->unlockBuffer(imgBuffer);
             return;
         }
@@ -2271,10 +1768,10 @@
         mCallbackConsumer->unlockBuffer(imgBuffer);
 
         // In one-shot mode, stop sending callbacks after the first one
-        if (k.mParameters.previewCallbackFlags &
+        if (l.mParameters.previewCallbackFlags &
                 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
             ALOGV("%s: clearing oneshot", __FUNCTION__);
-            k.mParameters.previewCallbackOneShot = false;
+            l.mParameters.previewCallbackOneShot = false;
         }
     }
 
@@ -2289,7 +1786,7 @@
         }
     }
 
-    LockedParameters::Key k(mParameters);
+    SharedParameters::Lock l(mParameters);
     // Only increment free if we're still using the same heap
     if (mCallbackHeapId == callbackHeapId) {
         mCallbackHeapFree++;
@@ -2305,7 +1802,7 @@
     ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
 
     {
-        LockedParameters::Key k(mParameters);
+        SharedParameters::Lock l(mParameters);
         CpuConsumer::LockedBuffer imgBuffer;
 
         res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
@@ -2316,8 +1813,8 @@
         }
 
         // TODO: Signal errors here upstream
-        if (k.mParameters.state != STILL_CAPTURE &&
-                k.mParameters.state != VIDEO_SNAPSHOT) {
+        if (l.mParameters.state != Parameters::STILL_CAPTURE &&
+                l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
             ALOGE("%s: Camera %d: Still image produced unexpectedly!",
                     __FUNCTION__, mCameraId);
             mCaptureConsumer->unlockBuffer(imgBuffer);
@@ -2340,16 +1837,16 @@
 
         mCaptureConsumer->unlockBuffer(imgBuffer);
 
-        switch (k.mParameters.state) {
-            case STILL_CAPTURE:
-                k.mParameters.state = STOPPED;
+        switch (l.mParameters.state) {
+            case Parameters::STILL_CAPTURE:
+                l.mParameters.state = Parameters::STOPPED;
                 break;
-            case VIDEO_SNAPSHOT:
-                k.mParameters.state = RECORD;
+            case Parameters::VIDEO_SNAPSHOT:
+                l.mParameters.state = Parameters::RECORD;
                 break;
             default:
                 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
-                        mCameraId, k.mParameters.state);
+                        mCameraId, l.mParameters.state);
                 break;
         }
 
@@ -2370,7 +1867,7 @@
     size_t heapIdx = 0;
     nsecs_t timestamp;
     {
-        LockedParameters::Key k(mParameters);
+        SharedParameters::Lock l(mParameters);
 
         BufferItemConsumer::BufferItem imgBuffer;
         res = mRecordingConsumer->acquireBuffer(&imgBuffer);
@@ -2385,8 +1882,8 @@
         ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
 
         // TODO: Signal errors here upstream
-        if (k.mParameters.state != RECORD &&
-                k.mParameters.state != VIDEO_SNAPSHOT) {
+        if (l.mParameters.state != Parameters::RECORD &&
+                l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
             ALOGV("%s: Camera %d: Discarding recording image buffers received after "
                     "recording done",
                     __FUNCTION__, mCameraId);
@@ -2462,792 +1959,8 @@
     }
 }
 
-camera_metadata_ro_entry_t Camera2Client::staticInfo(uint32_t tag,
-        size_t minCount, size_t maxCount) const {
-    status_t res;
-    camera_metadata_ro_entry_t entry = mDevice->info().find(tag);
-
-    if (CC_UNLIKELY( entry.count == 0 )) {
-        const char* tagSection = get_camera_metadata_section_name(tag);
-        if (tagSection == NULL) tagSection = "<unknown>";
-        const char* tagName = get_camera_metadata_tag_name(tag);
-        if (tagName == NULL) tagName = "<unknown>";
-
-        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
-                tagSection, tagName, tag);
-    } else if (CC_UNLIKELY(
-            (minCount != 0 && entry.count < minCount) ||
-            (maxCount != 0 && entry.count > maxCount) ) ) {
-        const char* tagSection = get_camera_metadata_section_name(tag);
-        if (tagSection == NULL) tagSection = "<unknown>";
-        const char* tagName = get_camera_metadata_tag_name(tag);
-        if (tagName == NULL) tagName = "<unknown>";
-        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
-                "Expected between %d and %d values, but got %d values",
-                tagSection, tagName, tag, minCount, maxCount, entry.count);
-    }
-
-    return entry;
-}
-
 /** Utility methods */
 
-status_t Camera2Client::buildDeviceInfo() {
-    if (mDeviceInfo != NULL) {
-        delete mDeviceInfo;
-    }
-    DeviceInfo *deviceInfo = new DeviceInfo;
-    mDeviceInfo = deviceInfo;
-
-    camera_metadata_ro_entry_t activeArraySize =
-        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
-    if (!activeArraySize.count) return NO_INIT;
-    deviceInfo->arrayWidth = activeArraySize.data.i32[0];
-    deviceInfo->arrayHeight = activeArraySize.data.i32[1];
-
-    camera_metadata_ro_entry_t availableFaceDetectModes =
-        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
-    if (!availableFaceDetectModes.count) return NO_INIT;
-
-    deviceInfo->bestFaceDetectMode =
-        ANDROID_STATS_FACE_DETECTION_OFF;
-    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
-        switch (availableFaceDetectModes.data.u8[i]) {
-            case ANDROID_STATS_FACE_DETECTION_OFF:
-                break;
-            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
-                if (deviceInfo->bestFaceDetectMode !=
-                        ANDROID_STATS_FACE_DETECTION_FULL) {
-                    deviceInfo->bestFaceDetectMode =
-                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
-                }
-                break;
-            case ANDROID_STATS_FACE_DETECTION_FULL:
-                deviceInfo->bestFaceDetectMode =
-                    ANDROID_STATS_FACE_DETECTION_FULL;
-                break;
-            default:
-                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
-                        __FUNCTION__, mCameraId,
-                        availableFaceDetectModes.data.u8[i]);
-                return NO_INIT;
-        }
-    }
-
-    camera_metadata_ro_entry_t maxFacesDetected =
-        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
-    if (!maxFacesDetected.count) return NO_INIT;
-
-    deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
-
-    return OK;
-}
-
-status_t Camera2Client::buildDefaultParameters() {
-    ATRACE_CALL();
-    LockedParameters::Key k(mParameters);
-
-    status_t res;
-    CameraParameters params;
-
-    camera_metadata_ro_entry_t availableProcessedSizes =
-        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
-    if (!availableProcessedSizes.count) return NO_INIT;
-
-    // TODO: Pick more intelligently
-    k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
-    k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
-    k.mParameters.videoWidth = k.mParameters.previewWidth;
-    k.mParameters.videoHeight = k.mParameters.previewHeight;
-
-    params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
-    params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
-    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
-            String8::format("%dx%d",
-                    k.mParameters.previewWidth, k.mParameters.previewHeight));
-    {
-        String8 supportedPreviewSizes;
-        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
-            if (i != 0) supportedPreviewSizes += ",";
-            supportedPreviewSizes += String8::format("%dx%d",
-                    availableProcessedSizes.data.i32[i],
-                    availableProcessedSizes.data.i32[i+1]);
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
-                supportedPreviewSizes);
-        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
-                supportedPreviewSizes);
-    }
-
-    camera_metadata_ro_entry_t availableFpsRanges =
-        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
-    if (!availableFpsRanges.count) return NO_INIT;
-
-    k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
-    k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
-
-    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
-            String8::format("%d,%d",
-                    k.mParameters.previewFpsRange[0],
-                    k.mParameters.previewFpsRange[1]));
-
-    {
-        String8 supportedPreviewFpsRange;
-        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
-            if (i != 0) supportedPreviewFpsRange += ",";
-            supportedPreviewFpsRange += String8::format("(%d,%d)",
-                    availableFpsRanges.data.i32[i],
-                    availableFpsRanges.data.i32[i+1]);
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
-                supportedPreviewFpsRange);
-    }
-
-    k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
-    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
-            formatEnumToString(k.mParameters.previewFormat)); // NV21
-
-    k.mParameters.previewTransform = degToTransform(0,
-            mCameraFacing == CAMERA_FACING_FRONT);
-
-    camera_metadata_ro_entry_t availableFormats =
-        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
-
-    {
-        String8 supportedPreviewFormats;
-        bool addComma = false;
-        for (size_t i=0; i < availableFormats.count; i++) {
-            if (addComma) supportedPreviewFormats += ",";
-            addComma = true;
-            switch (availableFormats.data.i32[i]) {
-            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_YUV422SP;
-                break;
-            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_YUV420SP;
-                break;
-            case HAL_PIXEL_FORMAT_YCbCr_422_I:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_YUV422I;
-                break;
-            case HAL_PIXEL_FORMAT_YV12:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_YUV420P;
-                break;
-            case HAL_PIXEL_FORMAT_RGB_565:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_RGB565;
-                break;
-            case HAL_PIXEL_FORMAT_RGBA_8888:
-                supportedPreviewFormats +=
-                    CameraParameters::PIXEL_FORMAT_RGBA8888;
-                break;
-            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
-            case HAL_PIXEL_FORMAT_RAW_SENSOR:
-            case HAL_PIXEL_FORMAT_BLOB:
-                addComma = false;
-                break;
-
-            default:
-                ALOGW("%s: Camera %d: Unknown preview format: %x",
-                        __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
-                addComma = false;
-                break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
-                supportedPreviewFormats);
-    }
-
-    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
-    // still have to do something sane for them
-
-    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
-            k.mParameters.previewFpsRange[0]);
-
-    {
-        String8 supportedPreviewFrameRates;
-        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
-            if (i != 0) supportedPreviewFrameRates += ",";
-            supportedPreviewFrameRates += String8::format("%d",
-                    availableFpsRanges.data.i32[i]);
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
-                supportedPreviewFrameRates);
-    }
-
-    camera_metadata_ro_entry_t availableJpegSizes =
-        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
-    if (!availableJpegSizes.count) return NO_INIT;
-
-    // TODO: Pick maximum
-    k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
-    k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
-
-    params.setPictureSize(k.mParameters.pictureWidth,
-            k.mParameters.pictureHeight);
-
-    {
-        String8 supportedPictureSizes;
-        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
-            if (i != 0) supportedPictureSizes += ",";
-            supportedPictureSizes += String8::format("%dx%d",
-                    availableJpegSizes.data.i32[i],
-                    availableJpegSizes.data.i32[i+1]);
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
-                supportedPictureSizes);
-    }
-
-    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
-    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
-            CameraParameters::PIXEL_FORMAT_JPEG);
-
-    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
-        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
-    if (!availableJpegThumbnailSizes.count) return NO_INIT;
-
-    // TODO: Pick default thumbnail size sensibly
-    k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
-    k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
-
-    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
-            k.mParameters.jpegThumbSize[0]);
-    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
-            k.mParameters.jpegThumbSize[1]);
-
-    {
-        String8 supportedJpegThumbSizes;
-        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
-            if (i != 0) supportedJpegThumbSizes += ",";
-            supportedJpegThumbSizes += String8::format("%dx%d",
-                    availableJpegThumbnailSizes.data.i32[i],
-                    availableJpegThumbnailSizes.data.i32[i+1]);
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
-                supportedJpegThumbSizes);
-    }
-
-    k.mParameters.jpegThumbQuality = 90;
-    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
-            k.mParameters.jpegThumbQuality);
-    k.mParameters.jpegQuality = 90;
-    params.set(CameraParameters::KEY_JPEG_QUALITY,
-            k.mParameters.jpegQuality);
-    k.mParameters.jpegRotation = 0;
-    params.set(CameraParameters::KEY_ROTATION,
-            k.mParameters.jpegRotation);
-
-    k.mParameters.gpsEnabled = false;
-    k.mParameters.gpsProcessingMethod = "unknown";
-    // GPS fields in CameraParameters are not set by implementation
-
-    k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
-    params.set(CameraParameters::KEY_WHITE_BALANCE,
-            CameraParameters::WHITE_BALANCE_AUTO);
-
-    camera_metadata_ro_entry_t availableWhiteBalanceModes =
-        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
-    {
-        String8 supportedWhiteBalance;
-        bool addComma = false;
-        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
-            if (addComma) supportedWhiteBalance += ",";
-            addComma = true;
-            switch (availableWhiteBalanceModes.data.u8[i]) {
-            case ANDROID_CONTROL_AWB_AUTO:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_AUTO;
-                break;
-            case ANDROID_CONTROL_AWB_INCANDESCENT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
-                break;
-            case ANDROID_CONTROL_AWB_FLUORESCENT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
-                break;
-            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
-                break;
-            case ANDROID_CONTROL_AWB_DAYLIGHT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
-                break;
-            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
-                break;
-            case ANDROID_CONTROL_AWB_TWILIGHT:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_TWILIGHT;
-                break;
-            case ANDROID_CONTROL_AWB_SHADE:
-                supportedWhiteBalance +=
-                    CameraParameters::WHITE_BALANCE_SHADE;
-                break;
-            // Skipping values not mappable to v1 API
-            case ANDROID_CONTROL_AWB_OFF:
-                addComma = false;
-                break;
-            default:
-                ALOGW("%s: Camera %d: Unknown white balance value: %d",
-                        __FUNCTION__, mCameraId,
-                        availableWhiteBalanceModes.data.u8[i]);
-                addComma = false;
-                break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
-                supportedWhiteBalance);
-    }
-
-    k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
-    params.set(CameraParameters::KEY_EFFECT,
-            CameraParameters::EFFECT_NONE);
-
-    camera_metadata_ro_entry_t availableEffects =
-        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
-    if (!availableEffects.count) return NO_INIT;
-    {
-        String8 supportedEffects;
-        bool addComma = false;
-        for (size_t i=0; i < availableEffects.count; i++) {
-            if (addComma) supportedEffects += ",";
-            addComma = true;
-            switch (availableEffects.data.u8[i]) {
-                case ANDROID_CONTROL_EFFECT_OFF:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_NONE;
-                    break;
-                case ANDROID_CONTROL_EFFECT_MONO:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_MONO;
-                    break;
-                case ANDROID_CONTROL_EFFECT_NEGATIVE:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_NEGATIVE;
-                    break;
-                case ANDROID_CONTROL_EFFECT_SOLARIZE:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_SOLARIZE;
-                    break;
-                case ANDROID_CONTROL_EFFECT_SEPIA:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_SEPIA;
-                    break;
-                case ANDROID_CONTROL_EFFECT_POSTERIZE:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_POSTERIZE;
-                    break;
-                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_WHITEBOARD;
-                    break;
-                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_BLACKBOARD;
-                    break;
-                case ANDROID_CONTROL_EFFECT_AQUA:
-                    supportedEffects +=
-                        CameraParameters::EFFECT_AQUA;
-                    break;
-                default:
-                    ALOGW("%s: Camera %d: Unknown effect value: %d",
-                        __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
-                    addComma = false;
-                    break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
-    }
-
-    k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
-    params.set(CameraParameters::KEY_ANTIBANDING,
-            CameraParameters::ANTIBANDING_AUTO);
-
-    camera_metadata_ro_entry_t availableAntibandingModes =
-        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
-    if (!availableAntibandingModes.count) return NO_INIT;
-    {
-        String8 supportedAntibanding;
-        bool addComma = false;
-        for (size_t i=0; i < availableAntibandingModes.count; i++) {
-            if (addComma) supportedAntibanding += ",";
-            addComma = true;
-            switch (availableAntibandingModes.data.u8[i]) {
-                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
-                    supportedAntibanding +=
-                        CameraParameters::ANTIBANDING_OFF;
-                    break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
-                    supportedAntibanding +=
-                        CameraParameters::ANTIBANDING_50HZ;
-                    break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
-                    supportedAntibanding +=
-                        CameraParameters::ANTIBANDING_60HZ;
-                    break;
-                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
-                    supportedAntibanding +=
-                        CameraParameters::ANTIBANDING_AUTO;
-                    break;
-                default:
-                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
-                        __FUNCTION__, mCameraId,
-                            availableAntibandingModes.data.u8[i]);
-                    addComma = false;
-                    break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
-                supportedAntibanding);
-    }
-
-    k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
-    params.set(CameraParameters::KEY_SCENE_MODE,
-            CameraParameters::SCENE_MODE_AUTO);
-
-    camera_metadata_ro_entry_t availableSceneModes =
-        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
-    if (!availableSceneModes.count) return NO_INIT;
-    {
-        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
-        bool addComma = true;
-        bool noSceneModes = false;
-        for (size_t i=0; i < availableSceneModes.count; i++) {
-            if (addComma) supportedSceneModes += ",";
-            addComma = true;
-            switch (availableSceneModes.data.u8[i]) {
-                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
-                    noSceneModes = true;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
-                    // Not in old API
-                    addComma = false;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_ACTION:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_ACTION;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_PORTRAIT;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_LANDSCAPE;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_NIGHT;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_THEATRE;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_BEACH:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_BEACH;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_SNOW:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_SNOW;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_SUNSET;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_STEADYPHOTO;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_FIREWORKS;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_SPORTS;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_PARTY:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_PARTY;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_CANDLELIGHT;
-                    break;
-                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
-                    supportedSceneModes +=
-                        CameraParameters::SCENE_MODE_BARCODE;
-                    break;
-                default:
-                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
-                        __FUNCTION__, mCameraId,
-                            availableSceneModes.data.u8[i]);
-                    addComma = false;
-                    break;
-            }
-        }
-        if (!noSceneModes) {
-            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
-                    supportedSceneModes);
-        }
-    }
-
-    camera_metadata_ro_entry_t flashAvailable =
-        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
-    if (!flashAvailable.count) return NO_INIT;
-
-    camera_metadata_ro_entry_t availableAeModes =
-        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
-    if (!availableAeModes.count) return NO_INIT;
-
-    if (flashAvailable.data.u8[0]) {
-        k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
-        params.set(CameraParameters::KEY_FLASH_MODE,
-                CameraParameters::FLASH_MODE_AUTO);
-
-        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
-        supportedFlashModes = supportedFlashModes +
-            "," + CameraParameters::FLASH_MODE_AUTO +
-            "," + CameraParameters::FLASH_MODE_ON +
-            "," + CameraParameters::FLASH_MODE_TORCH;
-        for (size_t i=0; i < availableAeModes.count; i++) {
-            if (availableAeModes.data.u8[i] ==
-                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
-                supportedFlashModes = supportedFlashModes + "," +
-                    CameraParameters::FLASH_MODE_RED_EYE;
-                break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
-                supportedFlashModes);
-    } else {
-        k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
-        params.set(CameraParameters::KEY_FLASH_MODE,
-                CameraParameters::FLASH_MODE_OFF);
-        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
-                CameraParameters::FLASH_MODE_OFF);
-    }
-
-    camera_metadata_ro_entry_t minFocusDistance =
-        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
-    if (!minFocusDistance.count) return NO_INIT;
-
-    camera_metadata_ro_entry_t availableAfModes =
-        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
-    if (!availableAfModes.count) return NO_INIT;
-
-    if (minFocusDistance.data.f[0] == 0) {
-        // Fixed-focus lens
-        k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
-        params.set(CameraParameters::KEY_FOCUS_MODE,
-                CameraParameters::FOCUS_MODE_FIXED);
-        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
-                CameraParameters::FOCUS_MODE_FIXED);
-    } else {
-        k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
-        params.set(CameraParameters::KEY_FOCUS_MODE,
-                CameraParameters::FOCUS_MODE_AUTO);
-        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
-        bool addComma = true;
-
-        for (size_t i=0; i < availableAfModes.count; i++) {
-            if (addComma) supportedFocusModes += ",";
-            addComma = true;
-            switch (availableAfModes.data.u8[i]) {
-                case ANDROID_CONTROL_AF_AUTO:
-                    supportedFocusModes +=
-                        CameraParameters::FOCUS_MODE_AUTO;
-                    break;
-                case ANDROID_CONTROL_AF_MACRO:
-                    supportedFocusModes +=
-                        CameraParameters::FOCUS_MODE_MACRO;
-                    break;
-                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
-                    supportedFocusModes +=
-                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
-                    break;
-                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
-                    supportedFocusModes +=
-                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
-                    break;
-                case ANDROID_CONTROL_AF_EDOF:
-                    supportedFocusModes +=
-                        CameraParameters::FOCUS_MODE_EDOF;
-                    break;
-                // Not supported in old API
-                case ANDROID_CONTROL_AF_OFF:
-                    addComma = false;
-                    break;
-                default:
-                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
-                        __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
-                    addComma = false;
-                    break;
-            }
-        }
-        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
-                supportedFocusModes);
-    }
-
-    camera_metadata_ro_entry_t max3aRegions =
-        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
-    if (!max3aRegions.count) return NO_INIT;
-
-    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
-            max3aRegions.data.i32[0]);
-    params.set(CameraParameters::KEY_FOCUS_AREAS,
-            "(0,0,0,0,0)");
-    k.mParameters.focusingAreas.clear();
-    k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
-
-    camera_metadata_ro_entry_t availableFocalLengths =
-        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
-    if (!availableFocalLengths.count) return NO_INIT;
-
-    float minFocalLength = availableFocalLengths.data.f[0];
-    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
-
-    camera_metadata_ro_entry_t sensorSize =
-        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
-    if (!sensorSize.count) return NO_INIT;
-
-    // The fields of view here assume infinity focus, maximum wide angle
-    float horizFov = 180 / M_PI *
-            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
-    float vertFov  = 180 / M_PI *
-            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
-    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
-    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
-
-    k.mParameters.exposureCompensation = 0;
-    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
-                k.mParameters.exposureCompensation);
-
-    camera_metadata_ro_entry_t exposureCompensationRange =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
-    if (!exposureCompensationRange.count) return NO_INIT;
-
-    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
-            exposureCompensationRange.data.i32[1]);
-    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
-            exposureCompensationRange.data.i32[0]);
-
-    camera_metadata_ro_entry_t exposureCompensationStep =
-        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
-    if (!exposureCompensationStep.count) return NO_INIT;
-
-    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
-            (float)exposureCompensationStep.data.r[0].numerator /
-            exposureCompensationStep.data.r[0].denominator);
-
-    k.mParameters.autoExposureLock = false;
-    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
-            CameraParameters::FALSE);
-    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
-            CameraParameters::TRUE);
-
-    k.mParameters.autoWhiteBalanceLock = false;
-    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
-            CameraParameters::FALSE);
-    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
-            CameraParameters::TRUE);
-
-    k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
-    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
-            max3aRegions.data.i32[0]);
-    params.set(CameraParameters::KEY_METERING_AREAS,
-            "(0,0,0,0,0)");
-
-    k.mParameters.zoom = 0;
-    params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
-    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
-
-    camera_metadata_ro_entry_t maxDigitalZoom =
-        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
-    if (!maxDigitalZoom.count) return NO_INIT;
-
-    {
-        String8 zoomRatios;
-        float zoom = 1.f;
-        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
-                (NUM_ZOOM_STEPS-1);
-        bool addComma = false;
-        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
-            if (addComma) zoomRatios += ",";
-            addComma = true;
-            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
-            zoom += zoomIncrement;
-        }
-        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
-    }
-
-    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
-            CameraParameters::TRUE);
-    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
-            CameraParameters::TRUE);
-
-    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
-            "Infinity,Infinity,Infinity");
-
-    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
-            mDeviceInfo->maxFaces);
-    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
-            0);
-
-    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
-            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
-
-    params.set(CameraParameters::KEY_RECORDING_HINT,
-            CameraParameters::FALSE);
-
-    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
-            CameraParameters::TRUE);
-
-    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
-            CameraParameters::FALSE);
-
-    camera_metadata_ro_entry_t availableVideoStabilizationModes =
-        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
-    if (!availableVideoStabilizationModes.count) return NO_INIT;
-
-    if (availableVideoStabilizationModes.count > 1) {
-        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
-                CameraParameters::TRUE);
-    } else {
-        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
-                CameraParameters::FALSE);
-    }
-
-    // Set up initial state for non-Camera.Parameters state variables
-
-    k.mParameters.storeMetadataInBuffers = true;
-    k.mParameters.playShutterSound = true;
-    k.mParameters.enableFaceDetect = false;
-
-    k.mParameters.enableFocusMoveMessages = false;
-    k.mParameters.afTriggerCounter = 0;
-    k.mParameters.currentAfTriggerId = -1;
-
-    k.mParameters.previewCallbackFlags = 0;
-
-    k.mParameters.state = STOPPED;
-
-    k.mParameters.paramsFlattened = params.flatten();
-
-    return OK;
-}
-
 status_t Camera2Client::updateRequests(const Parameters &params) {
     status_t res;
 
@@ -3271,14 +1984,15 @@
         return res;
     }
 
-    if (params.state == PREVIEW) {
+    if (params.state == Parameters::PREVIEW) {
         res = mDevice->setStreamingRequest(mPreviewRequest);
         if (res != OK) {
             ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
                     __FUNCTION__, mCameraId, strerror(-res), res);
             return res;
         }
-    } else if (params.state == RECORD || params.state == VIDEO_SNAPSHOT) {
+    } else if (params.state == Parameters::RECORD ||
+            params.state == Parameters::VIDEO_SNAPSHOT) {
         res = mDevice->setStreamingRequest(mRecordingRequest);
         if (res != OK) {
             ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
@@ -3435,7 +2149,7 @@
     status_t res;
     // Find out buffer size for JPEG
     camera_metadata_ro_entry_t maxJpegSize =
-            staticInfo(ANDROID_JPEG_MAX_SIZE);
+            mParameters.staticInfo(ANDROID_JPEG_MAX_SIZE);
     if (maxJpegSize.count == 0) {
         ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
                 __FUNCTION__, mCameraId);
@@ -3640,7 +2354,7 @@
 }
 
 status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
-        const Parameters &params) {
+        const Parameters &params) const {
     ATRACE_CALL();
     status_t res;
     res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
@@ -3730,10 +2444,14 @@
     int32_t *focusingAreas = new int32_t[focusingAreasSize];
     for (size_t i = 0; i < focusingAreasSize; i += 5) {
         if (params.focusingAreas[i].weight != 0) {
-            focusingAreas[i + 0] = normalizedXToArray(params.focusingAreas[i].left);
-            focusingAreas[i + 1] = normalizedYToArray(params.focusingAreas[i].top);
-            focusingAreas[i + 2] = normalizedXToArray(params.focusingAreas[i].right);
-            focusingAreas[i + 3] = normalizedYToArray(params.focusingAreas[i].bottom);
+            focusingAreas[i + 0] =
+                    params.normalizedXToArray(params.focusingAreas[i].left);
+            focusingAreas[i + 1] =
+                    params.normalizedYToArray(params.focusingAreas[i].top);
+            focusingAreas[i + 2] =
+                    params.normalizedXToArray(params.focusingAreas[i].right);
+            focusingAreas[i + 3] =
+                    params.normalizedYToArray(params.focusingAreas[i].bottom);
         } else {
             focusingAreas[i + 0] = 0;
             focusingAreas[i + 1] = 0;
@@ -3756,13 +2474,13 @@
     for (size_t i = 0; i < meteringAreasSize; i += 5) {
         if (params.meteringAreas[i].weight != 0) {
             meteringAreas[i + 0] =
-                normalizedXToArray(params.meteringAreas[i].left);
+                params.normalizedXToArray(params.meteringAreas[i].left);
             meteringAreas[i + 1] =
-                normalizedYToArray(params.meteringAreas[i].top);
+                params.normalizedYToArray(params.meteringAreas[i].top);
             meteringAreas[i + 2] =
-                normalizedXToArray(params.meteringAreas[i].right);
+                params.normalizedXToArray(params.meteringAreas[i].right);
             meteringAreas[i + 3] =
-                normalizedYToArray(params.meteringAreas[i].bottom);
+                params.normalizedYToArray(params.meteringAreas[i].bottom);
         } else {
             meteringAreas[i + 0] = 0;
             meteringAreas[i + 1] = 0;
@@ -3784,23 +2502,23 @@
     // chosen to maximize its area on the sensor
 
     camera_metadata_ro_entry_t maxDigitalZoom =
-            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
+            mParameters.staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
     float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
-            (NUM_ZOOM_STEPS-1);
+            (params.NUM_ZOOM_STEPS-1);
     float zoomRatio = 1 + zoomIncrement * params.zoom;
 
     float zoomLeft, zoomTop, zoomWidth, zoomHeight;
     if (params.previewWidth >= params.previewHeight) {
-        zoomWidth =  mDeviceInfo->arrayWidth / zoomRatio;
+        zoomWidth =  params.fastInfo.arrayWidth / zoomRatio;
         zoomHeight = zoomWidth *
                 params.previewHeight / params.previewWidth;
     } else {
-        zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
+        zoomHeight = params.fastInfo.arrayHeight / zoomRatio;
         zoomWidth = zoomHeight *
                 params.previewWidth / params.previewHeight;
     }
-    zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
-    zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
+    zoomLeft = (params.fastInfo.arrayWidth - zoomWidth) / 2;
+    zoomTop = (params.fastInfo.arrayHeight - zoomHeight) / 2;
 
     int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
     res = request->update(ANDROID_SCALER_CROP_REGION,
@@ -3817,7 +2535,7 @@
     if (res != OK) return res;
 
     uint8_t faceDetectMode = params.enableFaceDetect ?
-            mDeviceInfo->bestFaceDetectMode :
+            params.fastInfo.bestFaceDetectMode :
             (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
     res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
             &faceDetectMode, 1);
@@ -3826,294 +2544,6 @@
     return OK;
 }
 
-int Camera2Client::normalizedXToArray(int x) const {
-    return (x + 1000) * (mDeviceInfo->arrayWidth - 1) / 2000;
-}
-
-int Camera2Client::normalizedYToArray(int y) const {
-    return (y + 1000) * (mDeviceInfo->arrayHeight - 1) / 2000;
-}
-
-int Camera2Client::arrayXToNormalized(int width) const {
-    return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
-}
-
-int Camera2Client::arrayYToNormalized(int height) const {
-    return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
-}
-
-int Camera2Client::formatStringToEnum(const char *format) {
-    return
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
-            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
-            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
-            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
-            HAL_PIXEL_FORMAT_YV12 :         // YV12
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
-            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
-            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
-        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
-            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
-        -1;
-}
-
-const char* Camera2Client::formatEnumToString(int format) {
-    const char *fmt;
-    switch(format) {
-        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
-            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
-            break;
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
-            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
-            break;
-        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
-            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
-            break;
-        case HAL_PIXEL_FORMAT_YV12:        // YV12
-            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
-            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
-            break;
-        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
-            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
-            break;
-        case HAL_PIXEL_FORMAT_RAW_SENSOR:
-            ALOGW("Raw sensor preview format requested.");
-            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
-            break;
-        default:
-            ALOGE("%s: Unknown preview format: %x",
-                    __FUNCTION__,  format);
-            fmt = NULL;
-            break;
-    }
-    return fmt;
-}
-
-int Camera2Client::wbModeStringToEnum(const char *wbMode) {
-    return
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
-            ANDROID_CONTROL_AWB_AUTO :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
-            ANDROID_CONTROL_AWB_INCANDESCENT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
-            ANDROID_CONTROL_AWB_FLUORESCENT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
-            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
-            ANDROID_CONTROL_AWB_DAYLIGHT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
-            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
-            ANDROID_CONTROL_AWB_TWILIGHT :
-        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
-            ANDROID_CONTROL_AWB_SHADE :
-        -1;
-}
-
-int Camera2Client::effectModeStringToEnum(const char *effectMode) {
-    return
-        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
-            ANDROID_CONTROL_EFFECT_OFF :
-        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
-            ANDROID_CONTROL_EFFECT_MONO :
-        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
-            ANDROID_CONTROL_EFFECT_NEGATIVE :
-        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
-            ANDROID_CONTROL_EFFECT_SOLARIZE :
-        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
-            ANDROID_CONTROL_EFFECT_SEPIA :
-        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
-            ANDROID_CONTROL_EFFECT_POSTERIZE :
-        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
-            ANDROID_CONTROL_EFFECT_WHITEBOARD :
-        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
-            ANDROID_CONTROL_EFFECT_BLACKBOARD :
-        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
-            ANDROID_CONTROL_EFFECT_AQUA :
-        -1;
-}
-
-int Camera2Client::abModeStringToEnum(const char *abMode) {
-    return
-        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
-        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
-        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
-        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
-            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
-        -1;
-}
-
-int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
-    return
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
-            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
-            ANDROID_CONTROL_SCENE_MODE_ACTION :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
-            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
-            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
-            ANDROID_CONTROL_SCENE_MODE_NIGHT :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
-            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
-            ANDROID_CONTROL_SCENE_MODE_THEATRE :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
-            ANDROID_CONTROL_SCENE_MODE_BEACH :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
-            ANDROID_CONTROL_SCENE_MODE_SNOW :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
-            ANDROID_CONTROL_SCENE_MODE_SUNSET :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
-            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
-            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
-            ANDROID_CONTROL_SCENE_MODE_SPORTS :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
-            ANDROID_CONTROL_SCENE_MODE_PARTY :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
-            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
-        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
-            ANDROID_CONTROL_SCENE_MODE_BARCODE:
-        -1;
-}
-
-Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
-        const char *flashMode) {
-    return
-        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
-            Parameters::FLASH_MODE_OFF :
-        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
-            Parameters::FLASH_MODE_AUTO :
-        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
-            Parameters::FLASH_MODE_ON :
-        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
-            Parameters::FLASH_MODE_RED_EYE :
-        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
-            Parameters::FLASH_MODE_TORCH :
-        Parameters::FLASH_MODE_INVALID;
-}
-
-Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
-        const char *focusMode) {
-    return
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
-            Parameters::FOCUS_MODE_AUTO :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
-            Parameters::FOCUS_MODE_INFINITY :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
-            Parameters::FOCUS_MODE_MACRO :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
-            Parameters::FOCUS_MODE_FIXED :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
-            Parameters::FOCUS_MODE_EDOF :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
-            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
-        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
-            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
-        Parameters::FOCUS_MODE_INVALID;
-}
-
-status_t Camera2Client::parseAreas(const char *areasCStr,
-        Vector<Parameters::Area> *areas) {
-    static const size_t NUM_FIELDS = 5;
-    areas->clear();
-    if (areasCStr == NULL) {
-        // If no key exists, use default (0,0,0,0,0)
-        areas->push();
-        return OK;
-    }
-    String8 areasStr(areasCStr);
-    ssize_t areaStart = areasStr.find("(", 0) + 1;
-    while (areaStart != 0) {
-        const char* area = areasStr.string() + areaStart;
-        char *numEnd;
-        int vals[NUM_FIELDS];
-        for (size_t i = 0; i < NUM_FIELDS; i++) {
-            errno = 0;
-            vals[i] = strtol(area, &numEnd, 10);
-            if (errno || numEnd == area) return BAD_VALUE;
-            area = numEnd + 1;
-        }
-        areas->push(Parameters::Area(
-            vals[0], vals[1], vals[2], vals[3], vals[4]) );
-        areaStart = areasStr.find("(", areaStart) + 1;
-    }
-    return OK;
-}
-
-status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
-                                      size_t maxRegions) {
-    // Definition of valid area can be found in
-    // include/camera/CameraParameters.h
-    if (areas.size() == 0) return BAD_VALUE;
-    if (areas.size() == 1) {
-        if (areas[0].left == 0 &&
-                areas[0].top == 0 &&
-                areas[0].right == 0 &&
-                areas[0].bottom == 0 &&
-                areas[0].weight == 0) {
-            // Single (0,0,0,0,0) entry is always valid (== driver decides)
-            return OK;
-        }
-    }
-    if (areas.size() > maxRegions) {
-        ALOGE("%s: Too many areas requested: %d",
-                __FUNCTION__, areas.size());
-        return BAD_VALUE;
-    }
-
-    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
-         a != areas.end(); a++) {
-        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
-        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
-        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
-        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
-        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
-        if (a->left >= a->right) return BAD_VALUE;
-        if (a->top >= a->bottom) return BAD_VALUE;
-    }
-    return OK;
-}
-
-bool Camera2Client::boolFromString(const char *boolStr) {
-    return !boolStr ? false :
-        !strcmp(boolStr, CameraParameters::TRUE) ? true :
-        false;
-}
-
-int Camera2Client::degToTransform(int degrees, bool mirror) {
-    if (!mirror) {
-        if (degrees == 0) return 0;
-        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
-        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
-        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
-    } else {  // Do mirror (horizontal flip)
-        if (degrees == 0) {           // FLIP_H and ROT_0
-            return HAL_TRANSFORM_FLIP_H;
-        } else if (degrees == 90) {   // FLIP_H and ROT_90
-            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
-        } else if (degrees == 180) {  // FLIP_H and ROT_180
-            return HAL_TRANSFORM_FLIP_V;
-        } else if (degrees == 270) {  // FLIP_H and ROT_270
-            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
-        }
-    }
-    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
-    return -1;
-}
-
 size_t Camera2Client::calculateBufferSize(int width, int height,
         int format, int stride) {
     switch (format) {
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index a3ab128..4023397 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -19,7 +19,7 @@
 
 #include "Camera2Device.h"
 #include "CameraService.h"
-#include "camera/CameraParameters.h"
+#include "camera2/Parameters.h"
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
 #include <gui/CpuConsumer.h>
@@ -83,17 +83,6 @@
     virtual void notifyAutoWhitebalance(uint8_t newState, int triggerId);
 
 private:
-    enum State {
-        DISCONNECTED,
-        STOPPED,
-        WAITING_FOR_PREVIEW_WINDOW,
-        PREVIEW,
-        RECORD,
-        STILL_CAPTURE,
-        VIDEO_SNAPSHOT
-    };
-    static const char *getStateName(State state);
-
     /** ICamera interface-related private members */
 
     // Mutex that must be locked by methods implementing the ICamera interface.
@@ -107,7 +96,8 @@
     // up to the camera user
     mutable Mutex mICameraClientLock;
 
-    class Parameters;
+    typedef camera2::Parameters Parameters;
+    typedef camera2::CameraMetadata CameraMetadata;
 
     status_t setPreviewWindowL(const sp<IBinder>& binder,
             sp<ANativeWindow> window);
@@ -128,161 +118,8 @@
     status_t commandPingL();
     status_t commandSetVideoBufferCountL(size_t count);
 
-    // Current camera state; this is the contents of the CameraParameters object
-    // in a more-efficient format. The enum values are mostly based off the
-    // corresponding camera2 enums, not the camera1 strings. A few are defined
-    // here if they don't cleanly map to camera2 values.
-    struct Parameters {
-        int previewWidth, previewHeight;
-        int32_t previewFpsRange[2];
-        int previewFps; // deprecated, here only for tracking changes
-        int previewFormat;
-
-        int previewTransform; // set by CAMERA_CMD_SET_DISPLAY_ORIENTATION
-
-        int pictureWidth, pictureHeight;
-
-        int32_t jpegThumbSize[2];
-        int32_t jpegQuality, jpegThumbQuality;
-        int32_t jpegRotation;
-
-        bool gpsEnabled;
-        double gpsCoordinates[3];
-        int64_t gpsTimestamp;
-        String8 gpsProcessingMethod;
-
-        uint8_t wbMode;
-        uint8_t effectMode;
-        uint8_t antibandingMode;
-        uint8_t sceneMode;
-
-        enum flashMode_t {
-            FLASH_MODE_OFF = 0,
-            FLASH_MODE_AUTO,
-            FLASH_MODE_ON,
-            FLASH_MODE_TORCH,
-            FLASH_MODE_RED_EYE = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE,
-            FLASH_MODE_INVALID = -1
-        } flashMode;
-
-        enum focusMode_t {
-            FOCUS_MODE_AUTO = ANDROID_CONTROL_AF_AUTO,
-            FOCUS_MODE_MACRO = ANDROID_CONTROL_AF_MACRO,
-            FOCUS_MODE_CONTINUOUS_VIDEO = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO,
-            FOCUS_MODE_CONTINUOUS_PICTURE =
-                ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
-            FOCUS_MODE_EDOF = ANDROID_CONTROL_AF_EDOF,
-            FOCUS_MODE_INFINITY,
-            FOCUS_MODE_FIXED,
-            FOCUS_MODE_INVALID = -1
-        } focusMode;
-
-        struct Area {
-            int left, top, right, bottom;
-            int weight;
-            Area() {}
-            Area(int left, int top, int right, int bottom, int weight):
-                    left(left), top(top), right(right), bottom(bottom),
-                    weight(weight) {}
-        };
-        Vector<Area> focusingAreas;
-
-        int32_t exposureCompensation;
-        bool autoExposureLock;
-        bool autoWhiteBalanceLock;
-
-        Vector<Area> meteringAreas;
-
-        int zoom;
-
-        int videoWidth, videoHeight;
-
-        bool recordingHint;
-        bool videoStabilization;
-
-        String8 paramsFlattened;
-
-        // These parameters are also part of the camera API-visible state, but not directly
-        // listed in Camera.Parameters
-        bool storeMetadataInBuffers;
-        bool playShutterSound;
-        bool enableFaceDetect;
-
-        bool enableFocusMoveMessages;
-        int afTriggerCounter;
-        int currentAfTriggerId;
-        bool afInMotion;
-
-        uint32_t previewCallbackFlags;
-        bool previewCallbackOneShot;
-
-        // Overall camera state
-        State state;
-    };
-
-    // This class encapsulates the Parameters class so that it can only be accessed
-    // by constructing a Key object, which locks the LockedParameter's mutex.
-    class LockedParameters {
-      public:
-        class Key {
-          public:
-            Key(LockedParameters &p):
-                    mParameters(p.mParameters),
-                    mLockedParameters(p) {
-                mLockedParameters.mLock.lock();
-            }
-
-            ~Key() {
-                mLockedParameters.mLock.unlock();
-            }
-            Parameters &mParameters;
-          private:
-            // Disallow copying, default construction
-            Key();
-            Key(const Key &);
-            Key &operator=(const Key &);
-            LockedParameters &mLockedParameters;
-        };
-        class ReadKey {
-          public:
-            ReadKey(const LockedParameters &p):
-                    mParameters(p.mParameters),
-                    mLockedParameters(p) {
-                mLockedParameters.mLock.lock();
-            }
-
-            ~ReadKey() {
-                mLockedParameters.mLock.unlock();
-            }
-            const Parameters &mParameters;
-          private:
-            // Disallow copying, default construction
-            ReadKey();
-            ReadKey(const ReadKey &);
-            ReadKey &operator=(const ReadKey &);
-            const LockedParameters &mLockedParameters;
-        };
-
-        // Only use for dumping or other debugging
-        const Parameters &unsafeUnlock() {
-            return mParameters;
-        }
-      private:
-        Parameters mParameters;
-        mutable Mutex mLock;
-
-    } mParameters;
-
-    // Static device information; this is a subset of the information
-    // available through the staticInfo() method, used for frequently-accessed
-    // values or values that have to be calculated from the static information.
-    struct DeviceInfo {
-        int32_t arrayWidth;
-        int32_t arrayHeight;
-        uint8_t bestFaceDetectMode;
-        int32_t maxFaces;
-    };
-    const DeviceInfo *mDeviceInfo;
+    // Current camera device configuration
+    camera2::SharedParameters mParameters;
 
     /** Camera device-related private members */
 
@@ -291,8 +128,6 @@
     void     setPreviewCallbackFlagL(Parameters &params, int flag);
     status_t updateRequests(const Parameters &params);
 
-    // Number of zoom steps to simulate
-    static const unsigned int NUM_ZOOM_STEPS = 10;
     // Used with stream IDs
     static const int NO_STREAM = -1;
 
@@ -445,21 +280,8 @@
         sp<MemoryBase> *mBuffers;
     };
 
-    // Get values for static camera info entry. min/maxCount are used for error
-    // checking the number of values in the entry. 0 for max/minCount means to
-    // do no bounds check in that direction. In case of error, the entry data
-    // pointer is null and the count is 0.
-    camera_metadata_ro_entry_t staticInfo(uint32_t tag,
-            size_t minCount=0, size_t maxCount=0) const;
-
-    // Extract frequently-used camera static information into mDeviceInfo
-    status_t buildDeviceInfo();
-    // Convert static camera info from a camera2 device to the
-    // old API parameter map.
-    status_t buildDefaultParameters();
-
     // Update parameters all requests use, based on mParameters
-    status_t updateRequestCommon(CameraMetadata *request, const Parameters &params);
+    status_t updateRequestCommon(CameraMetadata *request, const Parameters &params) const;
 
     // Map from sensor active array pixel coordinates to normalized camera
     // parameter coordinates. The former are (0,0)-(array width - 1, array height
@@ -469,24 +291,6 @@
     int arrayXToNormalized(int width) const;
     int arrayYToNormalized(int height) const;
 
-    // Convert camera1 preview format string to camera2 enum
-    static int formatStringToEnum(const char *format);
-    static const char *formatEnumToString(int format);
-
-    static int wbModeStringToEnum(const char *wbMode);
-    static int effectModeStringToEnum(const char *effectMode);
-    static int abModeStringToEnum(const char *abMode);
-    static int sceneModeStringToEnum(const char *sceneMode);
-    static Parameters::flashMode_t flashModeStringToEnum(const char *flashMode);
-    static Parameters::focusMode_t focusModeStringToEnum(const char *focusMode);
-    static status_t parseAreas(const char *areasCStr,
-            Vector<Parameters::Area> *areas);
-    static status_t validateAreas(const Vector<Parameters::Area> &areas,
-                                  size_t maxRegions);
-    static bool boolFromString(const char *boolStr);
-
-    // Map from camera orientation + facing to gralloc transform enum
-    static int degToTransform(int degrees, bool mirror);
 
     static size_t calculateBufferSize(int width, int height,
             int format, int stride);
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 35c4e74..7cac025 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -156,7 +156,7 @@
     return res;
 }
 
-const CameraMetadata& Camera2Device::info() const {
+const camera2::CameraMetadata& Camera2Device::info() const {
     ALOGVV("%s: E", __FUNCTION__);
 
     return mDeviceInfo;
diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h
index 223d77a..64f4608 100644
--- a/services/camera/libcameraservice/Camera2Device.h
+++ b/services/camera/libcameraservice/Camera2Device.h
@@ -27,12 +27,14 @@
 #include <utils/Vector.h>
 
 #include "hardware/camera2.h"
-#include "CameraMetadata.h"
+#include "camera2/CameraMetadata.h"
 
 namespace android {
 
 class Camera2Device : public virtual RefBase {
   public:
+    typedef camera2::CameraMetadata CameraMetadata;
+
     Camera2Device(int id);
 
     ~Camera2Device();
diff --git a/services/camera/libcameraservice/CameraMetadata.cpp b/services/camera/libcameraservice/camera2/CameraMetadata.cpp
similarity index 99%
rename from services/camera/libcameraservice/CameraMetadata.cpp
rename to services/camera/libcameraservice/camera2/CameraMetadata.cpp
index b402115..95377b2 100644
--- a/services/camera/libcameraservice/CameraMetadata.cpp
+++ b/services/camera/libcameraservice/camera2/CameraMetadata.cpp
@@ -22,6 +22,7 @@
 
 namespace android {
 
+namespace camera2 {
 CameraMetadata::CameraMetadata() :
         mBuffer(NULL) {
 }
@@ -287,4 +288,5 @@
     return OK;
 }
 
+}; // namespace camera2
 }; // namespace android
diff --git a/services/camera/libcameraservice/CameraMetadata.h b/services/camera/libcameraservice/camera2/CameraMetadata.h
similarity index 96%
rename from services/camera/libcameraservice/CameraMetadata.h
rename to services/camera/libcameraservice/camera2/CameraMetadata.h
index afb8318..340414e 100644
--- a/services/camera/libcameraservice/CameraMetadata.h
+++ b/services/camera/libcameraservice/camera2/CameraMetadata.h
@@ -14,14 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SERVERS_CAMERA_METADATA_CPP
-#define ANDROID_SERVERS_CAMERA_METADATA_CPP
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA2METADATA_CPP
+#define ANDROID_SERVERS_CAMERA_CAMERA2METADATA_CPP
 
 #include "system/camera_metadata.h"
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
 namespace android {
+namespace camera2 {
 
 /**
  * A convenience wrapper around the C-based camera_metadata_t library.
@@ -161,6 +162,7 @@
 
 };
 
+}; // namespace camera2
 }; // namespace android
 
 #endif
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
new file mode 100644
index 0000000..91c5141
--- /dev/null
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -0,0 +1,1627 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Camera2::Parameters"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "Parameters.h"
+#include "system/camera.h"
+#include "camera/CameraParameters.h"
+
+namespace android {
+namespace camera2 {
+
+Parameters::Parameters(int cameraId,
+        int cameraFacing) :
+        cameraId(cameraId),
+        cameraFacing(cameraFacing),
+        info(NULL) {
+}
+
+Parameters::~Parameters() {
+}
+
+status_t Parameters::initialize(const CameraMetadata *info) {
+    status_t res;
+
+    if (info->entryCount() == 0) {
+        ALOGE("%s: No static information provided!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    Parameters::info = info;
+
+    res = buildFastInfo();
+    if (res != OK) return res;
+
+    CameraParameters params;
+
+    camera_metadata_ro_entry_t availableProcessedSizes =
+        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
+    if (!availableProcessedSizes.count) return NO_INIT;
+
+    // TODO: Pick more intelligently
+    previewWidth = availableProcessedSizes.data.i32[0];
+    previewHeight = availableProcessedSizes.data.i32[1];
+    videoWidth = previewWidth;
+    videoHeight = previewHeight;
+
+    params.setPreviewSize(previewWidth, previewHeight);
+    params.setVideoSize(videoWidth, videoHeight);
+    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
+            String8::format("%dx%d",
+                    previewWidth, previewHeight));
+    {
+        String8 supportedPreviewSizes;
+        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
+            if (i != 0) supportedPreviewSizes += ",";
+            supportedPreviewSizes += String8::format("%dx%d",
+                    availableProcessedSizes.data.i32[i],
+                    availableProcessedSizes.data.i32[i+1]);
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
+                supportedPreviewSizes);
+        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
+                supportedPreviewSizes);
+    }
+
+    camera_metadata_ro_entry_t availableFpsRanges =
+        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
+    if (!availableFpsRanges.count) return NO_INIT;
+
+    previewFpsRange[0] = availableFpsRanges.data.i32[0];
+    previewFpsRange[1] = availableFpsRanges.data.i32[1];
+
+    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
+            String8::format("%d,%d",
+                    previewFpsRange[0],
+                    previewFpsRange[1]));
+
+    {
+        String8 supportedPreviewFpsRange;
+        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
+            if (i != 0) supportedPreviewFpsRange += ",";
+            supportedPreviewFpsRange += String8::format("(%d,%d)",
+                    availableFpsRanges.data.i32[i],
+                    availableFpsRanges.data.i32[i+1]);
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
+                supportedPreviewFpsRange);
+    }
+
+    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
+            formatEnumToString(previewFormat)); // NV21
+
+    previewTransform = degToTransform(0,
+            cameraFacing == CAMERA_FACING_FRONT);
+
+    camera_metadata_ro_entry_t availableFormats =
+        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
+
+    {
+        String8 supportedPreviewFormats;
+        bool addComma = false;
+        for (size_t i=0; i < availableFormats.count; i++) {
+            if (addComma) supportedPreviewFormats += ",";
+            addComma = true;
+            switch (availableFormats.data.i32[i]) {
+            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_YUV422SP;
+                break;
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_YUV420SP;
+                break;
+            case HAL_PIXEL_FORMAT_YCbCr_422_I:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_YUV422I;
+                break;
+            case HAL_PIXEL_FORMAT_YV12:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_YUV420P;
+                break;
+            case HAL_PIXEL_FORMAT_RGB_565:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_RGB565;
+                break;
+            case HAL_PIXEL_FORMAT_RGBA_8888:
+                supportedPreviewFormats +=
+                    CameraParameters::PIXEL_FORMAT_RGBA8888;
+                break;
+            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
+            case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            case HAL_PIXEL_FORMAT_BLOB:
+                addComma = false;
+                break;
+
+            default:
+                ALOGW("%s: Camera %d: Unknown preview format: %x",
+                        __FUNCTION__, cameraId, availableFormats.data.i32[i]);
+                addComma = false;
+                break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
+                supportedPreviewFormats);
+    }
+
+    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
+    // still have to do something sane for them
+
+    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
+            previewFpsRange[0]);
+
+    {
+        String8 supportedPreviewFrameRates;
+        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
+            if (i != 0) supportedPreviewFrameRates += ",";
+            supportedPreviewFrameRates += String8::format("%d",
+                    availableFpsRanges.data.i32[i]);
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
+                supportedPreviewFrameRates);
+    }
+
+    camera_metadata_ro_entry_t availableJpegSizes =
+        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
+    if (!availableJpegSizes.count) return NO_INIT;
+
+    // TODO: Pick maximum
+    pictureWidth = availableJpegSizes.data.i32[0];
+    pictureHeight = availableJpegSizes.data.i32[1];
+
+    params.setPictureSize(pictureWidth,
+            pictureHeight);
+
+    {
+        String8 supportedPictureSizes;
+        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
+            if (i != 0) supportedPictureSizes += ",";
+            supportedPictureSizes += String8::format("%dx%d",
+                    availableJpegSizes.data.i32[i],
+                    availableJpegSizes.data.i32[i+1]);
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
+                supportedPictureSizes);
+    }
+
+    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
+    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
+            CameraParameters::PIXEL_FORMAT_JPEG);
+
+    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
+        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
+    if (!availableJpegThumbnailSizes.count) return NO_INIT;
+
+    // TODO: Pick default thumbnail size sensibly
+    jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
+    jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
+
+    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
+            jpegThumbSize[0]);
+    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
+            jpegThumbSize[1]);
+
+    {
+        String8 supportedJpegThumbSizes;
+        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
+            if (i != 0) supportedJpegThumbSizes += ",";
+            supportedJpegThumbSizes += String8::format("%dx%d",
+                    availableJpegThumbnailSizes.data.i32[i],
+                    availableJpegThumbnailSizes.data.i32[i+1]);
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
+                supportedJpegThumbSizes);
+    }
+
+    jpegThumbQuality = 90;
+    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
+            jpegThumbQuality);
+    jpegQuality = 90;
+    params.set(CameraParameters::KEY_JPEG_QUALITY,
+            jpegQuality);
+    jpegRotation = 0;
+    params.set(CameraParameters::KEY_ROTATION,
+            jpegRotation);
+
+    gpsEnabled = false;
+    gpsProcessingMethod = "unknown";
+    // GPS fields in CameraParameters are not set by implementation
+
+    wbMode = ANDROID_CONTROL_AWB_AUTO;
+    params.set(CameraParameters::KEY_WHITE_BALANCE,
+            CameraParameters::WHITE_BALANCE_AUTO);
+
+    camera_metadata_ro_entry_t availableWhiteBalanceModes =
+        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
+    {
+        String8 supportedWhiteBalance;
+        bool addComma = false;
+        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
+            if (addComma) supportedWhiteBalance += ",";
+            addComma = true;
+            switch (availableWhiteBalanceModes.data.u8[i]) {
+            case ANDROID_CONTROL_AWB_AUTO:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_AUTO;
+                break;
+            case ANDROID_CONTROL_AWB_INCANDESCENT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
+                break;
+            case ANDROID_CONTROL_AWB_FLUORESCENT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
+                break;
+            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
+                break;
+            case ANDROID_CONTROL_AWB_DAYLIGHT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
+                break;
+            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
+                break;
+            case ANDROID_CONTROL_AWB_TWILIGHT:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_TWILIGHT;
+                break;
+            case ANDROID_CONTROL_AWB_SHADE:
+                supportedWhiteBalance +=
+                    CameraParameters::WHITE_BALANCE_SHADE;
+                break;
+            // Skipping values not mappable to v1 API
+            case ANDROID_CONTROL_AWB_OFF:
+                addComma = false;
+                break;
+            default:
+                ALOGW("%s: Camera %d: Unknown white balance value: %d",
+                        __FUNCTION__, cameraId,
+                        availableWhiteBalanceModes.data.u8[i]);
+                addComma = false;
+                break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
+                supportedWhiteBalance);
+    }
+
+    effectMode = ANDROID_CONTROL_EFFECT_OFF;
+    params.set(CameraParameters::KEY_EFFECT,
+            CameraParameters::EFFECT_NONE);
+
+    camera_metadata_ro_entry_t availableEffects =
+        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
+    if (!availableEffects.count) return NO_INIT;
+    {
+        String8 supportedEffects;
+        bool addComma = false;
+        for (size_t i=0; i < availableEffects.count; i++) {
+            if (addComma) supportedEffects += ",";
+            addComma = true;
+            switch (availableEffects.data.u8[i]) {
+                case ANDROID_CONTROL_EFFECT_OFF:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_NONE;
+                    break;
+                case ANDROID_CONTROL_EFFECT_MONO:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_MONO;
+                    break;
+                case ANDROID_CONTROL_EFFECT_NEGATIVE:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_NEGATIVE;
+                    break;
+                case ANDROID_CONTROL_EFFECT_SOLARIZE:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_SOLARIZE;
+                    break;
+                case ANDROID_CONTROL_EFFECT_SEPIA:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_SEPIA;
+                    break;
+                case ANDROID_CONTROL_EFFECT_POSTERIZE:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_POSTERIZE;
+                    break;
+                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_WHITEBOARD;
+                    break;
+                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_BLACKBOARD;
+                    break;
+                case ANDROID_CONTROL_EFFECT_AQUA:
+                    supportedEffects +=
+                        CameraParameters::EFFECT_AQUA;
+                    break;
+                default:
+                    ALOGW("%s: Camera %d: Unknown effect value: %d",
+                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
+                    addComma = false;
+                    break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
+    }
+
+    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
+    params.set(CameraParameters::KEY_ANTIBANDING,
+            CameraParameters::ANTIBANDING_AUTO);
+
+    camera_metadata_ro_entry_t availableAntibandingModes =
+        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
+    if (!availableAntibandingModes.count) return NO_INIT;
+    {
+        String8 supportedAntibanding;
+        bool addComma = false;
+        for (size_t i=0; i < availableAntibandingModes.count; i++) {
+            if (addComma) supportedAntibanding += ",";
+            addComma = true;
+            switch (availableAntibandingModes.data.u8[i]) {
+                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
+                    supportedAntibanding +=
+                        CameraParameters::ANTIBANDING_OFF;
+                    break;
+                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
+                    supportedAntibanding +=
+                        CameraParameters::ANTIBANDING_50HZ;
+                    break;
+                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
+                    supportedAntibanding +=
+                        CameraParameters::ANTIBANDING_60HZ;
+                    break;
+                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
+                    supportedAntibanding +=
+                        CameraParameters::ANTIBANDING_AUTO;
+                    break;
+                default:
+                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
+                        __FUNCTION__, cameraId,
+                            availableAntibandingModes.data.u8[i]);
+                    addComma = false;
+                    break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
+                supportedAntibanding);
+    }
+
+    sceneMode = ANDROID_CONTROL_OFF;
+    params.set(CameraParameters::KEY_SCENE_MODE,
+            CameraParameters::SCENE_MODE_AUTO);
+
+    camera_metadata_ro_entry_t availableSceneModes =
+        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+    if (!availableSceneModes.count) return NO_INIT;
+    {
+        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
+        bool addComma = true;
+        bool noSceneModes = false;
+        for (size_t i=0; i < availableSceneModes.count; i++) {
+            if (addComma) supportedSceneModes += ",";
+            addComma = true;
+            switch (availableSceneModes.data.u8[i]) {
+                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
+                    noSceneModes = true;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
+                    // Not in old API
+                    addComma = false;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_ACTION:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_ACTION;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_PORTRAIT;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_LANDSCAPE;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_NIGHT;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_THEATRE;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_BEACH:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_BEACH;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_SNOW:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_SNOW;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_SUNSET;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_STEADYPHOTO;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_FIREWORKS;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_SPORTS;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_PARTY:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_PARTY;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_CANDLELIGHT;
+                    break;
+                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
+                    supportedSceneModes +=
+                        CameraParameters::SCENE_MODE_BARCODE;
+                    break;
+                default:
+                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
+                        __FUNCTION__, cameraId,
+                            availableSceneModes.data.u8[i]);
+                    addComma = false;
+                    break;
+            }
+        }
+        if (!noSceneModes) {
+            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
+                    supportedSceneModes);
+        }
+    }
+
+    camera_metadata_ro_entry_t flashAvailable =
+        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
+    if (!flashAvailable.count) return NO_INIT;
+
+    camera_metadata_ro_entry_t availableAeModes =
+        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
+    if (!availableAeModes.count) return NO_INIT;
+
+    if (flashAvailable.data.u8[0]) {
+        flashMode = Parameters::FLASH_MODE_AUTO;
+        params.set(CameraParameters::KEY_FLASH_MODE,
+                CameraParameters::FLASH_MODE_AUTO);
+
+        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
+        supportedFlashModes = supportedFlashModes +
+            "," + CameraParameters::FLASH_MODE_AUTO +
+            "," + CameraParameters::FLASH_MODE_ON +
+            "," + CameraParameters::FLASH_MODE_TORCH;
+        for (size_t i=0; i < availableAeModes.count; i++) {
+            if (availableAeModes.data.u8[i] ==
+                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
+                supportedFlashModes = supportedFlashModes + "," +
+                    CameraParameters::FLASH_MODE_RED_EYE;
+                break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
+                supportedFlashModes);
+    } else {
+        flashMode = Parameters::FLASH_MODE_OFF;
+        params.set(CameraParameters::KEY_FLASH_MODE,
+                CameraParameters::FLASH_MODE_OFF);
+        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
+                CameraParameters::FLASH_MODE_OFF);
+    }
+
+    camera_metadata_ro_entry_t minFocusDistance =
+        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
+    if (!minFocusDistance.count) return NO_INIT;
+
+    camera_metadata_ro_entry_t availableAfModes =
+        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
+    if (!availableAfModes.count) return NO_INIT;
+
+    if (minFocusDistance.data.f[0] == 0) {
+        // Fixed-focus lens
+        focusMode = Parameters::FOCUS_MODE_FIXED;
+        params.set(CameraParameters::KEY_FOCUS_MODE,
+                CameraParameters::FOCUS_MODE_FIXED);
+        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+                CameraParameters::FOCUS_MODE_FIXED);
+    } else {
+        focusMode = Parameters::FOCUS_MODE_AUTO;
+        params.set(CameraParameters::KEY_FOCUS_MODE,
+                CameraParameters::FOCUS_MODE_AUTO);
+        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
+        bool addComma = true;
+
+        for (size_t i=0; i < availableAfModes.count; i++) {
+            if (addComma) supportedFocusModes += ",";
+            addComma = true;
+            switch (availableAfModes.data.u8[i]) {
+                case ANDROID_CONTROL_AF_AUTO:
+                    supportedFocusModes +=
+                        CameraParameters::FOCUS_MODE_AUTO;
+                    break;
+                case ANDROID_CONTROL_AF_MACRO:
+                    supportedFocusModes +=
+                        CameraParameters::FOCUS_MODE_MACRO;
+                    break;
+                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
+                    supportedFocusModes +=
+                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
+                    break;
+                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
+                    supportedFocusModes +=
+                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
+                    break;
+                case ANDROID_CONTROL_AF_EDOF:
+                    supportedFocusModes +=
+                        CameraParameters::FOCUS_MODE_EDOF;
+                    break;
+                // Not supported in old API
+                case ANDROID_CONTROL_AF_OFF:
+                    addComma = false;
+                    break;
+                default:
+                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
+                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
+                    addComma = false;
+                    break;
+            }
+        }
+        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+                supportedFocusModes);
+    }
+
+    camera_metadata_ro_entry_t max3aRegions =
+        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
+    if (!max3aRegions.count) return NO_INIT;
+
+    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
+            max3aRegions.data.i32[0]);
+    params.set(CameraParameters::KEY_FOCUS_AREAS,
+            "(0,0,0,0,0)");
+    focusingAreas.clear();
+    focusingAreas.add(Parameters::Area(0,0,0,0,0));
+
+    camera_metadata_ro_entry_t availableFocalLengths =
+        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
+    if (!availableFocalLengths.count) return NO_INIT;
+
+    float minFocalLength = availableFocalLengths.data.f[0];
+    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
+
+    camera_metadata_ro_entry_t sensorSize =
+        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
+    if (!sensorSize.count) return NO_INIT;
+
+    // The fields of view here assume infinity focus, maximum wide angle
+    float horizFov = 180 / M_PI *
+            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
+    float vertFov  = 180 / M_PI *
+            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
+    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
+    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
+
+    exposureCompensation = 0;
+    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
+                exposureCompensation);
+
+    camera_metadata_ro_entry_t exposureCompensationRange =
+        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
+    if (!exposureCompensationRange.count) return NO_INIT;
+
+    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
+            exposureCompensationRange.data.i32[1]);
+    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
+            exposureCompensationRange.data.i32[0]);
+
+    camera_metadata_ro_entry_t exposureCompensationStep =
+        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
+    if (!exposureCompensationStep.count) return NO_INIT;
+
+    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
+            (float)exposureCompensationStep.data.r[0].numerator /
+            exposureCompensationStep.data.r[0].denominator);
+
+    autoExposureLock = false;
+    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
+            CameraParameters::FALSE);
+    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
+            CameraParameters::TRUE);
+
+    autoWhiteBalanceLock = false;
+    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
+            CameraParameters::FALSE);
+    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
+            CameraParameters::TRUE);
+
+    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
+    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
+            max3aRegions.data.i32[0]);
+    params.set(CameraParameters::KEY_METERING_AREAS,
+            "(0,0,0,0,0)");
+
+    zoom = 0;
+    params.set(CameraParameters::KEY_ZOOM, zoom);
+    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
+
+    camera_metadata_ro_entry_t maxDigitalZoom =
+        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
+    if (!maxDigitalZoom.count) return NO_INIT;
+
+    {
+        String8 zoomRatios;
+        float zoom = 1.f;
+        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
+                (NUM_ZOOM_STEPS-1);
+        bool addComma = false;
+        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
+            if (addComma) zoomRatios += ",";
+            addComma = true;
+            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
+            zoom += zoomIncrement;
+        }
+        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
+    }
+
+    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
+            CameraParameters::TRUE);
+    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
+            CameraParameters::TRUE);
+
+    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
+            "Infinity,Infinity,Infinity");
+
+    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
+            fastInfo.maxFaces);
+    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
+            0);
+
+    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
+            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
+
+    params.set(CameraParameters::KEY_RECORDING_HINT,
+            CameraParameters::FALSE);
+
+    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
+            CameraParameters::TRUE);
+
+    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
+            CameraParameters::FALSE);
+
+    camera_metadata_ro_entry_t availableVideoStabilizationModes =
+        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
+    if (!availableVideoStabilizationModes.count) return NO_INIT;
+
+    if (availableVideoStabilizationModes.count > 1) {
+        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
+                CameraParameters::TRUE);
+    } else {
+        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
+                CameraParameters::FALSE);
+    }
+
+    // Set up initial state for non-Camera.Parameters state variables
+
+    storeMetadataInBuffers = true;
+    playShutterSound = true;
+    enableFaceDetect = false;
+
+    enableFocusMoveMessages = false;
+    afTriggerCounter = 0;
+    currentAfTriggerId = -1;
+
+    previewCallbackFlags = 0;
+
+    state = STOPPED;
+
+    paramsFlattened = params.flatten();
+
+    return OK;
+}
+
+status_t Parameters::buildFastInfo() {
+
+    camera_metadata_ro_entry_t activeArraySize =
+        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
+    if (!activeArraySize.count) return NO_INIT;
+    int32_t arrayWidth = activeArraySize.data.i32[0];
+    int32_t arrayHeight = activeArraySize.data.i32[1];
+
+    camera_metadata_ro_entry_t availableFaceDetectModes =
+        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
+    if (!availableFaceDetectModes.count) return NO_INIT;
+
+    uint8_t bestFaceDetectMode =
+        ANDROID_STATS_FACE_DETECTION_OFF;
+    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
+        switch (availableFaceDetectModes.data.u8[i]) {
+            case ANDROID_STATS_FACE_DETECTION_OFF:
+                break;
+            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
+                if (bestFaceDetectMode !=
+                        ANDROID_STATS_FACE_DETECTION_FULL) {
+                    bestFaceDetectMode =
+                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
+                }
+                break;
+            case ANDROID_STATS_FACE_DETECTION_FULL:
+                bestFaceDetectMode =
+                    ANDROID_STATS_FACE_DETECTION_FULL;
+                break;
+            default:
+                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
+                        __FUNCTION__, cameraId,
+                        availableFaceDetectModes.data.u8[i]);
+                return NO_INIT;
+        }
+    }
+
+    camera_metadata_ro_entry_t maxFacesDetected =
+        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
+    if (!maxFacesDetected.count) return NO_INIT;
+
+    int32_t maxFaces = maxFacesDetected.data.i32[0];
+
+    fastInfo.arrayWidth = arrayWidth;
+    fastInfo.arrayHeight = arrayHeight;
+    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
+    fastInfo.maxFaces = maxFaces;
+    return OK;
+}
+
+camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
+        size_t minCount, size_t maxCount) const {
+    status_t res;
+    camera_metadata_ro_entry_t entry = info->find(tag);
+
+    if (CC_UNLIKELY( entry.count == 0 )) {
+        const char* tagSection = get_camera_metadata_section_name(tag);
+        if (tagSection == NULL) tagSection = "<unknown>";
+        const char* tagName = get_camera_metadata_tag_name(tag);
+        if (tagName == NULL) tagName = "<unknown>";
+
+        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
+                tagSection, tagName, tag);
+    } else if (CC_UNLIKELY(
+            (minCount != 0 && entry.count < minCount) ||
+            (maxCount != 0 && entry.count > maxCount) ) ) {
+        const char* tagSection = get_camera_metadata_section_name(tag);
+        if (tagSection == NULL) tagSection = "<unknown>";
+        const char* tagName = get_camera_metadata_tag_name(tag);
+        if (tagName == NULL) tagName = "<unknown>";
+        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
+                "Expected between %d and %d values, but got %d values",
+                tagSection, tagName, tag, minCount, maxCount, entry.count);
+    }
+
+    return entry;
+}
+
+status_t Parameters::set(const String8& params) {
+    status_t res;
+
+    CameraParameters newParams(params);
+
+    // TODO: Currently ignoring any changes to supposedly read-only parameters
+    // such as supported preview sizes, etc. Should probably produce an error if
+    // they're changed.
+
+    /** Extract and verify new parameters */
+
+    size_t i;
+
+    Parameters validatedParams(*this);
+
+    // PREVIEW_SIZE
+    newParams.getPreviewSize(&validatedParams.previewWidth,
+            &validatedParams.previewHeight);
+
+    if (validatedParams.previewWidth != previewWidth ||
+            validatedParams.previewHeight != previewHeight) {
+        if (state >= PREVIEW) {
+            ALOGE("%s: Preview size cannot be updated when preview "
+                    "is active! (Currently %d x %d, requested %d x %d",
+                    __FUNCTION__,
+                    previewWidth, previewHeight,
+                    validatedParams.previewWidth, validatedParams.previewHeight);
+            return BAD_VALUE;
+        }
+        camera_metadata_ro_entry_t availablePreviewSizes =
+            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
+            if ((availablePreviewSizes.data.i32[i] ==
+                    validatedParams.previewWidth) &&
+                (availablePreviewSizes.data.i32[i+1] ==
+                    validatedParams.previewHeight)) break;
+        }
+        if (i == availablePreviewSizes.count) {
+            ALOGE("%s: Requested preview size %d x %d is not supported",
+                    __FUNCTION__, validatedParams.previewWidth,
+                    validatedParams.previewHeight);
+            return BAD_VALUE;
+        }
+    }
+
+    // PREVIEW_FPS_RANGE
+    bool fpsRangeChanged = false;
+    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
+            &validatedParams.previewFpsRange[1]);
+    if (validatedParams.previewFpsRange[0] != previewFpsRange[0] ||
+            validatedParams.previewFpsRange[1] != previewFpsRange[1]) {
+        fpsRangeChanged = true;
+        camera_metadata_ro_entry_t availablePreviewFpsRanges =
+            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
+        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
+            if ((availablePreviewFpsRanges.data.i32[i] ==
+                    validatedParams.previewFpsRange[0]) &&
+                (availablePreviewFpsRanges.data.i32[i+1] ==
+                    validatedParams.previewFpsRange[1]) ) {
+                break;
+            }
+        }
+        if (i == availablePreviewFpsRanges.count) {
+            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
+                __FUNCTION__, validatedParams.previewFpsRange[0],
+                    validatedParams.previewFpsRange[1]);
+            return BAD_VALUE;
+        }
+        validatedParams.previewFps = validatedParams.previewFpsRange[0];
+    }
+
+    // PREVIEW_FORMAT
+    validatedParams.previewFormat =
+            formatStringToEnum(newParams.getPreviewFormat());
+    if (validatedParams.previewFormat != previewFormat) {
+        if (state >= PREVIEW) {
+            ALOGE("%s: Preview format cannot be updated when preview "
+                    "is active!", __FUNCTION__);
+            return BAD_VALUE;
+        }
+        camera_metadata_ro_entry_t availableFormats =
+            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
+        for (i = 0; i < availableFormats.count; i++) {
+            if (availableFormats.data.i32[i] == validatedParams.previewFormat)
+                break;
+        }
+        if (i == availableFormats.count) {
+            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
+                    __FUNCTION__, newParams.getPreviewFormat(),
+                    validatedParams.previewFormat);
+            return BAD_VALUE;
+        }
+    }
+
+    // PREVIEW_FRAME_RATE
+    // Deprecated, only use if the preview fps range is unchanged this time.
+    // The single-value FPS is the same as the minimum of the range.
+    if (!fpsRangeChanged) {
+        validatedParams.previewFps = newParams.getPreviewFrameRate();
+        if (validatedParams.previewFps != previewFps) {
+            camera_metadata_ro_entry_t availableFrameRates =
+                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+            for (i = 0; i < availableFrameRates.count; i+=2) {
+                if (availableFrameRates.data.i32[i] ==
+                        validatedParams.previewFps) break;
+            }
+            if (i == availableFrameRates.count) {
+                ALOGE("%s: Requested preview frame rate %d is not supported",
+                        __FUNCTION__, validatedParams.previewFps);
+                return BAD_VALUE;
+            }
+            validatedParams.previewFpsRange[0] =
+                    availableFrameRates.data.i32[i];
+            validatedParams.previewFpsRange[1] =
+                    availableFrameRates.data.i32[i+1];
+        }
+    }
+
+    // PICTURE_SIZE
+    newParams.getPictureSize(&validatedParams.pictureWidth,
+            &validatedParams.pictureHeight);
+    if (validatedParams.pictureWidth == pictureWidth ||
+            validatedParams.pictureHeight == pictureHeight) {
+        camera_metadata_ro_entry_t availablePictureSizes =
+            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
+        for (i = 0; i < availablePictureSizes.count; i+=2) {
+            if ((availablePictureSizes.data.i32[i] ==
+                    validatedParams.pictureWidth) &&
+                (availablePictureSizes.data.i32[i+1] ==
+                    validatedParams.pictureHeight)) break;
+        }
+        if (i == availablePictureSizes.count) {
+            ALOGE("%s: Requested picture size %d x %d is not supported",
+                    __FUNCTION__, validatedParams.pictureWidth,
+                    validatedParams.pictureHeight);
+            return BAD_VALUE;
+        }
+    }
+
+    // JPEG_THUMBNAIL_WIDTH/HEIGHT
+    validatedParams.jpegThumbSize[0] =
+            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+    validatedParams.jpegThumbSize[1] =
+            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
+            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
+        camera_metadata_ro_entry_t availableJpegThumbSizes =
+            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
+        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
+            if ((availableJpegThumbSizes.data.i32[i] ==
+                    validatedParams.jpegThumbSize[0]) &&
+                (availableJpegThumbSizes.data.i32[i+1] ==
+                    validatedParams.jpegThumbSize[1])) break;
+        }
+        if (i == availableJpegThumbSizes.count) {
+            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
+                    __FUNCTION__, validatedParams.jpegThumbSize[0],
+                    validatedParams.jpegThumbSize[1]);
+            return BAD_VALUE;
+        }
+    }
+
+    // JPEG_THUMBNAIL_QUALITY
+    validatedParams.jpegThumbQuality =
+            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+    if (validatedParams.jpegThumbQuality < 0 ||
+            validatedParams.jpegThumbQuality > 100) {
+        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
+                __FUNCTION__, validatedParams.jpegThumbQuality);
+        return BAD_VALUE;
+    }
+
+    // JPEG_QUALITY
+    validatedParams.jpegQuality =
+            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
+    if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
+        ALOGE("%s: Requested JPEG quality %d is not supported",
+                __FUNCTION__, validatedParams.jpegQuality);
+        return BAD_VALUE;
+    }
+
+    // ROTATION
+    validatedParams.jpegRotation =
+            newParams.getInt(CameraParameters::KEY_ROTATION);
+    if (validatedParams.jpegRotation != 0 &&
+            validatedParams.jpegRotation != 90 &&
+            validatedParams.jpegRotation != 180 &&
+            validatedParams.jpegRotation != 270) {
+        ALOGE("%s: Requested picture rotation angle %d is not supported",
+                __FUNCTION__, validatedParams.jpegRotation);
+        return BAD_VALUE;
+    }
+
+    // GPS
+
+    const char *gpsLatStr =
+            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
+    if (gpsLatStr != NULL) {
+        const char *gpsLongStr =
+                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
+        const char *gpsAltitudeStr =
+                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
+        const char *gpsTimeStr =
+                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
+        const char *gpsProcMethodStr =
+                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+        if (gpsLongStr == NULL ||
+                gpsAltitudeStr == NULL ||
+                gpsTimeStr == NULL ||
+                gpsProcMethodStr == NULL) {
+            ALOGE("%s: Incomplete set of GPS parameters provided",
+                    __FUNCTION__);
+            return BAD_VALUE;
+        }
+        char *endPtr;
+        errno = 0;
+        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
+        if (errno || endPtr == gpsLatStr) {
+            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
+            return BAD_VALUE;
+        }
+        errno = 0;
+        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
+        if (errno || endPtr == gpsLongStr) {
+            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
+            return BAD_VALUE;
+        }
+        errno = 0;
+        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
+        if (errno || endPtr == gpsAltitudeStr) {
+            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
+                    gpsAltitudeStr);
+            return BAD_VALUE;
+        }
+        errno = 0;
+        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
+        if (errno || endPtr == gpsTimeStr) {
+            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
+            return BAD_VALUE;
+        }
+        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
+
+        validatedParams.gpsEnabled = true;
+    } else {
+        validatedParams.gpsEnabled = false;
+    }
+
+    // WHITE_BALANCE
+    validatedParams.wbMode = wbModeStringToEnum(
+        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
+    if (validatedParams.wbMode != wbMode) {
+        camera_metadata_ro_entry_t availableWbModes =
+            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
+        for (i = 0; i < availableWbModes.count; i++) {
+            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
+        }
+        if (i == availableWbModes.count) {
+            ALOGE("%s: Requested white balance mode %s is not supported",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
+            return BAD_VALUE;
+        }
+    }
+
+    // EFFECT
+    validatedParams.effectMode = effectModeStringToEnum(
+        newParams.get(CameraParameters::KEY_EFFECT) );
+    if (validatedParams.effectMode != effectMode) {
+        camera_metadata_ro_entry_t availableEffectModes =
+            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
+        for (i = 0; i < availableEffectModes.count; i++) {
+            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
+        }
+        if (i == availableEffectModes.count) {
+            ALOGE("%s: Requested effect mode \"%s\" is not supported",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_EFFECT) );
+            return BAD_VALUE;
+        }
+    }
+
+    // ANTIBANDING
+    validatedParams.antibandingMode = abModeStringToEnum(
+        newParams.get(CameraParameters::KEY_ANTIBANDING) );
+    if (validatedParams.antibandingMode != antibandingMode) {
+        camera_metadata_ro_entry_t availableAbModes =
+            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
+        for (i = 0; i < availableAbModes.count; i++) {
+            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
+                break;
+        }
+        if (i == availableAbModes.count) {
+            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_ANTIBANDING));
+            return BAD_VALUE;
+        }
+    }
+
+    // SCENE_MODE
+    validatedParams.sceneMode = sceneModeStringToEnum(
+        newParams.get(CameraParameters::KEY_SCENE_MODE) );
+    if (validatedParams.sceneMode != sceneMode &&
+            validatedParams.sceneMode !=
+            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
+        camera_metadata_ro_entry_t availableSceneModes =
+            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+        for (i = 0; i < availableSceneModes.count; i++) {
+            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
+                break;
+        }
+        if (i == availableSceneModes.count) {
+            ALOGE("%s: Requested scene mode \"%s\" is not supported",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_SCENE_MODE));
+            return BAD_VALUE;
+        }
+    }
+
+    // FLASH_MODE
+    validatedParams.flashMode = flashModeStringToEnum(
+        newParams.get(CameraParameters::KEY_FLASH_MODE) );
+    if (validatedParams.flashMode != flashMode) {
+        camera_metadata_ro_entry_t flashAvailable =
+            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
+        if (!flashAvailable.data.u8[0] &&
+                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
+            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
+                    "No flash on device", __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_FLASH_MODE));
+            return BAD_VALUE;
+        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
+            camera_metadata_ro_entry_t availableAeModes =
+                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
+            for (i = 0; i < availableAeModes.count; i++) {
+                if (validatedParams.flashMode == availableAeModes.data.u8[i])
+                    break;
+            }
+            if (i == availableAeModes.count) {
+                ALOGE("%s: Requested flash mode \"%s\" is not supported",
+                        __FUNCTION__,
+                        newParams.get(CameraParameters::KEY_FLASH_MODE));
+                return BAD_VALUE;
+            }
+        } else if (validatedParams.flashMode == -1) {
+            ALOGE("%s: Requested flash mode \"%s\" is unknown",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_FLASH_MODE));
+            return BAD_VALUE;
+        }
+    }
+
+    // FOCUS_MODE
+    validatedParams.focusMode = focusModeStringToEnum(
+        newParams.get(CameraParameters::KEY_FOCUS_MODE));
+    if (validatedParams.focusMode != focusMode) {
+        validatedParams.currentAfTriggerId = -1;
+        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
+            camera_metadata_ro_entry_t minFocusDistance =
+                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
+            if (minFocusDistance.data.f[0] == 0) {
+                ALOGE("%s: Requested focus mode \"%s\" is not available: "
+                        "fixed focus lens",
+                        __FUNCTION__,
+                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
+                return BAD_VALUE;
+            } else if (validatedParams.focusMode !=
+                    Parameters::FOCUS_MODE_INFINITY) {
+                camera_metadata_ro_entry_t availableFocusModes =
+                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
+                for (i = 0; i < availableFocusModes.count; i++) {
+                    if (validatedParams.focusMode ==
+                            availableFocusModes.data.u8[i]) break;
+                }
+                if (i == availableFocusModes.count) {
+                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
+                            __FUNCTION__,
+                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
+                    return BAD_VALUE;
+                }
+            }
+        }
+    } else {
+        validatedParams.currentAfTriggerId = currentAfTriggerId;
+    }
+
+    // FOCUS_AREAS
+    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
+            &validatedParams.focusingAreas);
+    size_t max3aRegions =
+        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
+    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
+            max3aRegions);
+    if (res != OK) {
+        ALOGE("%s: Requested focus areas are malformed: %s",
+                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
+        return BAD_VALUE;
+    }
+
+    // EXPOSURE_COMPENSATION
+    validatedParams.exposureCompensation =
+        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
+    camera_metadata_ro_entry_t exposureCompensationRange =
+        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
+    if ((validatedParams.exposureCompensation <
+            exposureCompensationRange.data.i32[0]) ||
+        (validatedParams.exposureCompensation >
+            exposureCompensationRange.data.i32[1])) {
+        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
+                __FUNCTION__, validatedParams.exposureCompensation);
+        return BAD_VALUE;
+    }
+
+    // AUTO_EXPOSURE_LOCK (always supported)
+    validatedParams.autoExposureLock = boolFromString(
+        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
+
+    // AUTO_WHITEBALANCE_LOCK (always supported)
+    validatedParams.autoWhiteBalanceLock = boolFromString(
+        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
+
+    // METERING_AREAS
+    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
+            &validatedParams.meteringAreas);
+    if (res == OK) {
+        res = validateAreas(validatedParams.meteringAreas, max3aRegions);
+    }
+    if (res != OK) {
+        ALOGE("%s: Requested metering areas are malformed: %s",
+                __FUNCTION__,
+                newParams.get(CameraParameters::KEY_METERING_AREAS));
+        return BAD_VALUE;
+    }
+
+    // ZOOM
+    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
+    if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
+        ALOGE("%s: Requested zoom level %d is not supported",
+                __FUNCTION__, validatedParams.zoom);
+        return BAD_VALUE;
+    }
+
+    // VIDEO_SIZE
+    newParams.getVideoSize(&validatedParams.videoWidth,
+            &validatedParams.videoHeight);
+    if (validatedParams.videoWidth != videoWidth ||
+            validatedParams.videoHeight != videoHeight) {
+        if (state == RECORD) {
+            ALOGE("%s: Video size cannot be updated when recording is active!",
+                    __FUNCTION__);
+            return BAD_VALUE;
+        }
+        camera_metadata_ro_entry_t availableVideoSizes =
+            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
+        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
+            if ((availableVideoSizes.data.i32[i] ==
+                    validatedParams.videoWidth) &&
+                (availableVideoSizes.data.i32[i+1] ==
+                    validatedParams.videoHeight)) break;
+        }
+        if (i == availableVideoSizes.count) {
+            ALOGE("%s: Requested video size %d x %d is not supported",
+                    __FUNCTION__, validatedParams.videoWidth,
+                    validatedParams.videoHeight);
+            return BAD_VALUE;
+        }
+    }
+
+    // RECORDING_HINT (always supported)
+    validatedParams.recordingHint = boolFromString(
+        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
+
+    // VIDEO_STABILIZATION
+    validatedParams.videoStabilization = boolFromString(
+        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
+    camera_metadata_ro_entry_t availableVideoStabilizationModes =
+        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
+    if (validatedParams.videoStabilization &&
+            availableVideoStabilizationModes.count == 1) {
+        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
+    }
+
+    /** Update internal parameters */
+
+    validatedParams.paramsFlattened = params;
+    *this = validatedParams;
+
+    return OK;
+}
+
+const char* Parameters::getStateName(State state) {
+#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
+    switch(state) {
+        CASE_ENUM_TO_CHAR(DISCONNECTED)
+        CASE_ENUM_TO_CHAR(STOPPED)
+        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
+        CASE_ENUM_TO_CHAR(PREVIEW)
+        CASE_ENUM_TO_CHAR(RECORD)
+        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
+        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
+        default:
+            return "Unknown state!";
+            break;
+    }
+#undef CASE_ENUM_TO_CHAR
+}
+
+int Parameters::formatStringToEnum(const char *format) {
+    return
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
+            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
+            HAL_PIXEL_FORMAT_YV12 :         // YV12
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
+            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
+            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
+        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
+            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
+        -1;
+}
+
+const char* Parameters::formatEnumToString(int format) {
+    const char *fmt;
+    switch(format) {
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
+            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
+            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
+            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
+            break;
+        case HAL_PIXEL_FORMAT_YV12:        // YV12
+            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
+            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
+            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
+            break;
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            ALOGW("Raw sensor preview format requested.");
+            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
+            break;
+        default:
+            ALOGE("%s: Unknown preview format: %x",
+                    __FUNCTION__,  format);
+            fmt = NULL;
+            break;
+    }
+    return fmt;
+}
+
+int Parameters::wbModeStringToEnum(const char *wbMode) {
+    return
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
+            ANDROID_CONTROL_AWB_AUTO :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
+            ANDROID_CONTROL_AWB_INCANDESCENT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
+            ANDROID_CONTROL_AWB_FLUORESCENT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
+            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
+            ANDROID_CONTROL_AWB_DAYLIGHT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
+            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
+            ANDROID_CONTROL_AWB_TWILIGHT :
+        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
+            ANDROID_CONTROL_AWB_SHADE :
+        -1;
+}
+
+int Parameters::effectModeStringToEnum(const char *effectMode) {
+    return
+        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
+            ANDROID_CONTROL_EFFECT_OFF :
+        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
+            ANDROID_CONTROL_EFFECT_MONO :
+        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
+            ANDROID_CONTROL_EFFECT_NEGATIVE :
+        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
+            ANDROID_CONTROL_EFFECT_SOLARIZE :
+        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
+            ANDROID_CONTROL_EFFECT_SEPIA :
+        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
+            ANDROID_CONTROL_EFFECT_POSTERIZE :
+        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
+            ANDROID_CONTROL_EFFECT_WHITEBOARD :
+        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
+            ANDROID_CONTROL_EFFECT_BLACKBOARD :
+        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
+            ANDROID_CONTROL_EFFECT_AQUA :
+        -1;
+}
+
+int Parameters::abModeStringToEnum(const char *abMode) {
+    return
+        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
+            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
+        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
+            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
+        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
+            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
+        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
+            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
+        -1;
+}
+
+int Parameters::sceneModeStringToEnum(const char *sceneMode) {
+    return
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
+            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
+            ANDROID_CONTROL_SCENE_MODE_ACTION :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
+            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
+            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
+            ANDROID_CONTROL_SCENE_MODE_NIGHT :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
+            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
+            ANDROID_CONTROL_SCENE_MODE_THEATRE :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
+            ANDROID_CONTROL_SCENE_MODE_BEACH :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
+            ANDROID_CONTROL_SCENE_MODE_SNOW :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
+            ANDROID_CONTROL_SCENE_MODE_SUNSET :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
+            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
+            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
+            ANDROID_CONTROL_SCENE_MODE_SPORTS :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
+            ANDROID_CONTROL_SCENE_MODE_PARTY :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
+            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
+        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
+            ANDROID_CONTROL_SCENE_MODE_BARCODE:
+        -1;
+}
+
+Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
+        const char *flashMode) {
+    return
+        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
+            Parameters::FLASH_MODE_OFF :
+        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
+            Parameters::FLASH_MODE_AUTO :
+        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
+            Parameters::FLASH_MODE_ON :
+        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
+            Parameters::FLASH_MODE_RED_EYE :
+        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
+            Parameters::FLASH_MODE_TORCH :
+        Parameters::FLASH_MODE_INVALID;
+}
+
+Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
+        const char *focusMode) {
+    return
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
+            Parameters::FOCUS_MODE_AUTO :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
+            Parameters::FOCUS_MODE_INFINITY :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
+            Parameters::FOCUS_MODE_MACRO :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
+            Parameters::FOCUS_MODE_FIXED :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
+            Parameters::FOCUS_MODE_EDOF :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
+            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
+        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
+            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
+        Parameters::FOCUS_MODE_INVALID;
+}
+
+status_t Parameters::parseAreas(const char *areasCStr,
+        Vector<Parameters::Area> *areas) {
+    static const size_t NUM_FIELDS = 5;
+    areas->clear();
+    if (areasCStr == NULL) {
+        // If no key exists, use default (0,0,0,0,0)
+        areas->push();
+        return OK;
+    }
+    String8 areasStr(areasCStr);
+    ssize_t areaStart = areasStr.find("(", 0) + 1;
+    while (areaStart != 0) {
+        const char* area = areasStr.string() + areaStart;
+        char *numEnd;
+        int vals[NUM_FIELDS];
+        for (size_t i = 0; i < NUM_FIELDS; i++) {
+            errno = 0;
+            vals[i] = strtol(area, &numEnd, 10);
+            if (errno || numEnd == area) return BAD_VALUE;
+            area = numEnd + 1;
+        }
+        areas->push(Parameters::Area(
+            vals[0], vals[1], vals[2], vals[3], vals[4]) );
+        areaStart = areasStr.find("(", areaStart) + 1;
+    }
+    return OK;
+}
+
+status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
+                                      size_t maxRegions) {
+    // Definition of valid area can be found in
+    // include/camera/CameraParameters.h
+    if (areas.size() == 0) return BAD_VALUE;
+    if (areas.size() == 1) {
+        if (areas[0].left == 0 &&
+                areas[0].top == 0 &&
+                areas[0].right == 0 &&
+                areas[0].bottom == 0 &&
+                areas[0].weight == 0) {
+            // Single (0,0,0,0,0) entry is always valid (== driver decides)
+            return OK;
+        }
+    }
+    if (areas.size() > maxRegions) {
+        ALOGE("%s: Too many areas requested: %d",
+                __FUNCTION__, areas.size());
+        return BAD_VALUE;
+    }
+
+    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
+         a != areas.end(); a++) {
+        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
+        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
+        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
+        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
+        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
+        if (a->left >= a->right) return BAD_VALUE;
+        if (a->top >= a->bottom) return BAD_VALUE;
+    }
+    return OK;
+}
+
+bool Parameters::boolFromString(const char *boolStr) {
+    return !boolStr ? false :
+        !strcmp(boolStr, CameraParameters::TRUE) ? true :
+        false;
+}
+
+int Parameters::degToTransform(int degrees, bool mirror) {
+    if (!mirror) {
+        if (degrees == 0) return 0;
+        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
+        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
+        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
+    } else {  // Do mirror (horizontal flip)
+        if (degrees == 0) {           // FLIP_H and ROT_0
+            return HAL_TRANSFORM_FLIP_H;
+        } else if (degrees == 90) {   // FLIP_H and ROT_90
+            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
+        } else if (degrees == 180) {  // FLIP_H and ROT_180
+            return HAL_TRANSFORM_FLIP_V;
+        } else if (degrees == 270) {  // FLIP_H and ROT_270
+            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
+        }
+    }
+    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
+    return -1;
+}
+
+int Parameters::arrayXToNormalized(int width) const {
+    return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
+}
+
+int Parameters::arrayYToNormalized(int height) const {
+    return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
+}
+
+int Parameters::normalizedXToArray(int x) const {
+    return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
+}
+
+int Parameters::normalizedYToArray(int y) const {
+    return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
+}
+
+}; // namespace camera2
+}; // namespace android
diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h
new file mode 100644
index 0000000..817d001
--- /dev/null
+++ b/services/camera/libcameraservice/camera2/Parameters.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERA2PARAMETERS_H
+#define ANDROID_SERVERS_CAMERA_CAMERA2PARAMETERS_H
+
+#include <system/graphics.h>
+
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace camera2 {
+
+// Current camera state; this is the full state of the Camera under the old
+// camera API (contents of the CameraParameters object in a more-efficient
+// format, plus other state). The enum values are mostly based off the
+// corresponding camera2 enums, not the camera1 strings. A few are defined here
+// if they don't cleanly map to camera2 values.
+struct Parameters {
+    int cameraId;
+    int cameraFacing;
+
+    int previewWidth, previewHeight;
+    int32_t previewFpsRange[2];
+    int previewFps; // deprecated, here only for tracking changes
+    int previewFormat;
+
+    int previewTransform; // set by CAMERA_CMD_SET_DISPLAY_ORIENTATION
+
+    int pictureWidth, pictureHeight;
+
+    int32_t jpegThumbSize[2];
+    int32_t jpegQuality, jpegThumbQuality;
+    int32_t jpegRotation;
+
+    bool gpsEnabled;
+    double gpsCoordinates[3];
+    int64_t gpsTimestamp;
+    String8 gpsProcessingMethod;
+
+    uint8_t wbMode;
+    uint8_t effectMode;
+    uint8_t antibandingMode;
+    uint8_t sceneMode;
+
+    enum flashMode_t {
+        FLASH_MODE_OFF = 0,
+        FLASH_MODE_AUTO,
+        FLASH_MODE_ON,
+        FLASH_MODE_TORCH,
+        FLASH_MODE_RED_EYE = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE,
+        FLASH_MODE_INVALID = -1
+    } flashMode;
+
+    enum focusMode_t {
+        FOCUS_MODE_AUTO = ANDROID_CONTROL_AF_AUTO,
+        FOCUS_MODE_MACRO = ANDROID_CONTROL_AF_MACRO,
+        FOCUS_MODE_CONTINUOUS_VIDEO = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO,
+        FOCUS_MODE_CONTINUOUS_PICTURE = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
+        FOCUS_MODE_EDOF = ANDROID_CONTROL_AF_EDOF,
+        FOCUS_MODE_INFINITY,
+        FOCUS_MODE_FIXED,
+        FOCUS_MODE_INVALID = -1
+    } focusMode;
+
+    struct Area {
+        int left, top, right, bottom;
+        int weight;
+        Area() {}
+        Area(int left, int top, int right, int bottom, int weight):
+                left(left), top(top), right(right), bottom(bottom),
+                weight(weight) {}
+    };
+    Vector<Area> focusingAreas;
+
+    int32_t exposureCompensation;
+    bool autoExposureLock;
+    bool autoWhiteBalanceLock;
+
+    Vector<Area> meteringAreas;
+
+    int zoom;
+
+    int videoWidth, videoHeight;
+
+    bool recordingHint;
+    bool videoStabilization;
+
+    String8 paramsFlattened;
+
+    // These parameters are also part of the camera API-visible state, but not
+    // directly listed in Camera.Parameters
+    bool storeMetadataInBuffers;
+    bool playShutterSound;
+    bool enableFaceDetect;
+
+    bool enableFocusMoveMessages;
+    int afTriggerCounter;
+    int currentAfTriggerId;
+    bool afInMotion;
+
+    uint32_t previewCallbackFlags;
+    bool previewCallbackOneShot;
+
+    // Overall camera state
+    enum State {
+        DISCONNECTED,
+        STOPPED,
+        WAITING_FOR_PREVIEW_WINDOW,
+        PREVIEW,
+        RECORD,
+        STILL_CAPTURE,
+        VIDEO_SNAPSHOT
+    } state;
+
+    // Number of zoom steps to simulate
+    static const unsigned int NUM_ZOOM_STEPS = 10;
+
+    // Full static camera info, object owned by someone else, such as
+    // Camera2Device.
+    const CameraMetadata *info;
+
+    // Fast-access static device information; this is a subset of the
+    // information available through the staticInfo() method, used for
+    // frequently-accessed values or values that have to be calculated from the
+    // static information.
+    struct DeviceInfo {
+        int32_t arrayWidth;
+        int32_t arrayHeight;
+        uint8_t bestFaceDetectMode;
+        int32_t maxFaces;
+    } fastInfo;
+
+    // Parameter manipulation and setup methods
+
+    Parameters(int cameraId, int cameraFacing);
+    ~Parameters();
+
+    // Sets up default parameters
+    status_t initialize(const CameraMetadata *info);
+
+    // Build fast device info
+    status_t buildFastInfo();
+
+    // Get entry from camera static characteristics information. min/maxCount
+    // are used for error checking the number of values in the entry. 0 for
+    // max/minCount means to do no bounds check in that direction. In case of
+    // error, the entry data pointer is null and the count is 0.
+    camera_metadata_ro_entry_t staticInfo(uint32_t tag,
+            size_t minCount=0, size_t maxCount=0) const;
+
+    // Validate and update camera parameters based on new settings
+    status_t set(const String8 &params);
+
+    // Static methods for debugging and converting between camera1 and camera2
+    // parameters
+
+    static const char *getStateName(State state);
+
+    static int formatStringToEnum(const char *format);
+    static const char *formatEnumToString(int format);
+
+    static int wbModeStringToEnum(const char *wbMode);
+    static int effectModeStringToEnum(const char *effectMode);
+    static int abModeStringToEnum(const char *abMode);
+    static int sceneModeStringToEnum(const char *sceneMode);
+    static flashMode_t flashModeStringToEnum(const char *flashMode);
+    static focusMode_t focusModeStringToEnum(const char *focusMode);
+    static status_t parseAreas(const char *areasCStr,
+            Vector<Area> *areas);
+    static status_t validateAreas(const Vector<Area> &areas,
+                                  size_t maxRegions);
+    static bool boolFromString(const char *boolStr);
+
+    // Map from camera orientation + facing to gralloc transform enum
+    static int degToTransform(int degrees, bool mirror);
+
+    // Transform between (-1000,-1000)-(1000,1000) normalized coords from camera
+    // API and HAL2 (0,0)-(activePixelArray.width/height) coordinates
+    int arrayXToNormalized(int width) const;
+    int arrayYToNormalized(int height) const;
+    int normalizedXToArray(int x) const;
+    int normalizedYToArray(int y) const;
+
+};
+
+// This class encapsulates the Parameters class so that it can only be accessed
+// by constructing a Lock object, which locks the SharedParameter's mutex.
+class SharedParameters {
+  public:
+    SharedParameters(int cameraId, int cameraFacing):
+            mParameters(cameraId, cameraFacing) {
+    }
+
+    template<typename S, typename P>
+    class BaseLock {
+      public:
+        BaseLock(S &p):
+                mParameters(p.mParameters),
+                mSharedParameters(p) {
+            mSharedParameters.mLock.lock();
+        }
+
+        ~BaseLock() {
+            mSharedParameters.mLock.unlock();
+        }
+        P &mParameters;
+      private:
+        // Disallow copying, default construction
+        BaseLock();
+        BaseLock(const BaseLock &);
+        BaseLock &operator=(const BaseLock &);
+        S &mSharedParameters;
+    };
+    typedef BaseLock<SharedParameters, Parameters> Lock;
+    typedef BaseLock<const SharedParameters, const Parameters> ReadLock;
+
+    // Access static info, read-only and immutable, so no lock needed
+    camera_metadata_ro_entry_t staticInfo(uint32_t tag,
+            size_t minCount=0, size_t maxCount=0) const {
+        return mParameters.staticInfo(tag, minCount, maxCount);
+    }
+
+    // Only use for dumping or other debugging
+    const Parameters &unsafeAccess() {
+        return mParameters;
+    }
+  private:
+    Parameters mParameters;
+    mutable Mutex mLock;
+};
+
+
+}; // namespace camera2
+}; // namespace android
+
+#endif
