Merge tag 'android-11.0.0_r48' of https://android.googlesource.com/platform//frameworks/av into r

Android 11.0.0 Release 48 (RD2A.211001.002)

Change-Id: I4bbe883091b412cdaecc4927547ae0c7df5b0af0
diff --git a/camera/Android.bp b/camera/Android.bp
index fa36bb3..21ef9ee 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -14,6 +14,7 @@
 
 cc_library_shared {
     name: "libcamera_client",
+    defaults: ["camera_parameter_library_defaults"],
 
     aidl: {
         export_aidl_headers: true,
@@ -32,7 +33,6 @@
         // Source for camera interface parcelables, and manually-written interfaces
         "Camera.cpp",
         "CameraMetadata.cpp",
-        "CameraParameters.cpp",
         "CaptureResult.cpp",
         "CameraParameters2.cpp",
         "ICamera.cpp",
@@ -77,6 +77,16 @@
 
 }
 
+cc_library_static {
+    name: "libcamera_parameters",
+
+    export_include_dirs: [
+        "include",
+    ],
+    srcs: ["CameraParameters.cpp"],
+
+}
+
 // AIDL interface between camera clients and the camera service.
 filegroup {
     name: "libcamera_client_aidl",
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 68969cf..de8ac2f 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -237,6 +237,9 @@
 
 void CameraParameters::set(const char *key, const char *value)
 {
+    if (key == NULL || value == NULL)
+        return;
+
     // XXX i think i can do this with strspn()
     if (strchr(key, '=') || strchr(key, ';')) {
         //XXX ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index bef2ea0..be82ff4 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -51,7 +51,11 @@
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeInt32(msgType);
         data.writeInt32(ext1);
-        data.writeInt32(ext2);
+        if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+            data.writeFileDescriptor(ext2);
+        } else {
+            data.writeInt32(ext2);
+        }
         remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -129,8 +133,13 @@
             ALOGV("NOTIFY_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
             int32_t msgType = data.readInt32();
-            int32_t ext1 = data.readInt32();
-            int32_t ext2 = data.readInt32();
+            int32_t ext1    = data.readInt32();
+            int32_t ext2    = 0;
+            if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+                ext2 = data.readFileDescriptor();
+            } else {
+                ext2 = data.readInt32();
+            }
             notifyCallback(msgType, ext1, ext2);
             return NO_ERROR;
         } break;
diff --git a/camera/include/camera/CameraParameters2.h b/camera/include/camera/CameraParameters2.h
index f691cd6..5fae079 100644
--- a/camera/include/camera/CameraParameters2.h
+++ b/camera/include/camera/CameraParameters2.h
@@ -19,7 +19,7 @@
 
 #include <utils/Vector.h>
 #include <utils/String8.h>
-#include "CameraParameters.h"
+#include <camera/CameraParameters.h>
 
 namespace android {
 
diff --git a/include/media/AudioSession.h b/include/media/AudioSession.h
new file mode 120000
index 0000000..005e48e
--- /dev/null
+++ b/include/media/AudioSession.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioSession.h
\ No newline at end of file
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index e26a831..8dc7d9e 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -43,6 +43,7 @@
 sp<IAudioFlinger> AudioSystem::gAudioFlinger;
 sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
 std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
+audio_session_callback AudioSystem::gAudioSessionCallback = NULL;
 dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
 record_config_callback AudioSystem::gRecordConfigCallback = NULL;
 
@@ -753,6 +754,17 @@
     gRecordConfigCallback = cb;
 }
 
+/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    Mutex::Autolock _l(gLock);
+    gAudioSessionCallback = cb;
+
+    return NO_ERROR;
+}
+
 // client singleton for AudioPolicyService binder interface
 // protected by gLockAPS
 sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1686,6 +1698,27 @@
     return NO_ERROR;
 }
 
+status_t AudioSystem::setAppVolume(const String8& packageName, const float volume)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->setAppVolume(packageName, volume);
+}
+
+status_t AudioSystem::setAppMute(const String8& packageName, const bool mute)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->setAppMute(packageName, mute);
+}
+
+status_t AudioSystem::listAppTrackDatas(unsigned int *num, AppTrackData *vols)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->listAppTrackDatas(num, vols);
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
@@ -1812,6 +1845,32 @@
     }
 }
 
+// ---------------------------------------------------------------------------
+
+status_t AudioSystem::listAudioSessions(audio_stream_type_t stream,
+                                        Vector< sp<AudioSessionInfo>> &sessions)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->listAudioSessions(stream, sessions);
+}
+
+void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
+        sp<AudioSessionInfo>& info, bool added)
+{
+    ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)",
+            info->mStream, info->mSessionId, added);
+    audio_session_callback cb = NULL;
+    {
+        Mutex::Autolock _l(AudioSystem::gLock);
+        cb = gAudioSessionCallback;
+    }
+
+    if (cb != NULL) {
+        cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added);
+    }
+}
+
 void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
 {
     {
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index d3a037c..0abcb0b 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -91,7 +91,10 @@
     SET_MASTER_BALANCE,
     GET_MASTER_BALANCE,
     SET_EFFECT_SUSPENDED,
-    SET_AUDIO_HAL_PIDS
+    SET_AUDIO_HAL_PIDS,
+    SET_APP_VOLUME,
+    SET_APP_MUTE,
+    LIST_ACTIVE_APP_VOLUMES
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -276,6 +279,48 @@
         return NO_ERROR;
     }
 
+    virtual status_t setAppVolume(const String8& packageName, const float value) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeString8(packageName);
+        data.writeFloat(value);
+        remote()->transact(SET_APP_VOLUME, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setAppMute(const String8& packageName, const bool mute) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeString8(packageName);
+        data.writeInt32(mute);
+        remote()->transact(SET_APP_MUTE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t listAppTrackDatas(unsigned int *num_volumes, AppTrackData *volumes)
+    {
+        if (num_volumes == NULL || (*num_volumes != 0 && volumes == NULL)) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        unsigned int numVolsReq = (volumes == NULL) ? 0 : *num_volumes;
+        data.writeInt32(numVolsReq);
+        status_t status = remote()->transact(LIST_ACTIVE_APP_VOLUMES, data, &reply);
+        if (status != NO_ERROR ||
+                (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            return status;
+        }
+        *num_volumes = (unsigned int)reply.readInt32();
+        if (numVolsReq > *num_volumes) {
+            numVolsReq = *num_volumes;
+        }
+        if (numVolsReq > 0) {
+            reply.read(volumes, numVolsReq * sizeof(AppTrackData));
+        }
+        return status;
+    }
+
     virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
             audio_io_handle_t output)
     {
@@ -1621,6 +1666,45 @@
             reply->writeInt32(setAudioHalPids(pids));
             return NO_ERROR;
         }
+        case SET_APP_VOLUME: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            String8 packageName = data.readString8();
+            float volume = data.readFloat();
+            reply->writeInt32( setAppVolume(packageName, volume) );
+            return NO_ERROR;
+        }
+        case SET_APP_MUTE: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            String8 packageName = data.readString8();
+            bool muted = data.readInt32();
+            reply->writeInt32( setAppMute(packageName, muted) );
+            return NO_ERROR;
+        }
+        case LIST_ACTIVE_APP_VOLUMES: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            unsigned int numReq = data.readInt32();
+            if (numReq > MAX_ITEMS_PER_LIST) {
+                numReq = MAX_ITEMS_PER_LIST;
+            }
+            unsigned int numVol = numReq;
+            AppTrackData *vols = new (std::nothrow) AppTrackData[numVol];
+            if (vols == NULL) {
+                reply->writeInt32(NO_MEMORY);
+                reply->writeInt32(0);
+                return NO_ERROR;
+            }
+            status_t status = listAppTrackDatas(&numVol, vols);
+            reply->writeInt32(status);
+            reply->writeInt32(numVol);
+            if (status == NO_ERROR) {
+                if (numReq > numVol) {
+                    numReq = numVol;
+                }
+                reply->write(vols, numReq * sizeof(AppTrackData));
+            }
+            delete[] vols;
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 43a5369..d1d5477 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -120,6 +120,7 @@
     AUDIO_MODULES_UPDATED,  // oneway
     SET_CURRENT_IME_UID,
     REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
+    LIST_AUDIO_SESSIONS,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -1496,6 +1497,29 @@
         if (status != NO_ERROR) return status;
         return NO_ERROR;
     }
+
+    virtual status_t listAudioSessions(audio_stream_type_t streams,
+                                       Vector< sp<AudioSessionInfo>> &sessions)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(streams);
+        status_t status = remote()->transact(LIST_AUDIO_SESSIONS, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+
+        status = reply.readInt32();
+        if (status == NO_ERROR) {
+            size_t size = (size_t)reply.readUint32();
+            for (size_t i = 0; i < size && reply.dataAvail() > 0; i++) {
+                sp<AudioSessionInfo> info = new AudioSessionInfo();
+                info->readFromParcel(reply);
+                sessions.push_back(info);
+            }
+        }
+        return status;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -2231,6 +2255,23 @@
             return NO_ERROR;
         } break;
 
+        case LIST_AUDIO_SESSIONS: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_stream_type_t streams = (audio_stream_type_t)data.readInt32();
+
+            Vector< sp<AudioSessionInfo>> sessions;
+            status_t status = listAudioSessions(streams, sessions);
+
+            reply->writeInt32(status);
+            if (status == NO_ERROR) {
+                reply->writeUint32(static_cast<uint32_t>(sessions.size()));
+                for (size_t i = 0; i < sessions.size(); i++) {
+                    sessions[i]->writeToParcel(reply);
+                }
+            }
+            return NO_ERROR;
+        }
+
         case ACQUIRE_SOUNDTRIGGER_SESSION: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_session_t session = AUDIO_SESSION_NONE;
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index 0f9580c..eeefff9 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -33,6 +33,7 @@
     MIX_STATE_UPDATE,
     RECORDING_CONFIGURATION_UPDATE,
     VOLUME_GROUP_CHANGED,
+    OUTPUT_SESSION_EFFECTS_UPDATE,
 };
 
 // ----------------------------------------------------------------------
@@ -149,6 +150,19 @@
         data.writeInt32((int32_t) source);
         remote()->transact(RECORDING_CONFIGURATION_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
+        data.writeInt32(info->mStream);
+        data.writeInt32(info->mSessionId);
+        data.writeInt32(info->mFlags);
+        data.writeInt32(info->mChannelMask);
+        data.writeInt32(info->mUid);
+        data.writeInt32(added ? 1 : 0);
+        remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient");
@@ -202,6 +216,20 @@
                                            &deviceConfig, effects, patchHandle, source);
             return NO_ERROR;
         } break;
+    case OUTPUT_SESSION_EFFECTS_UPDATE: {
+            CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
+            audio_stream_type_t stream = static_cast<audio_stream_type_t>(data.readInt32());
+            audio_session_t sessionId = static_cast<audio_session_t>(data.readInt32());
+            audio_output_flags_t flags = static_cast<audio_output_flags_t>(data.readInt32());
+            audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(data.readInt32());
+            uid_t uid = static_cast<uid_t>(data.readInt32());
+            bool added = data.readInt32() > 0;
+
+            sp<AudioSessionInfo> info = new AudioSessionInfo(
+                    sessionId, stream, flags, channelMask, uid);
+            onOutputSessionEffectsUpdate(info, added);
+            return NO_ERROR;
+        } break;
     default:
         return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/include/media/AppTrackData.h b/media/libaudioclient/include/media/AppTrackData.h
new file mode 100644
index 0000000..5fd6bb8
--- /dev/null
+++ b/media/libaudioclient/include/media/AppTrackData.h
@@ -0,0 +1,44 @@
+#ifndef APP_TRACK_DATA_H
+#define APP_TRACK_DATA_H
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#define APP_TRACK_DATA_MAX_PACKAGENAME_LEN 128
+
+namespace android {
+    class AppTrackData : public Parcelable {
+    public:
+        char packageName[APP_TRACK_DATA_MAX_PACKAGENAME_LEN];
+        bool muted;
+        float volume;
+        bool active;
+
+        bool operator <(const AppTrackData &obj) const {
+            int t = strcmp(packageName, obj.packageName);
+            return t < 0;
+        }
+
+        /* Parcel */
+        status_t readFromParcel(const Parcel *parcel) override {
+            String8 pn = parcel->readString8();
+            strcpy(packageName, pn.c_str());
+            muted = parcel->readInt32();
+            volume = parcel->readFloat();
+            active = parcel->readInt32();
+            return NO_ERROR;
+        }
+
+        status_t writeToParcel(Parcel *parcel) const override {
+            (void)parcel->writeString8(String8(packageName));
+            (void)parcel->writeInt32(muted);
+            (void)parcel->writeFloat(volume);
+            (void)parcel->writeInt32(active);
+            return NO_ERROR;
+        }
+    };
+};
+
+#endif // APP_TRACK_DATA_H
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 00fe278..b7474fb 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -25,6 +25,7 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <cutils/multiuser.h>
+#include <media/AudioSession.h>
 
 namespace android {
 
@@ -48,6 +49,7 @@
 //   AudioSystem's implementation of the AudioPolicyClient interface
 // keep in sync with AudioSystem.java
 #define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0
+#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10
 
 #define MIX_STATE_DISABLED (-1)
 #define MIX_STATE_IDLE 0
diff --git a/media/libaudioclient/include/media/AudioSession.h b/media/libaudioclient/include/media/AudioSession.h
new file mode 100644
index 0000000..2bae521
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioSession.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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_AUDIOSESSION_H
+#define ANDROID_AUDIOSESSION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <system/audio.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+// class to store streaminfo
+class AudioSessionInfo : public RefBase {
+public:
+    AudioSessionInfo(audio_session_t session, audio_stream_type_t stream, audio_output_flags_t flags,
+            audio_channel_mask_t channelMask, uid_t uid) :
+        mSessionId(session), mStream(stream), mFlags(flags), mChannelMask(channelMask),
+        mUid(uid), mRefCount(0) {}
+
+    AudioSessionInfo() : mSessionId((audio_session_t) 0), mStream(AUDIO_STREAM_DEFAULT), mFlags(AUDIO_OUTPUT_FLAG_NONE), mChannelMask(AUDIO_CHANNEL_NONE), mUid(0) {}
+
+    /*virtual*/ ~AudioSessionInfo() {}
+
+    audio_session_t mSessionId;
+    audio_stream_type_t mStream;
+    audio_output_flags_t mFlags;
+    audio_channel_mask_t mChannelMask;
+    uid_t mUid;
+
+    // AudioPolicyManager keeps mLock, no need for lock on reference count here
+    int mRefCount;
+
+    void readFromParcel(const Parcel &parcel)  {
+        mSessionId = (audio_session_t) parcel.readInt32();
+        mStream = static_cast<audio_stream_type_t>(parcel.readInt32());
+        mFlags = static_cast<audio_output_flags_t>(parcel.readInt32());
+        mChannelMask = static_cast<audio_channel_mask_t>(parcel.readInt32());
+        mUid = static_cast<uid_t>(parcel.readInt32());
+    }
+
+    void writeToParcel(Parcel *parcel) const {
+        parcel->writeInt32(mSessionId);
+        parcel->writeInt32(mStream);
+        parcel->writeInt32(mFlags);
+        parcel->writeInt32(mChannelMask);
+        parcel->writeInt32(mUid);
+    }
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOSESSION_H
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 19c2cbd..d9e8ade 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -47,10 +47,13 @@
                                        std::vector<effect_descriptor_t> effects,
                                        audio_patch_handle_t patchHandle,
                                        audio_source_t source);
+typedef void (*audio_session_callback)(int event,
+        sp<AudioSessionInfo>& session, bool added);
 
 class IAudioFlinger;
 class IAudioPolicyService;
 class String8;
+class AppTrackData;
 
 class AudioSystem
 {
@@ -120,6 +123,7 @@
 
     static void setDynPolicyCallback(dynamic_policy_callback cb);
     static void setRecordConfigCallback(record_config_callback);
+    static status_t setAudioSessionCallback(audio_session_callback cb);
 
     // helper function to obtain AudioFlinger service handle
     static const sp<IAudioFlinger> get_audio_flinger();
@@ -460,6 +464,9 @@
     static status_t registerSoundTriggerCaptureStateListener(
             const sp<CaptureStateListener>& listener);
 
+    static status_t listAudioSessions(audio_stream_type_t streams,
+                                      Vector< sp<AudioSessionInfo>> &sessions);
+
     // ----------------------------------------------------------------------------
 
     class AudioVolumeGroupCallback : public RefBase
@@ -513,6 +520,10 @@
 
     static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
 
+    static status_t setAppVolume(const String8& packageName, const float value);
+    static status_t setAppMute(const String8& packageName, const bool value);
+    static status_t listAppTrackDatas(unsigned int *num, AppTrackData *vols);
+
 private:
 
     class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
@@ -593,6 +604,7 @@
                                                     std::vector<effect_descriptor_t> effects,
                                                     audio_patch_handle_t patchHandle,
                                                     audio_source_t source);
+        virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
 
     private:
         Mutex                               mLock;
@@ -619,6 +631,7 @@
     static std::set<audio_error_callback> gAudioErrorCallbacks;
     static dynamic_policy_callback gDynPolicyCallback;
     static record_config_callback gRecordConfigCallback;
+    static audio_session_callback gAudioSessionCallback;
 
     static size_t gInBuffSize;
     // previous parameters for recording buffer size queries
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index bcc11f4..646c4e9 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -30,6 +30,7 @@
 #include <media/DeviceDescriptorBase.h>
 #include <media/IAudioTrack.h>
 #include <media/IAudioFlingerClient.h>
+#include <media/AppTrackData.h>
 #include <system/audio.h>
 #include <system/audio_effect.h>
 #include <system/audio_policy.h>
@@ -540,6 +541,10 @@
     virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
 
     virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
+
+    virtual status_t setAppVolume(const String8& packageName, const float value) = 0;
+    virtual status_t setAppMute(const String8& packageName, const bool value) = 0;
+    virtual status_t listAppTrackDatas(unsigned int *num, AppTrackData *vols) = 0;
 };
 
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 376c6eb..b1001a8 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -254,6 +254,9 @@
     virtual status_t registerSoundTriggerCaptureStateListener(
         const sp<media::ICaptureStateListener>& listener,
         bool* result) = 0;
+
+    virtual status_t listAudioSessions(audio_stream_type_t streams,
+                                       Vector< sp<AudioSessionInfo>> &sessions) = 0;
 };
 
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index 47b31ee..bc36f74 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -25,6 +25,7 @@
 #include <system/audio_effect.h>
 #include <media/AudioPolicy.h>
 #include <media/AudioVolumeGroup.h>
+#include <media/AudioSession.h>
 
 namespace android {
 
@@ -65,6 +66,8 @@
             std::vector<effect_descriptor_t> effects,
             audio_patch_handle_t patchHandle,
             audio_source_t source) = 0;
+    // Notifies when a default effect set is attached to a session/stream
+    virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added) = 0;
 };
 
 
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 637322f..8be961c 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -240,7 +240,10 @@
 
     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoCodec failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoCodec *videoCodec =
         new MediaProfiles::VideoCodec(static_cast<video_encoder>(codec),
@@ -262,7 +265,10 @@
           !strcmp("channels",   atts[6]));
     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioCodec failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioCodec *audioCodec =
         new MediaProfiles::AudioCodec(static_cast<audio_encoder>(codec),
@@ -282,7 +288,10 @@
 
     const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]);
     const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioDecoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioDecoderCap *cap =
         new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec));
@@ -298,7 +307,10 @@
 
     const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]);
     const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoDecoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoDecoderCap *cap =
         new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec));
@@ -322,7 +334,10 @@
 
     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createVideoEncoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::VideoEncoderCap *cap =
         new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec),
@@ -346,7 +361,10 @@
 
     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
-    CHECK(codec != -1);
+    if (codec == -1) {
+      ALOGE("MediaProfiles::createAudioEncoderCap failed to locate codec %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::AudioEncoderCap *cap =
         new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]),
@@ -386,11 +404,17 @@
     const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/
             sizeof(sCamcorderQualityNameMap[0]);
     const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]);
-    CHECK(quality != -1);
+    if (quality == -1) {
+      ALOGE("MediaProfiles::createCamcorderProfile failed to locate quality %s", atts[1]);
+      return nullptr;
+    }
 
     const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
     const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]);
-    CHECK(fileFormat != -1);
+    if (fileFormat == -1) {
+      ALOGE("MediaProfiles::createCamcorderProfile failed to locate file format %s", atts[1]);
+      return nullptr;
+    }
 
     MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
     profile->mCameraId = cameraId;
@@ -462,24 +486,39 @@
         createAudioCodec(atts, profiles);
     } else if (strcmp("VideoEncoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mVideoEncoders.add(createVideoEncoderCap(atts));
+        MediaProfiles::VideoEncoderCap* cap = createVideoEncoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mVideoEncoders.add(cap);
+        }
     } else if (strcmp("AudioEncoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mAudioEncoders.add(createAudioEncoderCap(atts));
+        MediaProfiles::AudioEncoderCap* cap = createAudioEncoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mAudioEncoders.add(cap);
+        }
     } else if (strcmp("VideoDecoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mVideoDecoders.add(createVideoDecoderCap(atts));
+        MediaProfiles::VideoDecoderCap* cap = createVideoDecoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mVideoDecoders.add(cap);
+        }
     } else if (strcmp("AudioDecoderCap", name) == 0 &&
                strcmp("true", atts[3]) == 0) {
-        profiles->mAudioDecoders.add(createAudioDecoderCap(atts));
+        MediaProfiles::AudioDecoderCap* cap = createAudioDecoderCap(atts);
+        if (cap != nullptr) {
+          profiles->mAudioDecoders.add(cap);
+        }
     } else if (strcmp("EncoderOutputFileFormat", name) == 0) {
         profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
     } else if (strcmp("CamcorderProfiles", name) == 0) {
         profiles->mCurrentCameraId = getCameraId(atts);
         profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts);
     } else if (strcmp("EncoderProfile", name) == 0) {
-        profiles->mCamcorderProfiles.add(
-            createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
+      MediaProfiles::CamcorderProfile* profile = createCamcorderProfile(
+          profiles->mCurrentCameraId, atts, profiles->mCameraIds);
+      if (profile != nullptr) {
+        profiles->mCamcorderProfiles.add(profile);
+      }
     } else if (strcmp("ImageEncoding", name) == 0) {
         profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
     }
diff --git a/media/libmedia/include/media/mediaplayer.h b/media/libmedia/include/media/mediaplayer.h
index 7c29e50..bb0d8ad 100644
--- a/media/libmedia/include/media/mediaplayer.h
+++ b/media/libmedia/include/media/mediaplayer.h
@@ -207,7 +207,8 @@
                     public virtual IMediaDeathNotifier
 {
 public:
-    MediaPlayer(const std::string opPackageName = "");
+    MediaPlayer();
+    MediaPlayer(const std::string opPackageName);
     ~MediaPlayer();
             void            died();
             void            disconnect();
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 6079a2d..f1e48ad 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -41,6 +41,10 @@
 
 using media::VolumeShaper;
 
+MediaPlayer::MediaPlayer() : MediaPlayer("" /*opPackageName*/)
+{
+}
+
 MediaPlayer::MediaPlayer(const std::string opPackageName) : mOpPackageName(opPackageName)
 {
     ALOGV("constructor");
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 7897959..a7344de 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1663,7 +1663,7 @@
     Size videoSize;
     videoSize.width = mVideoWidth;
     videoSize.height = mVideoHeight;
-    if (mCaptureFpsEnable) {
+    if (mCaptureFpsEnable && mCaptureFps != mFrameRate) {
         if (!(mCaptureFps > 0.)) {
             ALOGE("Invalid mCaptureFps value: %lf", mCaptureFps);
             return BAD_VALUE;
@@ -1811,6 +1811,7 @@
             preferBFrames = false;
             tsLayers = 2; // use at least two layers as resulting video will likely be sped up
         } else if (mCaptureFps > maxPlaybackFps) { // slow-mo
+            format->setInt32("high-frame-rate", 1);
             maxPlaybackFps = mCaptureFps; // assume video will be played back at full capture speed
             preferBFrames = false;
         }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c1c4b55..8a81ef1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2350,9 +2350,6 @@
 void NuPlayer::performReset() {
     ALOGV("performReset");
 
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
     updatePlaybackTimer(true /* stopping */, "performReset");
     updateRebufferingTimer(true /* stopping */, true /* exiting */);
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 8e480bf..47881cc 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5294,9 +5294,7 @@
                             err = mOMXNode->getParameter(
                                     (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
                                     &presentation, sizeof(presentation));
-                            if (err != OK) {
-                                return err;
-                            }
+                            if (err == OK) {
                             notify->setInt32("aac-encoded-target-level",
                                              presentation.nEncodedTargetLevel);
                             notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
@@ -5309,6 +5307,7 @@
                             notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
                             notify->setInt32("aac-drc-output-loudness",
                                              presentation.nDrcOutputLoudness);
+			    }
                         }
                     }
                     break;
@@ -7995,6 +7994,7 @@
     // don't bother component if we don't have vendor extensions as they may not have implemented
     // the android vendor extension support, which will lead to unnecessary OMX failure logs.
     if (vendorKeys.empty()) {
+        mVendorExtensionsStatus = kExtensionsNone;
         return OK;
     }
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 9b3f420..be3fde8 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -162,6 +162,10 @@
         return OMX_COLOR_FormatAndroidOpaque;
     }
 
+    if (!strcmp(colorFormat, "YVU420SemiPlanar")) {
+        return OMX_QCOM_COLOR_FormatYVU420SemiPlanar;
+    }
+
     ALOGE("Uknown color format (%s), please add it to "
          "CameraSource::getColorFormat", colorFormat);
 
@@ -338,6 +342,12 @@
     return OK;
 }
 
+static int32_t getHighSpeedFrameRate(const CameraParameters& params) {
+    const char* hsr = params.get("video-hsr");
+    int32_t rate = (hsr != NULL && strncmp(hsr, "off", 3)) ? strtol(hsr, NULL, 10) : 0;
+    return std::min(rate, 240);
+}
+
 /*
  * Configure the camera to use the requested video size
  * (width and height) and/or frame rate. If both width and
@@ -385,11 +395,15 @@
     }
 
     if (frameRate != -1) {
-        CHECK(frameRate > 0 && frameRate <= 120);
+        CHECK(frameRate > 0 && frameRate <= 240);
         const char* supportedFrameRates =
                 params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
         CHECK(supportedFrameRates != NULL);
         ALOGV("Supported frame rates: %s", supportedFrameRates);
+        if (getHighSpeedFrameRate(*params)) {
+            ALOGI("Use default 30fps for HighSpeed %dfps", frameRate);
+            frameRate = 30;
+        }
         char buf[4];
         snprintf(buf, 4, "%d", frameRate);
         if (strstr(supportedFrameRates, buf) == NULL) {
@@ -491,6 +505,8 @@
         ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
         return UNKNOWN_ERROR;
     }
+    int32_t highSpeedRate = getHighSpeedFrameRate(params);
+    frameRateActual = highSpeedRate ? highSpeedRate : frameRateActual;
 
     // Check the actual video frame rate against the target/requested
     // video frame rate.
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index e0a6eb3..a00a178 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -298,7 +298,8 @@
     // The first 2 output frames from the encoder are: decoder specific info and
     // the compressed video frame data for the first input video frame.
     if (mNumFramesEncoded >= 1 && *timestampUs <
-        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
+        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs) &&
+        (mTimeBetweenFrameCaptureUs > mTimeBetweenTimeLapseVideoFramesUs + 1)) {
         // Skip all frames from last encoded frame until
         // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
         // Tell the camera to release its recording frame and return.
@@ -313,6 +314,12 @@
 
         mLastTimeLapseFrameRealTimestampUs = *timestampUs;
         *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+        // Update start-time once the captured-time reaches the expected start-time.
+        // Not doing so will result in CameraSource always dropping frames since
+        // updated-timestamp will never intersect start-timestamp
+        if ((mNumFramesReceived == 0 && mLastTimeLapseFrameRealTimestampUs >= mStartTimeUs)) {
+            mStartTimeUs = *timestampUs;
+        }
         return false;
     }
     return false;
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index c284ef7..1b3816d 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -111,8 +111,9 @@
         }
     }
 
-    int finalUsage = usage | consumerUsage;
-    ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#x", usage, consumerUsage, finalUsage);
+    uint64_t finalUsage = (usage | consumerUsage) & 0xffffffffLL;
+    ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#" PRIx64,
+            usage, consumerUsage, finalUsage);
     err = native_window_set_usage(nativeWindow, finalUsage);
     if (err != NO_ERROR) {
         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
@@ -126,7 +127,7 @@
         return err;
     }
 
-    ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x",
+    ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#" PRIx64,
             nativeWindow, width, height, format, rotation, finalUsage);
     return NO_ERROR;
 }
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 8698d33..9e2a339 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -1,5 +1,6 @@
 cc_defaults {
     name: "libstagefright_bufferqueue-defaults",
+    defaults: ["stagefright_qcom_legacy_defaults"],
     double_loadable: true,
 
     srcs: [
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index cff14ac..d031e91 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -891,11 +891,13 @@
         return UNKNOWN_ERROR;
     }
 
+#ifndef QCOM_BSP_LEGACY
     if ((android_dataspace)item.mDataspace != mLastDataspace) {
         onDataspaceChanged_l(
                 item.mDataspace,
                 (android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
     }
+#endif
 
     std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
     // use a GraphicBuffer for now as component is using GraphicBuffers to hold references
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 78b4f19..a049fc5 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -1,5 +1,6 @@
 cc_library_shared {
     name: "libstagefright_omx",
+    defaults: ["stagefright_qcom_legacy_defaults"],
     vendor_available: true,
     vndk: {
         enabled: true,
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index ac42373..d996e1a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -453,7 +453,11 @@
     mGraphicBufferEnabled[0] = false;
     mGraphicBufferEnabled[1] = false;
     mIsSecure = AString(name).endsWith(".secure");
+#ifdef QCOM_BSP_LEGACY
+    mLegacyAdaptiveExperiment = true;
+#else
     mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled("legacy-adaptive");
+#endif
 }
 
 OMXNodeInstance::~OMXNodeInstance() {
@@ -580,6 +584,10 @@
             break;
     }
 
+    if (mActiveBuffers.size() > 0) {
+        freeActiveBuffers();
+    }
+
     Mutex::Autolock _l(mLock);
 
     status_t err = mOwner->freeNode(this);
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index afca7c4..1759ff6 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -11,6 +11,9 @@
 
 cc_binary {
     name: "mediaserver",
+    defaults: [
+        "camera_in_mediaserver_defaults",
+    ],
 
     srcs: ["main_mediaserver.cpp"],
 
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 316732b..1621533 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -27,6 +27,10 @@
 #include "RegisterExtensions.h"
 
 // from LOCAL_C_INCLUDES
+#ifdef NO_CAMERA_SERVER
+#include "CameraService.h"
+#include <hidl/HidlTransportSupport.h>
+#endif
 #include "MediaPlayerService.h"
 #include "ResourceManagerService.h"
 
@@ -36,12 +40,20 @@
 {
     signal(SIGPIPE, SIG_IGN);
 
+#ifdef NO_CAMERA_SERVER
+    // Set 3 threads for HIDL calls
+    hardware::configureRpcThreadpool(3, /*willjoin*/ false);
+#endif
+
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm(defaultServiceManager());
     ALOGI("ServiceManager: %p", sm.get());
     AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
+#ifdef NO_CAMERA_SERVER
+    CameraService::instantiate();
+#endif
     registerExtensions();
     ::android::hardware::configureRpcThreadpool(16, false);
     ProcessState::self()->startThreadPool();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 764fdc3..39fb5f3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -25,6 +25,7 @@
 #include "Configuration.h"
 #include <dirent.h>
 #include <math.h>
+#include <stdio.h>
 #include <signal.h>
 #include <string>
 #include <sys/time.h>
@@ -863,6 +864,15 @@
         output.portId = portId;
 
         if (lStatus == NO_ERROR) {
+
+            // set volume
+            String8 trackCreatorPackage = track->getPackageName();
+            if (!trackCreatorPackage.isEmpty() && mAppTrackDataConfigs.find(trackCreatorPackage) != mAppTrackDataConfigs.end()) {
+                AppTrackData config = mAppTrackDataConfigs[trackCreatorPackage];
+                track->setAppMute(config.muted);
+                track->setAppVolume(config.volume);
+            }
+
             // Connect secondary outputs. Failure on a secondary output must not imped the primary
             // Any secondary output setup failure will lead to a desync between the AP and AF until
             // the track is destroyed.
@@ -1725,6 +1735,77 @@
     return 0;
 }
 
+status_t AudioFlinger::listAppTrackDatas(unsigned int *num, AppTrackData *vols)
+{
+    if (num == NULL || (*num != 0 && vols == NULL)) {
+        return BAD_VALUE;
+    }
+    std::set<AppTrackData> volSet;
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i);
+        thread->listAppTrackDatas(volSet);
+    }
+
+    if (vols == NULL || *num == 0) {
+        *num = volSet.size();
+    } else {
+        if (*num > volSet.size()) {
+            *num = volSet.size();
+        }
+        size_t written = 0;
+        for (AppTrackData vol : volSet) {
+            if (written >= *num) break;
+            strcpy(vols[written].packageName, vol.packageName);
+            vols[written].muted = vol.muted;
+            vols[written].active = vol.active;
+            vols[written++].volume = vol.volume;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setAppVolume(const String8& packageName, const float value)
+{
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
+        t->setAppVolume(packageName, value);
+    }
+
+    if (mAppTrackDataConfigs.find(packageName) == mAppTrackDataConfigs.end()) {
+        AppTrackData vol;
+        strcpy(vol.packageName, packageName.c_str());
+        vol.volume = value;
+        vol.muted = false;
+        mAppTrackDataConfigs[packageName] = vol;
+    } else {
+        mAppTrackDataConfigs[packageName].volume = value;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setAppMute(const String8& packageName, const bool value)
+{
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
+        t->setAppMute(packageName, value);
+    }
+    
+    if (mAppTrackDataConfigs.find(packageName) == mAppTrackDataConfigs.end()) {
+        AppTrackData vol;
+        strcpy(vol.packageName, packageName.c_str());
+        vol.volume = 1.0f;
+        vol.muted = value;
+        mAppTrackDataConfigs[packageName] = vol;
+    } else {
+        mAppTrackDataConfigs[packageName].muted = value;
+    }
+    return NO_ERROR;
+}
+
 status_t AudioFlinger::setVoiceVolume(float value)
 {
     status_t ret = initCheck();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 20f561e..324226b 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -106,6 +106,7 @@
 class AudioMixer;
 class AudioBuffer;
 class AudioResampler;
+class AppTrackData;
 class DeviceHalInterface;
 class DevicesFactoryHalCallback;
 class DevicesFactoryHalInterface;
@@ -330,6 +331,14 @@
     Mutex               mUnregisteredWritersLock;
 
 public:
+    status_t    setAppVolume(const String8& packageName, const float value);
+    status_t    setAppMute(const String8& packageName, const bool value);
+    status_t    listAppTrackDatas(unsigned int *num, AppTrackData *vols);
+
+private:
+    std::map<String8, AppTrackData>  mAppTrackDataConfigs;
+
+public:
 
     class SyncEvent;
 
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 3dfeb83..ff1f9ac 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2017,6 +2017,10 @@
 {
     Mutex::Autolock _l(mLock);
     clearInputBuffer_l();
+
+    for (size_t i = 0; i < mEffects.size(); i++) {
+        mEffects[i]->reset_l();
+    }
 }
 
 // Must be called with EffectChain::mLock locked
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a2df29b..918b814 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -136,10 +136,17 @@
     sp<media::VolumeShaper::State> getVolumeShaperState(int id);
     sp<media::VolumeHandler>   getVolumeHandler() { return mVolumeHandler; }
     /** Set the computed normalized final volume of the track.
-     * !masterMute * masterVolume * streamVolume * averageLRVolume */
+     * !masterMute * !appMuted * masterVolume * streamVolume * averageLRVolume * appVolume */
     void                setFinalVolume(float volume);
     float               getFinalVolume() const { return mFinalVolume; }
 
+    void                setAppVolume(float volume);
+    float               getAppVolume() const { return mAppVolume; }
+    void                setAppMute(bool val);
+    bool                isAppMuted() { return mAppMuted; }
+
+    String8             getPackageName() const { return mPackageName; }
+
     /** @return true if the track has changed (metadata or volume) since
      *          the last time this function was called,
      *          true if this function was never called since the track creation,
@@ -288,6 +295,8 @@
         for (auto& tp : mTeePatches) { f(tp.patchTrack); }
     };
 
+    String8             mPackageName;
+
     // The following fields are only for fast tracks, and should be in a subclass
     int                 mFastIndex; // index within FastMixerState::mFastTracks[];
                                     // either mFastIndex == -1 if not isFastTrack()
@@ -300,7 +309,9 @@
     volatile float      mCachedVolume;  // combined master volume and stream type volume;
                                         // 'volatile' means accessed without lock or
                                         // barrier, but is read/written atomically
-    float               mFinalVolume; // combine master volume, stream type volume and track volume
+    float               mFinalVolume; // combine master volume, stream type volume and track volume and relative volume
+    float               mAppVolume;  // for separate process volume control
+    bool                mAppMuted;
     sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
     bool                mResumeToStopping; // track was paused in stopping state.
     bool                mFlushHwPending; // track requests for thread flush
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1d0147d..419a7cb 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -23,9 +23,11 @@
 #include "Configuration.h"
 #include <math.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <memory>
 #include <sstream>
 #include <string>
+#include <set>
 #include <linux/futex.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -2405,6 +2407,43 @@
     return index;
 }
 
+void AudioFlinger::PlaybackThread::listAppTrackDatas(std::set<AppTrackData> &cup)
+{
+    Mutex::Autolock _l(mLock);
+    for (sp<Track> track : mTracks) {
+        if (!track->getPackageName().isEmpty()) {
+            AppTrackData av;
+            strcpy(av.packageName, track->getPackageName().c_str());
+            av.muted = track->isAppMuted();
+            av.volume = track->getAppVolume();
+            av.active = mActiveTracks.indexOf(track) >= 0;
+            cup.insert(av);
+        }
+    }
+}
+
+status_t AudioFlinger::PlaybackThread::setAppVolume(const String8& packageName, const float value)
+{
+    Mutex::Autolock _l(mLock);
+    for (sp<Track> track : mTracks) {
+        if (packageName == track->getPackageName()) {
+            track->setAppVolume(value);
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::PlaybackThread::setAppMute(const String8& packageName, const bool value)
+{
+    Mutex::Autolock _l(mLock);
+    for (sp<Track> track : mTracks) {
+        if (packageName == track->getPackageName()) {
+            track->setAppMute(value);
+        }
+    }
+    return NO_ERROR;
+}
+
 uint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
 {
     return latency;
@@ -5003,10 +5042,10 @@
                 }
                 sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
                 float volume;
-                if (track->isPlaybackRestricted() || mStreamTypes[track->streamType()].mute) {
+                if (track->isPlaybackRestricted() || mStreamTypes[track->streamType()].mute || track->isAppMuted()) {
                     volume = 0.f;
                 } else {
-                    volume = masterVolume * mStreamTypes[track->streamType()].volume;
+                    volume = masterVolume * mStreamTypes[track->streamType()].volume * track->getAppVolume();
                 }
 
                 handleVoipVolume_l(&volume);
@@ -5163,13 +5202,13 @@
             uint32_t vl, vr;       // in U8.24 integer format
             float vlf, vrf, vaf;   // in [0.0, 1.0] float format
             // read original volumes with volume control
-            float v = masterVolume * mStreamTypes[track->streamType()].volume;
+            float v = masterVolume * mStreamTypes[track->streamType()].volume * track->getAppVolume();
             // Always fetch volumeshaper volume to ensure state is updated.
             const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
             const float vh = track->getVolumeHandler()->getVolume(
                     track->mAudioTrackServerProxy->framesReleased()).first;
 
-            if (mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
+            if (mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted() || track->isAppMuted()) {
                 v = 0;
             }
 
@@ -5723,11 +5762,12 @@
             proxy->framesReleased());
     mVolumeShaperActive = shaperActive;
 
-    if (mMasterMute || mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
+    if (mMasterMute || mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted() || track->isAppMuted()) {
         left = right = 0;
     } else {
         float typeVolume = mStreamTypes[track->streamType()].volume;
-        const float v = mMasterVolume * typeVolume * shaperVolume;
+        float appVolume = track->getAppVolume();
+        const float v = mMasterVolume * typeVolume * shaperVolume * appVolume;
 
         gain_minifloat_packed_t vlr = proxy->getVolumeLR();
         left = float_from_gain(gain_minifloat_unpack_left(vlr));
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 6b33ad5..b8356d3 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -845,6 +845,10 @@
 
                 void        setVolumeForOutput_l(float left, float right) const override;
 
+                status_t    setAppVolume(const String8& packageName, const float value);
+                status_t    setAppMute(const String8& packageName, const bool muted);
+                void        listAppTrackDatas(std::set<AppTrackData> &cup);
+
                 sp<Track>   createTrack_l(
                                 const sp<AudioFlinger::Client>& client,
                                 audio_stream_type_t streamType,
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index f286d8a..1f4f622 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -567,6 +567,20 @@
     ALOGV_IF(sharedBuffer != 0, "%s(%d): sharedBuffer: %p, size: %zu",
             __func__, mId, sharedBuffer->unsecurePointer(), sharedBuffer->size());
 
+    /* get package name */
+    PermissionController permissionController;
+    Vector<String16> packages;
+    permissionController.getPackagesForUid(uid, packages);
+    if (!packages.isEmpty()) {
+        mPackageName = String8(packages[0]);
+    } else {
+        mPackageName = "";
+    }
+
+    /* init app volume */
+    mAppMuted = false;
+    mAppVolume = 1.0f;
+
     if (mCblk == NULL) {
         return;
     }
@@ -1264,6 +1278,16 @@
     }
 }
 
+void AudioFlinger::PlaybackThread::Track::setAppVolume(float volume)
+{
+    mAppVolume = volume;
+}
+
+void AudioFlinger::PlaybackThread::Track::setAppMute(bool val)
+{
+    mAppMuted = val;
+}
+
 void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backInserter) const
 {
     *backInserter++ = {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 8d0e5db..a350f6c 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -421,6 +421,8 @@
     // sessions to be preempted on modules that do not support sound trigger
     // recognition concurrently with audio capture.
     virtual void setSoundTriggerCaptureState(bool active) = 0;
+
+    virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& streamInfo, bool added) = 0;
 };
 
 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 0537365..4047d76 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -35,7 +35,7 @@
 
 // For mixed output and inputs, the policy will use max mixer sampling rates.
 // Do not limit sampling rate otherwise
-#define SAMPLE_RATE_HZ_MAX 192000
+#define SAMPLE_RATE_HZ_MAX 384000
 
 // Used when a client opens a capture stream, without specifying a desired sample rate.
 #define SAMPLE_RATE_HZ_DEFAULT 48000
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 39d1140..daced38 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -305,6 +305,7 @@
 
     DeviceVector mDevices; /**< current devices this output is routed to */
     wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
+    audio_io_handle_t mIoHandle;           // output handle
 
 protected:
     const sp<PolicyAudioPort> mPolicyAudioPort;
@@ -404,7 +405,6 @@
     DeviceVector filterSupportedDevices(const DeviceVector &devices) const;
 
     const sp<IOProfile> mProfile;          // I/O profile this output derives from
-    audio_io_handle_t mIoHandle;           // output handle
     uint32_t mLatency;                  //
     audio_output_flags_t mFlags;   //
     sp<SwAudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index d6d472b..e61af6f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -40,7 +40,7 @@
 
 AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
                                              AudioPolicyClientInterface *clientInterface)
-    : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
+    : mIoHandle(AUDIO_IO_HANDLE_NONE), mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
 {
     if (mPolicyAudioPort.get() != nullptr) {
         mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -278,7 +278,7 @@
 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
                                                  AudioPolicyClientInterface *clientInterface)
     : AudioOutputDescriptor(profile, clientInterface),
-    mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
+    mProfile(profile), mLatency(0),
     mFlags((audio_output_flags_t)0),
     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
     mDirectClientSession(AUDIO_SESSION_NONE)
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 7f339dc..136013a 100755
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -39,6 +39,11 @@
 
     audio_mode_t getPhoneState() const override { return mPhoneState; }
 
+    void setDpConnAndAllowedForVoice(bool connAndAllowed) override
+    {
+        mDpConnAndAllowedForVoice = connAndAllowed;
+    }
+
     status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override
     {
         mForceUse[usage] = config;
@@ -118,6 +123,11 @@
         return is_state_in_call(getPhoneState());
     }
 
+    inline bool getDpConnAndAllowedForVoice() const
+    {
+        return mDpConnAndAllowedForVoice;
+    }
+
     VolumeSource toVolumeSource(audio_stream_type_t stream) const
     {
         return static_cast<VolumeSource>(getVolumeGroupForStreamType(stream));
@@ -135,6 +145,8 @@
     VolumeGroupMap mVolumeGroups;
     LastRemovableMediaDevices mLastRemovableMediaDevices;
     audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
+    /* if display-port is connected and can be used for voip/voice */
+    bool mDpConnAndAllowedForVoice;
 
     /** current forced use configuration. */
     audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT] = {};
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index dfb20b5..650c15f 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -73,6 +73,14 @@
     virtual audio_mode_t getPhoneState() const = 0;
 
     /**
+     * Set whether display-port is connected and is allowed to be used
+     * for voice usecases
+     *
+     * @param[in] connAndAllowed: if display-port is connected and can be used
+     */
+    virtual void setDpConnAndAllowedForVoice(bool connAndAllowed) = 0;
+
+    /**
      * Set Force Use config for a given usage.
      *
      * @param[in] usage for which a configuration shall be forced.
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index b14d2bb..37f1a98 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -250,6 +250,10 @@
                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES});
                 if (!devices.isEmpty()) break;
             }
+            if (getDpConnAndAllowedForVoice() && isInCall()) {
+                devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
+                if (!devices.isEmpty()) break;
+            }
             devices = availableOutputDevices.getFirstDevicesFromTypes({
                     AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADSET,
                     AUDIO_DEVICE_OUT_LINE, AUDIO_DEVICE_OUT_USB_HEADSET,
@@ -340,6 +344,16 @@
                 }
             }
         }
+        // if display-port is connected and being used in voice usecase,
+        // play ringtone over speaker and display-port
+        if ((strategy == STRATEGY_SONIFICATION) && getDpConnAndAllowedForVoice()) {
+            DeviceVector devices2 = availableOutputDevices.getDevicesFromType(
+                    AUDIO_DEVICE_OUT_AUX_DIGITAL);
+            if (!devices2.isEmpty()) {
+                devices.add(devices2);
+                break;
+            }
+        }
         // The second device used for sonification is the same as the device used by media strategy
         FALLTHROUGH_INTENDED;
 
@@ -371,6 +385,13 @@
     // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
     case STRATEGY_REROUTING:
     case STRATEGY_MEDIA: {
+        if (isInCall() && devices.isEmpty()) {
+            // when in call, get the device for Phone strategy
+            devices = getDevicesForStrategyInt(
+                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
+            break;
+        }
+
         DeviceVector devices2;
         if (strategy != STRATEGY_SONIFICATION) {
             // no sonification on remote submix (e.g. WFD)
@@ -407,7 +428,8 @@
                         getLastRemovableMediaDevices(GROUP_WIRED));
             }
         }
-        if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {
+        if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION) &&
+                (devices.isEmpty())) {
             // no sonification on aux digital (e.g. HDMI)
             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
         }
@@ -416,6 +438,12 @@
             devices2 = availableOutputDevices.getDevicesFromType(
                     AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
         }
+        if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION) &&
+                (devices.isEmpty())) {
+            // no sonification on WFD sink
+            devices2 = availableOutputDevices.getDevicesFromType(
+                    AUDIO_DEVICE_OUT_PROXY);
+        }
         if (devices2.isEmpty()) {
             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b588f89..b2a670e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -506,7 +506,7 @@
         // when a device is disconnected, checks if an output is not used any more and
         // returns its handle if any.
         // transfers the audio tracks and effects from one output thread to another accordingly.
-        status_t checkOutputsForDevice(const sp<DeviceDescriptor>& device,
+        virtual status_t checkOutputsForDevice(const sp<DeviceDescriptor>& device,
                                        audio_policy_dev_state_t state,
                                        SortedVector<audio_io_handle_t>& outputs);
 
@@ -539,7 +539,7 @@
          * Must be called before updateDevicesAndOutputs()
          * @param attr to be considered
          */
-        void checkOutputForAttributes(const audio_attributes_t &attr);
+        virtual void checkOutputForAttributes(const audio_attributes_t &attr);
 
         bool followsSameRouting(const audio_attributes_t &lAttr,
                                 const audio_attributes_t &rAttr) const;
@@ -685,10 +685,10 @@
                                             uint32_t delayMs);
         bool isDeviceOfModule(const sp<DeviceDescriptor>& devDesc, const char *moduleId) const;
 
-        status_t startSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+        virtual status_t startSource(const sp<SwAudioOutputDescriptor>& outputDesc,
                              const sp<TrackClientDescriptor>& client,
                              uint32_t *delayMs);
-        status_t stopSource(const sp<SwAudioOutputDescriptor>& outputDesc,
+        virtual status_t stopSource(const sp<SwAudioOutputDescriptor>& outputDesc,
                             const sp<TrackClientDescriptor>& client);
 
         void clearAudioPatches(uid_t uid);
@@ -787,7 +787,7 @@
         std::unordered_set<audio_format_t> mManualSurroundFormats;
 
         std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
-private:
+protected:
         void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
 
         // Add or remove AC3 DTS encodings based on user preferences.
@@ -840,7 +840,7 @@
                 std::vector<sp<AudioPolicyMix>> *secondaryMixes,
                 output_type_t *outputType);
         // internal method to return the output handle for the given device and format
-        audio_io_handle_t getOutputForDevices(
+        virtual audio_io_handle_t getOutputForDevices(
                 const DeviceVector &devices,
                 audio_session_t session,
                 audio_stream_type_t stream,
@@ -885,7 +885,7 @@
         bool     isValidAttributes(const audio_attributes_t *paa);
 
         // Called by setDeviceConnectionState().
-        status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
+        virtual status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
                                              audio_policy_dev_state_t state,
                                              const char *device_address,
                                              const char *device_name,
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9fa7a53..177c3cb 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -236,6 +236,13 @@
     mAudioPolicyService->onAudioVolumeGroupChanged(group, flags);
 }
 
+void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate(
+        sp<AudioSessionInfo>& info, bool added)
+{
+    mAudioPolicyService->onOutputSessionEffectsUpdate(info, added);
+}
+
+
 audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
 {
     return AudioSystem::newAudioUniqueId(use);
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index b738633..a5e5bb8 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -31,6 +31,7 @@
 #include <utils/SortedVector.h>
 #include <cutils/config_utils.h>
 #include <binder/IPCThreadState.h>
+#include "AudioPolicyService.h"
 #include "AudioPolicyEffects.h"
 
 namespace android {
@@ -39,7 +40,8 @@
 // AudioPolicyEffects Implementation
 // ----------------------------------------------------------------------------
 
-AudioPolicyEffects::AudioPolicyEffects()
+AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) :
+    mAudioPolicyService(audioPolicyService)
 {
     status_t loadResult = loadAudioEffectXmlConfig();
     if (loadResult == NO_ERROR) {
@@ -238,6 +240,8 @@
 {
     status_t status = NO_ERROR;
 
+    ALOGV("addOutputSessionEffects %d", audioSession);
+
     Mutex::Autolock _l(mLock);
     // create audio processors according to stream
     // FIXME: should we have specific post processing settings for internal streams?
@@ -245,6 +249,22 @@
     if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
         stream = AUDIO_STREAM_MUSIC;
     }
+
+    // send the streaminfo notification only once
+    ssize_t sidx = mOutputAudioSessionInfo.indexOfKey(audioSession);
+    if (sidx >= 0) {
+        // AudioSessionInfo is existing and we just need to increase ref count
+        sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(sidx);
+        info->mRefCount++;
+
+        if (info->mRefCount == 1) {
+            mAudioPolicyService->onOutputSessionEffectsUpdate(info, true);
+        }
+        ALOGV("addOutputSessionEffects(): session info %d refCount=%d", audioSession, info->mRefCount);
+    } else {
+        ALOGV("addOutputSessionEffects(): no output stream info found for stream");
+    }
+
     ssize_t index = mOutputStreams.indexOfKey(stream);
     if (index < 0) {
         ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
@@ -290,6 +310,86 @@
     return status;
 }
 
+status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */,
+                                           audio_stream_type_t stream,
+                                           audio_session_t session)
+{
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+    if (idx >= 0) {
+        sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(idx);
+        if (info->mRefCount == 0) {
+            mOutputAudioSessionInfo.removeItemsAt(idx);
+        }
+        ALOGV("releaseOutputAudioSessionInfo() sessionId=%d refcount=%d",
+                session, info->mRefCount);
+    } else {
+        ALOGV("releaseOutputAudioSessionInfo() no session info found");
+    }
+    return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* output */,
+                                           audio_stream_type_t stream,
+                                           audio_session_t session,
+                                           audio_output_flags_t flags,
+                                           const audio_config_t *config, uid_t uid)
+{
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    // TODO: Handle other stream types based on client registration
+    if (stream != AUDIO_STREAM_MUSIC) {
+        return NO_ERROR;
+    }
+
+    // update AudioSessionInfo. This is used in the stream open/close path
+    // to notify userspace applications about session creation and
+    // teardown, allowing the app to make decisions about effects for
+    // a particular stream. This is independent of the current
+    // output_session_processing feature which forcibly attaches a
+    // static list of effects to a stream.
+    ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+    sp<AudioSessionInfo> info;
+    if (idx < 0) {
+        info = new AudioSessionInfo(session, stream, flags, config->channel_mask, uid);
+        mOutputAudioSessionInfo.add(session, info);
+    } else {
+        // the streaminfo may actually change
+        info = mOutputAudioSessionInfo.valueAt(idx);
+        info->mFlags = flags;
+        info->mChannelMask = config->channel_mask;
+    }
+
+    ALOGV("updateOutputAudioSessionInfo() sessionId=%d, flags=0x%x, channel_mask=0x%x uid=%d refCount=%d",
+            info->mSessionId, info->mFlags, info->mChannelMask, info->mUid, info->mRefCount);
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::listAudioSessions(audio_stream_type_t streams,
+                                               Vector< sp<AudioSessionInfo>> &sessions)
+{
+    ALOGV("listAudioSessions() streams %d", streams);
+
+    for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) {
+        sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(i);
+        if (streams == -1 || info->mStream == streams) {
+            sessions.push_back(info);
+        }
+    }
+
+    return NO_ERROR;
+}
+
 status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
                          audio_stream_type_t stream,
                          audio_session_t audioSession)
@@ -299,7 +399,19 @@
     (void) stream; // argument not used for now
 
     Mutex::Autolock _l(mLock);
-    ssize_t index = mOutputSessions.indexOfKey(audioSession);
+    ssize_t index = mOutputAudioSessionInfo.indexOfKey(audioSession);
+    if (index >= 0) {
+        sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(index);
+        info->mRefCount--;
+        if (info->mRefCount == 0) {
+            mAudioPolicyService->onOutputSessionEffectsUpdate(info, false);
+        }
+        ALOGV("releaseOutputSessionEffects(): session=%d refCount=%d", info->mSessionId, info->mRefCount);
+    } else {
+        ALOGV("releaseOutputSessionEffects: no stream info was attached to this stream");
+    }
+
+    index = mOutputSessions.indexOfKey(audioSession);
     if (index < 0) {
         ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
         return NO_ERROR;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 81c728d..137e37f 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -31,6 +31,8 @@
 
 namespace android {
 
+class AudioPolicyService;
+
 // ----------------------------------------------------------------------------
 
 // AudioPolicyEffects class
@@ -44,7 +46,7 @@
     // The constructor will parse audio_effects.conf
     // First it will look whether vendor specific file exists,
     // otherwise it will parse the system default file.
-	         AudioPolicyEffects();
+            AudioPolicyEffects(AudioPolicyService *audioPolicyService);
     virtual ~AudioPolicyEffects();
 
     // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService
@@ -106,6 +108,19 @@
     // Remove the default stream effect from wherever it's attached.
     status_t removeStreamDefaultEffect(audio_unique_id_t id);
 
+    status_t updateOutputAudioSessionInfo(audio_io_handle_t output,
+                             audio_stream_type_t stream,
+                             audio_session_t audioSession,
+                             audio_output_flags_t flags,
+                             const audio_config_t *config, uid_t uid);
+
+    status_t releaseOutputAudioSessionInfo(audio_io_handle_t output,
+                             audio_stream_type_t stream,
+                             audio_session_t audioSession);
+
+    status_t listAudioSessions(audio_stream_type_t streams,
+                             Vector< sp<AudioSessionInfo>> &sessions);
+
 private:
     void initDefaultDeviceEffects();
 
@@ -276,6 +291,11 @@
      * We must store the reference of the furture garantee real asynchronous operation.
      */
     std::future<void> mDefaultDeviceEffectFuture;
+
+    // Stream info for session events
+    KeyedVector< audio_session_t, sp<AudioSessionInfo> > mOutputAudioSessionInfo;
+
+    AudioPolicyService *mAudioPolicyService;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index df27f6e..0b15713 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -235,61 +235,72 @@
     }
 
     ALOGV("%s()", __func__);
-    Mutex::Autolock _l(mLock);
+    sp<AudioPolicyEffects> audioPolicyEffects;
+    {
+        Mutex::Autolock _l(mLock);
 
-    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
-        ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
-                "%s uid %d tried to pass itself off as %d", __func__, callingUid, uid);
-        uid = callingUid;
-    }
-    if (!mPackageManager.allowPlaybackCapture(uid)) {
-        attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
-    }
-    if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
-            && !bypassInterruptionPolicyAllowed(pid, uid)) {
-        attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
-    }
-    AutoCallerClear acc;
-    AudioPolicyInterface::output_type_t outputType;
-    result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
-                                                 config,
-                                                 &flags, selectedDeviceId, portId,
-                                                 secondaryOutputs,
-                                                 &outputType);
-
-    // FIXME: Introduce a way to check for the the telephony device before opening the output
-    if (result == NO_ERROR) {
-        // enforce permission (if any) required for each type of input
-        switch (outputType) {
-        case AudioPolicyInterface::API_OUTPUT_LEGACY:
-            break;
-        case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
-            if (!modifyPhoneStateAllowed(pid, uid)) {
-                ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
-                    __func__, uid);
-                result = PERMISSION_DENIED;
-            }
-            break;
-        case AudioPolicyInterface::API_OUT_MIX_PLAYBACK:
-            if (!modifyAudioRoutingAllowed(pid, uid)) {
-                ALOGE("%s() permission denied: modify audio routing not allowed for uid %d",
-                    __func__, uid);
-                result = PERMISSION_DENIED;
-            }
-            break;
-        case AudioPolicyInterface::API_OUTPUT_INVALID:
-        default:
-            LOG_ALWAYS_FATAL("%s() encountered an invalid output type %d",
-                __func__, (int)outputType);
+        const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
+            ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+                    "%s uid %d tried to pass itself off as %d", __func__, callingUid, uid);
+            uid = callingUid;
         }
+        if (!mPackageManager.allowPlaybackCapture(uid)) {
+            attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
+        }
+        if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
+                && !bypassInterruptionPolicyAllowed(pid, uid)) {
+            attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
+        }
+        AutoCallerClear acc;
+        AudioPolicyInterface::output_type_t outputType;
+        result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
+                                                     config,
+                                                     &flags, selectedDeviceId, portId,
+                                                     secondaryOutputs,
+                                                     &outputType);
+
+        // FIXME: Introduce a way to check for the the telephony device before opening the output
+        if (result == NO_ERROR) {
+            // enforce permission (if any) required for each type of input
+            switch (outputType) {
+            case AudioPolicyInterface::API_OUTPUT_LEGACY:
+                break;
+            case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
+                if (!modifyPhoneStateAllowed(pid, uid)) {
+                    ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
+                        __func__, uid);
+                    result = PERMISSION_DENIED;
+                }
+                break;
+            case AudioPolicyInterface::API_OUT_MIX_PLAYBACK:
+                if (!modifyAudioRoutingAllowed(pid, uid)) {
+                    ALOGE("%s() permission denied: modify audio routing not allowed for uid %d",
+                        __func__, uid);
+                    result = PERMISSION_DENIED;
+                }
+                break;
+            case AudioPolicyInterface::API_OUTPUT_INVALID:
+            default:
+                LOG_ALWAYS_FATAL("%s() encountered an invalid output type %d",
+                    __func__, (int)outputType);
+            }
+        }
+
+        if (result == NO_ERROR) {
+            sp <AudioPlaybackClient> client =
+                new AudioPlaybackClient(*attr, *output, uid, pid, session, *portId, *selectedDeviceId, *stream);
+            mAudioPlaybackClients.add(*portId, client);
+        }
+
+        audioPolicyEffects = mAudioPolicyEffects;
     }
 
-    if (result == NO_ERROR) {
-        sp <AudioPlaybackClient> client =
-            new AudioPlaybackClient(*attr, *output, uid, pid, session, *portId, *selectedDeviceId, *stream);
-        mAudioPlaybackClients.add(*portId, client);
+    if (result == NO_ERROR && audioPolicyEffects != 0) {
+        audioPolicyEffects->updateOutputAudioSessionInfo(*output, *stream,
+                session, flags, config, uid);
     }
+
     return result;
 }
 
@@ -393,11 +404,20 @@
         audioPolicyEffects->releaseOutputSessionEffects(
             client->io, client->stream, client->session);
     }
-    Mutex::Autolock _l(mLock);
-    mAudioPlaybackClients.removeItem(portId);
+    {
+        Mutex::Autolock _l(mLock);
+        mAudioPlaybackClients.removeItem(portId);
 
-    // called from internal thread: no need to clear caller identity
-    mAudioPolicyManager->releaseOutput(portId);
+        audioPolicyEffects = mAudioPolicyEffects;
+
+        // called from internal thread: no need to clear caller identity
+        mAudioPolicyManager->releaseOutput(portId);
+    }
+
+    if (audioPolicyEffects != 0) {
+        audioPolicyEffects->releaseOutputAudioSessionInfo(client->io,
+                client->stream, client->session);
+    }
 }
 
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
@@ -1534,4 +1554,24 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams,
+                                               Vector< sp<AudioSessionInfo>> &sessions)
+{
+    sp<AudioPolicyEffects> audioPolicyEffects;
+    {
+        Mutex::Autolock _l(mLock);
+        if (mAudioPolicyManager == NULL) {
+            return NO_INIT;
+        }
+        audioPolicyEffects = mAudioPolicyEffects;
+    }
+
+    if (audioPolicyEffects != 0) {
+        return audioPolicyEffects->listAudioSessions(streams, sessions);
+    }
+
+    // no errors here if effects are not available
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index a6e8989..fbd7614 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -78,7 +78,7 @@
         mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
     }
     // load audio processing modules
-    sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();
+    sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects(this);
     sp<UidPolicy> uidPolicy = new UidPolicy(this);
     sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
     {
@@ -293,6 +293,21 @@
     return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
 }
 
+void AudioPolicyService::onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+{
+    ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)",
+            info->mStream, info->mSessionId, added);
+    mOutputCommandThread->effectSessionUpdateCommand(info, added);
+}
+
+void AudioPolicyService::doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+{
+    Mutex::Autolock _l(mNotificationClientsLock);
+    for (size_t i = 0; i < mNotificationClients.size(); i++) {
+        mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(info, added);
+    }
+}
+
 AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
                                                      const sp<IAudioPolicyServiceClient>& client,
                                                      uid_t uid,
@@ -337,6 +352,13 @@
     }
 }
 
+void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate(
+        sp<AudioSessionInfo>& info, bool added)
+{
+    if (mAudioPolicyServiceClient != 0) {
+        mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(info, added);
+    }
+}
 
 void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
         const String8& regId, int32_t state)
@@ -1366,6 +1388,20 @@
                     svc->doOnNewAudioModulesAvailable();
                     mLock.lock();
                     } break;
+                case EFFECT_SESSION_UPDATE: {
+                    EffectSessionUpdateData *data =
+                            (EffectSessionUpdateData *)command->mParam.get();
+                    ALOGV("AudioCommandThread() processing effect session update %d %d %d",
+                            data->mAudioSessionInfo->mStream, data->mAudioSessionInfo->mSessionId,
+                            data->mAdded);
+                    svc = mService.promote();
+                    if (svc == 0) {
+                        break;
+                    }
+                    mLock.unlock();
+                    svc->doOnOutputSessionEffectsUpdate(data->mAudioSessionInfo, data->mAdded);
+                    mLock.lock();
+                    } break;
 
                 default:
                     ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
@@ -1662,6 +1698,20 @@
     sendCommand(command);
 }
 
+void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand(
+        sp<AudioSessionInfo>& streamInfo, bool added)
+{
+    sp<AudioCommand> command = new AudioCommand();
+    command->mCommand = EFFECT_SESSION_UPDATE;
+    EffectSessionUpdateData *data = new EffectSessionUpdateData();
+    data->mAudioSessionInfo = streamInfo;
+    data->mAdded = added;
+    command->mParam = data;
+    ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)",
+            streamInfo->mStream, streamInfo->mSessionId, added);
+    sendCommand(command);
+}
+
 status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
 {
     {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 869a963..fc61cce 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -288,6 +288,9 @@
             status_t doStopOutput(audio_port_handle_t portId);
             void doReleaseOutput(audio_port_handle_t portId);
 
+    virtual status_t listAudioSessions(audio_stream_type_t stream,
+                                       Vector< sp<AudioSessionInfo>>& sessions);
+
             status_t clientCreateAudioPatch(const struct audio_patch *patch,
                                       audio_patch_handle_t *handle,
                                       int delayMs);
@@ -327,6 +330,9 @@
                                     audio_session_t sessionId,
                                     bool suspended);
 
+            void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+            void doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+
 private:
                         AudioPolicyService() ANDROID_API;
     virtual             ~AudioPolicyService();
@@ -475,6 +481,7 @@
             RECORDING_CONFIGURATION_UPDATE,
             SET_EFFECT_SUSPENDED,
             AUDIO_MODULES_UPDATE,
+            EFFECT_SESSION_UPDATE,
         };
 
         AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -522,6 +529,8 @@
                                                           bool suspended);
                     void        audioModulesUpdateCommand();
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
+                    void        effectSessionUpdateCommand(sp<AudioSessionInfo>& info, bool added);
+
     private:
         class AudioCommandData;
 
@@ -625,6 +634,12 @@
             bool mSuspended;
         };
 
+        class EffectSessionUpdateData : public AudioCommandData {
+        public:
+            sp<AudioSessionInfo> mAudioSessionInfo;
+            bool mAdded;
+        };
+
         Mutex   mLock;
         Condition mWaitWorkCV;
         Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands
@@ -743,6 +758,8 @@
 
         void setSoundTriggerCaptureState(bool active) override;
 
+        virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+
      private:
         AudioPolicyService *mAudioPolicyService;
     };
@@ -771,6 +788,8 @@
                                                     audio_source_t source);
                             void      setAudioPortCallbacksEnabled(bool enabled);
                             void setAudioVolumeGroupCallbacksEnabled(bool enabled);
+                            void      onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info,
+                                                                   bool added);
 
                             uid_t uid() {
                                 return mUid;
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 501d922..76fae25 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -18,6 +18,11 @@
 
 cc_library_shared {
     name: "libcameraservice",
+    defaults: [
+        "no_cameraserver_defaults",
+        "qti_camera_device_defaults",
+        "target_camera_needs_client_info_defaults",
+    ],
 
     // Camera service source
 
@@ -127,7 +132,8 @@
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.device@3.5",
-        "android.hardware.camera.device@3.6"
+        "android.hardware.camera.device@3.6",
+        "vendor.lineage.camera.motor@1.0"
     ],
 
     static_libs: [
@@ -157,6 +163,5 @@
         "-Werror",
         "-Wno-ignored-qualifiers",
     ],
-
 }
 
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index e629cdd..7e8cc5b 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -512,6 +512,22 @@
     return device->setPreviewWindow(mSurface);
 }
 
+static void notifyCallback(int32_t, int32_t, int32_t, void*) {
+    /* Empty */
+}
+
+static void dataCallback(int32_t, const sp<IMemory>&, camera_frame_metadata_t*, void*) {
+    /* Empty */
+}
+
+static void dataCallbackTimestamp(nsecs_t, int32_t, const sp<IMemory>&, void*) {
+    /* Empty */
+}
+
+static void dataCallbackTimestampBatch(int32_t, const std::vector<HandleTimestampMessage>&,
+        void*) {
+    /* Empty */
+}
 status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
         const String8& cameraId) {
     sp<CameraHardwareInterface> device =
@@ -525,7 +541,8 @@
     }
 
     // need to set __get_memory in set_callbacks().
-    device->setCallbacks(NULL, NULL, NULL, NULL, NULL);
+    device->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, 
+            dataCallbackTimestampBatch, this);
 
     mParameters = device->getParameters();
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index e2fcb5a..ae9616b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -24,6 +24,10 @@
 #include <cstring>
 #include <ctime>
 #include <string>
+#ifdef TARGET_NEEDS_CLIENT_INFO
+#include <iostream>
+#include <fstream>
+#endif
 #include <sys/types.h>
 #include <inttypes.h>
 #include <pthread.h>
@@ -77,6 +81,8 @@
 #include "utils/TagMonitor.h"
 #include "utils/CameraThreadState.h"
 
+#include <vendor/lineage/camera/motor/1.0/ICameraMotor.h>
+
 namespace {
     const char* kPermissionServiceName = "permission";
 }; // namespace anonymous
@@ -94,6 +100,7 @@
 using hardware::camera::common::V1_0::TorchModeStatus;
 using hardware::camera2::utils::CameraIdAndSessionConfiguration;
 using hardware::camera2::utils::ConcurrentCameraIdCombination;
+using vendor::lineage::camera::motor::V1_0::ICameraMotor;
 
 // ----------------------------------------------------------------------------
 // Logging support -- this is for debugging only
@@ -252,8 +259,14 @@
     proxyBinder->pingForUserUpdate();
 }
 
-void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status,
-        SystemCameraKind systemCameraKind) {
+void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
+    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+    status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
+    if (res != OK) {
+        ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
+                cameraId.string());
+        return;
+    }
     Mutex::Autolock lock(mStatusListenerLock);
     for (auto& i : mListenerList) {
         if (shouldSkipStatusUpdates(systemCameraKind, i->isVendorListener(), i->getListenerPid(),
@@ -347,7 +360,7 @@
         Mutex::Autolock al(mTorchStatusMutex);
         mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
 
-        broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF, deviceKind);
+        broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF);
     }
 
     updateCameraNumAndIds();
@@ -508,19 +521,12 @@
 
 void CameraService::onTorchStatusChanged(const String8& cameraId,
         TorchModeStatus newStatus) {
-    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
-    status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
-    if (res != OK) {
-        ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
-                cameraId.string());
-        return;
-    }
     Mutex::Autolock al(mTorchStatusMutex);
-    onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
+    onTorchStatusChangedLocked(cameraId, newStatus);
 }
 
 void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
-        TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
+        TorchModeStatus newStatus) {
     ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
             __FUNCTION__, cameraId.string(), newStatus);
 
@@ -569,7 +575,7 @@
             }
         }
     }
-    broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
+    broadcastTorchModeStatus(cameraId, newStatus);
 }
 
 static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
@@ -963,7 +969,11 @@
 Status CameraService::initializeShimMetadata(int cameraId) {
     int uid = CameraThreadState::getCallingUid();
 
+#ifdef NO_CAMERA_SERVER
+    String16 internalPackageName("media");
+#else
     String16 internalPackageName("cameraserver");
+#endif
     String8 id = String8::format("%d", cameraId);
     Status ret = Status::ok();
     sp<Client> tmp = nullptr;
@@ -1044,7 +1054,9 @@
 static bool isTrustedCallingUid(uid_t uid) {
     switch (uid) {
         case AID_MEDIA:        // mediaserver
+#ifndef NO_CAMERA_SERVER
         case AID_CAMERASERVER: // cameraserver
+#endif
         case AID_RADIO:        // telephony
             return true;
         default:
@@ -1177,6 +1189,7 @@
                 clientName8.string(), clientUid, clientPid, cameraId.string());
     }
 
+#ifndef NO_CAMERA_SERVER
     // Make sure the UID is in an active state to use the camera
     if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
         int32_t procState = mUidPolicy->getProcState(callingUid);
@@ -1188,6 +1201,7 @@
                 clientName8.string(), clientUid, clientPid, cameraId.string(),
                 callingUid, procState);
     }
+#endif
 
     // If sensor privacy is enabled then prevent access to the camera
     if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
@@ -1782,6 +1796,11 @@
         } else {
             // Otherwise, add client to active clients list
             finishConnectLocked(client, partial);
+
+            sp<ICameraMotor> cameraMotor = ICameraMotor::getService();
+            if (cameraMotor != nullptr) {
+                cameraMotor->onConnect(cameraId.string());
+            }
         }
     } // lock is destroyed, allow further connect calls
 
@@ -2437,7 +2456,8 @@
                 ret = true;
             }
         }
-
+        //clear the evicted client list before acquring service lock again.
+        evicted.clear();
         // Reacquire mServiceLock
         mServiceLock.lock();
 
@@ -2849,6 +2869,11 @@
     }
     mDisconnected = true;
 
+    sp<ICameraMotor> cameraMotor = ICameraMotor::getService();
+    if (cameraMotor != nullptr) {
+        cameraMotor->onDisconnect(mCameraIdStr.string());
+    }
+
     sCameraService->removeByClient(this);
     sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
     sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
@@ -2883,6 +2908,10 @@
     return mClientPackageName;
 }
 
+bool CameraService::BasicClient::isFaceUnlockPackage() const {
+    std::string cpn = String8(mClientPackageName).string();
+    return cpn.compare("org.pixelexperience.faceunlock") == 0;
+}
 
 int CameraService::BasicClient::getClientPid() const {
     return mClientPid;
@@ -2943,7 +2972,7 @@
                 mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId,
                 String16("start camera ") + String16(mCameraIdStr));
 
-        if (res == AppOpsManager::MODE_ERRORED) {
+        if (!isFaceUnlockPackage() && res == AppOpsManager::MODE_ERRORED) {
             ALOGI("Camera %s: Access for \"%s\" has been revoked",
                     mCameraIdStr.string(), String8(mClientPackageName).string());
             return PERMISSION_DENIED;
@@ -2951,7 +2980,7 @@
 
         // If the calling Uid is trusted (a native service), the AppOpsManager could
         // return MODE_IGNORED. Do not treat such case as error.
-        if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
+        if (!isFaceUnlockPackage() && !mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
             ALOGI("Camera %s: Access for \"%s\" has been restricted",
                     mCameraIdStr.string(), String8(mClientPackageName).string());
             // Return the same error as for device policy manager rejection
@@ -2977,6 +3006,12 @@
     // Notify listeners of camera open/close status
     sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
 
+#ifdef TARGET_NEEDS_CLIENT_INFO
+    std::ofstream cpf("/data/misc/aosp/client_package_name");
+    std::string cpn = String8(mClientPackageName).string();
+    cpf << cpn;
+#endif
+
     return OK;
 }
 
@@ -3797,7 +3832,7 @@
                             TorchModeStatus::AVAILABLE_OFF :
                             TorchModeStatus::NOT_AVAILABLE;
                     if (torchStatus != newTorchStatus) {
-                        onTorchStatusChangedLocked(cameraId, newTorchStatus, deviceKind);
+                        onTorchStatusChangedLocked(cameraId, newTorchStatus);
                     }
                 }
             }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 5c4c96b..a192202 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -295,6 +295,9 @@
         // Override rotate-and-crop AUTO behavior
         virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop) = 0;
 
+        // Return if current package is face unlock
+        virtual bool isFaceUnlockPackage() const;
+
     protected:
         BasicClient(const sp<CameraService>& cameraService,
                 const sp<IBinder>& remoteCallback,
@@ -995,8 +998,7 @@
     // handle torch mode status change and invoke callbacks. mTorchStatusMutex
     // should be locked.
     void onTorchStatusChangedLocked(const String8& cameraId,
-            hardware::camera::common::V1_0::TorchModeStatus newStatus,
-            SystemCameraKind systemCameraKind);
+            hardware::camera::common::V1_0::TorchModeStatus newStatus);
 
     // get a camera's torch status. mTorchStatusMutex should be locked.
     status_t getTorchStatusLocked(const String8 &cameraId,
@@ -1085,8 +1087,7 @@
     static void pingCameraServiceProxy();
 
     void broadcastTorchModeStatus(const String8& cameraId,
-            hardware::camera::common::V1_0::TorchModeStatus status,
-            SystemCameraKind systemCameraKind);
+            hardware::camera::common::V1_0::TorchModeStatus status);
 
     void disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect);
 
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 892996c..43da23e 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -55,6 +55,9 @@
     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
     mPlayShutterSound = true;
+
+    mLongshotEnabled = false;
+    mBurstCnt = 0;
     LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
 }
 
@@ -672,6 +675,10 @@
                            CAMERA_MSG_COMPRESSED_IMAGE);
 
     enableMsgType(picMsgType);
+    mBurstCnt = mHardware->getParameters().getInt("num-snaps-per-shutter");
+    if(mBurstCnt <= 0)
+        mBurstCnt = 1;
+    LOG1("mBurstCnt = %d", mBurstCnt);
 
     return mHardware->takePicture();
 }
@@ -755,6 +762,20 @@
     } else if (cmd == CAMERA_CMD_PING) {
         // If mHardware is 0, checkPidAndHardware will return error.
         return OK;
+    } else if (cmd == CAMERA_CMD_HISTOGRAM_ON) {
+        enableMsgType(CAMERA_MSG_STATS_DATA);
+    } else if (cmd == CAMERA_CMD_HISTOGRAM_OFF) {
+        disableMsgType(CAMERA_MSG_STATS_DATA);
+    } else if (cmd == CAMERA_CMD_METADATA_ON) {
+        enableMsgType(CAMERA_MSG_META_DATA);
+    } else if (cmd == CAMERA_CMD_METADATA_OFF) {
+        disableMsgType(CAMERA_MSG_META_DATA);
+    } else if ( cmd == CAMERA_CMD_LONGSHOT_ON ) {
+        mLongshotEnabled = true;
+    } else if ( cmd == CAMERA_CMD_LONGSHOT_OFF ) {
+        mLongshotEnabled = false;
+        disableMsgType(CAMERA_MSG_SHUTTER);
+        disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
     }
 
     return mHardware->sendCommand(cmd, arg1, arg2);
@@ -954,7 +975,9 @@
         c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
         if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
     }
-    disableMsgType(CAMERA_MSG_SHUTTER);
+    if ( !mLongshotEnabled ) {
+        disableMsgType(CAMERA_MSG_SHUTTER);
+    }
 
     // Shutters only happen in response to takePicture, so mark device as
     // idle now, until preview is restarted
@@ -1040,7 +1063,13 @@
 
 // picture callback - compressed picture ready
 void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
-    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+    if (mBurstCnt)
+        mBurstCnt--;
+
+    if (!mBurstCnt && !mLongshotEnabled) {
+        LOG1("handleCompressedPicture mBurstCnt = %d", mBurstCnt);
+        disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+    }
 
     sp<hardware::ICameraClient> c = mRemoteCallback;
     mLock.unlock();
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index a7eb960..12d6ad5 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -183,6 +183,9 @@
     // This function keeps trying to grab mLock, or give up if the message
     // is found to be disabled. It returns true if mLock is grabbed.
     bool                    lockIfMessageWanted(int32_t msgType);
+
+    bool                 mLongshotEnabled;
+    int                  mBurstCnt;
 };
 
 }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index e35b436..8cb7130 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -92,6 +92,13 @@
     mInputStream(),
     mStreamingRequestId(REQUEST_ID_NONE),
     mRequestIdCounter(0) {
+    mPrivilegedClient = false;
+    char value[PROPERTY_VALUE_MAX];
+    property_get("persist.vendor.camera.privapp.list", value, "");
+    String16 packagelist(value);
+    if (packagelist.contains(clientPackageName.string())) {
+        mPrivilegedClient = true;
+    }
 
     ATRACE_CALL();
     ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
@@ -1425,7 +1432,7 @@
     uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
                            GraphicBuffer::USAGE_HW_TEXTURE |
                            GraphicBuffer::USAGE_HW_COMPOSER;
-    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
+    bool flexibleConsumer = !mPrivilegedClient && (consumerUsage & disallowedFlags) == 0 &&
             (consumerUsage & allowedFlags) != 0;
 
     surface = new Surface(gbp, useAsync);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 9d3874f..378099f 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -335,6 +335,7 @@
     static const int32_t REQUEST_ID_NONE = -1;
 
     int32_t mRequestIdCounter;
+    static inline bool mPrivilegedClient;
 
     // The list of output streams whose surfaces are deferred. We have to track them separately
     // as there are no surfaces available and can not be put into mStreamMap. Once the deferred
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index 62ef681..61cada6 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -136,6 +136,27 @@
     return hardware::Void();
 }
 
+#ifdef QTI_CAMERA_DEVICE
+hardware::Return<void> CameraHardwareInterface::QDataCallback(
+        DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
+        const vendor::qti::hardware::camera::device::V1_0::QCameraFrameMetadata& metadata) {
+    camera_memory_t* mem = nullptr;
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        if (mHidlMemPoolMap.count(data) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+            return hardware::Void();
+        }
+        mem = mHidlMemPoolMap.at(data);
+    }
+    camera_frame_metadata_t md;
+    md.number_of_faces = metadata.faces.size();
+    md.faces = (camera_face_t*) metadata.faces.data();
+    sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
+    return hardware::Void();
+}
+#endif
+
 hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
         DataCallbackMsg msgType, uint32_t data,
         uint32_t bufferIndex, int64_t timestamp) {
@@ -591,12 +612,16 @@
             //       Either document why it is safe in this case or address the
             //       issue (e.g. by copying).
             VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
-            // Caching the handle here because md->pHandle will be subject to HAL's edit
-            native_handle_t* nh = md->pHandle;
-            hidl_handle frame = nh;
-            mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
-            native_handle_close(nh);
-            native_handle_delete(nh);
+            if (md->eType == kMetadataBufferTypeNativeHandleSource) {
+                // Caching the handle here because md->pHandle will be subject to HAL's edit
+                native_handle_t* nh = md->pHandle;
+                hidl_handle frame = nh;
+                mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
+                native_handle_close(nh);
+                native_handle_delete(nh);
+            } else {
+                mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
+            }
         } else {
             mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
         }
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index e519b04..4a20b6a 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -29,6 +29,9 @@
 #include <hardware/camera.h>
 
 #include <common/CameraProviderManager.h>
+#ifdef QTI_CAMERA_DEVICE
+#include <vendor/qti/hardware/camera/device/1.0/IQCameraDeviceCallback.h>
+#endif
 
 namespace android {
 
@@ -85,7 +88,11 @@
 
 class CameraHardwareInterface :
         public virtual RefBase,
+#ifdef QTI_CAMERA_DEVICE
+        public virtual vendor::qti::hardware::camera::device::V1_0::IQCameraDeviceCallback,
+#else
         public virtual hardware::camera::device::V1_0::ICameraDeviceCallback,
+#endif
         public virtual hardware::camera::device::V1_0::ICameraDevicePreviewCallback {
 
 public:
@@ -395,6 +402,12 @@
             hardware::camera::device::V1_0::DataCallbackMsg msgType,
             const hardware::hidl_vec<
                     hardware::camera::device::V1_0::HandleTimestampMessage>&) override;
+#ifdef QTI_CAMERA_DEVICE
+    hardware::Return<void> QDataCallback(
+            hardware::camera::device::V1_0::DataCallbackMsg msgType,
+            uint32_t data, uint32_t bufferIndex,
+            const vendor::qti::hardware::camera::device::V1_0::QCameraFrameMetadata& metadata) override;
+#endif
 
     /**
      * Implementation of android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index d5f136b..abe274a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -627,9 +627,6 @@
             (maxJpegResolution.width * maxJpegResolution.height);
     ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
             kMinJpegBufferSize;
-    if (jpegBufferSize > maxJpegBufferSize) {
-        jpegBufferSize = maxJpegBufferSize;
-    }
 
     return jpegBufferSize;
 }