Merge "Remove codec callback for now."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b8a9711..20da925 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -51,6 +51,10 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudioflinger.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicy_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicy.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicy_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicy.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicyservice_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicymanager_intermediates)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/camera/Android.mk b/camera/Android.mk
index 5774b6f..c10e38a 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -50,7 +50,7 @@
 
 LOCAL_C_INCLUDES += \
 	system/media/camera/include \
-	system/media/private/camera/include
+	system/media/private/camera/include \
 
 LOCAL_MODULE:= libcamera_client
 
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index af091f4..161f842 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <camera/CameraParameters.h>
+#include <system/graphics.h>
 
 namespace android {
 // Parameter keys to communicate between camera application and driver.
@@ -483,4 +484,45 @@
     return NO_ERROR;
 }
 
+void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
+    const char* supportedPreviewFormats =
+          get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+
+    String8 fmtStr(supportedPreviewFormats);
+    char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
+
+    char* savePtr;
+    char* fmt = strtok_r(prevFmts, ",", &savePtr);
+    while (fmt) {
+        int actual = previewFormatToEnum(fmt);
+        if (actual != -1) {
+            formats.add(actual);
+        }
+        fmt = strtok_r(NULL, ",", &savePtr);
+    }
+    fmtStr.unlockBuffer(fmtStr.size());
+}
+
+
+int CameraParameters::previewFormatToEnum(const char* format) {
+    return
+        !format ?
+            HAL_PIXEL_FORMAT_YCrCb_420_SP :
+        !strcmp(format, PIXEL_FORMAT_YUV422SP) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
+        !strcmp(format, PIXEL_FORMAT_YUV420SP) ?
+            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
+        !strcmp(format, PIXEL_FORMAT_YUV422I) ?
+            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
+        !strcmp(format, PIXEL_FORMAT_YUV420P) ?
+            HAL_PIXEL_FORMAT_YV12 :         // YV12
+        !strcmp(format, PIXEL_FORMAT_RGB565) ?
+            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
+        !strcmp(format, PIXEL_FORMAT_RGBA8888) ?
+            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
+        !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ?
+            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
+        -1;
+}
+
 }; // namespace android
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp
index 59dce91..3f72f34 100644
--- a/camera/VendorTagDescriptor.cpp
+++ b/camera/VendorTagDescriptor.cpp
@@ -349,18 +349,18 @@
 
     size_t size = mTagToNameMap.size();
     if (size == 0) {
-        fdprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
+        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
                 indentation, "");
         return;
     }
 
-    fdprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
+    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
             indentation, "", size);
     for (size_t i = 0; i < size; ++i) {
         uint32_t tag =  mTagToNameMap.keyAt(i);
 
         if (verbosity < 1) {
-            fdprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
+            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
             continue;
         }
         String8 name = mTagToNameMap.valueAt(i);
@@ -369,7 +369,7 @@
         int type = mTagToTypeMap.valueFor(tag);
         const char* typeName = (type >= 0 && type < NUM_TYPES) ?
                 camera_metadata_type_names[type] : "UNKNOWN";
-        fdprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
+        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
             "", tag, name.string(), type, typeName, sectionName.string());
     }
 
diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp
index ad65955..ff4a0c2 100644
--- a/camera/camera2/ICameraDeviceUser.cpp
+++ b/camera/camera2/ICameraDeviceUser.cpp
@@ -37,6 +37,8 @@
     SUBMIT_REQUEST,
     SUBMIT_REQUEST_LIST,
     CANCEL_REQUEST,
+    BEGIN_CONFIGURE,
+    END_CONFIGURE,
     DELETE_STREAM,
     CREATE_STREAM,
     CREATE_DEFAULT_REQUEST,
@@ -174,6 +176,26 @@
         return res;
     }
 
+    virtual status_t beginConfigure()
+    {
+        ALOGV("beginConfigure");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+        remote()->transact(BEGIN_CONFIGURE, data, &reply);
+        reply.readExceptionCode();
+        return reply.readInt32();
+    }
+
+    virtual status_t endConfigure()
+    {
+        ALOGV("endConfigure");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+        remote()->transact(END_CONFIGURE, data, &reply);
+        reply.readExceptionCode();
+        return reply.readInt32();
+    }
+
     virtual status_t deleteStream(int streamId)
     {
         Parcel data, reply;
@@ -456,6 +478,18 @@
             reply->writeInt64(lastFrameNumber);
             return NO_ERROR;
         }
+        case BEGIN_CONFIGURE: {
+            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+            reply->writeNoException();
+            reply->writeInt32(beginConfigure());
+            return NO_ERROR;
+        } break;
+        case END_CONFIGURE: {
+            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+            reply->writeNoException();
+            reply->writeInt32(endConfigure());
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index d521543..c6074fc 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -102,6 +102,12 @@
     void dump() const;
     status_t dump(int fd, const Vector<String16>& args) const;
 
+    /**
+     * Returns a Vector containing the supported preview formats
+     * as enums given in graphics.h.
+     */
+    void getSupportedPreviewFormats(Vector<int>& formats) const;
+
     // Parameter keys to communicate between camera application and driver.
     // The access (read/write, read only, or write only) is viewed from the
     // perspective of applications, not driver.
@@ -674,6 +680,13 @@
     // High-dynamic range mode
     static const char LIGHTFX_HDR[];
 
+    /**
+     * Returns the the supported preview formats as an enum given in graphics.h
+     * corrsponding to the format given in the input string or -1 if no such
+     * conversion exists.
+     */
+    static int previewFormatToEnum(const char* format);
+
 private:
     DefaultKeyedVector<String8,String8>    mMap;
 };
diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h
index 913696f..35488bb 100644
--- a/include/camera/camera2/ICameraDeviceUser.h
+++ b/include/camera/camera2/ICameraDeviceUser.h
@@ -78,6 +78,27 @@
                                           /*out*/
                                           int64_t* lastFrameNumber = NULL) = 0;
 
+    /**
+     * Begin the device configuration.
+     *
+     * <p>
+     * beginConfigure must be called before any call to deleteStream, createStream,
+     * or endConfigure.  It is not valid to call this when the device is not idle.
+     * <p>
+     */
+    virtual status_t        beginConfigure() = 0;
+
+    /**
+     * End the device configuration.
+     *
+     * <p>
+     * endConfigure must be called after stream configuration is complete (i.e. after
+     * a call to beginConfigure and subsequent createStream/deleteStream calls).  This
+     * must be called before any requests can be submitted.
+     * <p>
+     */
+    virtual status_t        endConfigure() = 0;
+
     virtual status_t        deleteStream(int streamId) = 0;
     virtual status_t        createStream(
             int width, int height, int format,
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1c808d0..db61e85 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -203,23 +203,6 @@
         mFrameSize = sizeof(uint8_t);
     }
 
-    // validate framecount
-    size_t minFrameCount;
-    status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
-            sampleRate, format, channelMask);
-    if (status != NO_ERROR) {
-        ALOGE("getMinFrameCount() failed for sampleRate %u, format %#x, channelMask %#x; status %d",
-                sampleRate, format, channelMask, status);
-        return status;
-    }
-    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
-
-    if (frameCount == 0) {
-        frameCount = minFrameCount;
-    } else if (frameCount < minFrameCount) {
-        ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount);
-        return BAD_VALUE;
-    }
     // mFrameCount is initialized in openRecord_l
     mReqFrameCount = frameCount;
 
@@ -242,7 +225,7 @@
     }
 
     // create the IAudioRecord
-    status = openRecord_l(0 /*epoch*/);
+    status_t status = openRecord_l(0 /*epoch*/);
 
     if (status != NO_ERROR) {
         if (mAudioRecordThread != 0) {
@@ -464,6 +447,29 @@
     size_t frameCount = mReqFrameCount;
 
     if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) {
+        // validate framecount
+        // If fast track was not requested, this preserves
+        // the old behavior of validating on client side.
+        // FIXME Eventually the validation should be done on server side
+        // regardless of whether it's a fast or normal track.  It's debatable
+        // whether to account for the input latency to provision buffers appropriately.
+        size_t minFrameCount;
+        status = AudioRecord::getMinFrameCount(&minFrameCount,
+                mSampleRate, mFormat, mChannelMask);
+        if (status != NO_ERROR) {
+            ALOGE("getMinFrameCount() failed for sampleRate %u, format %#x, channelMask %#x; "
+                    "status %d",
+                    mSampleRate, mFormat, mChannelMask, status);
+            return status;
+        }
+
+        if (frameCount == 0) {
+            frameCount = minFrameCount;
+        } else if (frameCount < minFrameCount) {
+            ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount);
+            return BAD_VALUE;
+        }
+
         // Make sure that application is notified with sufficient margin before overrun
         if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
             mNotificationFramesAct = frameCount/2;
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 27a3718..219dbfd 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -19,9 +19,9 @@
 
 #include <private/media/AudioTrackShared.h>
 #include <utils/Log.h>
-extern "C" {
-#include "../private/bionic_futex.h"
-}
+
+#include <linux/futex.h>
+#include <sys/syscall.h>
 
 namespace android {
 
@@ -206,12 +206,12 @@
         }
         int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
         if (!(old & CBLK_FUTEX_WAKE)) {
-            int rc;
             if (measure && !beforeIsValid) {
                 clock_gettime(CLOCK_MONOTONIC, &before);
                 beforeIsValid = true;
             }
-            int ret = __futex_syscall4(&cblk->mFutex,
+            errno = 0;
+            (void) syscall(__NR_futex, &cblk->mFutex,
                     mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
             // update total elapsed time spent waiting
             if (measure) {
@@ -230,16 +230,16 @@
                 before = after;
                 beforeIsValid = true;
             }
-            switch (ret) {
-            case 0:             // normal wakeup by server, or by binderDied()
-            case -EWOULDBLOCK:  // benign race condition with server
-            case -EINTR:        // wait was interrupted by signal or other spurious wakeup
-            case -ETIMEDOUT:    // time-out expired
+            switch (errno) {
+            case 0:            // normal wakeup by server, or by binderDied()
+            case EWOULDBLOCK:  // benign race condition with server
+            case EINTR:        // wait was interrupted by signal or other spurious wakeup
+            case ETIMEDOUT:    // time-out expired
                 // FIXME these error/non-0 status are being dropped
                 break;
             default:
-                ALOGE("%s unexpected error %d", __func__, ret);
-                status = -ret;
+                status = errno;
+                ALOGE("%s unexpected error %s", __func__, strerror(status));
                 goto end;
             }
         }
@@ -295,7 +295,7 @@
     audio_track_cblk_t* cblk = mCblk;
     if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) {
         // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process
-        (void) __futex_syscall3(&cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+        (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
                 1);
     }
 }
@@ -304,7 +304,7 @@
 {
     audio_track_cblk_t* cblk = mCblk;
     if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) {
-        (void) __futex_syscall3(&cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+        (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
                 1);
     }
 }
@@ -435,18 +435,18 @@
         }
         int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
         if (!(old & CBLK_FUTEX_WAKE)) {
-            int rc;
-            int ret = __futex_syscall4(&cblk->mFutex,
+            errno = 0;
+            (void) syscall(__NR_futex, &cblk->mFutex,
                     mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
-            switch (ret) {
-            case 0:             // normal wakeup by server, or by binderDied()
-            case -EWOULDBLOCK:  // benign race condition with server
-            case -EINTR:        // wait was interrupted by signal or other spurious wakeup
-            case -ETIMEDOUT:    // time-out expired
+            switch (errno) {
+            case 0:            // normal wakeup by server, or by binderDied()
+            case EWOULDBLOCK:  // benign race condition with server
+            case EINTR:        // wait was interrupted by signal or other spurious wakeup
+            case ETIMEDOUT:    // time-out expired
                 break;
             default:
-                ALOGE("%s unexpected error %d", __func__, ret);
-                status = -ret;
+                status = errno;
+                ALOGE("%s unexpected error %s", __func__, strerror(status));
                 goto end;
             }
         }
@@ -535,7 +535,7 @@
             if (front != rear) {
                 int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
                 if (!(old & CBLK_FUTEX_WAKE)) {
-                    (void) __futex_syscall3(&cblk->mFutex,
+                    (void) syscall(__NR_futex, &cblk->mFutex,
                             mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
                 }
             }
@@ -638,7 +638,7 @@
         ALOGV("mAvailToClient=%u stepCount=%u minimum=%u", mAvailToClient, stepCount, minimum);
         int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
         if (!(old & CBLK_FUTEX_WAKE)) {
-            (void) __futex_syscall3(&cblk->mFutex,
+            (void) syscall(__NR_futex, &cblk->mFutex,
                     mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
         }
     }
@@ -683,7 +683,7 @@
     bool old =
             (android_atomic_or(CBLK_STREAM_END_DONE, &cblk->mFlags) & CBLK_STREAM_END_DONE) != 0;
     if (!old) {
-        (void) __futex_syscall3(&cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+        (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
                 1);
     }
     return old;
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index 4d9a1fa..4d14904 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -438,7 +438,7 @@
 void NBLog::Reader::dumpLine(const String8& timestamp, String8& body)
 {
     if (mFd >= 0) {
-        fdprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
+        dprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
     } else {
         ALOGI("%.*s%s %s", mIndent, "", timestamp.string(), body.string());
     }
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/MediaBuffer.cpp
index 11b80bf..8af0880 100644
--- a/media/libstagefright/MediaBuffer.cpp
+++ b/media/libstagefright/MediaBuffer.cpp
@@ -27,7 +27,6 @@
 #include <media/stagefright/MetaData.h>
 
 #include <ui/GraphicBuffer.h>
-#include <sys/atomics.h>
 
 namespace android {
 
@@ -92,7 +91,7 @@
         return;
     }
 
-    int prevCount = __atomic_dec(&mRefCount);
+    int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
     if (prevCount == 1) {
         if (mObserver == NULL) {
             delete this;
@@ -112,7 +111,7 @@
 }
 
 void MediaBuffer::add_ref() {
-    (void) __atomic_inc(&mRefCount);
+    (void) __sync_fetch_and_add(&mRefCount, 1);
 }
 
 void *MediaBuffer::data() const {
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 5bc3f2f..786bf0d 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -15,7 +15,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libaudioflinger \
-	libaudiopolicy \
+	libaudiopolicyservice \
 	libcamera_metadata\
 	libcameraservice \
 	libmedialogservice \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 45e17f8..9bd0e9b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -143,7 +143,7 @@
     if (rc) {
         goto out;
     }
-    if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {
+    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
         ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
         rc = BAD_VALUE;
         goto out;
@@ -427,7 +427,7 @@
         if (mLogMemoryDealer != 0) {
             sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
             if (binder != 0) {
-                fdprintf(fd, "\nmedia.log:\n");
+                dprintf(fd, "\nmedia.log:\n");
                 Vector<String16> args;
                 binder->dump(fd, args);
             }
@@ -635,8 +635,12 @@
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the Track so that the
         // Client destructor is called by the TrackBase destructor with mClientLock held
-        Mutex::Autolock _cl(mClientLock);
-        client.clear();
+        // Don't hold mClientLock when releasing the reference on the track as the
+        // destructor will acquire it.
+        {
+            Mutex::Autolock _cl(mClientLock);
+            client.clear();
+        }
         track.clear();
         goto Exit;
     }
@@ -1173,7 +1177,7 @@
     }
 
     // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the
-    // ThreadBase mutex and teh locknig order is ThreadBase::mLock then AudioFlinger::mClientLock.
+    // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock.
     if (clientAdded) {
         // the config change is always sent from playback or record threads to avoid deadlock
         // with AudioSystem::gLock
@@ -1419,8 +1423,12 @@
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the RecordTrack so that the
         // Client destructor is called by the TrackBase destructor with mClientLock held
-        Mutex::Autolock _cl(mClientLock);
-        client.clear();
+        // Don't hold mClientLock when releasing the reference on the track as the
+        // destructor will acquire it.
+        {
+            Mutex::Autolock _cl(mClientLock);
+            client.clear();
+        }
         recordTrack.clear();
         goto Exit;
     }
@@ -2380,6 +2388,11 @@
         if (handle != 0 && id != NULL) {
             *id = handle->id();
         }
+        if (handle == 0) {
+            // remove local strong reference to Client with mClientLock held
+            Mutex::Autolock _cl(mClientLock);
+            client.clear();
+        }
     }
 
 Exit:
@@ -2590,7 +2603,7 @@
             }
         } else {
             if (fd >= 0) {
-                fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
+                dprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
             }
         }
         char teeTime[16];
@@ -2644,11 +2657,11 @@
             write(teeFd, &temp, sizeof(temp));
             close(teeFd);
             if (fd >= 0) {
-                fdprintf(fd, "tee copied to %s\n", teePath);
+                dprintf(fd, "tee copied to %s\n", teePath);
             }
         } else {
             if (fd >= 0) {
-                fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
+                dprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
             }
         }
     }
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 805eaa4..8d57451 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -34,6 +34,7 @@
 #include <system/audio.h>
 
 #include <audio_utils/primitives.h>
+#include <audio_utils/format.h>
 #include <common_time/local_clock.h>
 #include <common_time/cc_helper.h>
 
@@ -88,6 +89,103 @@
     }
 }
 
+template <typename T>
+T min(const T& a, const T& b)
+{
+    return a < b ? a : b;
+}
+
+AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
+        audio_format_t inputFormat, audio_format_t outputFormat) :
+        mTrackBufferProvider(NULL),
+        mChannels(channels),
+        mInputFormat(inputFormat),
+        mOutputFormat(outputFormat),
+        mInputFrameSize(channels * audio_bytes_per_sample(inputFormat)),
+        mOutputFrameSize(channels * audio_bytes_per_sample(outputFormat)),
+        mOutputData(NULL),
+        mOutputCount(0),
+        mConsumed(0)
+{
+    ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat);
+    if (requiresInternalBuffers()) {
+        mOutputCount = 256;
+        (void)posix_memalign(&mOutputData, 32, mOutputCount * mOutputFrameSize);
+    }
+    mBuffer.frameCount = 0;
+}
+
+AudioMixer::ReformatBufferProvider::~ReformatBufferProvider()
+{
+    ALOGV("~ReformatBufferProvider(%p)", this);
+    if (mBuffer.frameCount != 0) {
+        mTrackBufferProvider->releaseBuffer(&mBuffer);
+    }
+    free(mOutputData);
+}
+
+status_t AudioMixer::ReformatBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
+        int64_t pts) {
+    //ALOGV("ReformatBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)",
+    //        this, pBuffer, pBuffer->frameCount, pts);
+    if (!requiresInternalBuffers()) {
+        status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
+        if (res == OK) {
+            memcpy_by_audio_format(pBuffer->raw, mOutputFormat, pBuffer->raw, mInputFormat,
+                    pBuffer->frameCount * mChannels);
+        }
+        return res;
+    }
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = pBuffer->frameCount;
+        status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
+        // TODO: Track down a bug in the upstream provider
+        // LOG_ALWAYS_FATAL_IF(res == OK && mBuffer.frameCount == 0,
+        //        "ReformatBufferProvider::getNextBuffer():"
+        //        " Invalid zero framecount returned from getNextBuffer()");
+        if (res != OK || mBuffer.frameCount == 0) {
+            pBuffer->raw = NULL;
+            pBuffer->frameCount = 0;
+            return res;
+        }
+    }
+    ALOG_ASSERT(mConsumed < mBuffer.frameCount);
+    size_t count = min(mOutputCount, mBuffer.frameCount - mConsumed);
+    count = min(count, pBuffer->frameCount);
+    pBuffer->raw = mOutputData;
+    pBuffer->frameCount = count;
+    //ALOGV("reformatting %d frames from %#x to %#x, %d chan",
+    //        pBuffer->frameCount, mInputFormat, mOutputFormat, mChannels);
+    memcpy_by_audio_format(pBuffer->raw, mOutputFormat,
+            (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize, mInputFormat,
+            pBuffer->frameCount * mChannels);
+    return OK;
+}
+
+void AudioMixer::ReformatBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
+    //ALOGV("ReformatBufferProvider(%p)::releaseBuffer(%p(%zu))",
+    //        this, pBuffer, pBuffer->frameCount);
+    if (!requiresInternalBuffers()) {
+        mTrackBufferProvider->releaseBuffer(pBuffer);
+        return;
+    }
+    // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
+    mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
+    if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
+        mConsumed = 0;
+        mTrackBufferProvider->releaseBuffer(&mBuffer);
+        // ALOG_ASSERT(mBuffer.frameCount == 0);
+    }
+    pBuffer->raw = NULL;
+    pBuffer->frameCount = 0;
+}
+
+void AudioMixer::ReformatBufferProvider::reset() {
+    if (mBuffer.frameCount != 0) {
+        mTrackBufferProvider->releaseBuffer(&mBuffer);
+    }
+    mConsumed = 0;
+}
 
 // ----------------------------------------------------------------------------
 bool AudioMixer::sIsMultichannelCapable = false;
@@ -153,8 +251,13 @@
     mState.mLog = log;
 }
 
-int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
+int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
+        audio_format_t format, int sessionId)
 {
+    if (!isValidPcmTrackFormat(format)) {
+        ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
+        return -1;
+    }
     uint32_t names = (~mTrackNames) & mConfiguredNames;
     if (names != 0) {
         int n = __builtin_ctz(names);
@@ -176,7 +279,8 @@
         // t->frameCount
         t->channelCount = audio_channel_count_from_out_mask(channelMask);
         t->enabled = false;
-        t->format = 16;
+        ALOGV_IF(channelMask != AUDIO_CHANNEL_OUT_STEREO,
+                "Non-stereo channel mask: %d\n", channelMask);
         t->channelMask = channelMask;
         t->sessionId = sessionId;
         // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
@@ -191,9 +295,15 @@
         // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
         t->mainBuffer = NULL;
         t->auxBuffer = NULL;
+        t->mInputBufferProvider = NULL;
+        t->mReformatBufferProvider = NULL;
         t->downmixerBufferProvider = NULL;
         t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
-
+        t->mFormat = format;
+        t->mMixerInFormat = AUDIO_FORMAT_PCM_16_BIT;
+        if (t->mFormat != t->mMixerInFormat) {
+            prepareTrackForReformat(t, n);
+        }
         status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
         if (status != OK) {
             ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
@@ -237,9 +347,9 @@
     if (pTrack->downmixerBufferProvider != NULL) {
         // this track had previously been configured with a downmixer, delete it
         ALOGV(" deleting old downmixer");
-        pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
         delete pTrack->downmixerBufferProvider;
         pTrack->downmixerBufferProvider = NULL;
+        reconfigureBufferProviders(pTrack);
     } else {
         ALOGV(" nothing to do, no downmixer to delete");
     }
@@ -333,21 +443,51 @@
     }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
 
     // initialization successful:
-    // - keep track of the real buffer provider in case it was set before
-    pDbp->mTrackBufferProvider = pTrack->bufferProvider;
-    // - we'll use the downmix effect integrated inside this
-    //    track's buffer provider, and we'll use it as the track's buffer provider
     pTrack->downmixerBufferProvider = pDbp;
-    pTrack->bufferProvider = pDbp;
-
+    reconfigureBufferProviders(pTrack);
     return NO_ERROR;
 
 noDownmixForActiveTrack:
     delete pDbp;
     pTrack->downmixerBufferProvider = NULL;
+    reconfigureBufferProviders(pTrack);
     return NO_INIT;
 }
 
+void AudioMixer::unprepareTrackForReformat(track_t* pTrack, int trackName __unused) {
+    ALOGV("AudioMixer::unprepareTrackForReformat(%d)", trackName);
+    if (pTrack->mReformatBufferProvider != NULL) {
+        delete pTrack->mReformatBufferProvider;
+        pTrack->mReformatBufferProvider = NULL;
+        reconfigureBufferProviders(pTrack);
+    }
+}
+
+status_t AudioMixer::prepareTrackForReformat(track_t* pTrack, int trackName)
+{
+    ALOGV("AudioMixer::prepareTrackForReformat(%d) with format %#x", trackName, pTrack->mFormat);
+    // discard the previous reformatter if there was one
+     unprepareTrackForReformat(pTrack, trackName);
+     pTrack->mReformatBufferProvider = new ReformatBufferProvider(
+             audio_channel_count_from_out_mask(pTrack->channelMask),
+             pTrack->mFormat, pTrack->mMixerInFormat);
+     reconfigureBufferProviders(pTrack);
+     return NO_ERROR;
+}
+
+void AudioMixer::reconfigureBufferProviders(track_t* pTrack)
+{
+    pTrack->bufferProvider = pTrack->mInputBufferProvider;
+    if (pTrack->mReformatBufferProvider) {
+        pTrack->mReformatBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
+        pTrack->bufferProvider = pTrack->mReformatBufferProvider;
+    }
+    if (pTrack->downmixerBufferProvider) {
+        pTrack->downmixerBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
+        pTrack->bufferProvider = pTrack->downmixerBufferProvider;
+    }
+}
+
 void AudioMixer::deleteTrackName(int name)
 {
     ALOGV("AudioMixer::deleteTrackName(%d)", name);
@@ -364,6 +504,8 @@
     track.resampler = NULL;
     // delete the downmixer
     unprepareTrackForDownmix(&mState.tracks[name], name);
+    // delete the reformatter
+    unprepareTrackForReformat(&mState.tracks[name], name);
 
     mTrackNames &= ~(1<<name);
 }
@@ -435,9 +577,20 @@
                 invalidateState(1 << name);
             }
             break;
-        case FORMAT:
-            ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT);
-            break;
+        case FORMAT: {
+            audio_format_t format = static_cast<audio_format_t>(valueInt);
+            if (track.mFormat != format) {
+                ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
+                track.mFormat = format;
+                ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
+                //if (track.mFormat != track.mMixerInFormat)
+                {
+                    ALOGD("Reformatting!");
+                    prepareTrackForReformat(&track, name);
+                }
+                invalidateState(1 << name);
+            }
+            } break;
         // FIXME do we want to support setting the downmix type from AudioFlinger?
         //         for a specific track? or per mixer?
         /* case DOWNMIX_TYPE:
@@ -550,8 +703,9 @@
                 } else {
                     quality = AudioResampler::DEFAULT_QUALITY;
                 }
+                const int bits = mMixerInFormat == AUDIO_FORMAT_PCM_16_BIT ? 16 : /* FLOAT */ 32;
                 resampler = AudioResampler::create(
-                        format,
+                        bits,
                         // the resampler sees the number of channels after the downmixer, if any
                         (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
                         devSampleRate, quality);
@@ -596,21 +750,13 @@
     name -= TRACK0;
     ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
 
-    if (mState.tracks[name].downmixerBufferProvider != NULL) {
-        // update required?
-        if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) {
-            ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider);
-            // setting the buffer provider for a track that gets downmixed consists in:
-            //  1/ setting the buffer provider to the "downmix / buffer provider" wrapper
-            //     so it's the one that gets called when the buffer provider is needed,
-            mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider;
-            //  2/ saving the buffer provider for the track so the wrapper can use it
-            //     when it downmixes.
-            mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider;
-        }
-    } else {
-        mState.tracks[name].bufferProvider = bufferProvider;
+    if (mState.tracks[name].mReformatBufferProvider != NULL) {
+        mState.tracks[name].mReformatBufferProvider->reset();
+    } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
     }
+
+    mState.tracks[name].mInputBufferProvider = bufferProvider;
+    reconfigureBufferProviders(&mState.tracks[name]);
 }
 
 
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 09e63a6..573ba96 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -104,7 +104,10 @@
     // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
 
     // Allocate a track name.  Returns new track name if successful, -1 on failure.
-    int         getTrackName(audio_channel_mask_t channelMask, int sessionId);
+    // The failure could be because of an invalid channelMask or format, or that
+    // the track capacity of the mixer is exceeded.
+    int         getTrackName(audio_channel_mask_t channelMask,
+                             audio_format_t format, int sessionId);
 
     // Free an allocated track by name
     void        deleteTrackName(int name);
@@ -122,6 +125,13 @@
 
     size_t      getUnreleasedFrames(int name) const;
 
+    static inline bool isValidPcmTrackFormat(audio_format_t format) {
+        return format == AUDIO_FORMAT_PCM_16_BIT ||
+                format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
+                format == AUDIO_FORMAT_PCM_32_BIT ||
+                format == AUDIO_FORMAT_PCM_FLOAT;
+    }
+
 private:
 
     enum {
@@ -143,6 +153,7 @@
     struct state_t;
     struct track_t;
     class DownmixerBufferProvider;
+    class ReformatBufferProvider;
 
     typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp,
                            int32_t* aux);
@@ -170,7 +181,7 @@
         uint16_t    frameCount;
 
         uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
-        uint8_t     format;         // always 16
+        uint8_t     unused_padding; // formerly format, was always 16
         uint16_t    enabled;        // actually bool
         audio_channel_mask_t channelMask;
 
@@ -193,14 +204,19 @@
         int32_t*           auxBuffer;
 
         // 16-byte boundary
-
+        AudioBufferProvider*     mInputBufferProvider;    // 4 bytes
+        ReformatBufferProvider*  mReformatBufferProvider; // 4 bytes
         DownmixerBufferProvider* downmixerBufferProvider; // 4 bytes
 
         int32_t     sessionId;
 
-        audio_format_t mMixerFormat; // at this time: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+        // 16-byte boundary
+        audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+        audio_format_t mFormat;          // input track format
+        audio_format_t mMixerInFormat;   // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+                                         // each track must be converted to this format.
 
-        int32_t     padding[1];
+        int32_t        mUnused[1];       // alignment padding
 
         // 16-byte boundary
 
@@ -239,6 +255,35 @@
         effect_config_t    mDownmixConfig;
     };
 
+    // AudioBufferProvider wrapper that reformats track to acceptable mixer input type
+    class ReformatBufferProvider : public AudioBufferProvider {
+    public:
+        ReformatBufferProvider(int32_t channels,
+                audio_format_t inputFormat, audio_format_t outputFormat);
+        virtual ~ReformatBufferProvider();
+
+        // overrides AudioBufferProvider methods
+        virtual status_t getNextBuffer(Buffer* buffer, int64_t pts);
+        virtual void releaseBuffer(Buffer* buffer);
+
+        void reset();
+        inline bool requiresInternalBuffers() {
+            return true; //mInputFrameSize < mOutputFrameSize;
+        }
+
+        AudioBufferProvider* mTrackBufferProvider;
+        int32_t              mChannels;
+        audio_format_t       mInputFormat;
+        audio_format_t       mOutputFormat;
+        size_t               mInputFrameSize;
+        size_t               mOutputFrameSize;
+        // (only) required for reformatting to a larger size.
+        AudioBufferProvider::Buffer mBuffer;
+        void*                mOutputData;
+        size_t               mOutputCount;
+        size_t               mConsumed;
+    };
+
     // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc.
     uint32_t        mTrackNames;
 
@@ -266,6 +311,9 @@
     static status_t initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask);
     static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum);
     static void unprepareTrackForDownmix(track_t* pTrack, int trackName);
+    static status_t prepareTrackForReformat(track_t* pTrack, int trackNum);
+    static void unprepareTrackForReformat(track_t* pTrack, int trackName);
+    static void reconfigureBufferProviders(track_t* pTrack);
 
     static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
             int32_t* aux);
diff --git a/services/audioflinger/AudioWatchdog.cpp b/services/audioflinger/AudioWatchdog.cpp
index 93d185e..877e776 100644
--- a/services/audioflinger/AudioWatchdog.cpp
+++ b/services/audioflinger/AudioWatchdog.cpp
@@ -34,7 +34,7 @@
     } else {
         strcpy(buf, "N/A\n");
     }
-    fdprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
+    dprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
             mUnderruns, mLogs, buf);
 }
 
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 1caed11..f0ce902 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -26,7 +26,6 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include "Configuration.h"
-#include <sys/atomics.h>
 #include <time.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -224,13 +223,16 @@
             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
             ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
             if (mixer != NULL) {
-                name = mixer->getTrackName(fastTrack->mChannelMask, AUDIO_SESSION_OUTPUT_MIX);
+                name = mixer->getTrackName(fastTrack->mChannelMask,
+                        fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
                 ALOG_ASSERT(name >= 0);
                 fastTrackNames[i] = name;
                 mixer->setBufferProvider(name, bufferProvider);
                 mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
                         (void *) mixBuffer);
                 // newly allocated track names default to full scale volume
+                mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+                        (void *)(uintptr_t)fastTrack->mFormat);
                 mixer->enable(name);
             }
             generations[i] = fastTrack->mGeneration;
@@ -259,6 +261,8 @@
                     }
                     mixer->setParameter(name, AudioMixer::RESAMPLE,
                             AudioMixer::REMOVE, NULL);
+                    mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
+                            (void *)(uintptr_t)fastTrack->mFormat);
                     mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
                             (void *)(uintptr_t) fastTrack->mChannelMask);
                     // already enabled
@@ -281,7 +285,7 @@
     const size_t frameCount = current->mFrameCount;
 
     if ((command & FastMixerState::MIX) && (mixer != NULL) && isWarm) {
-        ALOG_ASSERT(mixBuffer != NULL);
+        ALOG_ASSERT(mMixerBuffer != NULL);
         // for each track, update volume and check for underrun
         unsigned currentTrackMask = current->mTrackMask;
         while (currentTrackMask != 0) {
@@ -461,7 +465,7 @@
 void FastMixerDumpState::dump(int fd) const
 {
     if (mCommand == FastMixerState::INITIAL) {
-        fdprintf(fd, "  FastMixer not initialized\n");
+        dprintf(fd, "  FastMixer not initialized\n");
         return;
     }
 #define COMMAND_MAX 32
@@ -495,10 +499,10 @@
     double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
             (mMeasuredWarmupTs.tv_nsec / 1000000.0);
     double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
-    fdprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
-                 "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
-                 "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
-                 "            mixPeriod=%.2f ms\n",
+    dprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
+                "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
+                "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
+                "            mixPeriod=%.2f ms\n",
                  string, mWriteSequence, mFramesWritten,
                  mNumTracks, mWriteErrors, mUnderruns, mOverruns,
                  mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
@@ -550,26 +554,26 @@
 #endif
     }
     if (n) {
-        fdprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
-                     wall.n() * mixPeriodSec);
-        fdprintf(fd, "    wall clock time in ms per mix cycle:\n"
-                     "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                     wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
-                     wall.stddev()*1e-6);
-        fdprintf(fd, "    raw CPU load in us per mix cycle:\n"
-                     "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                     loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
-                     loadNs.stddev()*1e-3);
+        dprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
+                    wall.n() * mixPeriodSec);
+        dprintf(fd, "    wall clock time in ms per mix cycle:\n"
+                    "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+                    wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
+                    wall.stddev()*1e-6);
+        dprintf(fd, "    raw CPU load in us per mix cycle:\n"
+                    "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+                    loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
+                    loadNs.stddev()*1e-3);
     } else {
-        fdprintf(fd, "  No FastMixer statistics available currently\n");
+        dprintf(fd, "  No FastMixer statistics available currently\n");
     }
 #ifdef CPU_FREQUENCY_STATISTICS
-    fdprintf(fd, "  CPU clock frequency in MHz:\n"
-                 "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                 kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
-    fdprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
-                 "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
-                 loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
+    dprintf(fd, "  CPU clock frequency in MHz:\n"
+                "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+                kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
+    dprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
+                "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
+                loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
 #endif
     if (tail != NULL) {
         qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
@@ -580,12 +584,12 @@
             left.sample(tail[i]);
             right.sample(tail[n - (i + 1)]);
         }
-        fdprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
-                     "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
-                     "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                     left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
-                     right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
-                     right.stddev()*1e-6);
+        dprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
+                    "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
+                    "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+                    left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
+                    right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
+                    right.stddev()*1e-6);
         delete[] tail;
     }
 #endif
@@ -595,9 +599,9 @@
     // Instead we always display all tracks, with an indication
     // of whether we think the track is active.
     uint32_t trackMask = mTrackMask;
-    fdprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
+    dprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
             FastMixerState::kMaxFastTracks, trackMask);
-    fdprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
+    dprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
     for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
         bool isActive = trackMask & 1;
         const FastTrackDump *ftDump = &mTracks[i];
@@ -617,7 +621,7 @@
             mostRecent = "?";
             break;
         }
-        fdprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
+        dprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
                 (underruns.mBitFields.mFull) & UNDERRUN_MASK,
                 (underruns.mBitFields.mPartial) & UNDERRUN_MASK,
                 (underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 981c1a7..db89ef4 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -17,13 +17,11 @@
 #ifndef ANDROID_AUDIO_FAST_MIXER_H
 #define ANDROID_AUDIO_FAST_MIXER_H
 
+#include <linux/futex.h>
+#include <sys/syscall.h>
 #include <utils/Debug.h>
-#if 1   // FIXME move to where used
-extern "C" {
-#include "../private/bionic_futex.h"
-}
-#endif
 #include "FastThread.h"
+#include <utils/Thread.h>
 #include "StateQueue.h"
 #include "FastMixerState.h"
 #include "FastMixerDumpState.h"
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 8e6d0d4..3aa8dad 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -20,7 +20,7 @@
 
 FastTrack::FastTrack() :
     mBufferProvider(NULL), mVolumeProvider(NULL),
-    mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0)
+    mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mFormat(AUDIO_FORMAT_INVALID), mGeneration(0)
 {
 }
 
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index e388fb3..661c9ca 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -45,6 +45,7 @@
     ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active
     VolumeProvider*         mVolumeProvider; // optional; if NULL then full-scale
     audio_channel_mask_t    mChannelMask;    // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO
+    audio_format_t          mFormat;         // track format
     int                     mGeneration;     // increment when any field is assigned
 };
 
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index 8a216b3..216dace 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -20,10 +20,9 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include "Configuration.h"
+#include <linux/futex.h>
+#include <sys/syscall.h>
 #include <utils/Log.h>
-extern "C" {
-#include "../private/bionic_futex.h"
-}
 #include <utils/Trace.h>
 #include "FastThread.h"
 
@@ -157,7 +156,7 @@
                 ALOG_ASSERT(coldFutexAddr != NULL);
                 int32_t old = android_atomic_dec(coldFutexAddr);
                 if (old <= 0) {
-                    __futex_syscall4(coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
+                    syscall(__NR_futex, coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
                 }
                 int policy = sched_getscheduler(0);
                 if (!(policy == SCHED_FIFO || policy == SCHED_RR)) {
diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/StateQueue.cpp
index 48399c0..7e01c9f 100644
--- a/services/audioflinger/StateQueue.cpp
+++ b/services/audioflinger/StateQueue.cpp
@@ -28,12 +28,12 @@
 #ifdef STATE_QUEUE_DUMP
 void StateQueueObserverDump::dump(int fd)
 {
-    fdprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
+    dprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
 }
 
 void StateQueueMutatorDump::dump(int fd)
 {
-    fdprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
+    dprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
             mPushDirty, mPushAck, mBlockedSequence);
 }
 #endif
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ce08ff1..7843387 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -505,30 +505,30 @@
 
     bool locked = AudioFlinger::dumpTryLock(mLock);
     if (!locked) {
-        fdprintf(fd, "thread %p maybe dead locked\n", this);
+        dprintf(fd, "thread %p maybe dead locked\n", this);
     }
 
-    fdprintf(fd, "  I/O handle: %d\n", mId);
-    fdprintf(fd, "  TID: %d\n", getTid());
-    fdprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
-    fdprintf(fd, "  Sample rate: %u\n", mSampleRate);
-    fdprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
-    fdprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
-    fdprintf(fd, "  Channel Count: %u\n", mChannelCount);
-    fdprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
+    dprintf(fd, "  I/O handle: %d\n", mId);
+    dprintf(fd, "  TID: %d\n", getTid());
+    dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
+    dprintf(fd, "  Sample rate: %u\n", mSampleRate);
+    dprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
+    dprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
+    dprintf(fd, "  Channel Count: %u\n", mChannelCount);
+    dprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
             channelMaskToString(mChannelMask, mType != RECORD).string());
-    fdprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
-    fdprintf(fd, "  Frame size: %zu\n", mFrameSize);
-    fdprintf(fd, "  Pending config events:");
+    dprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
+    dprintf(fd, "  Frame size: %zu\n", mFrameSize);
+    dprintf(fd, "  Pending config events:");
     size_t numConfig = mConfigEvents.size();
     if (numConfig) {
         for (size_t i = 0; i < numConfig; i++) {
             mConfigEvents[i]->dump(buffer, SIZE);
-            fdprintf(fd, "\n    %s", buffer);
+            dprintf(fd, "\n    %s", buffer);
         }
-        fdprintf(fd, "\n");
+        dprintf(fd, "\n");
     } else {
-        fdprintf(fd, " none\n");
+        dprintf(fd, " none\n");
     }
 
     if (locked) {
@@ -1191,15 +1191,15 @@
 
     // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
     FastTrackUnderruns underruns = getFastTrackUnderruns(0);
-    fdprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
+    dprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
             underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
 
     size_t numtracks = mTracks.size();
     size_t numactive = mActiveTracks.size();
-    fdprintf(fd, "  %d Tracks", numtracks);
+    dprintf(fd, "  %d Tracks", numtracks);
     size_t numactiveseen = 0;
     if (numtracks) {
-        fdprintf(fd, " of which %d are active\n", numactive);
+        dprintf(fd, " of which %d are active\n", numactive);
         Track::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks; ++i) {
             sp<Track> track = mTracks[i];
@@ -1231,22 +1231,21 @@
     }
 
     write(fd, result.string(), result.size());
-
 }
 
 void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
 {
-    fdprintf(fd, "\nOutput thread %p:\n", this);
-    fdprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
-    fdprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
-    fdprintf(fd, "  Total writes: %d\n", mNumWrites);
-    fdprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
-    fdprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
-    fdprintf(fd, "  Suspend count: %d\n", mSuspended);
-    fdprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
-    fdprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
-    fdprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
-    fdprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
+    dprintf(fd, "\nOutput thread %p:\n", this);
+    dprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
+    dprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    dprintf(fd, "  Total writes: %d\n", mNumWrites);
+    dprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
+    dprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
+    dprintf(fd, "  Suspend count: %d\n", mSuspended);
+    dprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
+    dprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
+    dprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
+    dprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
 
     dumpBase(fd, args);
 }
@@ -2683,6 +2682,8 @@
         // wrap the source side of the MonoPipe to make it an AudioBufferProvider
         fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));
         fastTrack->mVolumeProvider = NULL;
+        fastTrack->mChannelMask = mChannelMask; // mPipeSink channel mask for audio to FastMixer
+        fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
         fastTrack->mGeneration++;
         state->mFastTracksGen++;
         state->mTrackMask = 1;
@@ -2752,7 +2753,7 @@
         if (state->mCommand == FastMixerState::COLD_IDLE) {
             int32_t old = android_atomic_inc(&mFastMixerFutex);
             if (old == -1) {
-                (void) __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
+                (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
             }
         }
         state->mCommand = FastMixerState::EXIT;
@@ -2809,7 +2810,7 @@
             if (state->mCommand == FastMixerState::COLD_IDLE) {
                 int32_t old = android_atomic_inc(&mFastMixerFutex);
                 if (old == -1) {
-                    (void) __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
+                    (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
                 }
 #ifdef AUDIO_WATCHDOG
                 if (mAudioWatchdog != 0) {
@@ -3135,6 +3136,7 @@
                     fastTrack->mBufferProvider = eabp;
                     fastTrack->mVolumeProvider = vp;
                     fastTrack->mChannelMask = track->mChannelMask;
+                    fastTrack->mFormat = track->mFormat;
                     fastTrack->mGeneration++;
                     state->mTrackMask |= 1 << j;
                     didModify = true;
@@ -3526,9 +3528,10 @@
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask, int sessionId)
+int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask,
+        audio_format_t format, int sessionId)
 {
-    return mAudioMixer->getTrackName(channelMask, sessionId);
+    return mAudioMixer->getTrackName(channelMask, format, sessionId);
 }
 
 // deleteTrackName_l() must be called with ThreadBase::mLock held
@@ -3641,7 +3644,8 @@
             delete mAudioMixer;
             mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
             for (size_t i = 0; i < mTracks.size() ; i++) {
-                int name = getTrackName_l(mTracks[i]->mChannelMask, mTracks[i]->mSessionId);
+                int name = getTrackName_l(mTracks[i]->mChannelMask,
+                        mTracks[i]->mFormat, mTracks[i]->mSessionId);
                 if (name < 0) {
                     break;
                 }
@@ -3673,7 +3677,7 @@
 
     PlaybackThread::dumpInternals(fd, args);
 
-    fdprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
+    dprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
 
     // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
     const FastMixerDumpState copy(mFastMixerDumpState);
@@ -3932,7 +3936,7 @@
 
 // getTrackName_l() must be called with ThreadBase::mLock held
 int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
-        int sessionId __unused)
+        audio_format_t format __unused, int sessionId __unused)
 {
     return 0;
 }
@@ -5128,6 +5132,7 @@
         // to be at least 2 x the record thread frame count and cover audio hardware latency.
         // This is probably too conservative, but legacy application code may depend on it.
         // If you change this calculation, also review the start threshold which is related.
+        // FIXME It's not clear how input latency actually matters.  Perhaps this should be 0.
         uint32_t latencyMs = 50; // FIXME mInput->stream->get_latency(mInput->stream);
         size_t mNormalFrameCount = 2048; // FIXME
         uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
@@ -5360,12 +5365,12 @@
 
 void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
 {
-    fdprintf(fd, "\nInput thread %p:\n", this);
+    dprintf(fd, "\nInput thread %p:\n", this);
 
     if (mActiveTracks.size() > 0) {
-        fdprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
+        dprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
     } else {
-        fdprintf(fd, "  No active record clients\n");
+        dprintf(fd, "  No active record clients\n");
     }
 
     dumpBase(fd, args);
@@ -5380,9 +5385,9 @@
     size_t numtracks = mTracks.size();
     size_t numactive = mActiveTracks.size();
     size_t numactiveseen = 0;
-    fdprintf(fd, "  %d Tracks", numtracks);
+    dprintf(fd, "  %d Tracks", numtracks);
     if (numtracks) {
-        fdprintf(fd, " of which %d are active\n", numactive);
+        dprintf(fd, " of which %d are active\n", numactive);
         RecordTrack::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<RecordTrack> track = mTracks[i];
@@ -5396,7 +5401,7 @@
             }
         }
     } else {
-        fdprintf(fd, "\n");
+        dprintf(fd, "\n");
     }
 
     if (numactiveseen != numactive) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index cc2b246..44008e5 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -301,6 +301,8 @@
                 // If a thread does not have such a heap, this method returns 0.
                 virtual sp<MemoryDealer>    readOnlyHeap() const { return 0; }
 
+                virtual sp<IMemory> pipeMemory() const { return 0; }
+
     mutable     Mutex                   mLock;
 
 protected:
@@ -619,7 +621,8 @@
 
     // Allocate a track name for a given channel mask.
     //   Returns name >= 0 if successful, -1 on failure.
-    virtual int             getTrackName_l(audio_channel_mask_t channelMask, int sessionId) = 0;
+    virtual int             getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId) = 0;
     virtual void            deleteTrackName_l(int name) = 0;
 
     // Time to sleep between cycles when:
@@ -772,7 +775,8 @@
 
 protected:
     virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
+    virtual     int         getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId);
     virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
@@ -825,7 +829,8 @@
                                                    status_t& status);
 
 protected:
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
+    virtual     int         getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId);
     virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    activeSleepTimeUs() const;
     virtual     uint32_t    idleSleepTimeUs() const;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 5f13be3..4cba3fd 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -39,6 +39,13 @@
         STARTING_2,     // for RecordTrack only
     };
 
+    // where to allocate the data buffer
+    enum alloc_type {
+        ALLOC_CBLK,     // allocate immediately after control block
+        ALLOC_READONLY, // allocate from a separate read-only heap per thread
+        ALLOC_PIPE,     // do not allocate; use the pipe buffer
+    };
+
                         TrackBase(ThreadBase *thread,
                                 const sp<Client>& client,
                                 uint32_t sampleRate,
@@ -50,7 +57,7 @@
                                 int uid,
                                 IAudioFlinger::track_flags_t flags,
                                 bool isOut,
-                                bool useReadOnlyHeap = false);
+                                alloc_type alloc = ALLOC_CBLK);
     virtual             ~TrackBase();
     virtual status_t    initCheck() const { return getCblk() != 0 ? NO_ERROR : NO_MEMORY; }
 
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index de1782d..7ddc71c 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -21,6 +21,7 @@
 
 #include "Configuration.h"
 #include <math.h>
+#include <sys/syscall.h>
 #include <utils/Log.h>
 
 #include <private/media/AudioTrackShared.h>
@@ -72,7 +73,7 @@
             int clientUid,
             IAudioFlinger::track_flags_t flags,
             bool isOut,
-            bool useReadOnlyHeap)
+            alloc_type alloc)
     :   RefBase(),
         mThread(thread),
         mClient(client),
@@ -116,7 +117,7 @@
     // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
     size_t size = sizeof(audio_track_cblk_t);
     size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize;
-    if (sharedBuffer == 0 && !useReadOnlyHeap) {
+    if (sharedBuffer == 0 && alloc == ALLOC_CBLK) {
         size += bufferSize;
     }
 
@@ -138,7 +139,8 @@
     // construct the shared structure in-place.
     if (mCblk != NULL) {
         new(mCblk) audio_track_cblk_t();
-        if (useReadOnlyHeap) {
+        switch (alloc) {
+        case ALLOC_READONLY: {
             const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
             if (roHeap == 0 ||
                     (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
@@ -152,7 +154,17 @@
                 return;
             }
             memset(mBuffer, 0, bufferSize);
-        } else {
+            } break;
+        case ALLOC_PIPE:
+            mBufferMemory = thread->pipeMemory();
+            // mBuffer is the virtual address as seen from current process (mediaserver),
+            // and should normally be coming from mBufferMemory->pointer().
+            // However in this case the TrackBase does not reference the buffer directly.
+            // It should references the buffer via the pipe.
+            // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
+            mBuffer = NULL;
+            break;
+        case ALLOC_CBLK:
             // clear all buffers
             if (sharedBuffer == 0) {
                 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
@@ -163,6 +175,7 @@
                 mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
 #endif
             }
+            break;
         }
 
 #ifdef TEE_SINK
@@ -384,7 +397,7 @@
     }
     mServerProxy = mAudioTrackServerProxy;
 
-    mName = thread->getTrackName_l(channelMask, sessionId);
+    mName = thread->getTrackName_l(channelMask, format, sessionId);
     if (mName < 0) {
         ALOGE("no more track names available");
         return;
@@ -1008,7 +1021,7 @@
     android_atomic_or(CBLK_INVALID, &cblk->mFlags);
     android_atomic_release_store(0x40000000, &cblk->mFutex);
     // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
-    (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
+    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
     mIsInvalid = true;
 }
 
@@ -1841,7 +1854,7 @@
     :   TrackBase(thread, client, sampleRate, format,
                   channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid,
                   flags, false /*isOut*/,
-                  (flags & IAudioFlinger::TRACK_FAST) != 0 /*useReadOnlyHeap*/),
+                  (flags & IAudioFlinger::TRACK_FAST) != 0 ? ALLOC_READONLY : ALLOC_CBLK),
         mOverflow(false), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpOutFrameCount(0),
         // See real initialization of mRsmpInFront at RecordThread::start()
         mRsmpInUnrel(0), mRsmpInFront(0), mFramesToDrop(0), mResamplerBufferProvider(NULL)
@@ -1937,7 +1950,7 @@
     android_atomic_or(CBLK_INVALID, &cblk->mFlags);
     android_atomic_release_store(0x40000000, &cblk->mFutex);
     // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
-    (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
+    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
 }
 
 
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index f270bfc..a22ad9d 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -5,7 +5,6 @@
 LOCAL_SRC_FILES:= \
     AudioPolicyService.cpp
 
-USE_LEGACY_AUDIO_POLICY = 1
 ifeq ($(USE_LEGACY_AUDIO_POLICY), 1)
 LOCAL_SRC_FILES += \
     AudioPolicyInterfaceImplLegacy.cpp \
@@ -15,8 +14,7 @@
 else
 LOCAL_SRC_FILES += \
     AudioPolicyInterfaceImpl.cpp \
-    AudioPolicyClientImpl.cpp \
-    AudioPolicyManager.cpp
+    AudioPolicyClientImpl.cpp
 endif
 
 LOCAL_C_INCLUDES := \
@@ -31,14 +29,42 @@
     libbinder \
     libmedia \
     libhardware \
-    libhardware_legacy
+    libhardware_legacy \
+
+ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
+LOCAL_SHARED_LIBRARIES += \
+    libaudiopolicymanager
+endif
 
 LOCAL_STATIC_LIBRARIES := \
     libmedia_helper \
     libserviceutility
 
-LOCAL_MODULE:= libaudiopolicy
+LOCAL_MODULE:= libaudiopolicyservice
 
 LOCAL_CFLAGS += -fvisibility=hidden
 
 include $(BUILD_SHARED_LIBRARY)
+
+ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
+ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyManager.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog
+
+LOCAL_STATIC_LIBRARIES := \
+    libmedia_helper
+
+LOCAL_MODULE:= libaudiopolicymanager
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
+endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index fe1e707..9fd35e1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -39,6 +39,8 @@
 #include <utils/String16.h>
 #include <utils/Trace.h>
 #include <system/camera_vendor_tags.h>
+#include <system/camera_metadata.h>
+#include <system/camera.h>
 
 #include "CameraService.h"
 #include "api1/CameraClient.h"
@@ -178,6 +180,9 @@
         {
            Mutex::Autolock al(mServiceLock);
 
+           /* Remove cached parameters from shim cache */
+           mShimParams.removeItem(cameraId);
+
            /* Find all clients that we need to disconnect */
            sp<BasicClient> client = mClient[cameraId].promote();
            if (client.get() != NULL) {
@@ -236,6 +241,96 @@
     return rc;
 }
 
+
+status_t CameraService::generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo) {
+    status_t ret = OK;
+    struct CameraInfo info;
+    if ((ret = getCameraInfo(cameraId, &info)) != OK) {
+        return ret;
+    }
+
+    CameraMetadata shimInfo;
+    int32_t orientation = static_cast<int32_t>(info.orientation);
+    if ((ret = shimInfo.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1)) != OK) {
+        return ret;
+    }
+
+    uint8_t facing = (info.facing == CAMERA_FACING_FRONT) ?
+            ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
+    if ((ret = shimInfo.update(ANDROID_LENS_FACING, &facing, 1)) != OK) {
+        return ret;
+    }
+
+    ssize_t index = -1;
+    {   // Scope for service lock
+        Mutex::Autolock lock(mServiceLock);
+        index = mShimParams.indexOfKey(cameraId);
+        // Release service lock so initializeShimMetadata can be called correctly.
+    }
+
+    if (index < 0) {
+        int64_t token = IPCThreadState::self()->clearCallingIdentity();
+        ret = initializeShimMetadata(cameraId);
+        IPCThreadState::self()->restoreCallingIdentity(token);
+        if (ret != OK) {
+            return ret;
+        }
+    }
+
+    Vector<Size> sizes;
+    Vector<int32_t> formats;
+    const char* supportedPreviewFormats;
+    {   // Scope for service lock
+        Mutex::Autolock lock(mServiceLock);
+        index = mShimParams.indexOfKey(cameraId);
+
+        mShimParams[index].getSupportedPreviewSizes(/*out*/sizes);
+
+        mShimParams[index].getSupportedPreviewFormats(/*out*/formats);
+    }
+
+    // Always include IMPLEMENTATION_DEFINED
+    formats.add(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+
+    const size_t INTS_PER_CONFIG = 4;
+
+    // Build available stream configurations metadata
+    size_t streamConfigSize = sizes.size() * formats.size() * INTS_PER_CONFIG;
+    int32_t streamConfigs[streamConfigSize];
+    size_t configIndex = 0;
+    for (size_t i = 0; i < formats.size(); ++i) {
+        for (size_t j = 0; j < sizes.size(); ++j) {
+            streamConfigs[configIndex++] = formats[i];
+            streamConfigs[configIndex++] = sizes[j].width;
+            streamConfigs[configIndex++] = sizes[j].height;
+            streamConfigs[configIndex++] =
+                    ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
+        }
+    }
+
+    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+            streamConfigs, streamConfigSize)) != OK) {
+        return ret;
+    }
+
+    int64_t fakeMinFrames[0];
+    // TODO: Fixme, don't fake min frame durations.
+    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+            fakeMinFrames, 0)) != OK) {
+        return ret;
+    }
+
+    int64_t fakeStalls[0];
+    // TODO: Fixme, don't fake stall durations.
+    if ((ret = shimInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+            fakeStalls, 0)) != OK) {
+        return ret;
+    }
+
+    *cameraInfo = shimInfo;
+    return OK;
+}
+
 status_t CameraService::getCameraCharacteristics(int cameraId,
                                                 CameraMetadata* cameraInfo) {
     if (!cameraInfo) {
@@ -248,33 +343,37 @@
         return -ENODEV;
     }
 
-    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
-        // TODO: Remove this check once HAL1 shim is in place.
-        ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
         ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
         return BAD_VALUE;
     }
 
     int facing;
-    if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
-        // TODO: Remove this check once HAL1 shim is in place.
-        ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
-        return BAD_VALUE;
-    }
+    status_t ret = OK;
+    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
+            getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
+        /**
+         * Backwards compatibility mode for old HALs:
+         * - Convert CameraInfo into static CameraMetadata properties.
+         * - Retrieve cached CameraParameters for this camera.  If none exist,
+         *   attempt to open CameraClient and retrieve the CameraParameters.
+         * - Convert cached CameraParameters into static CameraMetadata
+         *   properties.
+         */
+        ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);
 
-    if (getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1) {
-        // Disable HAL2.x support for camera2 API for now.
-        ALOGW("%s: HAL2.x doesn't support getCameraCharacteristics for now", __FUNCTION__);
-        return BAD_VALUE;
-    }
+        if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
+            return ret;
+        }
 
-    struct camera_info info;
-    status_t ret = mModule->get_camera_info(cameraId, &info);
-    *cameraInfo = info.static_camera_characteristics;
+    } else {
+        /**
+         * Normal HAL 2.1+ codepath.
+         */
+        struct camera_info info;
+        ret = mModule->get_camera_info(cameraId, &info);
+        *cameraInfo = info.static_camera_characteristics;
+    }
 
     return ret;
 }
@@ -285,12 +384,6 @@
         return -ENODEV;
     }
 
-    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_2) {
-        // TODO: Remove this check once HAL1 shim is in place.
-        ALOGW("%s: Only HAL module version V2.2 or higher supports vendor tags", __FUNCTION__);
-        return -EOPNOTSUPP;
-    }
-
     desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
     return OK;
 }
@@ -372,6 +465,54 @@
     return true;
 }
 
+status_t CameraService::initializeShimMetadata(int cameraId) {
+    int pid = getCallingPid();
+    int uid = getCallingUid();
+    status_t ret = validateConnect(cameraId, uid);
+    if (ret != OK) {
+        return ret;
+    }
+
+    bool needsNewClient = false;
+    sp<Client> client;
+
+    String16 internalPackageName("media");
+    {   // Scope for service lock
+        Mutex::Autolock lock(mServiceLock);
+        if (mClient[cameraId] != NULL) {
+            client = static_cast<Client*>(mClient[cameraId].promote().get());
+        }
+        if (client == NULL) {
+            needsNewClient = true;
+            ret = connectHelperLocked(/*cameraClient*/NULL, // Empty binder callbacks
+                                      cameraId,
+                                      internalPackageName,
+                                      uid,
+                                      pid,
+                                      client);
+
+            if (ret != OK) {
+                return ret;
+            }
+        }
+
+        if (client == NULL) {
+            ALOGE("%s: Could not connect to client camera device.", __FUNCTION__);
+            return BAD_VALUE;
+        }
+
+        String8 rawParams = client->getParameters();
+        CameraParameters params(rawParams);
+        mShimParams.add(cameraId, params);
+    }
+
+    // Close client if one was opened solely for this call
+    if (needsNewClient) {
+        client->disconnect();
+    }
+    return OK;
+}
+
 status_t CameraService::validateConnect(int cameraId,
                                     /*inout*/
                                     int& clientUid) const {
@@ -468,6 +609,64 @@
     return true;
 }
 
+status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClient,
+                                      int cameraId,
+                                      const String16& clientPackageName,
+                                      int clientUid,
+                                      int callingPid,
+                                      /*out*/
+                                      sp<Client>& client) {
+
+    int facing = -1;
+    int deviceVersion = getDeviceVersion(cameraId, &facing);
+
+    // If there are other non-exclusive users of the camera,
+    //  this will tear them down before we can reuse the camera
+    if (isValidCameraId(cameraId)) {
+        // transition from PRESENT -> NOT_AVAILABLE
+        updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
+                     cameraId);
+    }
+
+    switch(deviceVersion) {
+      case CAMERA_DEVICE_API_VERSION_1_0:
+        client = new CameraClient(this, cameraClient,
+                clientPackageName, cameraId,
+                facing, callingPid, clientUid, getpid());
+        break;
+      case CAMERA_DEVICE_API_VERSION_2_0:
+      case CAMERA_DEVICE_API_VERSION_2_1:
+      case CAMERA_DEVICE_API_VERSION_3_0:
+      case CAMERA_DEVICE_API_VERSION_3_1:
+      case CAMERA_DEVICE_API_VERSION_3_2:
+        client = new Camera2Client(this, cameraClient,
+                clientPackageName, cameraId,
+                facing, callingPid, clientUid, getpid(),
+                deviceVersion);
+        break;
+      case -1:
+        ALOGE("Invalid camera id %d", cameraId);
+        return BAD_VALUE;
+      default:
+        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
+        return INVALID_OPERATION;
+    }
+
+    status_t status = connectFinishUnsafe(client, client->getRemote());
+    if (status != OK) {
+        // this is probably not recoverable.. maybe the client can try again
+        // OK: we can only get here if we were originally in PRESENT state
+        updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
+        return status;
+    }
+
+    mClient[cameraId] = client;
+    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
+         getpid());
+
+    return OK;
+}
+
 status_t CameraService::connect(
         const sp<ICameraClient>& cameraClient,
         int cameraId,
@@ -501,52 +700,16 @@
             return OK;
         }
 
-        int facing = -1;
-        int deviceVersion = getDeviceVersion(cameraId, &facing);
-
-        // If there are other non-exclusive users of the camera,
-        //  this will tear them down before we can reuse the camera
-        if (isValidCameraId(cameraId)) {
-            // transition from PRESENT -> NOT_AVAILABLE
-            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
-                         cameraId);
-        }
-
-        switch(deviceVersion) {
-          case CAMERA_DEVICE_API_VERSION_1_0:
-            client = new CameraClient(this, cameraClient,
-                    clientPackageName, cameraId,
-                    facing, callingPid, clientUid, getpid());
-            break;
-          case CAMERA_DEVICE_API_VERSION_2_0:
-          case CAMERA_DEVICE_API_VERSION_2_1:
-          case CAMERA_DEVICE_API_VERSION_3_0:
-          case CAMERA_DEVICE_API_VERSION_3_1:
-          case CAMERA_DEVICE_API_VERSION_3_2:
-            client = new Camera2Client(this, cameraClient,
-                    clientPackageName, cameraId,
-                    facing, callingPid, clientUid, getpid(),
-                    deviceVersion);
-            break;
-          case -1:
-            ALOGE("Invalid camera id %d", cameraId);
-            return BAD_VALUE;
-          default:
-            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
-            return INVALID_OPERATION;
-        }
-
-        status_t status = connectFinishUnsafe(client, client->getRemote());
+        status = connectHelperLocked(cameraClient,
+                                     cameraId,
+                                     clientPackageName,
+                                     clientUid,
+                                     callingPid,
+                                     client);
         if (status != OK) {
-            // this is probably not recoverable.. maybe the client can try again
-            // OK: we can only get here if we were originally in PRESENT state
-            updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
             return status;
         }
 
-        mClient[cameraId] = client;
-        LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
-             getpid());
     }
     // important: release the mutex here so the client can call back
     //    into the service from its destructor (can be at the end of the call)
@@ -561,8 +724,9 @@
     if (status != OK) {
         return status;
     }
-
-    remoteCallback->linkToDeath(this);
+    if (remoteCallback != NULL) {
+        remoteCallback->linkToDeath(this);
+    }
 
     return OK;
 }
@@ -800,9 +964,13 @@
     if (client != 0) {
         // Found our camera, clear and leave.
         LOG1("removeClient: clear camera %d", outIndex);
-        mClient[outIndex].clear();
 
-        client->getRemote()->unlinkToDeath(this);
+        sp<IBinder> remote = client->getRemote();
+        if (remote != NULL) {
+            remote->unlinkToDeath(this);
+        }
+
+        mClient[outIndex].clear();
     } else {
 
         sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 76ea7be..ee39d52 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
 #include <utils/Vector.h>
+#include <utils/KeyedVector.h>
 #include <binder/AppOpsManager.h>
 #include <binder/BinderService.h>
 #include <binder/IAppOpsCallback.h>
@@ -32,6 +33,7 @@
 #include <camera/camera2/ICameraDeviceCallbacks.h>
 #include <camera/VendorTagDescriptor.h>
 #include <camera/CaptureResult.h>
+#include <camera/CameraParameters.h>
 
 #include <camera/ICameraServiceListener.h>
 
@@ -395,6 +397,43 @@
     bool                isValidCameraId(int cameraId);
 
     bool                setUpVendorTags();
+
+    /**
+     * A mapping of camera ids to CameraParameters returned by that camera device.
+     *
+     * This cache is used to generate CameraCharacteristic metadata when using
+     * the HAL1 shim.
+     */
+    KeyedVector<int, CameraParameters>    mShimParams;
+
+    /**
+     * Initialize and cache the metadata used by the HAL1 shim for a given cameraId.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    status_t            initializeShimMetadata(int cameraId);
+
+    /**
+     * Generate the CameraCharacteristics metadata required by the Camera2 API
+     * from the available HAL1 CameraParameters and CameraInfo.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    status_t            generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo);
+
+    /**
+     * Connect a new camera client.  This should only be used while holding the
+     * mutex for mServiceLock.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    status_t            connectHelperLocked(const sp<ICameraClient>& cameraClient,
+                                      int cameraId,
+                                      const String16& clientPackageName,
+                                      int clientUid,
+                                      int callingPid,
+                                      /*out*/
+                                      sp<Client>& client);
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 65592d3..dece764 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -2028,24 +2028,7 @@
 }
 
 int Parameters::formatStringToEnum(const char *format) {
-    return
-        !format ?
-            HAL_PIXEL_FORMAT_YCrCb_420_SP :
-        !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;
+    return CameraParameters::previewFormatToEnum(format);
 }
 
 const char* Parameters::formatEnumToString(int format) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 5a48a62..4fce1b3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -246,6 +246,18 @@
     return res;
 }
 
+status_t CameraDeviceClient::beginConfigure() {
+    // TODO: Implement this.
+    ALOGE("%s: Not implemented yet.", __FUNCTION__);
+    return OK;
+}
+
+status_t CameraDeviceClient::endConfigure() {
+    // TODO: Implement this.
+    ALOGE("%s: Not implemented yet.", __FUNCTION__);
+    return OK;
+}
+
 status_t CameraDeviceClient::deleteStream(int streamId) {
     ATRACE_CALL();
     ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 0b37784..9981dfe 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -76,6 +76,10 @@
                                         /*out*/
                                         int64_t* lastFrameNumber = NULL);
 
+    virtual status_t beginConfigure();
+
+    virtual status_t endConfigure();
+
     // Returns -EBUSY if device is not idle
     virtual status_t      deleteStream(int streamId);
 
diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp
index 346e15f..374dc5e 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.cpp
+++ b/services/camera/libcameraservice/utils/CameraTraces.cpp
@@ -74,10 +74,10 @@
         return BAD_VALUE;
     }
 
-    fdprintf(fd, "Camera traces (%zu):\n", pcsList.size());
+    dprintf(fd, "Camera traces (%zu):\n", pcsList.size());
 
     if (pcsList.empty()) {
-        fdprintf(fd, "  No camera traces collected.\n");
+        dprintf(fd, "  No camera traces collected.\n");
     }
 
     // Print newest items first
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index 0c7fbbd..41dab1f 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -60,7 +60,7 @@
     static const String16 sDump("android.permission.DUMP");
     if (!(IPCThreadState::self()->getCallingUid() == AID_MEDIA ||
             PermissionCache::checkCallingPermission(sDump))) {
-        fdprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
+        dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
                 IPCThreadState::self()->getCallingPid(),
                 IPCThreadState::self()->getCallingUid());
         return NO_ERROR;
@@ -74,7 +74,7 @@
     for (size_t i = 0; i < namedReaders.size(); i++) {
         const NamedReader& namedReader = namedReaders[i];
         if (fd >= 0) {
-            fdprintf(fd, "\n%s:\n", namedReader.name());
+            dprintf(fd, "\n%s:\n", namedReader.name());
         } else {
             ALOGI("%s:", namedReader.name());
         }