Merge "Add Quad channel output to AudioPolicyManager" into lmp-dev
diff --git a/camera/CameraUtils.cpp b/camera/CameraUtils.cpp
index 3ff181d..1ff63ab 100644
--- a/camera/CameraUtils.cpp
+++ b/camera/CameraUtils.cpp
@@ -73,18 +73,25 @@
                 return INVALID_OPERATION;
         }
     } else {
+        // Front camera needs to be horizontally flipped for
+        // mirror-like behavior.
+        // Note: Flips are applied before rotates.
         switch (orientation) {
             case 0:
-                flags = HAL_TRANSFORM_FLIP_H;
+                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
                 break;
             case 90:
-                flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
+                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+                        NATIVE_WINDOW_TRANSFORM_ROT_270;
                 break;
             case 180:
-                flags = HAL_TRANSFORM_FLIP_V;
+                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+                        NATIVE_WINDOW_TRANSFORM_ROT_180;
                 break;
             case 270:
-                flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
+                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+                        NATIVE_WINDOW_TRANSFORM_ROT_90;
+
                 break;
             default:
                 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 9ea18de..cf34991 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -139,12 +139,12 @@
     // return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
     static uint32_t getInputFramesLost(audio_io_handle_t ioHandle);
 
-    // Allocate a new audio session ID and return that new ID.
-    // If unable to contact AudioFlinger, returns AUDIO_SESSION_ALLOCATE instead.
-    // FIXME If AudioFlinger were to ever exhaust the session ID namespace,
-    //       this method could fail by returning either AUDIO_SESSION_ALLOCATE
-    //       or an unspecified existing session ID.
-    static int newAudioSessionId();
+    // Allocate a new unique ID for use as an audio session ID or I/O handle.
+    // If unable to contact AudioFlinger, returns AUDIO_UNIQUE_ID_ALLOCATE instead.
+    // FIXME If AudioFlinger were to ever exhaust the unique ID namespace,
+    //       this method could fail by returning either AUDIO_UNIQUE_ID_ALLOCATE
+    //       or an unspecified existing unique ID.
+    static audio_unique_id_t newAudioUniqueId();
 
     static void acquireAudioSessionId(int audioSession, pid_t pid);
     static void releaseAudioSessionId(int audioSession, pid_t pid);
@@ -237,9 +237,12 @@
                                     int sessionId,
                                     audio_input_flags_t);
 
-    static status_t startInput(audio_io_handle_t input);
-    static status_t stopInput(audio_io_handle_t input);
-    static void releaseInput(audio_io_handle_t input);
+    static status_t startInput(audio_io_handle_t input,
+                               audio_session_t session);
+    static status_t stopInput(audio_io_handle_t input,
+                              audio_session_t session);
+    static void releaseInput(audio_io_handle_t input,
+                             audio_session_t session);
     static status_t initStreamVolume(audio_stream_type_t stream,
                                       int indexMin,
                                       int indexMax);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 31312d3..82ec09c 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -145,26 +145,26 @@
     virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
             audio_channel_mask_t channelMask) const = 0;
 
-    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
-                                         audio_devices_t *pDevices,
-                                         uint32_t *pSamplingRate,
-                                         audio_format_t *pFormat,
-                                         audio_channel_mask_t *pChannelMask,
-                                         uint32_t *pLatencyMs,
-                                         audio_output_flags_t flags,
-                                         const audio_offload_info_t *offloadInfo = NULL) = 0;
+    virtual status_t openOutput(audio_module_handle_t module,
+                                audio_io_handle_t *output,
+                                audio_config_t *config,
+                                audio_devices_t *devices,
+                                const String8& address,
+                                uint32_t *latencyMs,
+                                audio_output_flags_t flags) = 0;
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
                                     audio_io_handle_t output2) = 0;
     virtual status_t closeOutput(audio_io_handle_t output) = 0;
     virtual status_t suspendOutput(audio_io_handle_t output) = 0;
     virtual status_t restoreOutput(audio_io_handle_t output) = 0;
 
-    virtual audio_io_handle_t openInput(audio_module_handle_t module,
-                                        audio_devices_t *pDevices,
-                                        uint32_t *pSamplingRate,
-                                        audio_format_t *pFormat,
-                                        audio_channel_mask_t *pChannelMask,
-                                        audio_input_flags_t flags) = 0;
+    virtual status_t openInput(audio_module_handle_t module,
+                               audio_io_handle_t *input,
+                               audio_config_t *config,
+                               audio_devices_t *device,
+                               const String8& address,
+                               audio_source_t source,
+                               audio_input_flags_t flags) = 0;
     virtual status_t closeInput(audio_io_handle_t input) = 0;
 
     virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
@@ -176,7 +176,7 @@
 
     virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
 
-    virtual int newAudioSessionId() = 0;
+    virtual audio_unique_id_t newAudioUniqueId() = 0;
 
     virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0;
     virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index e08b5ae..abbda32 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -75,9 +75,12 @@
                                     audio_channel_mask_t channelMask,
                                     int audioSession,
                                     audio_input_flags_t flags) = 0;
-    virtual status_t startInput(audio_io_handle_t input) = 0;
-    virtual status_t stopInput(audio_io_handle_t input) = 0;
-    virtual void releaseInput(audio_io_handle_t input) = 0;
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session) = 0;
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session) = 0;
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session) = 0;
     virtual status_t initStreamVolume(audio_stream_type_t stream,
                                       int indexMin,
                                       int indexMax) = 0;
diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h
index 9eceea3..949d49e 100644
--- a/include/media/stagefright/foundation/ABase.h
+++ b/include/media/stagefright/foundation/ABase.h
@@ -22,4 +22,31 @@
     name(const name &); \
     name &operator=(const name &)
 
+/* Returns true if the size parameter is safe for new array allocation (32-bit)
+ *
+ * Example usage:
+ *
+ * if (!isSafeArraySize<uint32_t>(arraySize)) {
+ *     return BAD_VALUE;
+ * }
+ * ...
+ * uint32_t *myArray = new uint32_t[arraySize];
+ *
+ * There is a bug in gcc versions earlier than 4.8 where the new[] array allocation
+ * will overflow in the internal 32 bit heap allocation, resulting in an
+ * underallocated array. This is a security issue that allows potential overwriting
+ * of other heap data.
+ *
+ * An alternative to checking is to create a safe new array template function which
+ * either throws a std::bad_alloc exception or returns NULL/nullptr_t; NULL considered
+ * safe since normal access of NULL throws an exception.
+ *
+ * https://securityblog.redhat.com/2012/10/31/array-allocation-in-cxx/
+ */
+template <typename T, typename S>
+bool isSafeArraySize(S size) {
+    return size >= 0                            // in case S is signed, ignored if not.
+            && size <= 0xffffffff / sizeof(T);  // max-unsigned-32-bit-int / element-size.
+}
+
 #endif  // A_BASE_H_
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 80c8c5e..9e7ba88 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -214,7 +214,7 @@
     // mNotificationFramesAct is initialized in openRecord_l
 
     if (sessionId == AUDIO_SESSION_ALLOCATE) {
-        mSessionId = AudioSystem::newAudioSessionId();
+        mSessionId = AudioSystem::newAudioUniqueId();
     } else {
         mSessionId = sessionId;
     }
@@ -572,7 +572,7 @@
     }
 
 release:
-    AudioSystem::releaseInput(input);
+    AudioSystem::releaseInput(input, (audio_session_t)mSessionId);
     if (status == NO_ERROR) {
         status = NO_INIT;
     }
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index fd5824b..365a594 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -427,11 +427,11 @@
     return result;
 }
 
-int AudioSystem::newAudioSessionId()
+audio_unique_id_t AudioSystem::newAudioUniqueId()
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
-    if (af == 0) return AUDIO_SESSION_ALLOCATE;
-    return af->newAudioSessionId();
+    if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
+    return af->newAudioUniqueId();
 }
 
 void AudioSystem::acquireAudioSessionId(int audioSession, pid_t pid)
@@ -696,25 +696,28 @@
     return aps->getInput(inputSource, samplingRate, format, channelMask, sessionId, flags);
 }
 
-status_t AudioSystem::startInput(audio_io_handle_t input)
+status_t AudioSystem::startInput(audio_io_handle_t input,
+                                 audio_session_t session)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->startInput(input);
+    return aps->startInput(input, session);
 }
 
-status_t AudioSystem::stopInput(audio_io_handle_t input)
+status_t AudioSystem::stopInput(audio_io_handle_t input,
+                                audio_session_t session)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->stopInput(input);
+    return aps->stopInput(input, session);
 }
 
-void AudioSystem::releaseInput(audio_io_handle_t input)
+void AudioSystem::releaseInput(audio_io_handle_t input,
+                               audio_session_t session)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return;
-    aps->releaseInput(input);
+    aps->releaseInput(input, session);
 }
 
 status_t AudioSystem::initStreamVolume(audio_stream_type_t stream,
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index bd7ea46..5331fce 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -434,61 +434,40 @@
         return reply.readInt64();
     }
 
-    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
-                                         audio_devices_t *pDevices,
-                                         uint32_t *pSamplingRate,
-                                         audio_format_t *pFormat,
-                                         audio_channel_mask_t *pChannelMask,
-                                         uint32_t *pLatencyMs,
-                                         audio_output_flags_t flags,
-                                         const audio_offload_info_t *offloadInfo)
+    virtual status_t openOutput(audio_module_handle_t module,
+                                audio_io_handle_t *output,
+                                audio_config_t *config,
+                                audio_devices_t *devices,
+                                const String8& address,
+                                uint32_t *latencyMs,
+                                audio_output_flags_t flags)
     {
+        if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) {
+            return BAD_VALUE;
+        }
         Parcel data, reply;
-        audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
-        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
-        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
-        audio_channel_mask_t channelMask = pChannelMask != NULL ?
-                *pChannelMask : (audio_channel_mask_t)0;
-        uint32_t latency = pLatencyMs != NULL ? *pLatencyMs : 0;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(module);
-        data.writeInt32(devices);
-        data.writeInt32(samplingRate);
-        data.writeInt32(format);
-        data.writeInt32(channelMask);
-        data.writeInt32(latency);
+        data.write(config, sizeof(audio_config_t));
+        data.writeInt32(*devices);
+        data.writeString8(address);
         data.writeInt32((int32_t) flags);
-        // hasOffloadInfo
-        if (offloadInfo == NULL) {
-            data.writeInt32(0);
-        } else {
-            data.writeInt32(1);
-            data.write(offloadInfo, sizeof(audio_offload_info_t));
+        status_t status = remote()->transact(OPEN_OUTPUT, data, &reply);
+        if (status != NO_ERROR) {
+            *output = AUDIO_IO_HANDLE_NONE;
+            return status;
         }
-        remote()->transact(OPEN_OUTPUT, data, &reply);
-        audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
-        ALOGV("openOutput() returned output, %d", output);
-        devices = (audio_devices_t)reply.readInt32();
-        if (pDevices != NULL) {
-            *pDevices = devices;
+        status = (status_t)reply.readInt32();
+        if (status != NO_ERROR) {
+            *output = AUDIO_IO_HANDLE_NONE;
+            return status;
         }
-        samplingRate = reply.readInt32();
-        if (pSamplingRate != NULL) {
-            *pSamplingRate = samplingRate;
-        }
-        format = (audio_format_t) reply.readInt32();
-        if (pFormat != NULL) {
-            *pFormat = format;
-        }
-        channelMask = (audio_channel_mask_t)reply.readInt32();
-        if (pChannelMask != NULL) {
-            *pChannelMask = channelMask;
-        }
-        latency = reply.readInt32();
-        if (pLatencyMs != NULL) {
-            *pLatencyMs = latency;
-        }
-        return output;
+        *output = (audio_io_handle_t)reply.readInt32();
+        ALOGV("openOutput() returned output, %d", *output);
+        reply.read(config, sizeof(audio_config_t));
+        *devices = (audio_devices_t)reply.readInt32();
+        *latencyMs = reply.readInt32();
+        return NO_ERROR;
     }
 
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
@@ -529,46 +508,40 @@
         return reply.readInt32();
     }
 
-    virtual audio_io_handle_t openInput(audio_module_handle_t module,
-                                        audio_devices_t *pDevices,
-                                        uint32_t *pSamplingRate,
-                                        audio_format_t *pFormat,
-                                        audio_channel_mask_t *pChannelMask,
-                                        audio_input_flags_t flags)
+    virtual status_t openInput(audio_module_handle_t module,
+                               audio_io_handle_t *input,
+                               audio_config_t *config,
+                               audio_devices_t *device,
+                               const String8& address,
+                               audio_source_t source,
+                               audio_input_flags_t flags)
     {
+        if (input == NULL || config == NULL || device == NULL) {
+            return BAD_VALUE;
+        }
         Parcel data, reply;
-        audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
-        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
-        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
-        audio_channel_mask_t channelMask = pChannelMask != NULL ?
-                *pChannelMask : (audio_channel_mask_t)0;
-
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(module);
-        data.writeInt32(devices);
-        data.writeInt32(samplingRate);
-        data.writeInt32(format);
-        data.writeInt32(channelMask);
+        data.writeInt32(*input);
+        data.write(config, sizeof(audio_config_t));
+        data.writeInt32(*device);
+        data.writeString8(address);
+        data.writeInt32(source);
         data.writeInt32(flags);
-        remote()->transact(OPEN_INPUT, data, &reply);
-        audio_io_handle_t input = (audio_io_handle_t) reply.readInt32();
-        devices = (audio_devices_t)reply.readInt32();
-        if (pDevices != NULL) {
-            *pDevices = devices;
+        status_t status = remote()->transact(OPEN_INPUT, data, &reply);
+        if (status != NO_ERROR) {
+            *input = AUDIO_IO_HANDLE_NONE;
+            return status;
         }
-        samplingRate = reply.readInt32();
-        if (pSamplingRate != NULL) {
-            *pSamplingRate = samplingRate;
+        status = (status_t)reply.readInt32();
+        if (status != NO_ERROR) {
+            *input = AUDIO_IO_HANDLE_NONE;
+            return status;
         }
-        format = (audio_format_t) reply.readInt32();
-        if (pFormat != NULL) {
-            *pFormat = format;
-        }
-        channelMask = (audio_channel_mask_t)reply.readInt32();
-        if (pChannelMask != NULL) {
-            *pChannelMask = channelMask;
-        }
-        return input;
+        *input = (audio_io_handle_t)reply.readInt32();
+        reply.read(config, sizeof(audio_config_t));
+        *device = (audio_devices_t)reply.readInt32();
+        return NO_ERROR;
     }
 
     virtual status_t closeInput(int input)
@@ -631,12 +604,12 @@
         return (uint32_t) reply.readInt32();
     }
 
-    virtual int newAudioSessionId()
+    virtual audio_unique_id_t newAudioUniqueId()
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
-        int id = AUDIO_SESSION_ALLOCATE;
+        audio_unique_id_t id = AUDIO_SESSION_ALLOCATE;
         if (status == NO_ERROR) {
             id = reply.readInt32();
         }
@@ -1103,32 +1076,23 @@
         case OPEN_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
+            audio_config_t config;
+            data.read(&config, sizeof(audio_config_t));
             audio_devices_t devices = (audio_devices_t)data.readInt32();
-            uint32_t samplingRate = data.readInt32();
-            audio_format_t format = (audio_format_t) data.readInt32();
-            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
-            uint32_t latency = data.readInt32();
+            String8 address(data.readString8());
             audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
-            bool hasOffloadInfo = data.readInt32() != 0;
-            audio_offload_info_t offloadInfo;
-            if (hasOffloadInfo) {
-                data.read(&offloadInfo, sizeof(audio_offload_info_t));
-            }
-            audio_io_handle_t output = openOutput(module,
-                                                 &devices,
-                                                 &samplingRate,
-                                                 &format,
-                                                 &channelMask,
-                                                 &latency,
-                                                 flags,
-                                                 hasOffloadInfo ? &offloadInfo : NULL);
+            uint32_t latencyMs;
+            audio_io_handle_t output;
+            status_t status = openOutput(module, &output, &config,
+                                         &devices, address, &latencyMs, flags);
             ALOGV("OPEN_OUTPUT output, %d", output);
-            reply->writeInt32((int32_t) output);
-            reply->writeInt32(devices);
-            reply->writeInt32(samplingRate);
-            reply->writeInt32(format);
-            reply->writeInt32(channelMask);
-            reply->writeInt32(latency);
+            reply->writeInt32((int32_t)status);
+            if (status == NO_ERROR) {
+                reply->writeInt32((int32_t)output);
+                reply->write(&config, sizeof(audio_config_t));
+                reply->writeInt32(devices);
+                reply->writeInt32(latencyMs);
+            }
             return NO_ERROR;
         } break;
         case OPEN_DUPLICATE_OUTPUT: {
@@ -1156,23 +1120,22 @@
         case OPEN_INPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
-            audio_devices_t devices = (audio_devices_t)data.readInt32();
-            uint32_t samplingRate = data.readInt32();
-            audio_format_t format = (audio_format_t) data.readInt32();
-            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
+            audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
+            audio_config_t config;
+            data.read(&config, sizeof(audio_config_t));
+            audio_devices_t device = (audio_devices_t)data.readInt32();
+            String8 address(data.readString8());
+            audio_source_t source = (audio_source_t)data.readInt32();
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
 
-            audio_io_handle_t input = openInput(module,
-                                             &devices,
-                                             &samplingRate,
-                                             &format,
-                                             &channelMask,
-                                             flags);
-            reply->writeInt32((int32_t) input);
-            reply->writeInt32(devices);
-            reply->writeInt32(samplingRate);
-            reply->writeInt32(format);
-            reply->writeInt32(channelMask);
+            status_t status = openInput(module, &input, &config,
+                                        &device, address, source, flags);
+            reply->writeInt32((int32_t) status);
+            if (status == NO_ERROR) {
+                reply->writeInt32((int32_t) input);
+                reply->write(&config, sizeof(audio_config_t));
+                reply->writeInt32(device);
+            }
             return NO_ERROR;
         } break;
         case CLOSE_INPUT: {
@@ -1213,7 +1176,7 @@
         } break;
         case NEW_AUDIO_SESSION_ID: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(newAudioSessionId());
+            reply->writeInt32(newAudioUniqueId());
             return NO_ERROR;
         } break;
         case ACQUIRE_AUDIO_SESSION_ID: {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 40dfb58..1593b17 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -240,29 +240,35 @@
         return static_cast <audio_io_handle_t> (reply.readInt32());
     }
 
-    virtual status_t startInput(audio_io_handle_t input)
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(input);
+        data.writeInt32(session);
         remote()->transact(START_INPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
 
-    virtual status_t stopInput(audio_io_handle_t input)
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(input);
+        data.writeInt32(session);
         remote()->transact(STOP_INPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
     }
 
-    virtual void releaseInput(audio_io_handle_t input)
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(input);
+        data.writeInt32(session);
         remote()->transact(RELEASE_INPUT, data, &reply);
     }
 
@@ -723,21 +729,24 @@
         case START_INPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
-            reply->writeInt32(static_cast <uint32_t>(startInput(input)));
+            audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+            reply->writeInt32(static_cast <uint32_t>(startInput(input, session)));
             return NO_ERROR;
         } break;
 
         case STOP_INPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
-            reply->writeInt32(static_cast <uint32_t>(stopInput(input)));
+            audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+            reply->writeInt32(static_cast <uint32_t>(stopInput(input, session)));
             return NO_ERROR;
         } break;
 
         case RELEASE_INPUT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
-            releaseInput(input);
+            audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+            releaseInput(input, session);
             return NO_ERROR;
         } break;
 
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 2b7ea97..6cd377a 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -59,7 +59,7 @@
     mLeftVolume = mRightVolume = 1.0;
     mVideoWidth = mVideoHeight = 0;
     mLockThreadId = 0;
-    mAudioSessionId = AudioSystem::newAudioSessionId();
+    mAudioSessionId = AudioSystem::newAudioUniqueId();
     AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
     mSendLevel = 0;
     mRetransmitEndpointValid = false;
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index e9c5e8e..dacb144 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -62,18 +62,18 @@
 
 player_type MediaPlayerFactory::getDefaultPlayerType() {
     char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.use-nuplayer", value, NULL)
+    if (property_get("media.stagefright.use-awesome", value, NULL)
             && (!strcmp("1", value) || !strcasecmp("true", value))) {
-        return NU_PLAYER;
+        return STAGEFRIGHT_PLAYER;
     }
 
     // TODO: remove this EXPERIMENTAL developer settings property
-    if (property_get("persist.sys.media.use-nuplayer", value, NULL)
+    if (property_get("persist.sys.media.use-awesome", value, NULL)
             && !strcasecmp("true", value)) {
-        return NU_PLAYER;
+        return STAGEFRIGHT_PLAYER;
     }
 
-    return STAGEFRIGHT_PLAYER;
+    return NU_PLAYER;
 }
 
 status_t MediaPlayerFactory::registerFactory(IFactory* factory,
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 63a907c..0b09f58 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -42,6 +42,7 @@
         uid_t uid)
     : Source(notify),
       mFetchSubtitleDataGeneration(0),
+      mFetchTimedTextDataGeneration(0),
       mDurationUs(0ll),
       mAudioIsVorbis(false),
       mIsWidevine(isWidevine),
@@ -61,6 +62,7 @@
         int fd, int64_t offset, int64_t length)
     : Source(notify),
       mFetchSubtitleDataGeneration(0),
+      mFetchTimedTextDataGeneration(0),
       mDurationUs(0ll),
       mAudioIsVorbis(false) {
     DataSource::RegisterDefaultSniffers();
@@ -135,7 +137,6 @@
         }
 
         if (track != NULL) {
-            CHECK_EQ(track->start(), (status_t)OK);
             mSources.push(track);
             int64_t durationUs;
             if (meta->findInt64(kKeyDuration, &durationUs)) {
@@ -182,6 +183,7 @@
     ALOGI("start");
 
     if (mAudioTrack.mSource != NULL) {
+        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);
         mAudioTrack.mPackets =
             new AnotherPacketSource(mAudioTrack.mSource->getFormat());
 
@@ -189,6 +191,7 @@
     }
 
     if (mVideoTrack.mSource != NULL) {
+        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);
         mVideoTrack.mPackets =
             new AnotherPacketSource(mVideoTrack.mSource->getFormat());
 
@@ -204,66 +207,29 @@
     switch (msg->what()) {
       case kWhatFetchSubtitleData:
       {
-          int32_t generation;
-          CHECK(msg->findInt32("generation", &generation));
-          if (generation != mFetchSubtitleDataGeneration) {
-              // stale
-              break;
-          }
+          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
+                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
+          break;
+      }
 
-          int32_t avail;
-          if (mSubtitleTrack.mPackets->hasBufferAvailable(&avail)) {
-              break;
-          }
-
-          int64_t timeUs;
-          CHECK(msg->findInt64("timeUs", &timeUs));
-
-          int64_t subTimeUs;
-          readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, timeUs, &subTimeUs);
-
-          const int64_t oneSecUs = 1000000ll;
-          const int64_t delayUs = subTimeUs - timeUs - oneSecUs;
-          sp<AMessage> msg2 = new AMessage(kWhatSendSubtitleData, id());
-          msg2->setInt32("generation", generation);
-          msg2->post(delayUs < 0 ? 0 : delayUs);
-          ALOGV("kWhatFetchSubtitleData generation %d, delayUs %lld",
-                  mFetchSubtitleDataGeneration, delayUs);
-
+      case kWhatFetchTimedTextData:
+      {
+          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
+                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
           break;
       }
 
       case kWhatSendSubtitleData:
       {
-          int32_t generation;
-          CHECK(msg->findInt32("generation", &generation));
-          if (generation != mFetchSubtitleDataGeneration) {
-              // stale
-              break;
-          }
+          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
+                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
+          break;
+      }
 
-          int64_t subTimeUs;
-          if (mSubtitleTrack.mPackets->nextBufferTime(&subTimeUs) != OK) {
-              break;
-          }
-
-          int64_t nextSubTimeUs;
-          readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, -1, &nextSubTimeUs);
-
-          sp<ABuffer> buffer;
-          status_t dequeueStatus = mSubtitleTrack.mPackets->dequeueAccessUnit(&buffer);
-          if (dequeueStatus != OK) {
-              ALOGE("kWhatSendSubtitleData dequeueAccessUnit: %d", dequeueStatus);
-          } else {
-              sp<AMessage> notify = dupNotify();
-              notify->setInt32("what", kWhatSubtitleData);
-              notify->setBuffer("buffer", buffer);
-              notify->post();
-
-              const int64_t delayUs = nextSubTimeUs - subTimeUs;
-              msg->post(delayUs < 0 ? 0 : delayUs);
-          }
-
+      case kWhatSendTimedTextData:
+      {
+          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
+                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
           break;
       }
 
@@ -290,7 +256,11 @@
           }
 
 
+          if (track->mSource != NULL) {
+              track->mSource->stop();
+          }
           track->mSource = source;
+          track->mSource->start();
           track->mIndex = trackIndex;
 
           status_t avail;
@@ -317,6 +287,74 @@
     }
 }
 
+void NuPlayer::GenericSource::fetchTextData(
+        uint32_t sendWhat,
+        media_track_type type,
+        int32_t curGen,
+        sp<AnotherPacketSource> packets,
+        sp<AMessage> msg) {
+    int32_t msgGeneration;
+    CHECK(msg->findInt32("generation", &msgGeneration));
+    if (msgGeneration != curGen) {
+        // stale
+        return;
+    }
+
+    int32_t avail;
+    if (packets->hasBufferAvailable(&avail)) {
+        return;
+    }
+
+    int64_t timeUs;
+    CHECK(msg->findInt64("timeUs", &timeUs));
+
+    int64_t subTimeUs;
+    readBuffer(type, timeUs, &subTimeUs);
+
+    int64_t delayUs = subTimeUs - timeUs;
+    if (msg->what() == kWhatFetchSubtitleData) {
+        const int64_t oneSecUs = 1000000ll;
+        delayUs -= oneSecUs;
+    }
+    sp<AMessage> msg2 = new AMessage(sendWhat, id());
+    msg2->setInt32("generation", msgGeneration);
+    msg2->post(delayUs < 0 ? 0 : delayUs);
+}
+
+void NuPlayer::GenericSource::sendTextData(
+        uint32_t what,
+        media_track_type type,
+        int32_t curGen,
+        sp<AnotherPacketSource> packets,
+        sp<AMessage> msg) {
+    int32_t msgGeneration;
+    CHECK(msg->findInt32("generation", &msgGeneration));
+    if (msgGeneration != curGen) {
+        // stale
+        return;
+    }
+
+    int64_t subTimeUs;
+    if (packets->nextBufferTime(&subTimeUs) != OK) {
+        return;
+    }
+
+    int64_t nextSubTimeUs;
+    readBuffer(type, -1, &nextSubTimeUs);
+
+    sp<ABuffer> buffer;
+    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
+    if (dequeueStatus == OK) {
+        sp<AMessage> notify = dupNotify();
+        notify->setInt32("what", what);
+        notify->setBuffer("buffer", buffer);
+        notify->post();
+
+        const int64_t delayUs = nextSubTimeUs - subTimeUs;
+        msg->post(delayUs < 0 ? 0 : delayUs);
+    }
+}
+
 sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
     sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
 
@@ -351,27 +389,49 @@
         readBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO, -1ll);
     }
 
-    if (mSubtitleTrack.mSource == NULL) {
+    if (mSubtitleTrack.mSource == NULL && mTimedTextTrack.mSource == NULL) {
         return result;
     }
 
-    CHECK(mSubtitleTrack.mPackets != NULL);
+    if (mSubtitleTrack.mSource != NULL) {
+        CHECK(mSubtitleTrack.mPackets != NULL);
+    }
+    if (mTimedTextTrack.mSource != NULL) {
+        CHECK(mTimedTextTrack.mPackets != NULL);
+    }
+
     if (result != OK) {
-        mSubtitleTrack.mPackets->clear();
-        mFetchSubtitleDataGeneration++;
+        if (mSubtitleTrack.mSource != NULL) {
+            mSubtitleTrack.mPackets->clear();
+            mFetchSubtitleDataGeneration++;
+        }
+        if (mTimedTextTrack.mSource != NULL) {
+            mTimedTextTrack.mPackets->clear();
+            mFetchTimedTextDataGeneration++;
+        }
         return result;
     }
 
     int64_t timeUs;
     status_t eosResult; // ignored
     CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
-    if (!mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
+
+    if (mSubtitleTrack.mSource != NULL
+            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
         sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
         msg->setInt64("timeUs", timeUs);
         msg->setInt32("generation", mFetchSubtitleDataGeneration);
         msg->post();
     }
 
+    if (mTimedTextTrack.mSource != NULL
+            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
+        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
+        msg->setInt64("timeUs", timeUs);
+        msg->setInt32("generation", mFetchTimedTextDataGeneration);
+        msg->post();
+    }
+
     return result;
 }
 
@@ -430,19 +490,53 @@
     return format;
 }
 
+ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
+    const Track *track = NULL;
+    switch (type) {
+    case MEDIA_TRACK_TYPE_VIDEO:
+        track = &mVideoTrack;
+        break;
+    case MEDIA_TRACK_TYPE_AUDIO:
+        track = &mAudioTrack;
+        break;
+    case MEDIA_TRACK_TYPE_TIMEDTEXT:
+        track = &mTimedTextTrack;
+        break;
+    case MEDIA_TRACK_TYPE_SUBTITLE:
+        track = &mSubtitleTrack;
+        break;
+    default:
+        break;
+    }
+
+    if (track != NULL && track->mSource != NULL) {
+        return track->mIndex;
+    }
+
+    return -1;
+}
+
 status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
-    ALOGV("selectTrack: %zu", trackIndex);
+    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
     if (trackIndex >= mSources.size()) {
         return BAD_INDEX;
     }
 
     if (!select) {
-        if (mSubtitleTrack.mSource == NULL || trackIndex != mSubtitleTrack.mIndex) {
+        Track* track = NULL;
+        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
+            track = &mSubtitleTrack;
+            mFetchSubtitleDataGeneration++;
+        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
+            track = &mTimedTextTrack;
+            mFetchTimedTextDataGeneration++;
+        }
+        if (track == NULL) {
             return INVALID_OPERATION;
         }
-        mSubtitleTrack.mSource = NULL;
-        mSubtitleTrack.mPackets->clear();
-        mFetchSubtitleDataGeneration++;
+        track->mSource->stop();
+        track->mSource = NULL;
+        track->mPackets->clear();
         return OK;
     }
 
@@ -451,18 +545,31 @@
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
     if (!strncasecmp(mime, "text/", 5)) {
-        if (mSubtitleTrack.mSource != NULL && mSubtitleTrack.mIndex == trackIndex) {
+        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
+        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
+        if (track->mSource != NULL && track->mIndex == trackIndex) {
             return OK;
         }
-        mSubtitleTrack.mIndex = trackIndex;
-        mSubtitleTrack.mSource = mSources.itemAt(trackIndex);
-        if (mSubtitleTrack.mPackets == NULL) {
-            mSubtitleTrack.mPackets = new AnotherPacketSource(mSubtitleTrack.mSource->getFormat());
+        track->mIndex = trackIndex;
+        if (track->mSource != NULL) {
+            track->mSource->stop();
+        }
+        track->mSource = mSources.itemAt(trackIndex);
+        track->mSource->start();
+        if (track->mPackets == NULL) {
+            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
         } else {
-            mSubtitleTrack.mPackets->clear();
+            track->mPackets->clear();
+            track->mPackets->setFormat(track->mSource->getFormat());
 
         }
-        mFetchSubtitleDataGeneration++;
+
+        if (isSubtitle) {
+            mFetchSubtitleDataGeneration++;
+        } else {
+            mFetchTimedTextDataGeneration++;
+        }
+
         return OK;
     } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
         bool audio = !strncasecmp(mime, "audio/", 6);
@@ -529,12 +636,19 @@
         memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
     }
 
+    sp<AMessage> meta = ab->meta();
+
     int64_t timeUs;
     CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
-
-    sp<AMessage> meta = ab->meta();
     meta->setInt64("timeUs", timeUs);
 
+    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
+        const char *mime;
+        CHECK(mTimedTextTrack.mSource != NULL
+                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+        meta->setString("mime", mime);
+    }
+
     int64_t durationUs;
     if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
         meta->setInt64("durationUs", durationUs);
@@ -567,6 +681,9 @@
         case MEDIA_TRACK_TYPE_SUBTITLE:
             track = &mSubtitleTrack;
             break;
+        case MEDIA_TRACK_TYPE_TIMEDTEXT:
+            track = &mTimedTextTrack;
+            break;
         default:
             TRESPASS();
     }
@@ -602,7 +719,9 @@
             // formatChange && seeking: track whose source is changed during selection
             // formatChange && !seeking: track whose source is not changed during selection
             // !formatChange: normal seek
-            if ((seeking || formatChange) && trackType != MEDIA_TRACK_TYPE_SUBTITLE) {
+            if ((seeking || formatChange)
+                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
+                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
                 ATSParser::DiscontinuityType type = formatChange
                         ? (seeking
                                 ? ATSParser::DISCONTINUITY_FORMATCHANGE
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 4e25d55..3c5f55c 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -58,6 +58,7 @@
     virtual status_t getDuration(int64_t *durationUs);
     virtual size_t getTrackCount() const;
     virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
+    virtual ssize_t getSelectedTrack(media_track_type type) const;
     virtual status_t selectTrack(size_t trackIndex, bool select);
     virtual status_t seekTo(int64_t seekTimeUs);
 
@@ -73,7 +74,9 @@
 private:
     enum {
         kWhatFetchSubtitleData,
+        kWhatFetchTimedTextData,
         kWhatSendSubtitleData,
+        kWhatSendTimedTextData,
         kWhatChangeAVSource,
     };
 
@@ -88,8 +91,10 @@
     Track mAudioTrack;
     Track mVideoTrack;
     Track mSubtitleTrack;
+    Track mTimedTextTrack;
 
     int32_t mFetchSubtitleDataGeneration;
+    int32_t mFetchTimedTextDataGeneration;
     int64_t mDurationUs;
     bool mAudioIsVorbis;
     bool mIsWidevine;
@@ -98,6 +103,14 @@
 
     void initFromDataSource(const sp<DataSource> &dataSource);
 
+    void fetchTextData(
+            uint32_t what, media_track_type type,
+            int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);
+
+    void sendTextData(
+            uint32_t what, media_track_type type,
+            int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);
+
     sp<ABuffer> mediaBufferToABuffer(
             MediaBuffer *mbuf,
             media_track_type trackType,
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index bad43f2..bdd6d56 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -330,6 +330,10 @@
     }
 
     mTimeToSampleCount = U32_AT(&header[4]);
+    uint64_t allocSize = mTimeToSampleCount * 2 * sizeof(uint32_t);
+    if (allocSize > SIZE_MAX) {
+        return ERROR_OUT_OF_RANGE;
+    }
     mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
 
     size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
@@ -372,6 +376,11 @@
     }
 
     mNumCompositionTimeDeltaEntries = numEntries;
+    uint64_t allocSize = numEntries * 2 * sizeof(uint32_t);
+    if (allocSize > SIZE_MAX) {
+        return ERROR_OUT_OF_RANGE;
+    }
+
     mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
 
     if (mDataSource->readAt(
@@ -417,6 +426,11 @@
         ALOGV("Table of sync samples is empty or has only a single entry!");
     }
 
+    uint64_t allocSize = mNumSyncSamples * sizeof(uint32_t);
+    if (allocSize > SIZE_MAX) {
+        return ERROR_OUT_OF_RANGE;
+    }
+
     mSyncSamples = new uint32_t[mNumSyncSamples];
     size_t size = mNumSyncSamples * sizeof(uint32_t);
     if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f10a561..bd7121e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1097,7 +1097,7 @@
 
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
-    struct audio_config config;
+    audio_config_t config;
     memset(&config, 0, sizeof(config));
     config.sample_rate = sampleRate;
     config.channel_mask = channelMask;
@@ -1577,17 +1577,21 @@
 
 
 sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,
-                                                            audio_devices_t device,
-                                                            struct audio_config *config,
+                                                            audio_io_handle_t *output,
+                                                            audio_config_t *config,
+                                                            audio_devices_t devices,
+                                                            const String8& address,
                                                             audio_output_flags_t flags)
 {
-    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, device);
+    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
     if (outHwDev == NULL) {
-        return AUDIO_IO_HANDLE_NONE;
+        return 0;
     }
 
     audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
-    audio_io_handle_t id = nextUniqueId();
+    if (*output == AUDIO_IO_HANDLE_NONE) {
+        *output = nextUniqueId();
+    }
 
     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
 
@@ -1604,7 +1608,7 @@
             //config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
             //config->format = AUDIO_FORMAT_PCM_32_BIT;
             //config->format = AUDIO_FORMAT_PCM_8_24_BIT;
-            // ALOGV("openOutput() upgrading format to %#08x", config.format);
+            // ALOGV("openOutput_l() upgrading format to %#08x", config->format);
         }
         if (kEnableExtendedChannels) {
             // Specify channel mask (uncomment one below to choose)
@@ -1615,14 +1619,15 @@
     }
 
     status_t status = hwDevHal->open_output_stream(hwDevHal,
-                                          id,
-                                          device,
-                                          flags,
-                                          config,
-                                          &outStream);
+                                                   *output,
+                                                   devices,
+                                                   flags,
+                                                   config,
+                                                   &outStream,
+                                                   address.string());
 
     mHardwareStatus = AUDIO_HW_IDLE;
-    ALOGV("openOutput() openOutputStream returned output %p, sampleRate %d, Format %#x, "
+    ALOGV("openOutput_l() openOutputStream returned output %p, sampleRate %d, Format %#x, "
             "channelMask %#x, status %d",
             outStream,
             config->sample_rate,
@@ -1631,76 +1636,53 @@
             status);
 
     if (status == NO_ERROR && outStream != NULL) {
-        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);
+        AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags);
 
         PlaybackThread *thread;
         if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
-            thread = new OffloadThread(this, output, id, device);
-            ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);
+            thread = new OffloadThread(this, outputStream, *output, devices);
+            ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread);
         } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
                 || !isValidPcmSinkFormat(config->format)
                 || !isValidPcmSinkChannelMask(config->channel_mask)) {
-            thread = new DirectOutputThread(this, output, id, device);
-            ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
+            thread = new DirectOutputThread(this, outputStream, *output, devices);
+            ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread);
         } else {
-            thread = new MixerThread(this, output, id, device);
-            ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
+            thread = new MixerThread(this, outputStream, *output, devices);
+            ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread);
         }
-        mPlaybackThreads.add(id, thread);
+        mPlaybackThreads.add(*output, thread);
         return thread;
     }
 
     return 0;
 }
 
-audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
-                                           audio_devices_t *pDevices,
-                                           uint32_t *pSamplingRate,
-                                           audio_format_t *pFormat,
-                                           audio_channel_mask_t *pChannelMask,
-                                           uint32_t *pLatencyMs,
-                                           audio_output_flags_t flags,
-                                           const audio_offload_info_t *offloadInfo)
+status_t AudioFlinger::openOutput(audio_module_handle_t module,
+                                  audio_io_handle_t *output,
+                                  audio_config_t *config,
+                                  audio_devices_t *devices,
+                                  const String8& address,
+                                  uint32_t *latencyMs,
+                                  audio_output_flags_t flags)
 {
-    struct audio_config config;
-    memset(&config, 0, sizeof(config));
-    config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
-    config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
-    config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
-    if (offloadInfo != NULL) {
-        config.offload_info = *offloadInfo;
-    }
-
     ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",
               module,
-              (pDevices != NULL) ? *pDevices : 0,
-              config.sample_rate,
-              config.format,
-              config.channel_mask,
+              (devices != NULL) ? *devices : 0,
+              config->sample_rate,
+              config->format,
+              config->channel_mask,
               flags);
-    ALOGV("openOutput(), offloadInfo %p version 0x%04x",
-          offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version);
 
-    if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
-        return AUDIO_IO_HANDLE_NONE;
+    if (*devices == AUDIO_DEVICE_NONE) {
+        return BAD_VALUE;
     }
 
     Mutex::Autolock _l(mLock);
 
-    sp<PlaybackThread> thread = openOutput_l(module, *pDevices, &config, flags);
+    sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
     if (thread != 0) {
-        if (pSamplingRate != NULL) {
-            *pSamplingRate = config.sample_rate;
-        }
-        if (pFormat != NULL) {
-            *pFormat = config.format;
-        }
-        if (pChannelMask != NULL) {
-            *pChannelMask = config.channel_mask;
-        }
-        if (pLatencyMs != NULL) {
-            *pLatencyMs = thread->latency();
-        }
+        *latencyMs = thread->latency();
 
         // notify client processes of the new output creation
         thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED);
@@ -1715,12 +1697,12 @@
             mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode);
             mHardwareStatus = AUDIO_HW_IDLE;
 
-            mPrimaryOutputSampleRate = config.sample_rate;
+            mPrimaryOutputSampleRate = config->sample_rate;
         }
-        return thread->id();
+        return NO_ERROR;
     }
 
-    return AUDIO_IO_HANDLE_NONE;
+    return NO_INIT;
 }
 
 audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
@@ -1851,75 +1833,59 @@
     return NO_ERROR;
 }
 
-audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
-                                          audio_devices_t *pDevices,
-                                          uint32_t *pSamplingRate,
-                                          audio_format_t *pFormat,
-                                          audio_channel_mask_t *pChannelMask,
+status_t AudioFlinger::openInput(audio_module_handle_t module,
+                                          audio_io_handle_t *input,
+                                          audio_config_t *config,
+                                          audio_devices_t *device,
+                                          const String8& address,
+                                          audio_source_t source,
                                           audio_input_flags_t flags)
 {
     Mutex::Autolock _l(mLock);
 
-    if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
-        return AUDIO_IO_HANDLE_NONE;
+    if (*device == AUDIO_DEVICE_NONE) {
+        return BAD_VALUE;
     }
 
-    struct audio_config config;
-    memset(&config, 0, sizeof(config));
-    config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
-    config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
-    config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
-
-    uint32_t reqSamplingRate = config.sample_rate;
-    audio_format_t reqFormat = config.format;
-    audio_channel_mask_t reqChannelMask = config.channel_mask;
-
-    sp<RecordThread> thread = openInput_l(module, *pDevices, &config, flags);
+    sp<RecordThread> thread = openInput_l(module, input, config, *device, address, source, flags);
 
     if (thread != 0) {
-        if (pSamplingRate != NULL) {
-            *pSamplingRate = reqSamplingRate;
-        }
-        if (pFormat != NULL) {
-            *pFormat = config.format;
-        }
-        if (pChannelMask != NULL) {
-            *pChannelMask = reqChannelMask;
-        }
-
         // notify client processes of the new input creation
         thread->audioConfigChanged(AudioSystem::INPUT_OPENED);
-        return thread->id();
+        return NO_ERROR;
     }
-    return AUDIO_IO_HANDLE_NONE;
+    return NO_INIT;
 }
 
 sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t module,
+                                                         audio_io_handle_t *input,
+                                                         audio_config_t *config,
                                                          audio_devices_t device,
-                                                         struct audio_config *config,
+                                                         const String8& address,
+                                                         audio_source_t source,
                                                          audio_input_flags_t flags)
 {
-    uint32_t reqSamplingRate = config->sample_rate;
-    audio_format_t reqFormat = config->format;
-    audio_channel_mask_t reqChannelMask = config->channel_mask;
-
     AudioHwDevice *inHwDev = findSuitableHwDev_l(module, device);
     if (inHwDev == NULL) {
+        *input = AUDIO_IO_HANDLE_NONE;
         return 0;
     }
 
-    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
-    audio_io_handle_t id = nextUniqueId();
+    if (*input == AUDIO_IO_HANDLE_NONE) {
+        *input = nextUniqueId();
+    }
 
+    audio_config_t halconfig = *config;
+    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
     audio_stream_in_t *inStream = NULL;
-    status_t status = inHwHal->open_input_stream(inHwHal, id, device, config,
-                                        &inStream, flags);
-    ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %#x, Channels %x, "
-            "flags %#x, status %d",
+    status_t status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+                                        &inStream, flags, address.string(), source);
+    ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d"
+           ", Format %#x, Channels %x, flags %#x, status %d",
             inStream,
-            config->sample_rate,
-            config->format,
-            config->channel_mask,
+            halconfig.sample_rate,
+            halconfig.format,
+            halconfig.channel_mask,
             flags,
             status);
 
@@ -1927,14 +1893,15 @@
     // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
     // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
     if (status == BAD_VALUE &&
-        reqFormat == config->format && config->format == AUDIO_FORMAT_PCM_16_BIT &&
-        (config->sample_rate <= 2 * reqSamplingRate) &&
-        (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2) &&
-        (audio_channel_count_from_in_mask(reqChannelMask) <= FCC_2)) {
+            config->format == halconfig.format && halconfig.format == AUDIO_FORMAT_PCM_16_BIT &&
+        (halconfig.sample_rate <= 2 * config->sample_rate) &&
+        (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_2) &&
+        (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2)) {
         // FIXME describe the change proposed by HAL (save old values so we can log them here)
-        ALOGV("openInput() reopening with proposed sampling rate and channel mask");
+        ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
         inStream = NULL;
-        status = inHwHal->open_input_stream(inHwHal, id, device, config, &inStream, flags);
+        status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+                                            &inStream, flags, address.string(), source);
         // FIXME log this new status; HAL should not propose any further changes
     }
 
@@ -1990,25 +1957,26 @@
         }
 #endif
 
-        AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
+        AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream);
 
         // Start record thread
         // RecordThread requires both input and output device indication to forward to audio
         // pre processing modules
         sp<RecordThread> thread = new RecordThread(this,
-                                  input,
-                                  id,
+                                  inputStream,
+                                  *input,
                                   primaryOutputDevice_l(),
                                   device
 #ifdef TEE_SINK
                                   , teeSink
 #endif
                                   );
-        mRecordThreads.add(id, thread);
-        ALOGV("openInput() created record thread: ID %d thread %p", id, thread.get());
+        mRecordThreads.add(*input, thread);
+        ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
         return thread;
     }
 
+    *input = AUDIO_IO_HANDLE_NONE;
     return 0;
 }
 
@@ -2069,7 +2037,7 @@
 }
 
 
-int AudioFlinger::newAudioSessionId()
+audio_unique_id_t AudioFlinger::newAudioUniqueId()
 {
     return nextUniqueId();
 }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ab4c567..31c5a1a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -158,14 +158,13 @@
     virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format,
                                                audio_channel_mask_t channelMask) const;
 
-    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
-                                         audio_devices_t *pDevices,
-                                         uint32_t *pSamplingRate,
-                                         audio_format_t *pFormat,
-                                         audio_channel_mask_t *pChannelMask,
-                                         uint32_t *pLatencyMs,
-                                         audio_output_flags_t flags,
-                                         const audio_offload_info_t *offloadInfo);
+    virtual status_t openOutput(audio_module_handle_t module,
+                                audio_io_handle_t *output,
+                                audio_config_t *config,
+                                audio_devices_t *devices,
+                                const String8& address,
+                                uint32_t *latencyMs,
+                                audio_output_flags_t flags);
 
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
                                                   audio_io_handle_t output2);
@@ -176,12 +175,13 @@
 
     virtual status_t restoreOutput(audio_io_handle_t output);
 
-    virtual audio_io_handle_t openInput(audio_module_handle_t module,
-                                        audio_devices_t *pDevices,
-                                        uint32_t *pSamplingRate,
-                                        audio_format_t *pFormat,
-                                        audio_channel_mask_t *pChannelMask,
-                                        audio_input_flags_t flags);
+    virtual status_t openInput(audio_module_handle_t module,
+                               audio_io_handle_t *input,
+                               audio_config_t *config,
+                               audio_devices_t *device,
+                               const String8& address,
+                               audio_source_t source,
+                               audio_input_flags_t flags);
 
     virtual status_t closeInput(audio_io_handle_t input);
 
@@ -194,7 +194,7 @@
 
     virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
 
-    virtual int newAudioSessionId();
+    virtual audio_unique_id_t newAudioUniqueId();
 
     virtual void acquireAudioSessionId(int audioSession, pid_t pid);
 
@@ -331,7 +331,7 @@
     // Set kEnableExtendedChannels to true to enable greater than stereo output
     // for the MixerThread and device sink.  Number of channels allowed is
     // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS.
-    static const bool kEnableExtendedChannels = false;
+    static const bool kEnableExtendedChannels = true;
 
     // Returns true if channel mask is permitted for the PCM sink in the MixerThread
     static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
@@ -515,12 +515,17 @@
               MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
               RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
               sp<RecordThread> openInput_l(audio_module_handle_t module,
+                                           audio_io_handle_t *input,
+                                           audio_config_t *config,
                                            audio_devices_t device,
-                                           struct audio_config *config,
+                                           const String8& address,
+                                           audio_source_t source,
                                            audio_input_flags_t flags);
               sp<PlaybackThread> openOutput_l(audio_module_handle_t module,
-                                              audio_devices_t device,
-                                              struct audio_config *config,
+                                              audio_io_handle_t *output,
+                                              audio_config_t *config,
+                                              audio_devices_t devices,
+                                              const String8& address,
                                               audio_output_flags_t flags);
 
               void closeOutputFinish(sp<PlaybackThread> thread);
diff --git a/services/audioflinger/AudioMixerOps.h b/services/audioflinger/AudioMixerOps.h
index 49131f6..f7376a8 100644
--- a/services/audioflinger/AudioMixerOps.h
+++ b/services/audioflinger/AudioMixerOps.h
@@ -184,7 +184,7 @@
 template <typename TO, typename TI>
 inline void MixAccum(TO *auxaccum, TI value) {
     if (!is_same<TO, TI>::value) {
-        LOG_ALWAYS_FATAL("MixAccum type not properly specialized: %d %d\n",
+        LOG_ALWAYS_FATAL("MixAccum type not properly specialized: %zu %zu\n",
                 sizeof(TO), sizeof(TI));
     }
     *auxaccum += value;
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index e201ff8..159ab70 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -82,17 +82,17 @@
 void AudioResamplerDyn<TC, TI, TO>::InBuffer::resize(int CHANNELS, int halfNumCoefs)
 {
     // calculate desired state size
-    int stateCount = halfNumCoefs * CHANNELS * 2 * kStateSizeMultipleOfFilterLength;
+    size_t stateCount = halfNumCoefs * CHANNELS * 2 * kStateSizeMultipleOfFilterLength;
 
     // check if buffer needs resizing
     if (mState
             && stateCount == mStateCount
-            && mRingFull-mState == mStateCount-halfNumCoefs*CHANNELS) {
+            && mRingFull-mState == (ssize_t) (mStateCount-halfNumCoefs*CHANNELS)) {
         return;
     }
 
     // create new buffer
-    TI* state;
+    TI* state = NULL;
     (void)posix_memalign(reinterpret_cast<void**>(&state), 32, stateCount*sizeof(*state));
     memset(state, 0, stateCount*sizeof(*state));
 
@@ -213,7 +213,7 @@
 void AudioResamplerDyn<TC, TI, TO>::createKaiserFir(Constants &c,
         double stopBandAtten, int inSampleRate, int outSampleRate, double tbwCheat)
 {
-    TC* buf;
+    TC* buf = NULL;
     static const double atten = 0.9998;   // to avoid ripple overflow
     double fcr;
     double tbw = firKaiserTbw(c.mHalfNumCoefs, stopBandAtten);
diff --git a/services/audioflinger/AudioResamplerFirProcess.h b/services/audioflinger/AudioResamplerFirProcess.h
index d130013..efc8055 100644
--- a/services/audioflinger/AudioResamplerFirProcess.h
+++ b/services/audioflinger/AudioResamplerFirProcess.h
@@ -177,7 +177,7 @@
 template <int CHANNELS, int STRIDE, typename TFUNC, typename TC, typename TI, typename TO, typename TINTERP>
 static inline
 void ProcessBase(TO* const out,
-        int count,
+        size_t count,
         const TC* coefsP,
         const TC* coefsN,
         const TI* sP,
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index bf509e7..49422a9 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -231,14 +231,16 @@
                         goto exit;
                     }
                 } else {
-                    struct audio_config config;
-                    config.sample_rate = 0;
-                    config.channel_mask = AUDIO_CHANNEL_NONE;
-                    config.format = AUDIO_FORMAT_DEFAULT;
+                    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+                    audio_devices_t device = patch->sinks[0].ext.device.type;
+                    String8 address = String8(patch->sinks[0].ext.device.address);
+                    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
                     newPatch->mPlaybackThread = audioflinger->openOutput_l(
                                                              patch->sinks[0].ext.device.hw_module,
-                                                             patch->sinks[0].ext.device.type,
+                                                             &output,
                                                              &config,
+                                                             device,
+                                                             address,
                                                              AUDIO_OUTPUT_FLAG_NONE);
                     ALOGV("audioflinger->openOutput_l() returned %p",
                                           newPatch->mPlaybackThread.get());
@@ -249,14 +251,19 @@
                 }
                 uint32_t channelCount = newPatch->mPlaybackThread->channelCount();
                 audio_devices_t device = patch->sources[0].ext.device.type;
-                struct audio_config config;
+                String8 address = String8(patch->sources[0].ext.device.address);
+                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
                 audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
                 config.sample_rate = newPatch->mPlaybackThread->sampleRate();
                 config.channel_mask = inChannelMask;
                 config.format = newPatch->mPlaybackThread->format();
+                audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
                 newPatch->mRecordThread = audioflinger->openInput_l(src_module,
-                                                                    device,
+                                                                    &input,
                                                                     &config,
+                                                                    device,
+                                                                    address,
+                                                                    AUDIO_SOURCE_MIC,
                                                                     AUDIO_INPUT_FLAG_NONE);
                 ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
                       newPatch->mRecordThread.get(), inChannelMask);
@@ -298,14 +305,22 @@
                         status = BAD_VALUE;
                         goto exit;
                     }
-                    AudioParameter param;
-                    param.addInt(String8(AudioParameter::keyRouting),
+                    char *address;
+                    if (strcmp(patch->sources[0].ext.device.address, "") != 0) {
+                        address = audio_device_address_to_parameter(
+                                                            patch->sources[0].ext.device.type,
+                                                            patch->sources[0].ext.device.address);
+                    } else {
+                        address = (char *)calloc(1, 1);
+                    }
+                    AudioParameter param = AudioParameter(String8(address));
+                    free(address);
+                    param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING),
                                  (int)patch->sources[0].ext.device.type);
-                    param.addInt(String8(AudioParameter::keyInputSource),
-                                                         (int)patch->sinks[0].ext.mix.usecase.source);
-
+                    param.addInt(String8(AUDIO_PARAMETER_STREAM_INPUT_SOURCE),
+                                                     (int)patch->sinks[0].ext.mix.usecase.source);
                     ALOGV("createAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
-                                                                          param.toString().string());
+                                                                      param.toString().string());
                     status = thread->setParameters(param.toString());
                 }
             }
@@ -348,8 +363,17 @@
                 for (unsigned int i = 0; i < patch->num_sinks; i++) {
                     type |= patch->sinks[i].ext.device.type;
                 }
-                AudioParameter param;
-                param.addInt(String8(AudioParameter::keyRouting), (int)type);
+                char *address;
+                if (strcmp(patch->sinks[0].ext.device.address, "") != 0) {
+                    address = audio_device_address_to_parameter(
+                                                                patch->sinks[0].ext.device.type,
+                                                                patch->sinks[0].ext.device.address);
+                } else {
+                    address = (char *)calloc(1, 1);
+                }
+                AudioParameter param = AudioParameter(String8(address));
+                free(address);
+                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
                 status = thread->setParameters(param.toString());
             }
 
@@ -578,7 +602,7 @@
                     break;
                 }
                 AudioParameter param;
-                param.addInt(String8(AudioParameter::keyRouting), 0);
+                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
                 ALOGV("releaseAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
                                                                       param.toString().string());
                 status = thread->setParameters(param.toString());
@@ -605,7 +629,7 @@
                 status = thread->sendReleaseAudioPatchConfigEvent(mPatches[index]->mHalHandle);
             } else {
                 AudioParameter param;
-                param.addInt(String8(AudioParameter::keyRouting), (int)0);
+                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
                 status = thread->setParameters(param.toString());
             }
         } break;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c959b9f..2e2f533 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5297,11 +5297,13 @@
                     //       to keep mRsmpInBuffer full so resampler always has sufficient input
                     size_t framesInNeeded;
                     // FIXME only re-calculate when it changes, and optimize for common ratios
-                    double inOverOut = (double) mSampleRate / activeTrack->mSampleRate;
-                    double outOverIn = (double) activeTrack->mSampleRate / mSampleRate;
-                    framesInNeeded = ceil(framesOut * inOverOut) + 1;
+                    // Do not precompute in/out because floating point is not associative
+                    // e.g. a*b/c != a*(b/c).
+                    const double in(mSampleRate);
+                    const double out(activeTrack->mSampleRate);
+                    framesInNeeded = ceil(framesOut * in / out) + 1;
                     ALOGV("need %u frames in to produce %u out given in/out ratio of %.4g",
-                                framesInNeeded, framesOut, inOverOut);
+                                framesInNeeded, framesOut, in / out);
                     // Although we theoretically have framesIn in circular buffer, some of those are
                     // unreleased frames, and thus must be discounted for purpose of budgeting.
                     size_t unreleased = activeTrack->mRsmpInUnrel;
@@ -5309,24 +5311,24 @@
                     if (framesIn < framesInNeeded) {
                         ALOGV("not enough to resample: have %u frames in but need %u in to "
                                 "produce %u out given in/out ratio of %.4g",
-                                framesIn, framesInNeeded, framesOut, inOverOut);
-                        size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * outOverIn) : 0;
+                                framesIn, framesInNeeded, framesOut, in / out);
+                        size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * out / in) : 0;
                         LOG_ALWAYS_FATAL_IF(newFramesOut >= framesOut);
                         if (newFramesOut == 0) {
                             break;
                         }
-                        framesInNeeded = ceil(newFramesOut * inOverOut) + 1;
+                        framesInNeeded = ceil(newFramesOut * in / out) + 1;
                         ALOGV("now need %u frames in to produce %u out given out/in ratio of %.4g",
-                                framesInNeeded, newFramesOut, outOverIn);
+                                framesInNeeded, newFramesOut, out / in);
                         LOG_ALWAYS_FATAL_IF(framesIn < framesInNeeded);
                         ALOGV("success 2: have %u frames in and need %u in to produce %u out "
                               "given in/out ratio of %.4g",
-                              framesIn, framesInNeeded, newFramesOut, inOverOut);
+                              framesIn, framesInNeeded, newFramesOut, in / out);
                         framesOut = newFramesOut;
                     } else {
                         ALOGV("success 1: have %u in and need %u in to produce %u out "
                             "given in/out ratio of %.4g",
-                            framesIn, framesInNeeded, framesOut, inOverOut);
+                            framesIn, framesInNeeded, framesOut, in / out);
                     }
 
                     // reallocate mRsmpOutBuffer as needed; we will grow but never shrink
@@ -5647,7 +5649,7 @@
         status_t status = NO_ERROR;
         if (recordTrack->isExternalTrack()) {
             mLock.unlock();
-            status = AudioSystem::startInput(mId);
+            status = AudioSystem::startInput(mId, (audio_session_t)recordTrack->sessionId());
             mLock.lock();
             // FIXME should verify that recordTrack is still in mActiveTracks
             if (status != NO_ERROR) {
@@ -5682,7 +5684,7 @@
 
 startError:
     if (recordTrack->isExternalTrack()) {
-        AudioSystem::stopInput(mId);
+        AudioSystem::stopInput(mId, (audio_session_t)recordTrack->sessionId());
     }
     recordTrack->clearSyncStartEvent();
     // FIXME I wonder why we do not reset the state here?
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e81697f..48093da 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2050,7 +2050,7 @@
     if (thread != 0) {
         RecordThread *recordThread = (RecordThread *)thread.get();
         if (recordThread->stop(this) && isExternalTrack()) {
-            AudioSystem::stopInput(recordThread->id());
+            AudioSystem::stopInput(recordThread->id(), (audio_session_t)mSessionId);
         }
     }
 }
@@ -2064,9 +2064,9 @@
         if (thread != 0) {
             if (isExternalTrack()) {
                 if (mState == ACTIVE || mState == RESUMING) {
-                    AudioSystem::stopInput(thread->id());
+                    AudioSystem::stopInput(thread->id(), (audio_session_t)mSessionId);
                 }
-                AudioSystem::releaseInput(thread->id());
+                AudioSystem::releaseInput(thread->id(), (audio_session_t)mSessionId);
             }
             Mutex::Autolock _l(thread->mLock);
             RecordThread *recordThread = (RecordThread *) thread.get();
diff --git a/services/audioflinger/tests/resampler_tests.cpp b/services/audioflinger/tests/resampler_tests.cpp
index 169ce02..d6217ba 100644
--- a/services/audioflinger/tests/resampler_tests.cpp
+++ b/services/audioflinger/tests/resampler_tests.cpp
@@ -60,7 +60,7 @@
         int check = memcmp((const char*)reference + i * outputFrameSize,
                 (const char*)test + i * outputFrameSize, outputFrameSize);
         if (check) {
-            ALOGE("Failure at frame %d", i);
+            ALOGE("Failure at frame %zu", i);
             ASSERT_EQ(check, 0); /* fails */
         }
     }
diff --git a/services/audioflinger/tests/test-mixer.cpp b/services/audioflinger/tests/test-mixer.cpp
index 5a00f40..9a4fad6 100644
--- a/services/audioflinger/tests/test-mixer.cpp
+++ b/services/audioflinger/tests/test-mixer.cpp
@@ -62,7 +62,7 @@
     info.samplerate = sampleRate;
     info.channels = channels;
     info.format = SF_FORMAT_WAV | (isBufferFloat ? SF_FORMAT_FLOAT : SF_FORMAT_PCM_16);
-    printf("saving file:%s  channels:%d  samplerate:%d  frames:%d\n",
+    printf("saving file:%s  channels:%u  samplerate:%u  frames:%zu\n",
             filename, info.channels, info.samplerate, frames);
     SNDFILE *sf = sf_open(filename, SFM_WRITE, &info);
     if (sf == NULL) {
diff --git a/services/audioflinger/tests/test_utils.h b/services/audioflinger/tests/test_utils.h
index e446216..3d51cdc 100644
--- a/services/audioflinger/tests/test_utils.h
+++ b/services/audioflinger/tests/test_utils.h
@@ -120,7 +120,7 @@
         }
         if (!mInputIncr.empty()) {
             size_t provided = mInputIncr[mNextIdx++];
-            ALOGV("getNextBuffer() mValue[%d]=%u not %u",
+            ALOGV("getNextBuffer() mValue[%zu]=%zu not %zu",
                     mNextIdx-1, provided, buffer->frameCount);
             if (provided < buffer->frameCount) {
                 buffer->frameCount = provided;
@@ -129,8 +129,8 @@
                 mNextIdx = 0;
             }
         }
-        ALOGV("getNextBuffer() requested %u frames out of %u frames available"
-                " and returned %u frames\n",
+        ALOGV("getNextBuffer() requested %zu frames out of %zu frames available"
+                " and returned %zu frames",
                 requestedFrames, mNumFrames - mNextFrame, buffer->frameCount);
         mUnrel = buffer->frameCount;
         if (buffer->frameCount > 0) {
@@ -145,14 +145,14 @@
     virtual void releaseBuffer(Buffer* buffer)
     {
         if (buffer->frameCount > mUnrel) {
-            ALOGE("releaseBuffer() released %u frames but only %u available "
-                    "to release\n", buffer->frameCount, mUnrel);
+            ALOGE("releaseBuffer() released %zu frames but only %zu available "
+                    "to release", buffer->frameCount, mUnrel);
             mNextFrame += mUnrel;
             mUnrel = 0;
         } else {
 
-            ALOGV("releaseBuffer() released %u frames out of %u frames available "
-                    "to release\n", buffer->frameCount, mUnrel);
+            ALOGV("releaseBuffer() released %zu frames out of %zu frames available "
+                    "to release", buffer->frameCount, mUnrel);
             mNextFrame += buffer->frameCount;
             mUnrel -= buffer->frameCount;
         }
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp
index b5af089..c0019d1 100644
--- a/services/audiopolicy/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/AudioPolicyClientImpl.cpp
@@ -35,22 +35,20 @@
     return af->loadHwModule(name);
 }
 
-audio_io_handle_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
-                               audio_devices_t *pDevices,
-                               uint32_t *pSamplingRate,
-                               audio_format_t *pFormat,
-                               audio_channel_mask_t *pChannelMask,
-                               uint32_t *pLatencyMs,
-                               audio_output_flags_t flags,
-                               const audio_offload_info_t *offloadInfo)
+status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
+                                                           audio_io_handle_t *output,
+                                                           audio_config_t *config,
+                                                           audio_devices_t *devices,
+                                                           const String8& address,
+                                                           uint32_t *latencyMs,
+                                                           audio_output_flags_t flags)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
+        return PERMISSION_DENIED;
     }
-    return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
-                          pLatencyMs, flags, offloadInfo);
+    return af->openOutput(module, output, config, devices, address, latencyMs, flags);
 }
 
 audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput(
@@ -97,20 +95,21 @@
     return af->restoreOutput(output);
 }
 
-audio_io_handle_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
-                              audio_devices_t *pDevices,
-                              uint32_t *pSamplingRate,
-                              audio_format_t *pFormat,
-                              audio_channel_mask_t *pChannelMask,
-                              audio_input_flags_t flags)
+status_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
+                                                          audio_io_handle_t *input,
+                                                          audio_config_t *config,
+                                                          audio_devices_t *device,
+                                                          const String8& address,
+                                                          audio_source_t source,
+                                                          audio_input_flags_t flags)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
+        return PERMISSION_DENIED;
     }
 
-    return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask, flags);
+    return af->openInput(module, input, config, device, address, source, flags);
 }
 
 status_t AudioPolicyService::AudioPolicyClient::closeInput(audio_io_handle_t input)
@@ -213,4 +212,9 @@
     mAudioPolicyService->onAudioPatchListUpdate();
 }
 
+audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId()
+{
+    return AudioSystem::newAudioUniqueId();
+}
+
 }; // namespace android
diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
index 97e12cc..9639096 100644
--- a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
@@ -62,6 +62,46 @@
     return af->loadHwModule(name);
 }
 
+static audio_io_handle_t open_output(audio_module_handle_t module,
+                                    audio_devices_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    audio_format_t *pFormat,
+                                    audio_channel_mask_t *pChannelMask,
+                                    uint32_t *pLatencyMs,
+                                    audio_output_flags_t flags,
+                                    const audio_offload_info_t *offloadInfo)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return AUDIO_IO_HANDLE_NONE;
+    }
+
+    if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL ||
+            pDevices == NULL || pLatencyMs == NULL) {
+        return AUDIO_IO_HANDLE_NONE;
+    }
+    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+    config.sample_rate = *pSamplingRate;
+    config.format = *pFormat;
+    config.channel_mask = *pChannelMask;
+    if (offloadInfo != NULL) {
+        config.offload_info = *offloadInfo;
+    }
+    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+    status_t status = af->openOutput(module, &output, &config, pDevices,
+                                     String8(""), pLatencyMs, flags);
+    if (status == NO_ERROR) {
+        *pSamplingRate = config.sample_rate;
+        *pFormat = config.format;
+        *pChannelMask = config.channel_mask;
+        if (offloadInfo != NULL) {
+            *offloadInfo = config.offload_info;
+        }
+    }
+    return output;
+}
+
 // deprecated: replaced by aps_open_output_on_module()
 audio_io_handle_t aps_open_output(void *service __unused,
                                          audio_devices_t *pDevices,
@@ -71,14 +111,8 @@
                                          uint32_t *pLatencyMs,
                                          audio_output_flags_t flags)
 {
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-
-    return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
-                          pLatencyMs, flags);
+    return open_output((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
+                          pLatencyMs, flags, NULL);
 }
 
 audio_io_handle_t aps_open_output_on_module(void *service __unused,
@@ -91,12 +125,7 @@
                                                    audio_output_flags_t flags,
                                                    const audio_offload_info_t *offloadInfo)
 {
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-    return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
+    return open_output(module, pDevices, pSamplingRate, pFormat, pChannelMask,
                           pLatencyMs, flags, offloadInfo);
 }
 
@@ -144,6 +173,37 @@
     return af->restoreOutput(output);
 }
 
+static audio_io_handle_t open_input(audio_module_handle_t module,
+                                    audio_devices_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    audio_format_t *pFormat,
+                                    audio_channel_mask_t *pChannelMask)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return AUDIO_IO_HANDLE_NONE;
+    }
+
+    if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || pDevices == NULL) {
+        return AUDIO_IO_HANDLE_NONE;
+    }
+    audio_config_t config = AUDIO_CONFIG_INITIALIZER;;
+    config.sample_rate = *pSamplingRate;
+    config.format = *pFormat;
+    config.channel_mask = *pChannelMask;
+    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+    status_t status = af->openInput(module, &input, &config, pDevices,
+                                    String8(""), AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+    if (status == NO_ERROR) {
+        *pSamplingRate = config.sample_rate;
+        *pFormat = config.format;
+        *pChannelMask = config.channel_mask;
+    }
+    return input;
+}
+
+
 // deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
 audio_io_handle_t aps_open_input(void *service __unused,
                                         audio_devices_t *pDevices,
@@ -152,14 +212,7 @@
                                         audio_channel_mask_t *pChannelMask,
                                         audio_in_acoustics_t acoustics __unused)
 {
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-
-    return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
-            AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+    return  open_input((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask);
 }
 
 audio_io_handle_t aps_open_input_on_module(void *service __unused,
@@ -169,14 +222,7 @@
                                                   audio_format_t *pFormat,
                                                   audio_channel_mask_t *pChannelMask)
 {
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-
-    return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
-            AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+    return  open_input(module, pDevices, pSamplingRate, pFormat, pChannelMask);
 }
 
 int aps_close_input(void *service __unused, audio_io_handle_t input)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index d45776b..50ee803 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -112,14 +112,17 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     audio_channel_mask_t channelMask,
-                                    audio_in_acoustics_t acoustics,
+                                    audio_session_t session,
                                     audio_input_flags_t flags) = 0;
     // indicates to the audio policy manager that the input starts being used.
-    virtual status_t startInput(audio_io_handle_t input) = 0;
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session) = 0;
     // indicates to the audio policy manager that the input stops being used.
-    virtual status_t stopInput(audio_io_handle_t input) = 0;
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session) = 0;
     // releases the input.
-    virtual void releaseInput(audio_io_handle_t input) = 0;
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session) = 0;
 
     //
     // volume control functions
@@ -211,14 +214,13 @@
     // in case the audio policy manager has no specific requirements for the output being opened.
     // When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
     // The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
-    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
-                                         audio_devices_t *pDevices,
-                                         uint32_t *pSamplingRate,
-                                         audio_format_t *pFormat,
-                                         audio_channel_mask_t *pChannelMask,
-                                         uint32_t *pLatencyMs,
-                                         audio_output_flags_t flags,
-                                         const audio_offload_info_t *offloadInfo = NULL) = 0;
+    virtual status_t openOutput(audio_module_handle_t module,
+                                audio_io_handle_t *output,
+                                audio_config_t *config,
+                                audio_devices_t *devices,
+                                const String8& address,
+                                uint32_t *latencyMs,
+                                audio_output_flags_t flags) = 0;
     // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
     // a special mixer thread in the AudioFlinger.
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0;
@@ -235,12 +237,13 @@
     //
 
     // opens an audio input
-    virtual audio_io_handle_t openInput(audio_module_handle_t module,
-                                        audio_devices_t *pDevices,
-                                        uint32_t *pSamplingRate,
-                                        audio_format_t *pFormat,
-                                        audio_channel_mask_t *pChannelMask,
-                                        audio_input_flags_t flags) = 0;
+    virtual status_t openInput(audio_module_handle_t module,
+                               audio_io_handle_t *input,
+                               audio_config_t *config,
+                               audio_devices_t *device,
+                               const String8& address,
+                               audio_source_t source,
+                               audio_input_flags_t flags) = 0;
     // closes an audio input
     virtual status_t closeInput(audio_io_handle_t input) = 0;
     //
@@ -287,6 +290,8 @@
     virtual void onAudioPortListUpdate() = 0;
 
     virtual void onAudioPatchListUpdate() = 0;
+
+    virtual audio_unique_id_t newAudioUniqueId() = 0;
 };
 
 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 4a55bec..75745b3 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -232,8 +232,8 @@
     Mutex::Autolock _l(mLock);
     // the audio_in_acoustics_t parameter is ignored by get_input()
     audio_io_handle_t input = mAudioPolicyManager->getInput(inputSource, samplingRate,
-                                                   format, channelMask, (audio_in_acoustics_t) 0,
-                                                   flags);
+                                                   format, channelMask,
+                                                   (audio_session_t)audioSession, flags);
 
     if (input == 0) {
         return input;
@@ -248,33 +248,36 @@
     return input;
 }
 
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+                                        audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mAudioPolicyManager->startInput(input);
+    return mAudioPolicyManager->startInput(input, session);
 }
 
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+                                       audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mAudioPolicyManager->stopInput(input);
+    return mAudioPolicyManager->stopInput(input, session);
 }
 
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return;
     }
     Mutex::Autolock _l(mLock);
-    mAudioPolicyManager->releaseInput(input);
+    mAudioPolicyManager->releaseInput(input, session);
 
     // release audio processors from the input
     status_t status = mAudioPolicyEffects->releaseInputEffects(input);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 5ef02e5..aa46ace 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -235,7 +235,8 @@
     return input;
 }
 
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+                                        audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
@@ -245,7 +246,8 @@
     return mpAudioPolicy->start_input(mpAudioPolicy, input);
 }
 
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+                                       audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
@@ -255,7 +257,8 @@
     return mpAudioPolicy->stop_input(mpAudioPolicy, input);
 }
 
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 603c44b..65d52d0 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -86,6 +86,7 @@
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
@@ -687,8 +688,9 @@
         audio_output_flags_t flags,
         const audio_offload_info_t *offloadInfo)
 {
-    audio_io_handle_t output = 0;
+    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
     uint32_t latency = 0;
+    status_t status;
 
 #ifdef AUDIO_POLICY_TEST
     if (mCurOutput != 0) {
@@ -699,21 +701,26 @@
             ALOGV("getOutput() opening test output");
             sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
             outputDesc->mDevice = mTestDevice;
-            outputDesc->mSamplingRate = mTestSamplingRate;
-            outputDesc->mFormat = mTestFormat;
-            outputDesc->mChannelMask = mTestChannels;
             outputDesc->mLatency = mTestLatencyMs;
             outputDesc->mFlags =
                     (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
             outputDesc->mRefCount[stream] = 0;
-            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
-                                            &outputDesc->mSamplingRate,
-                                            &outputDesc->mFormat,
-                                            &outputDesc->mChannelMask,
-                                            &outputDesc->mLatency,
-                                            outputDesc->mFlags,
-                                            offloadInfo);
-            if (mTestOutputs[mCurOutput]) {
+            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+            config.sample_rate = mTestSamplingRate;
+            config.channel_mask = mTestChannels;
+            config.format = mTestFormat;
+            config.offload_info = *offloadInfo;
+            status = mpClientInterface->openOutput(0,
+                                                  &mTestOutputs[mCurOutput],
+                                                  &config,
+                                                  &outputDesc->mDevice,
+                                                  String8(""),
+                                                  &outputDesc->mLatency,
+                                                  outputDesc->mFlags);
+            if (status == NO_ERROR) {
+                outputDesc->mSamplingRate = config.sample_rate;
+                outputDesc->mFormat = config.format;
+                outputDesc->mChannelMask = config.channel_mask;
                 AudioParameter outputCmd = AudioParameter();
                 outputCmd.addInt(String8("set_id"),mCurOutput);
                 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
@@ -771,37 +778,42 @@
         }
         outputDesc = new AudioOutputDescriptor(profile);
         outputDesc->mDevice = device;
-        outputDesc->mSamplingRate = samplingRate;
-        outputDesc->mFormat = format;
-        outputDesc->mChannelMask = channelMask;
         outputDesc->mLatency = 0;
         outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
-        outputDesc->mRefCount[stream] = 0;
-        outputDesc->mStopTime[stream] = 0;
-        outputDesc->mDirectOpenCount = 1;
-        output = mpClientInterface->openOutput(profile->mModule->mHandle,
-                                        &outputDesc->mDevice,
-                                        &outputDesc->mSamplingRate,
-                                        &outputDesc->mFormat,
-                                        &outputDesc->mChannelMask,
-                                        &outputDesc->mLatency,
-                                        outputDesc->mFlags,
-                                        offloadInfo);
+        audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+        config.sample_rate = samplingRate;
+        config.channel_mask = channelMask;
+        config.format = format;
+        config.offload_info = *offloadInfo;
+        status = mpClientInterface->openOutput(profile->mModule->mHandle,
+                                               &output,
+                                               &config,
+                                               &outputDesc->mDevice,
+                                               String8(""),
+                                               &outputDesc->mLatency,
+                                               outputDesc->mFlags);
 
         // only accept an output with the requested parameters
-        if (output == 0 ||
-            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
-            (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) ||
-            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
+        if (status != NO_ERROR ||
+            (samplingRate != 0 && samplingRate != config.sample_rate) ||
+            (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
+            (channelMask != 0 && channelMask != config.channel_mask)) {
             ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
                     "format %d %d, channelMask %04x %04x", output, samplingRate,
                     outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
                     outputDesc->mChannelMask);
-            if (output != 0) {
+            if (output != AUDIO_IO_HANDLE_NONE) {
                 mpClientInterface->closeOutput(output);
             }
-            return 0;
+            return AUDIO_IO_HANDLE_NONE;
         }
+        outputDesc->mSamplingRate = config.sample_rate;
+        outputDesc->mChannelMask = config.channel_mask;
+        outputDesc->mFormat = config.format;
+        outputDesc->mRefCount[stream] = 0;
+        outputDesc->mStopTime[stream] = 0;
+        outputDesc->mDirectOpenCount = 1;
+
         audio_io_handle_t srcOutput = getOutputForEffect();
         addOutput(output, outputDesc);
         audio_io_handle_t dstOutput = getOutputForEffect();
@@ -1052,18 +1064,18 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     audio_channel_mask_t channelMask,
-                                    audio_in_acoustics_t acoustics,
+                                    audio_session_t session,
                                     audio_input_flags_t flags)
 {
-    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x, "
+    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
           "flags %#x",
-          inputSource, samplingRate, format, channelMask, acoustics, flags);
+          inputSource, samplingRate, format, channelMask, session, flags);
 
     audio_devices_t device = getDeviceForInputSource(inputSource);
 
     if (device == AUDIO_DEVICE_NONE) {
         ALOGW("getInput() could not find device for inputSource %d", inputSource);
-        return 0;
+        return AUDIO_IO_HANDLE_NONE;
     }
 
     // adapt channel selection to input source
@@ -1090,49 +1102,57 @@
         ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, "
                 "channelMask 0x%X, flags %#x",
                 device, samplingRate, format, channelMask, flags);
-        return 0;
+        return AUDIO_IO_HANDLE_NONE;
     }
 
     if (profile->mModule->mHandle == 0) {
         ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
-        return 0;
+        return AUDIO_IO_HANDLE_NONE;
+    }
+
+    audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+    config.sample_rate = samplingRate;
+    config.channel_mask = channelMask;
+    config.format = format;
+    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+    status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+                                                   &input,
+                                                   &config,
+                                                   &device,
+                                                   String8(""),
+                                                   inputSource,
+                                                   flags);
+
+    // only accept input with the exact requested set of parameters
+    if (status != NO_ERROR ||
+        (samplingRate != config.sample_rate) ||
+        (format != config.format) ||
+        (channelMask != config.channel_mask)) {
+        ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
+                samplingRate, format, channelMask);
+        if (input != AUDIO_IO_HANDLE_NONE) {
+            mpClientInterface->closeInput(input);
+        }
+        return AUDIO_IO_HANDLE_NONE;
     }
 
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
-
     inputDesc->mInputSource = inputSource;
-    inputDesc->mDevice = device;
+    inputDesc->mRefCount = 0;
+    inputDesc->mOpenRefCount = 1;
     inputDesc->mSamplingRate = samplingRate;
     inputDesc->mFormat = format;
     inputDesc->mChannelMask = channelMask;
-    inputDesc->mRefCount = 0;
-    inputDesc->mOpenRefCount = 1;
+    inputDesc->mDevice = device;
+    inputDesc->mSessions.add(session);
 
-    audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
-                                    &inputDesc->mDevice,
-                                    &inputDesc->mSamplingRate,
-                                    &inputDesc->mFormat,
-                                    &inputDesc->mChannelMask,
-                                    flags);
-
-    // only accept input with the exact requested set of parameters
-    if (input == 0 ||
-        (samplingRate != inputDesc->mSamplingRate) ||
-        (format != inputDesc->mFormat) ||
-        (channelMask != inputDesc->mChannelMask)) {
-        ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
-                samplingRate, format, channelMask);
-        if (input != 0) {
-            mpClientInterface->closeInput(input);
-        }
-        return 0;
-    }
     addInput(input, inputDesc);
     mpClientInterface->onAudioPortListUpdate();
     return input;
 }
 
-status_t AudioPolicyManager::startInput(audio_io_handle_t input)
+status_t AudioPolicyManager::startInput(audio_io_handle_t input,
+                                        audio_session_t session)
 {
     ALOGV("startInput() input %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1142,6 +1162,12 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("startInput() unknown session %d on input %d", session, input);
+        return BAD_VALUE;
+    }
+
     // virtual input devices are compatible with other input devices
     if (!isVirtualInputDevice(inputDesc->mDevice)) {
 
@@ -1154,8 +1180,8 @@
             sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
             if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
                 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
-                stopInput(activeInput);
-                releaseInput(activeInput);
+                stopInput(activeInput, activeDesc->mSessions.itemAt(0));
+                releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
             } else {
                 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
                 return INVALID_OPERATION;
@@ -1180,7 +1206,8 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::stopInput(audio_io_handle_t input)
+status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
+                                       audio_session_t session)
 {
     ALOGV("stopInput() input %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1190,6 +1217,12 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("stopInput() unknown session %d on input %d", session, input);
+        return BAD_VALUE;
+    }
+
     if (inputDesc->mRefCount == 0) {
         ALOGW("stopInput() input %d already stopped", input);
         return INVALID_OPERATION;
@@ -1209,7 +1242,8 @@
     return NO_ERROR;
 }
 
-void AudioPolicyManager::releaseInput(audio_io_handle_t input)
+void AudioPolicyManager::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session)
 {
     ALOGV("releaseInput() %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1219,6 +1253,13 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
     ALOG_ASSERT(inputDesc != 0);
+
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("releaseInput() unknown session %d on input %d", session, input);
+        return;
+    }
+    inputDesc->mSessions.remove(session);
     if (inputDesc->mOpenRefCount == 0) {
         ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
         return;
@@ -2318,19 +2359,28 @@
                 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
 
                 outputDesc->mDevice = profileType;
-                audio_io_handle_t output = mpClientInterface->openOutput(
-                                                outProfile->mModule->mHandle,
-                                                &outputDesc->mDevice,
-                                                &outputDesc->mSamplingRate,
-                                                &outputDesc->mFormat,
-                                                &outputDesc->mChannelMask,
-                                                &outputDesc->mLatency,
-                                                outputDesc->mFlags);
-                if (output == 0) {
+                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+                config.sample_rate = outputDesc->mSamplingRate;
+                config.channel_mask = outputDesc->mChannelMask;
+                config.format = outputDesc->mFormat;
+                audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+                status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
+                                                                &output,
+                                                                &config,
+                                                                &outputDesc->mDevice,
+                                                                String8(""),
+                                                                &outputDesc->mLatency,
+                                                                outputDesc->mFlags);
+
+                if (status != NO_ERROR) {
                     ALOGW("Cannot open output stream for device %08x on hw module %s",
                           outputDesc->mDevice,
                           mHwModules[i]->mName);
                 } else {
+                    outputDesc->mSamplingRate = config.sample_rate;
+                    outputDesc->mChannelMask = config.channel_mask;
+                    outputDesc->mFormat = config.format;
+
                     for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {
                         audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
                         ssize_t index =
@@ -2369,15 +2419,21 @@
 
                 inputDesc->mInputSource = AUDIO_SOURCE_MIC;
                 inputDesc->mDevice = profileType;
-                audio_io_handle_t input = mpClientInterface->openInput(
-                                                    inProfile->mModule->mHandle,
-                                                    &inputDesc->mDevice,
-                                                    &inputDesc->mSamplingRate,
-                                                    &inputDesc->mFormat,
-                                                    &inputDesc->mChannelMask,
-                                                    AUDIO_INPUT_FLAG_NONE /*FIXME*/);
 
-                if (input != 0) {
+                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+                config.sample_rate = inputDesc->mSamplingRate;
+                config.channel_mask = inputDesc->mChannelMask;
+                config.format = inputDesc->mFormat;
+                audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+                status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,
+                                                               &input,
+                                                               &config,
+                                                               &inputDesc->mDevice,
+                                                               String8(""),
+                                                               AUDIO_SOURCE_MIC,
+                                                               AUDIO_INPUT_FLAG_NONE);
+
+                if (status == NO_ERROR) {
                     for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {
                         audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;
                         ssize_t index =
@@ -2576,17 +2632,25 @@
 
                 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
                 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
-                mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
-                                                &outputDesc->mDevice,
-                                                &outputDesc->mSamplingRate,
-                                                &outputDesc->mFormat,
-                                                &outputDesc->mChannelMask,
-                                                &outputDesc->mLatency,
-                                                outputDesc->mFlags);
-                if (mPrimaryOutput == 0) {
-                    ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
-                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
+                audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+                config.sample_rate = outputDesc->mSamplingRate;
+                config.channel_mask = outputDesc->mChannelMask;
+                config.format = outputDesc->mFormat;
+                status_t status = mpClientInterface->openOutput(moduleHandle,
+                                                                &mPrimaryOutput,
+                                                                &config,
+                                                                &outputDesc->mDevice,
+                                                                String8(""),
+                                                                &outputDesc->mLatency,
+                                                                outputDesc->mFlags);
+                if (status != NO_ERROR) {
+                    ALOGE("Failed to reopen hardware output stream, "
+                        "samplingRate: %d, format %d, channels %d",
+                        outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
                 } else {
+                    outputDesc->mSamplingRate = config.sample_rate;
+                    outputDesc->mChannelMask = config.channel_mask;
+                    outputDesc->mFormat = config.format;
                     AudioParameter outputCmd = AudioParameter();
                     outputCmd.addInt(String8("set_id"), 0);
                     mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
@@ -2638,16 +2702,6 @@
     nextAudioPortGeneration();
 }
 
-String8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address)
-{
-    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
-        return String8("a2dp_sink_address=")+address;
-    } else if (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
-        return String8("mix=")+address;
-    }
-    return address;
-}
-
 void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
         const String8 address /*in*/,
         SortedVector<audio_io_handle_t>& outputs /*out*/) {
@@ -2740,23 +2794,31 @@
                                                       device, address.string(), profile.get());
             desc = new AudioOutputDescriptor(profile);
             desc->mDevice = device;
-            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
-            offloadInfo.sample_rate = desc->mSamplingRate;
-            offloadInfo.format = desc->mFormat;
-            offloadInfo.channel_mask = desc->mChannelMask;
+            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+            config.sample_rate = desc->mSamplingRate;
+            config.channel_mask = desc->mChannelMask;
+            config.format = desc->mFormat;
+            config.offload_info.sample_rate = desc->mSamplingRate;
+            config.offload_info.channel_mask = desc->mChannelMask;
+            config.offload_info.format = desc->mFormat;
+            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+            status_t status = mpClientInterface->openOutput(profile->mModule->mHandle,
+                                                            &output,
+                                                            &config,
+                                                            &desc->mDevice,
+                                                            address,
+                                                            &desc->mLatency,
+                                                            desc->mFlags);
+            if (status == NO_ERROR) {
+                desc->mSamplingRate = config.sample_rate;
+                desc->mChannelMask = config.channel_mask;
+                desc->mFormat = config.format;
 
-            audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle,
-                                                                       &desc->mDevice,
-                                                                       &desc->mSamplingRate,
-                                                                       &desc->mFormat,
-                                                                       &desc->mChannelMask,
-                                                                       &desc->mLatency,
-                                                                       desc->mFlags,
-                                                                       &offloadInfo);
-            if (output != 0) {
                 // Here is where the out_set_parameters() for card & device gets called
                 if (!address.isEmpty()) {
-                    mpClientInterface->setParameters(output, addressToParameter(device, address));
+                    char *param = audio_device_address_to_parameter(device, address);
+                    mpClientInterface->setParameters(output, String8(param));
+                    free(param);
                 }
 
                 // Here is where we step through and resolve any "dynamic" fields
@@ -2800,31 +2862,36 @@
                          (profile->mChannelMasks.size() < 2))) {
                     ALOGW("checkOutputsForDevice() missing param");
                     mpClientInterface->closeOutput(output);
-                    output = 0;
+                    output = AUDIO_IO_HANDLE_NONE;
                 } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 ||
                             profile->mChannelMasks[0] == 0) {
                     mpClientInterface->closeOutput(output);
-                    desc->mSamplingRate = profile->pickSamplingRate();
-                    desc->mFormat = profile->pickFormat();
-                    desc->mChannelMask = profile->pickChannelMask();
-                    offloadInfo.sample_rate = desc->mSamplingRate;
-                    offloadInfo.format = desc->mFormat;
-                    offloadInfo.channel_mask = desc->mChannelMask;
-                    output = mpClientInterface->openOutput(
-                                                    profile->mModule->mHandle,
-                                                    &desc->mDevice,
-                                                    &desc->mSamplingRate,
-                                                    &desc->mFormat,
-                                                    &desc->mChannelMask,
-                                                    &desc->mLatency,
-                                                    desc->mFlags,
-                                                    &offloadInfo);
+                    config.sample_rate = profile->pickSamplingRate();
+                    config.channel_mask = profile->pickChannelMask();
+                    config.format = profile->pickFormat();
+                    config.offload_info.sample_rate = config.sample_rate;
+                    config.offload_info.channel_mask = config.channel_mask;
+                    config.offload_info.format = config.format;
+                    status = mpClientInterface->openOutput(profile->mModule->mHandle,
+                                                           &output,
+                                                           &config,
+                                                           &desc->mDevice,
+                                                           address,
+                                                           &desc->mLatency,
+                                                           desc->mFlags);
+                    if (status == NO_ERROR) {
+                        desc->mSamplingRate = config.sample_rate;
+                        desc->mChannelMask = config.channel_mask;
+                        desc->mFormat = config.format;
+                    } else {
+                        output = AUDIO_IO_HANDLE_NONE;
+                    }
                 }
 
-                if (output != 0) {
+                if (output != AUDIO_IO_HANDLE_NONE) {
                     addOutput(output, desc);
                     if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
-                        audio_io_handle_t duplicatedOutput = 0;
+                        audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
 
                         // set initial stream volume for device
                         applyStreamVolumes(output, device, 0, true);
@@ -2834,9 +2901,10 @@
                         // open a duplicating output thread for the new output and the primary output
                         duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
                                                                                   mPrimaryOutput);
-                        if (duplicatedOutput != 0) {
+                        if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
                             // add duplicated output descriptor
-                            sp<AudioOutputDescriptor> dupOutputDesc = new AudioOutputDescriptor(NULL);
+                            sp<AudioOutputDescriptor> dupOutputDesc =
+                                    new AudioOutputDescriptor(NULL);
                             dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
                             dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
                             dupOutputDesc->mSamplingRate = desc->mSamplingRate;
@@ -2851,12 +2919,14 @@
                             mpClientInterface->closeOutput(output);
                             mOutputs.removeItem(output);
                             nextAudioPortGeneration();
-                            output = 0;
+                            output = AUDIO_IO_HANDLE_NONE;
                         }
                     }
                 }
+            } else {
+                output = AUDIO_IO_HANDLE_NONE;
             }
-            if (output == 0) {
+            if (output == AUDIO_IO_HANDLE_NONE) {
                 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
                 profiles.removeAt(profile_index);
                 profile_index--;
@@ -2985,17 +3055,28 @@
             ALOGV("opening input for device 0x%X with params %s", device, address.string());
             desc = new AudioInputDescriptor(profile);
             desc->mDevice = device;
+            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+            config.sample_rate = desc->mSamplingRate;
+            config.channel_mask = desc->mChannelMask;
+            config.format = desc->mFormat;
+            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+            status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+                                                           &input,
+                                                           &config,
+                                                           &desc->mDevice,
+                                                           address,
+                                                           AUDIO_SOURCE_MIC,
+                                                           AUDIO_INPUT_FLAG_NONE /*FIXME*/);
 
-            audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
-                                            &desc->mDevice,
-                                            &desc->mSamplingRate,
-                                            &desc->mFormat,
-                                            &desc->mChannelMask,
-                                            AUDIO_INPUT_FLAG_NONE /*FIXME*/);
+            if (status == NO_ERROR) {
+                desc->mSamplingRate = config.sample_rate;
+                desc->mChannelMask = config.channel_mask;
+                desc->mFormat = config.format;
 
-            if (input != 0) {
                 if (!address.isEmpty()) {
-                    mpClientInterface->setParameters(input, addressToParameter(device, address));
+                    char *param = audio_device_address_to_parameter(device, address);
+                    mpClientInterface->setParameters(input, String8(param));
+                    free(param);
                 }
 
                 // Here is where we step through and resolve any "dynamic" fields
@@ -3035,7 +3116,7 @@
                      ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
                     ALOGW("checkInputsForDevice() direct input missing param");
                     mpClientInterface->closeInput(input);
-                    input = 0;
+                    input = AUDIO_IO_HANDLE_NONE;
                 }
 
                 if (input != 0) {
@@ -3043,7 +3124,7 @@
                 }
             } // endif input != 0
 
-            if (input == 0) {
+            if (input == AUDIO_IO_HANDLE_NONE) {
                 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
                 profiles.removeAt(profile_index);
                 profile_index--;
@@ -5495,12 +5576,14 @@
     return channelMask;
 }
 
+/* format in order of increasing preference */
 const audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = {
         AUDIO_FORMAT_DEFAULT,
         AUDIO_FORMAT_PCM_16_BIT,
         AUDIO_FORMAT_PCM_8_24_BIT,
         AUDIO_FORMAT_PCM_24_BIT_PACKED,
         AUDIO_FORMAT_PCM_32_BIT,
+        AUDIO_FORMAT_PCM_FLOAT,
 };
 
 int AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1,
@@ -5542,7 +5625,9 @@
     }
 
     audio_format_t format = AUDIO_FORMAT_DEFAULT;
-    audio_format_t bestFormat = BEST_MIXER_FORMAT;
+    audio_format_t bestFormat =
+            AudioPolicyManager::AudioPort::sPcmFormatCompareTable[
+                ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1];
     // For mixed output and inputs, use best mixer output format. Do not
     // limit format otherwise
     if ((mType != AUDIO_PORT_TYPE_MIX) ||
@@ -5622,7 +5707,7 @@
             if (i == 0 && strcmp(formatStr, "") == 0) {
                 snprintf(buffer, SIZE, "Dynamic");
             } else {
-                snprintf(buffer, SIZE, "%-48s", formatStr);
+                snprintf(buffer, SIZE, "%s", formatStr);
             }
             result.append(buffer);
             result.append(i == (mFormats.size() - 1) ? "" : ", ");
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 62b3ce5..e28a362 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -53,10 +53,7 @@
 #define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
 
 #define MAX_MIXER_SAMPLING_RATE 48000
-#define MAX_MIXER_CHANNEL_COUNT 2
-// See AudioPort::compareFormats()
-#define WORST_MIXER_FORMAT AUDIO_FORMAT_PCM_16_BIT
-#define BEST_MIXER_FORMAT AUDIO_FORMAT_PCM_24_BIT_PACKED
+#define MAX_MIXER_CHANNEL_COUNT 8
 
 // ----------------------------------------------------------------------------
 // AudioPolicyManager implements audio policy manager behavior common to all platforms.
@@ -107,15 +104,18 @@
                                             uint32_t samplingRate,
                                             audio_format_t format,
                                             audio_channel_mask_t channelMask,
-                                            audio_in_acoustics_t acoustics,
+                                            audio_session_t session,
                                             audio_input_flags_t flags);
 
         // indicates to the audio policy manager that the input starts being used.
-        virtual status_t startInput(audio_io_handle_t input);
+        virtual status_t startInput(audio_io_handle_t input,
+                                    audio_session_t session);
 
         // indicates to the audio policy manager that the input stops being used.
-        virtual status_t stopInput(audio_io_handle_t input);
-        virtual void releaseInput(audio_io_handle_t input);
+        virtual status_t stopInput(audio_io_handle_t input,
+                                   audio_session_t session);
+        virtual void releaseInput(audio_io_handle_t input,
+                                  audio_session_t session);
         virtual void closeAllInputs();
         virtual void initStreamVolume(audio_stream_type_t stream,
                                                     int indexMin,
@@ -485,6 +485,7 @@
             uint32_t mOpenRefCount;
             audio_source_t mInputSource;                // input source selected by application (mediarecorder.h)
             const sp<IOProfile> mProfile;                  // I/O profile this output derives from
+            SortedVector<audio_session_t> mSessions;  // audio sessions attached to this input
 
             virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const;
@@ -802,8 +803,6 @@
         uint32_t nextUniqueId();
         uint32_t nextAudioPortGeneration();
         uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
-        // converts device address to string sent to audio HAL via setParameters
-        static String8 addressToParameter(audio_devices_t device, const String8 address);
         // internal method to return the output handle for the given device and format
         audio_io_handle_t getOutputForDevice(
                 audio_devices_t device,
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index 08942ee..97236e3 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -91,9 +91,12 @@
                                     audio_channel_mask_t channelMask,
                                     int audioSession,
                                     audio_input_flags_t flags);
-    virtual status_t startInput(audio_io_handle_t input);
-    virtual status_t stopInput(audio_io_handle_t input);
-    virtual void releaseInput(audio_io_handle_t input);
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session);
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session);
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session);
     virtual status_t initStreamVolume(audio_stream_type_t stream,
                                       int indexMin,
                                       int indexMax);
@@ -361,14 +364,13 @@
         // in case the audio policy manager has no specific requirements for the output being opened.
         // When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
         // The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
-        virtual audio_io_handle_t openOutput(audio_module_handle_t module,
-                                             audio_devices_t *pDevices,
-                                             uint32_t *pSamplingRate,
-                                             audio_format_t *pFormat,
-                                             audio_channel_mask_t *pChannelMask,
-                                             uint32_t *pLatencyMs,
-                                             audio_output_flags_t flags,
-                                             const audio_offload_info_t *offloadInfo = NULL);
+        virtual status_t openOutput(audio_module_handle_t module,
+                                    audio_io_handle_t *output,
+                                    audio_config_t *config,
+                                    audio_devices_t *devices,
+                                    const String8& address,
+                                    uint32_t *latencyMs,
+                                    audio_output_flags_t flags);
         // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
         // a special mixer thread in the AudioFlinger.
         virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2);
@@ -386,10 +388,11 @@
 
         // opens an audio input
         virtual audio_io_handle_t openInput(audio_module_handle_t module,
-                                            audio_devices_t *pDevices,
-                                            uint32_t *pSamplingRate,
-                                            audio_format_t *pFormat,
-                                            audio_channel_mask_t *pChannelMask,
+                                            audio_io_handle_t *input,
+                                            audio_config_t *config,
+                                            audio_devices_t *devices,
+                                            const String8& address,
+                                            audio_source_t source,
                                             audio_input_flags_t flags);
         // closes an audio input
         virtual status_t closeInput(audio_io_handle_t input);
@@ -437,6 +440,8 @@
         virtual void onAudioPortListUpdate();
         virtual void onAudioPatchListUpdate();
 
+        virtual audio_unique_id_t newAudioUniqueId();
+
      private:
         AudioPolicyService *mAudioPolicyService;
     };
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 648e82c..7766b90 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -235,7 +235,8 @@
     }
 
     struct camera_info info;
-    status_t rc = mModule->get_camera_info(cameraId, &info);
+    status_t rc = filterGetInfoErrorCode(
+        mModule->get_camera_info(cameraId, &info));
     cameraInfo->facing = info.facing;
     cameraInfo->orientation = info.orientation;
     return rc;
@@ -367,7 +368,7 @@
          * Normal HAL 2.1+ codepath.
          */
         struct camera_info info;
-        ret = mModule->get_camera_info(cameraId, &info);
+        ret = filterGetInfoErrorCode(mModule->get_camera_info(cameraId, &info));
         *cameraInfo = info.static_camera_characteristics;
     }
 
@@ -404,23 +405,28 @@
     return deviceVersion;
 }
 
-bool CameraService::isValidCameraId(int cameraId) {
-    int facing;
-    int deviceVersion = getDeviceVersion(cameraId, &facing);
-
-    switch(deviceVersion) {
-      case CAMERA_DEVICE_API_VERSION_1_0:
-      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:
-        return true;
-      default:
-        return false;
+status_t CameraService::filterOpenErrorCode(status_t err) {
+    switch(err) {
+        case NO_ERROR:
+        case -EBUSY:
+        case -EINVAL:
+        case -EUSERS:
+            return err;
+        default:
+            break;
     }
+    return -ENODEV;
+}
 
-    return false;
+status_t CameraService::filterGetInfoErrorCode(status_t err) {
+    switch(err) {
+        case NO_ERROR:
+        case -EINVAL:
+            return err;
+        default:
+            break;
+    }
+    return -ENODEV;
 }
 
 bool CameraService::setUpVendorTags() {
@@ -665,14 +671,6 @@
     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);
-    }
-
     if (halVersion < 0 || halVersion == deviceVersion) {
         // Default path: HAL version is unspecified by caller, create CameraClient
         // based on device version reported by the HAL.
@@ -719,8 +717,6 @@
     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;
     }
 
@@ -970,14 +966,6 @@
         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:
             ALOGW("Camera using old HAL version: %d", deviceVersion);
@@ -1002,8 +990,6 @@
         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;
         }
 
@@ -1427,13 +1413,15 @@
 void CameraService::BasicClient::disconnect() {
     ALOGV("BasicClient::disconnect");
     mCameraService->removeClientByRemote(mRemoteBinder);
+
+    finishCameraOps();
     // client shouldn't be able to call into us anymore
     mClientPid = 0;
 }
 
 status_t CameraService::BasicClient::startCameraOps() {
     int32_t res;
-
+    // Notify app ops that the camera is not available
     mOpsCallback = new OpsCallback(this);
 
     {
@@ -1451,16 +1439,39 @@
                 mCameraId, String8(mClientPackageName).string());
         return PERMISSION_DENIED;
     }
+
     mOpsActive = true;
+
+    // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
+    mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
+            mCameraId);
+
     return OK;
 }
 
 status_t CameraService::BasicClient::finishCameraOps() {
+    // Check if startCameraOps succeeded, and if so, finish the camera op
     if (mOpsActive) {
+        // Notify app ops that the camera is available again
         mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
                 mClientPackageName);
         mOpsActive = false;
+
+        // Notify device availability listeners that this camera is available
+        // again
+
+        StatusVector rejectSourceStates;
+        rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
+        rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
+
+        // Transition to PRESENT if the camera is not in either of above 2
+        // states
+        mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
+                mCameraId,
+                &rejectSourceStates);
+
     }
+    // Always stop watching, even if no camera op is active
     mAppOpsManager.stopWatchingMode(mOpsCallback);
     mOpsCallback.clear();
 
@@ -1531,15 +1542,6 @@
     ALOGV("Client::disconnect");
     BasicClient::disconnect();
     mCameraService->setCameraFree(mCameraId);
-
-    StatusVector rejectSourceStates;
-    rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
-    rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
-
-    // Transition to PRESENT if the camera is not in either of above 2 states
-    mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
-                                 mCameraId,
-                                 &rejectSourceStates);
 }
 
 CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 28590eb..cb98c96 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -138,6 +138,10 @@
     // CameraDeviceFactory functionality
     int                 getDeviceVersion(int cameraId, int* facing = NULL);
 
+    /////////////////////////////////////////////////////////////////////
+    // Shared utilities
+    static status_t     filterOpenErrorCode(status_t err);
+    static status_t     filterGetInfoErrorCode(status_t err);
 
     /////////////////////////////////////////////////////////////////////
     // CameraClient functionality
@@ -149,20 +153,19 @@
 
     class BasicClient : public virtual RefBase {
     public:
-        virtual status_t initialize(camera_module_t *module) = 0;
-
-        virtual void          disconnect() = 0;
+        virtual status_t    initialize(camera_module_t *module) = 0;
+        virtual void        disconnect();
 
         // because we can't virtually inherit IInterface, which breaks
         // virtual inheritance
         virtual sp<IBinder> asBinderWrapper() = 0;
 
         // Return the remote callback binder object (e.g. IProCameraCallbacks)
-        sp<IBinder>     getRemote() {
+        sp<IBinder>         getRemote() {
             return mRemoteBinder;
         }
 
-        virtual status_t      dump(int fd, const Vector<String16>& args) = 0;
+        virtual status_t    dump(int fd, const Vector<String16>& args) = 0;
 
     protected:
         BasicClient(const sp<CameraService>& cameraService,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 13c9f48..24d173c 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -112,8 +112,6 @@
 
     TClientBase::mDestructionStarted = true;
 
-    TClientBase::finishCameraOps();
-
     disconnect();
 
     ALOGI("Closed Camera %d", TClientBase::mCameraId);
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 2746f6f..6386838 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -105,8 +105,8 @@
                                                CAMERA_DEVICE_API_VERSION_1_0,
                                                (hw_device_t **)&mDevice);
         } else {
-            rc = module->methods->open(module, mName.string(),
-                                           (hw_device_t **)&mDevice);
+            rc = CameraService::filterOpenErrorCode(module->methods->open(
+                module, mName.string(), (hw_device_t **)&mDevice));
         }
         if (rc != OK) {
             ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index 89c6b10..8c2520e 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -30,6 +30,7 @@
 #include <utils/Trace.h>
 #include <utils/Timers.h>
 #include "Camera2Device.h"
+#include "CameraService.h"
 
 namespace android {
 
@@ -67,8 +68,8 @@
 
     camera2_device_t *device;
 
-    res = module->common.methods->open(&module->common, name,
-            reinterpret_cast<hw_device_t**>(&device));
+    res = CameraService::filterOpenErrorCode(module->common.methods->open(
+        &module->common, name, reinterpret_cast<hw_device_t**>(&device)));
 
     if (res != OK) {
         ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
@@ -1087,25 +1088,33 @@
     }
 
     if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
-        res = native_window_set_buffers_geometry(mConsumerInterface.get(),
-                mSize, 1, mFormat);
+        res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
+                mSize, 1);
         if (res != OK) {
-            ALOGE("%s: Unable to configure compressed stream buffer geometry"
+            ALOGE("%s: Unable to configure compressed stream buffer dimensions"
                     " %d x %d, size %zu for stream %d",
                     __FUNCTION__, mWidth, mHeight, mSize, mId);
             return res;
         }
     } else {
-        res = native_window_set_buffers_geometry(mConsumerInterface.get(),
-                mWidth, mHeight, mFormat);
+        res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
+                mWidth, mHeight);
         if (res != OK) {
-            ALOGE("%s: Unable to configure stream buffer geometry"
-                    " %d x %d, format 0x%x for stream %d",
-                    __FUNCTION__, mWidth, mHeight, mFormat, mId);
+            ALOGE("%s: Unable to configure stream buffer dimensions"
+                    " %d x %d for stream %d",
+                    __FUNCTION__, mWidth, mHeight, mId);
             return res;
         }
     }
 
+    res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
+    if (res != OK) {
+        ALOGE("%s: Unable to configure stream buffer format"
+                " %#x for stream %d",
+                __FUNCTION__, mFormat, mId);
+        return res;
+    }
+
     int maxConsumerBuffers;
     res = mConsumerInterface->query(mConsumerInterface.get(),
             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 44e8822..a6214cc 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -48,6 +48,7 @@
 #include "device3/Camera3OutputStream.h"
 #include "device3/Camera3InputStream.h"
 #include "device3/Camera3ZslStream.h"
+#include "CameraService.h"
 
 using namespace android::camera3;
 
@@ -104,8 +105,9 @@
     camera3_device_t *device;
 
     ATRACE_BEGIN("camera3->open");
-    res = module->common.methods->open(&module->common, deviceName.string(),
-            reinterpret_cast<hw_device_t**>(&device));
+    res = CameraService::filterOpenErrorCode(module->common.methods->open(
+        &module->common, deviceName.string(),
+        reinterpret_cast<hw_device_t**>(&device)));
     ATRACE_END();
 
     if (res != OK) {
@@ -124,7 +126,8 @@
     }
 
     camera_info info;
-    res = module->get_camera_info(mId, &info);
+    res = CameraService::filterGetInfoErrorCode(module->get_camera_info(
+        mId, &info));
     if (res != OK) return res;
 
     if (info.device_version != device->common.version) {
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 7ec649b..169eb82 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -289,20 +289,25 @@
 
     if (mMaxSize == 0) {
         // For buffers of known size
-        res = native_window_set_buffers_geometry(mConsumer.get(),
-                camera3_stream::width, camera3_stream::height,
-                camera3_stream::format);
+        res = native_window_set_buffers_dimensions(mConsumer.get(),
+                camera3_stream::width, camera3_stream::height);
     } else {
         // For buffers with bounded size
-        res = native_window_set_buffers_geometry(mConsumer.get(),
-                mMaxSize, 1,
-                camera3_stream::format);
+        res = native_window_set_buffers_dimensions(mConsumer.get(),
+                mMaxSize, 1);
     }
     if (res != OK) {
-        ALOGE("%s: Unable to configure stream buffer geometry"
-                " %d x %d, format %x for stream %d",
+        ALOGE("%s: Unable to configure stream buffer dimensions"
+                " %d x %d (maxSize %zu) for stream %d",
                 __FUNCTION__, camera3_stream::width, camera3_stream::height,
-                camera3_stream::format, mId);
+                mMaxSize, mId);
+        return res;
+    }
+    res = native_window_set_buffers_format(mConsumer.get(),
+            camera3_stream::format);
+    if (res != OK) {
+        ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
+                __FUNCTION__, camera3_stream::format, mId);
         return res;
     }