Merge "const correctness on downmix and upmix" into lmp-dev
diff --git a/camera/Android.mk b/camera/Android.mk
index c10e38a..bbdb47d 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -36,6 +36,7 @@
 	camera2/CaptureRequest.cpp \
 	ProCamera.cpp \
 	CameraBase.cpp \
+	CameraUtils.cpp \
 	VendorTagDescriptor.cpp
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/camera/CameraUtils.cpp b/camera/CameraUtils.cpp
new file mode 100644
index 0000000..3ff181d
--- /dev/null
+++ b/camera/CameraUtils.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CameraUtils"
+//#define LOG_NDEBUG 0
+
+#include <camera/CameraUtils.h>
+
+#include <system/window.h>
+#include <system/graphics.h>
+
+#include <utils/Log.h>
+
+namespace android {
+
+status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
+                /*out*/int32_t* transform) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (transform == NULL) {
+        ALOGW("%s: null transform", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    *transform = 0;
+
+    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
+    if (entry.count == 0) {
+        ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
+    if (entry.count == 0) {
+        ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    int32_t& flags = *transform;
+
+    bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
+    int orientation = entry.data.i32[0];
+    if (!mirror) {
+        switch (orientation) {
+            case 0:
+                flags = 0;
+                break;
+            case 90:
+                flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
+                break;
+            case 180:
+                flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
+                break;
+            case 270:
+                flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
+                break;
+            default:
+                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
+                      __FUNCTION__, orientation);
+                return INVALID_OPERATION;
+        }
+    } else {
+        switch (orientation) {
+            case 0:
+                flags = HAL_TRANSFORM_FLIP_H;
+                break;
+            case 90:
+                flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
+                break;
+            case 180:
+                flags = HAL_TRANSFORM_FLIP_V;
+                break;
+            case 270:
+                flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
+                break;
+            default:
+                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
+                      __FUNCTION__, orientation);
+                return INVALID_OPERATION;
+        }
+
+    }
+
+    /**
+     * This magic flag makes surfaceflinger un-rotate the buffers
+     * to counter the extra global device UI rotation whenever the user
+     * physically rotates the device.
+     *
+     * By doing this, the camera buffer always ends up aligned
+     * with the physical camera for a "see through" effect.
+     *
+     * In essence, the buffer only gets rotated during preview use-cases.
+     * The user is still responsible to re-create streams of the proper
+     * aspect ratio, or the preview will end up looking non-uniformly
+     * stretched.
+     */
+    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+
+    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
+
+    return OK;
+}
+
+
+} /* namespace android */
diff --git a/include/camera/CameraUtils.h b/include/camera/CameraUtils.h
new file mode 100644
index 0000000..c06f05d
--- /dev/null
+++ b/include/camera/CameraUtils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CAMERA_CLIENT_CAMERAUTILS_H
+#define ANDROID_CAMERA_CLIENT_CAMERAUTILS_H
+
+#include <camera/CameraMetadata.h>
+#include <utils/Errors.h>
+
+#include <stdint.h>
+
+namespace android {
+
+/**
+ * CameraUtils contains utility methods that are shared between the native
+ * camera client, and the camera service.
+ */
+class CameraUtils {
+    public:
+        /**
+         * Calculate the ANativeWindow transform from the static camera
+         * metadata.  This is based on the sensor orientation and lens facing
+         * attributes of the camera device.
+         *
+         * Returns OK on success, or a negative error code.
+         */
+        static status_t getRotationTransform(const CameraMetadata& staticInfo,
+                /*out*/int32_t* transform);
+    private:
+        CameraUtils();
+};
+
+} /* namespace android */
+
+#endif /* ANDROID_CAMERA_CLIENT_CAMERAUTILS_H */
+
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 38ee82b..6c2cbe3 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -223,6 +223,8 @@
         pContext->pBundledContext->bBassTempDisabled        = LVM_FALSE;
         pContext->pBundledContext->bVirtualizerEnabled      = LVM_FALSE;
         pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
+        pContext->pBundledContext->nOutputDevice            = AUDIO_DEVICE_NONE;
+        pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
         pContext->pBundledContext->NumberEffectsEnabled     = 0;
         pContext->pBundledContext->NumberEffectsCalled      = 0;
         pContext->pBundledContext->firstVolume              = LVM_TRUE;
@@ -1166,6 +1168,177 @@
     //ALOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n\n");
 }    /* end setStrength */
 
+//----------------------------------------------------------------------------
+// VirtualizerIsDeviceSupported()
+//----------------------------------------------------------------------------
+// Purpose:
+// Check if an audio device type is supported by this implementation
+//
+// Inputs:
+//  deviceType   the type of device that affects the processing (e.g. for binaural vs transaural)
+// Output:
+//  -EINVAL      if the configuration is not supported or it is unknown
+//  0            if the configuration is supported
+//----------------------------------------------------------------------------
+int VirtualizerIsDeviceSupported(audio_devices_t deviceType) {
+    switch (deviceType) {
+    case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+    case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+        return 0;
+    default :
+        return -EINVAL;
+    }
+}
+
+//----------------------------------------------------------------------------
+// VirtualizerIsConfigurationSupported()
+//----------------------------------------------------------------------------
+// Purpose:
+// Check if a channel mask + audio device type is supported by this implementation
+//
+// Inputs:
+//  channelMask  the channel mask of the input to virtualize
+//  deviceType   the type of device that affects the processing (e.g. for binaural vs transaural)
+// Output:
+//  -EINVAL      if the configuration is not supported or it is unknown
+//  0            if the configuration is supported
+//----------------------------------------------------------------------------
+int VirtualizerIsConfigurationSupported(audio_channel_mask_t channelMask,
+        audio_devices_t deviceType) {
+    uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
+    if ((channelCount == 0) || (channelCount > 2)) {
+        return -EINVAL;
+    }
+
+    return VirtualizerIsDeviceSupported(deviceType);
+}
+
+//----------------------------------------------------------------------------
+// VirtualizerForceVirtualizationMode()
+//----------------------------------------------------------------------------
+// Purpose:
+// Force the virtualization mode to that of the given audio device
+//
+// Inputs:
+//  pContext     effect engine context
+//  forcedDevice the type of device whose virtualization mode we'll always use
+// Output:
+//  -EINVAL      if the device is not supported or is unknown
+//  0            if the device is supported and the virtualization mode forced
+//
+//----------------------------------------------------------------------------
+int VirtualizerForceVirtualizationMode(EffectContext *pContext, audio_devices_t forcedDevice) {
+    ALOGV("VirtualizerForceVirtualizationMode: forcedDev=0x%x enabled=%d tmpDisabled=%d",
+            forcedDevice, pContext->pBundledContext->bVirtualizerEnabled,
+            pContext->pBundledContext->bVirtualizerTempDisabled);
+    int status = 0;
+    bool useVirtualizer = false;
+
+    if (VirtualizerIsDeviceSupported(forcedDevice) != 0) {
+        // forced device is not supported, make it behave as a reset of forced mode
+        forcedDevice = AUDIO_DEVICE_NONE;
+        // but return an error
+        status = -EINVAL;
+    }
+
+    if (forcedDevice == AUDIO_DEVICE_NONE) {
+        // disabling forced virtualization mode:
+        // verify whether the virtualization should be enabled or disabled
+        if (VirtualizerIsDeviceSupported(pContext->pBundledContext->nOutputDevice) == 0) {
+            useVirtualizer = (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE);
+        }
+        pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
+    } else {
+        // forcing virtualization mode: here we already know the device is supported
+        pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+        // only enable for a supported mode, when the effect is enabled
+        useVirtualizer = (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE);
+    }
+
+    if (useVirtualizer) {
+        if (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_TRUE) {
+            ALOGV("\tVirtualizerForceVirtualizationMode re-enable LVM_VIRTUALIZER");
+            android::LvmEffect_enable(pContext);
+            pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
+        } else {
+            ALOGV("\tVirtualizerForceVirtualizationMode leaving LVM_VIRTUALIZER enabled");
+        }
+    } else {
+        if (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_FALSE) {
+            ALOGV("\tVirtualizerForceVirtualizationMode disable LVM_VIRTUALIZER");
+            android::LvmEffect_disable(pContext);
+            pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
+        } else {
+            ALOGV("\tVirtualizerForceVirtualizationMode leaving LVM_VIRTUALIZER disabled");
+        }
+    }
+
+    ALOGV("\tafter VirtualizerForceVirtualizationMode: enabled=%d tmpDisabled=%d",
+            pContext->pBundledContext->bVirtualizerEnabled,
+            pContext->pBundledContext->bVirtualizerTempDisabled);
+
+    return status;
+}
+//----------------------------------------------------------------------------
+// VirtualizerGetSpeakerAngles()
+//----------------------------------------------------------------------------
+// Purpose:
+// Get the virtual speaker angles for a channel mask + audio device type
+// configuration which is guaranteed to be supported by this implementation
+//
+// Inputs:
+//  channelMask:   the channel mask of the input to virtualize
+//  deviceType     the type of device that affects the processing (e.g. for binaural vs transaural)
+// Input/Output:
+//  pSpeakerAngles the array of integer where each speaker angle is written as a triplet in the
+//                 following format:
+//                    int32_t a bit mask with a single value selected for each speaker, following
+//                            the convention of the audio_channel_mask_t type
+//                    int32_t a value in degrees expressing the speaker azimuth, where 0 is in front
+//                            of the user, 180 behind, -90 to the left, 90 to the right of the user
+//                    int32_t a value in degrees expressing the speaker elevation, where 0 is the
+//                            horizontal plane, +90 is directly above the user, -90 below
+//
+//----------------------------------------------------------------------------
+void VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask __unused,
+        audio_devices_t deviceType __unused, int32_t *pSpeakerAngles) {
+    // the channel count is guaranteed to be 1 or 2
+    // the device is guaranteed to be of type headphone
+    // this virtualizer is always 2in with speakers at -90 and 90deg of azimuth, 0deg of elevation
+    *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_LEFT;
+    *pSpeakerAngles++ = -90; // azimuth
+    *pSpeakerAngles++ = 0;   // elevation
+    *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+    *pSpeakerAngles++ = 90;  // azimuth
+    *pSpeakerAngles   = 0;   // elevation
+}
+
+//----------------------------------------------------------------------------
+// VirtualizerGetVirtualizationMode()
+//----------------------------------------------------------------------------
+// Purpose:
+// Retrieve the current device whose processing mode is used by this effect
+//
+// Output:
+//   AUDIO_DEVICE_NONE if the effect is not virtualizing
+//   or the device type if the effect is virtualizing
+//----------------------------------------------------------------------------
+audio_devices_t VirtualizerGetVirtualizationMode(EffectContext *pContext) {
+    audio_devices_t virtDevice = AUDIO_DEVICE_NONE;
+    if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE)
+            && (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_FALSE)) {
+        if (pContext->pBundledContext->nVirtualizerForcedDevice != AUDIO_DEVICE_NONE) {
+            // virtualization mode is forced, return that device
+            virtDevice = pContext->pBundledContext->nVirtualizerForcedDevice;
+        } else {
+            // no forced mode, return the current device
+            virtDevice = pContext->pBundledContext->nOutputDevice;
+        }
+    }
+    ALOGV("VirtualizerGetVirtualizationMode() returning 0x%x", virtDevice);
+    return virtDevice;
+}
 
 //----------------------------------------------------------------------------
 // EqualizerLimitBandLevels()
@@ -1903,7 +2076,17 @@
             }
             *pValueSize = sizeof(int16_t);
             break;
-
+        case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES:
+            // return value size can only be interpreted as relative to input value,
+            // deferring validity check to below
+            break;
+        case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
+            if (*pValueSize != sizeof(uint32_t)){
+                ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
+                return -EINVAL;
+            }
+            *pValueSize = sizeof(uint32_t);
+            break;
         default:
             ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid param %d", param);
             return -EINVAL;
@@ -1924,13 +2107,36 @@
             //        *(int16_t *)pValue);
             break;
 
+        case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: {
+            const audio_channel_mask_t channelMask = (audio_channel_mask_t) *pParamTemp++;
+            const audio_devices_t deviceType = (audio_devices_t) *pParamTemp;
+            uint32_t nbChannels = audio_channel_count_from_out_mask(channelMask);
+            if (*pValueSize < 3 * nbChannels * sizeof(int32_t)){
+                ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
+                return -EINVAL;
+            }
+            // verify the configuration is supported
+            status = VirtualizerIsConfigurationSupported(channelMask, deviceType);
+            if (status == 0) {
+                ALOGV("VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES supports mask=0x%x device=0x%x",
+                        channelMask, deviceType);
+                // configuration is supported, get the angles
+                VirtualizerGetSpeakerAngles(channelMask, deviceType, (int32_t *)pValue);
+            }
+            }
+            break;
+
+        case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
+            *(uint32_t *)pValue  = (uint32_t) VirtualizerGetVirtualizationMode(pContext);
+            break;
+
         default:
             ALOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid param %d", param);
             status = -EINVAL;
             break;
     }
 
-    //ALOGV("\tVirtualizer_getParameter end");
+    ALOGV("\tVirtualizer_getParameter end returning status=%d", status);
     return status;
 } /* end Virtualizer_getParameter */
 
@@ -1965,6 +2171,15 @@
             VirtualizerSetStrength(pContext, (int32_t)strength);
             //ALOGV("\tVirtualizer_setParameter() Called pVirtualizer->setStrength");
            break;
+
+        case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: {
+            const audio_devices_t deviceType = *(audio_devices_t *) pValue;
+            status = VirtualizerForceVirtualizationMode(pContext, deviceType);
+            //ALOGV("VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE device=0x%x result=%d",
+            //        deviceType, status);
+            }
+            break;
+
         default:
             ALOGV("\tLVM_ERROR : Virtualizer_setParameter() invalid param %d", param);
             break;
@@ -2865,7 +3080,6 @@
                                                               (void *)p->data,
                                                               &p->vsize,
                                                               p->data + voffset);
-
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
 
                 //ALOGV("\tVirtualizer_command EFFECT_CMD_GET_PARAM "
@@ -2976,14 +3190,17 @@
                                                                     p->data + p->psize);
             }
             if(pContext->EffectType == LVM_VIRTUALIZER){
+              // Warning this log will fail to properly read an int32_t value, assumes int16_t
               //ALOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d",
               //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
               //        *replySize,
               //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
-                if (pCmdData   == NULL||
-                    cmdSize    != (sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
-                    pReplyData == NULL||
+                if (pCmdData   == NULL ||
+                    // legal parameters are int16_t or int32_t
+                    cmdSize    > (sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int32_t)) ||
+                    cmdSize    < (sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t)) ||
+                    pReplyData == NULL ||
                     *replySize != sizeof(int32_t)){
                     ALOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
                             "EFFECT_CMD_SET_PARAM: ERROR");
@@ -3075,6 +3292,7 @@
         {
             ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start");
             uint32_t device = *(uint32_t *)pCmdData;
+            pContext->pBundledContext->nOutputDevice = (audio_devices_t) device;
 
             if (pContext->EffectType == LVM_BASS_BOOST) {
                 if((device == AUDIO_DEVICE_OUT_SPEAKER) ||
@@ -3110,37 +3328,38 @@
                 }
             }
             if (pContext->EffectType == LVM_VIRTUALIZER) {
-                if((device == AUDIO_DEVICE_OUT_SPEAKER)||
-                        (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)||
-                        (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
-                          *(int32_t *)pCmdData);
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
+                if (pContext->pBundledContext->nVirtualizerForcedDevice == AUDIO_DEVICE_NONE) {
+                    // default case unless configuration is forced
+                    if (android::VirtualizerIsDeviceSupported(device) != 0) {
+                        ALOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
+                                *(int32_t *)pCmdData);
+                        ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
 
-                    //If a device doesnt support virtualizer the effect must be temporarily disabled
-                    // the effect must still report its original state as this can only be changed
-                    // by the ENABLE/DISABLE command
+                        //If a device doesnt support virtualizer the effect must be temporarily
+                        // disabled the effect must still report its original state as this can
+                        // only be changed by the ENABLE/DISABLE command
 
-                    if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) {
-                        ALOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_VIRTUALIZER %d",
-                              *(int32_t *)pCmdData);
-                        android::LvmEffect_disable(pContext);
+                        if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) {
+                            ALOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_VIRTUALIZER %d",
+                                    *(int32_t *)pCmdData);
+                            android::LvmEffect_disable(pContext);
+                        }
+                        pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
+                    } else {
+                        ALOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_VIRTUALIZER %d",
+                                *(int32_t *)pCmdData);
+
+                        // If a device supports virtualizer and the effect has been temporarily
+                        // disabled previously then re-enable it
+
+                        if(pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE){
+                            ALOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_VIRTUALIZER %d",
+                                    *(int32_t *)pCmdData);
+                            android::LvmEffect_enable(pContext);
+                        }
+                        pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
                     }
-                    pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
-                } else {
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_VIRTUALIZER %d",
-                          *(int32_t *)pCmdData);
-
-                    // If a device supports virtualizer and the effect has been temporarily disabled
-                    // previously then re-enable it
-
-                    if(pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE){
-                        ALOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_VIRTUALIZER %d",
-                              *(int32_t *)pCmdData);
-                        android::LvmEffect_enable(pContext);
-                    }
-                    pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
-                }
+                } // else virtualization mode is forced to a certain device, nothing to do
             }
             ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE end");
             break;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 330bb32..420f973 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -73,6 +73,8 @@
     bool                            bBassTempDisabled;        /* Flag for Bass to be re-enabled */
     bool                            bVirtualizerEnabled;      /* Flag for Virtualizer */
     bool                            bVirtualizerTempDisabled; /* Flag for effect to be re-enabled */
+    audio_devices_t                 nOutputDevice;            /* Output device for the effect */
+    audio_devices_t                 nVirtualizerForcedDevice; /* Forced device virtualization mode*/
     int                             NumberEffectsEnabled;     /* Effects in this session */
     int                             NumberEffectsCalled;      /* Effects called so far */
     bool                            firstVolume;              /* No smoothing on first Vol change */
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 67e6d7b..fad6c33 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -75,8 +75,7 @@
     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     mConsumer->setConsumerName(name);
     mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
-    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
-            GRALLOC_USAGE_HW_TEXTURE);
+    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER);
 
     mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount);
     if (mInitCheck != NO_ERROR) {
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 406988c..0a246f2 100755
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -485,4 +485,17 @@
     return INVALID_OPERATION;
 }
 
+audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr __unused,
+                                    uint32_t samplingRate,
+                                    audio_format_t format,
+                                    audio_channel_mask_t channelMask,
+                                    audio_output_flags_t flags,
+                                    const audio_offload_info_t *offloadInfo)
+{
+    //FIXME: temporary to fix build with USE_LEGACY_AUDIO_POLICY
+    audio_stream_type_t stream = AUDIO_STREAM_MUSIC;
+    return getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
+}
+
+
 }; // namespace android
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index de42cee..b8611f8 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -23,6 +23,7 @@
 #include <utils/Trace.h>
 #include <gui/Surface.h>
 #include <camera/camera2/CaptureRequest.h>
+#include <camera/CameraUtils.h>
 
 #include "common/CameraDeviceBase.h"
 #include "api2/CameraDeviceClient.h"
@@ -656,91 +657,8 @@
 status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
     ALOGV("%s: begin", __FUNCTION__);
 
-    if (transform == NULL) {
-        ALOGW("%s: null transform", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    *transform = 0;
-
     const CameraMetadata& staticInfo = mDevice->info();
-    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
-    if (entry.count == 0) {
-        ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
-                "static metadata!", __FUNCTION__, mCameraId);
-        return INVALID_OPERATION;
-    }
-
-    camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
-    if (entry.count == 0) {
-        ALOGE("%s: Camera %d: Can't find android.lens.facing in "
-                "static metadata!", __FUNCTION__, mCameraId);
-        return INVALID_OPERATION;
-    }
-
-    int32_t& flags = *transform;
-
-    bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
-    int orientation = entry.data.i32[0];
-    if (!mirror) {
-        switch (orientation) {
-            case 0:
-                flags = 0;
-                break;
-            case 90:
-                flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
-                break;
-            case 180:
-                flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
-                break;
-            case 270:
-                flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
-                break;
-            default:
-                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
-                      __FUNCTION__, orientation);
-                return INVALID_OPERATION;
-        }
-    } else {
-        switch (orientation) {
-            case 0:
-                flags = HAL_TRANSFORM_FLIP_H;
-                break;
-            case 90:
-                flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
-                break;
-            case 180:
-                flags = HAL_TRANSFORM_FLIP_V;
-                break;
-            case 270:
-                flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
-                break;
-            default:
-                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
-                      __FUNCTION__, orientation);
-                return INVALID_OPERATION;
-        }
-
-    }
-
-    /**
-     * This magic flag makes surfaceflinger un-rotate the buffers
-     * to counter the extra global device UI rotation whenever the user
-     * physically rotates the device.
-     *
-     * By doing this, the camera buffer always ends up aligned
-     * with the physical camera for a "see through" effect.
-     *
-     * In essence, the buffer only gets rotated during preview use-cases.
-     * The user is still responsible to re-create streams of the proper
-     * aspect ratio, or the preview will end up looking non-uniformly
-     * stretched.
-     */
-    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
-
-    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
-
-    return OK;
+    return CameraUtils::getRotationTransform(staticInfo, transform);
 }
 
 } // namespace android