Merge "Effects: Add atomic_wp<T>, update setThread."
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 818b4d0..28e037f 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -94,6 +94,24 @@
         return err;
     }
 
+    int histogramType = HISTOGRAM_TYPE_UNKNOWN;
+    if ((err = parcel->readInt32(&histogramType)) != OK) {
+        ALOGE("%s: Failed to read histogram type from parcel", __FUNCTION__);
+        return err;
+    }
+
+    std::vector<float> histogramBins;
+    if ((err = parcel->readFloatVector(&histogramBins)) != OK) {
+        ALOGE("%s: Failed to read histogram bins from parcel", __FUNCTION__);
+        return err;
+    }
+
+    std::vector<int64_t> histogramCounts;
+    if ((err = parcel->readInt64Vector(&histogramCounts)) != OK) {
+        ALOGE("%s: Failed to read histogram counts from parcel", __FUNCTION__);
+        return err;
+    }
+
     mWidth = width;
     mHeight = height;
     mFormat = format;
@@ -104,6 +122,9 @@
     mStartLatencyMs = startLatencyMs;
     mMaxHalBuffers = maxHalBuffers;
     mMaxAppBuffers = maxAppBuffers;
+    mHistogramType = histogramType;
+    mHistogramBins = std::move(histogramBins);
+    mHistogramCounts = std::move(histogramCounts);
 
     return OK;
 }
@@ -166,6 +187,21 @@
         return err;
     }
 
+    if ((err = parcel->writeInt32(mHistogramType)) != OK) {
+        ALOGE("%s: Failed to write histogram type", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeFloatVector(mHistogramBins)) != OK) {
+        ALOGE("%s: Failed to write histogram bins!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64Vector(mHistogramCounts)) != OK) {
+        ALOGE("%s: Failed to write histogram counts!", __FUNCTION__);
+        return err;
+    }
+
     return OK;
 }
 
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 27a756f..c398aca 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -27,6 +27,11 @@
  */
 class CameraStreamStats : public android::Parcelable {
 public:
+    enum HistogramType {
+        HISTOGRAM_TYPE_UNKNOWN = 0,
+        HISTOGRAM_TYPE_CAPTURE_LATENCY = 1,
+    };
+
     int mWidth;
     int mHeight;
     int mFormat;
@@ -45,15 +50,26 @@
     int mMaxHalBuffers;
     int mMaxAppBuffers;
 
+    // Histogram type. So far only capture latency histogram is supported.
+    int mHistogramType;
+    // The bounary values separating adjacent histogram bins.
+    // A vector of {h1, h2, h3} represents bins of [0, h1), [h1, h2), [h2, h3),
+    // and [h3, infinity)
+    std::vector<float> mHistogramBins;
+    // The counts for all histogram bins.
+    // size(mHistogramBins) + 1 = size(mHistogramCounts)
+    std::vector<int64_t> mHistogramCounts;
+
     CameraStreamStats() :
             mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0),
             mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
-            mMaxHalBuffers(0), mMaxAppBuffers(0) {}
+            mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
     CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage,
             int maxHalBuffers, int maxAppBuffers)
             : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace),
               mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
-              mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers) {}
+              mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers),
+              mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
 
     virtual status_t readFromParcel(const android::Parcel* parcel) override;
     virtual status_t writeToParcel(android::Parcel* parcel) const override;
diff --git a/media/codec2/vndk/C2DmaBufAllocator.cpp b/media/codec2/vndk/C2DmaBufAllocator.cpp
index 59e82e2..750aa31 100644
--- a/media/codec2/vndk/C2DmaBufAllocator.cpp
+++ b/media/codec2/vndk/C2DmaBufAllocator.cpp
@@ -315,8 +315,8 @@
         if (mUsageMapper) {
             res = mUsageMapper(usage, capacity, heap_name, flags);
         } else {
-            // No system-uncached yet, so disabled for now
-            if (0 && !(usage.expected & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE)))
+            if (C2DmaBufAllocator::system_uncached_supported() &&
+                !(usage.expected & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE)))
                 *heap_name = "system-uncached";
             else
                 *heap_name = "system";
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 499ab72..dee3bf6 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -822,7 +822,13 @@
                 };
 
                 static C2R setDmaBufUsage(bool /* mayBlock */, C2P<C2StoreDmaBufUsageInfo> &me) {
-                    strncpy(me.set().m.heapName, "system", me.v.flexCount());
+                    long long usage = (long long)me.get().m.usage;
+                    if (C2DmaBufAllocator::system_uncached_supported() &&
+                        !(usage & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE))) {
+                        strncpy(me.set().m.heapName, "system-uncached", me.v.flexCount());
+                    } else {
+                        strncpy(me.set().m.heapName, "system", me.v.flexCount());
+                    }
                     me.set().m.allocFlags = 0;
                     return C2R::Ok();
                 };
diff --git a/media/codec2/vndk/include/C2DmaBufAllocator.h b/media/codec2/vndk/include/C2DmaBufAllocator.h
index abb8307..d84c8c6 100644
--- a/media/codec2/vndk/include/C2DmaBufAllocator.h
+++ b/media/codec2/vndk/include/C2DmaBufAllocator.h
@@ -84,6 +84,16 @@
     void setUsageMapper(const UsageMapperFn& mapper, uint64_t minUsage, uint64_t maxUsage,
                         uint64_t blockSize);
 
+    static bool system_uncached_supported(void) {
+        static int cached_result = -1;
+
+        if (cached_result == -1) {
+            struct stat buffer;
+            cached_result = (stat("/dev/dma_heap/system-uncached", &buffer) == 0);
+        }
+        return (cached_result == 1);
+    };
+
    private:
     c2_status_t mInit;
     BufferAllocator mBufferAllocator;
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 0522099..c2f7229 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -85,7 +85,7 @@
     mDeviceType = (audio_devices_t) parcel->readInt32();
     mDeviceAddress = parcel->readString8();
     mCbFlags = (uint32_t)parcel->readInt32();
-    mAllowPrivilegedPlaybackCapture = parcel->readBool();
+    mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
     mVoiceCommunicationCaptureAllowed = parcel->readBool();
     size_t size = (size_t)parcel->readInt32();
     if (size > MAX_CRITERIA_PER_MIX) {
@@ -110,7 +110,7 @@
     parcel->writeInt32(mDeviceType);
     parcel->writeString8(mDeviceAddress);
     parcel->writeInt32(mCbFlags);
-    parcel->writeBool(mAllowPrivilegedPlaybackCapture);
+    parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
     parcel->writeBool(mVoiceCommunicationCaptureAllowed);
     size_t size = mCriteria.size();
     if (size > MAX_CRITERIA_PER_MIX) {
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 00fe278..08b3da1 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -120,7 +120,7 @@
     String8         mDeviceAddress;
     uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
     /** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
-    bool            mAllowPrivilegedPlaybackCapture = false;
+    bool            mAllowPrivilegedMediaPlaybackCapture = false;
     /** Indicates if the caller can capture voice communication output */
     bool            mVoiceCommunicationCaptureAllowed = false;
 };
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index a3e9589..5cfea81 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -122,9 +122,9 @@
             spaces, "", ::android::toString(mDeviceTypeAddr.mType).c_str()));
 
     dst->append(base::StringPrintf(
-            "%*s- supported encapsulation modes: %u", spaces, "", mEncapsulationModes));
+            "%*s- supported encapsulation modes: %u\n", spaces, "", mEncapsulationModes));
     dst->append(base::StringPrintf(
-            "%*s- supported encapsulation metadata types: %u",
+            "%*s- supported encapsulation metadata types: %u\n",
             spaces, "", mEncapsulationMetadataTypes));
 
     if (mDeviceTypeAddr.address().size() != 0) {
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
index 5a52ea5..d08c66d 100644
--- a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -41,7 +41,7 @@
         "libmediandk",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     cflags: [
         "-Werror",
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index c0cc862..09afb1f 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -302,11 +302,13 @@
     }
 
     int32_t result;
-    if (APermissionManager_checkPermission("android.permission.WRITE_MEDIA_STORAGE", pid, uid,
-                                           &result) == PERMISSION_MANAGER_STATUS_OK &&
-        result == PERMISSION_MANAGER_PERMISSION_GRANTED) {
-        mTrustedUids.insert(uid);
-        return true;
+    if (__builtin_available(android 31, *)) {
+        if (APermissionManager_checkPermission("android.permission.WRITE_MEDIA_STORAGE", pid, uid,
+                                               &result) == PERMISSION_MANAGER_STATUS_OK &&
+            result == PERMISSION_MANAGER_PERMISSION_GRANTED) {
+            mTrustedUids.insert(uid);
+            return true;
+        }
     }
 
     return false;
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/libmediatranscoding/TranscodingUidPolicy.cpp
index a725387..b0fa545 100644
--- a/media/libmediatranscoding/TranscodingUidPolicy.cpp
+++ b/media/libmediatranscoding/TranscodingUidPolicy.cpp
@@ -48,8 +48,9 @@
 }
 
 void TranscodingUidPolicy::registerSelf() {
-    mUidObserver = AActivityManager_addUidImportanceListener(
-            &OnUidImportance, -1, (void*)this);
+    if (__builtin_available(android 31, *)) {
+        mUidObserver = AActivityManager_addUidImportanceListener(&OnUidImportance, -1, (void*)this);
+    }
 
     if (mUidObserver == nullptr) {
         ALOGE("Failed to register uid observer");
@@ -62,12 +63,16 @@
 }
 
 void TranscodingUidPolicy::unregisterSelf() {
-    AActivityManager_removeUidImportanceListener(mUidObserver);
-    mUidObserver = nullptr;
+    if (__builtin_available(android 31, *)) {
+        AActivityManager_removeUidImportanceListener(mUidObserver);
+        mUidObserver = nullptr;
 
-    Mutex::Autolock _l(mUidLock);
-    mRegistered = false;
-    ALOGI("Unregistered uid observer");
+        Mutex::Autolock _l(mUidLock);
+        mRegistered = false;
+        ALOGI("Unregistered uid observer");
+    } else {
+        ALOGE("Failed to unregister uid observer");
+    }
 }
 
 void TranscodingUidPolicy::setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) {
@@ -86,8 +91,10 @@
     }
 
     int32_t state = IMPORTANCE_UNKNOWN;
-    if (mRegistered && AActivityManager_isUidActive(uid)) {
-        state = AActivityManager_getUidImportance(uid);
+    if (__builtin_available(android 31, *)) {
+        if (mRegistered && AActivityManager_isUidActive(uid)) {
+            state = AActivityManager_getUidImportance(uid);
+        }
     }
 
     ALOGV("%s: inserting new uid: %u, procState %d", __FUNCTION__, uid, state);
diff --git a/media/libstagefright/tests/Android.bp b/media/libstagefright/tests/Android.bp
index a7f94c1..5f3f72c 100644
--- a/media/libstagefright/tests/Android.bp
+++ b/media/libstagefright/tests/Android.bp
@@ -20,7 +20,7 @@
         "frameworks/native/include/media/openmax",
     ],
 
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
 
     cflags: [
         "-Werror",
@@ -44,4 +44,4 @@
         "-Werror",
         "-Wall",
     ],
-}
\ No newline at end of file
+}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index fc1d0e2..c024a85 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -208,24 +208,25 @@
         // Loopback render mixes are created from a public API and thus restricted
         // to non sensible audio that have not opted out.
         if (is_mix_loopback_render(mix->mRouteFlags)) {
-            auto hasFlag = [](auto flags, auto flag) { return (flags & flag) == flag; };
-            if (hasFlag(attributes.flags, AUDIO_FLAG_NO_SYSTEM_CAPTURE)) {
-                return MixMatchStatus::NO_MATCH;
-            }
-            if (!mix->mAllowPrivilegedPlaybackCapture &&
-                hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
-                return MixMatchStatus::NO_MATCH;
-            }
-            if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION &&
-                !mix->mVoiceCommunicationCaptureAllowed) {
-                return MixMatchStatus::NO_MATCH;
-            }
             if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
                   attributes.usage == AUDIO_USAGE_MEDIA ||
                   attributes.usage == AUDIO_USAGE_GAME ||
                   attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION)) {
                 return MixMatchStatus::NO_MATCH;
             }
+            auto hasFlag = [](auto flags, auto flag) { return (flags & flag) == flag; };
+            if (hasFlag(attributes.flags, AUDIO_FLAG_NO_SYSTEM_CAPTURE)) {
+                return MixMatchStatus::NO_MATCH;
+            }
+
+            if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION) {
+                if (!mix->mVoiceCommunicationCaptureAllowed) {
+                    return MixMatchStatus::NO_MATCH;
+                }
+            } else if (!mix->mAllowPrivilegedMediaPlaybackCapture &&
+                hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
+                return MixMatchStatus::NO_MATCH;
+            }
         }
 
         int userId = (int) multiuser_get_user_id(uid);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 51abef1..65bae77 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3547,7 +3547,9 @@
                                             offloadInfo.channel_mask,
                                             AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,
                                             true /* directOnly */);
-    ALOGV("%s: profile %sfound", __func__, profile != 0 ? "" : "NOT ");
+    ALOGV("%s: profile %sfound%s", __func__, profile != nullptr ? "" : "NOT ",
+            (profile != nullptr && (profile->getFlags() & AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD) != 0)
+            ? ", supports gapless" : "");
     if (profile == nullptr) {
         return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 10bf707..66f9fbd 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1241,7 +1241,7 @@
             return mix.mVoiceCommunicationCaptureAllowed; });
 
     bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
-            return mix.mAllowPrivilegedPlaybackCapture; });
+            return mix.mAllowPrivilegedMediaPlaybackCapture; });
 
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     const pid_t callingPid = IPCThreadState::self()->getCallingPid();
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 92c8e30..e80404b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2161,6 +2161,14 @@
                 streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
                 streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
                 streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
+                streamStats[i].mHistogramType =
+                        hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
+                streamStats[i].mHistogramBins.assign(
+                        stats->second.mCaptureLatencyBins.begin(),
+                        stats->second.mCaptureLatencyBins.end());
+                streamStats[i].mHistogramCounts.assign(
+                        stats->second.mCaptureLatencyHistogram.begin(),
+                        stats->second.mCaptureLatencyHistogram.end());
             }
         }
         listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
index 83965c4..7a7707c 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
@@ -18,12 +18,21 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <numeric>
+
+#include <inttypes.h>
 #include <utils/Log.h>
 
 #include "SessionStatsBuilder.h"
 
 namespace android {
 
+// Bins for capture latency: [0, 100], [100, 200], [200, 300], ...
+// [1300, 2100], [2100, inf].
+// Capture latency is in the unit of millisecond.
+const std::array<int32_t, StreamStats::LATENCY_BIN_COUNT-1> StreamStats::mCaptureLatencyBins {
+        { 100, 200, 300, 400, 500, 700, 900, 1300, 2100 } };
+
 status_t SessionStatsBuilder::addStream(int id) {
     std::lock_guard<std::mutex> l(mLock);
     StreamStats stats;
@@ -52,10 +61,14 @@
     mCounterStopped = false;
     mDeviceError = false;
     for (auto& streamStats : mStatsMap) {
-        streamStats.second.mRequestedFrameCount = 0;
-        streamStats.second.mDroppedFrameCount = 0;
-        streamStats.second.mCounterStopped = false;
-        streamStats.second.mStartLatencyMs = 0;
+        StreamStats& streamStat = streamStats.second;
+        streamStat.mRequestedFrameCount = 0;
+        streamStat.mDroppedFrameCount = 0;
+        streamStat.mCounterStopped = false;
+        streamStat.mStartLatencyMs = 0;
+
+        std::fill(streamStat.mCaptureLatencyHistogram.begin(),
+                streamStat.mCaptureLatencyHistogram.end(), 0);
     }
 }
 
@@ -66,23 +79,28 @@
 
 void SessionStatsBuilder::stopCounter(int id) {
     std::lock_guard<std::mutex> l(mLock);
-    mStatsMap[id].mCounterStopped = true;
+    StreamStats& streamStat = mStatsMap[id];
+    streamStat.mCounterStopped = true;
 }
 
 void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) {
     std::lock_guard<std::mutex> l(mLock);
+
     auto it = mStatsMap.find(id);
-    if (it != mStatsMap.end()) {
-         if (!it->second.mCounterStopped) {
-             it->second.mRequestedFrameCount++;
-             if (dropped) {
-                 it->second.mDroppedFrameCount++;
-             } else if (it->second.mRequestedFrameCount == 1) {
-                 // The capture latency for the first request.
-                 it->second.mStartLatencyMs = captureLatencyMs;
-             }
-         }
+    if (it == mStatsMap.end()) return;
+
+    StreamStats& streamStat = it->second;
+    if (streamStat.mCounterStopped) return;
+
+    streamStat.mRequestedFrameCount++;
+    if (dropped) {
+        streamStat.mDroppedFrameCount++;
+    } else if (streamStat.mRequestedFrameCount - streamStat.mDroppedFrameCount == 1) {
+        // The capture latency for the first request.
+        streamStat.mStartLatencyMs = captureLatencyMs;
     }
+
+    streamStat.updateLatencyHistogram(captureLatencyMs);
 }
 
 void SessionStatsBuilder::stopCounter() {
@@ -95,10 +113,10 @@
 
 void SessionStatsBuilder::incResultCounter(bool dropped) {
     std::lock_guard<std::mutex> l(mLock);
-    if (!mCounterStopped) {
-        mRequestCount ++;
-        if (dropped) mErrorResultCount++;
-    }
+    if (mCounterStopped) return;
+
+    mRequestCount++;
+    if (dropped) mErrorResultCount++;
 }
 
 void SessionStatsBuilder::onDeviceError() {
@@ -106,4 +124,18 @@
     mDeviceError = true;
 }
 
+void StreamStats::updateLatencyHistogram(int32_t latencyMs) {
+    size_t i;
+    for (i = 0; i < mCaptureLatencyBins.size(); i++) {
+        if (latencyMs < mCaptureLatencyBins[i]) {
+            mCaptureLatencyHistogram[i] ++;
+            break;
+        }
+    }
+
+    if (i == mCaptureLatencyBins.size()) {
+        mCaptureLatencyHistogram[i]++;
+    }
+}
+
 }; // namespace android
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.h b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
index 7943637..c23abb6 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.h
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
@@ -19,22 +19,38 @@
 
 #include <utils/Errors.h>
 
-#include <mutex>
+#include <array>
 #include <map>
+#include <mutex>
 
 namespace android {
 
 // Helper class to build stream stats
 struct StreamStats {
+    // Fields for buffer drop
     int64_t mRequestedFrameCount;
     int64_t mDroppedFrameCount;
     bool mCounterStopped;
+
+    // Fields for stream startup latency
     int32_t mStartLatencyMs;
 
+    // Fields for capture latency measurement
+    const static int LATENCY_BIN_COUNT = 10;
+    // Boundary values separating between adjacent bins, excluding 0 and
+    // infinity.
+    const static std::array<int32_t, LATENCY_BIN_COUNT-1> mCaptureLatencyBins;
+    // Counter values for all histogram bins. One more entry than mCaptureLatencyBins.
+    std::array<int64_t, LATENCY_BIN_COUNT> mCaptureLatencyHistogram;
+
     StreamStats() : mRequestedFrameCount(0),
                      mDroppedFrameCount(0),
                      mCounterStopped(false),
-                     mStartLatencyMs(0) {}
+                     mStartLatencyMs(0),
+                     mCaptureLatencyHistogram{}
+                  {}
+
+    void updateLatencyHistogram(int32_t latencyMs);
 };
 
 // Helper class to build session stats
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index b7b51a6..10b8135 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,6 +15,9 @@
 ** limitations under the License.
 */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "main_extractorservice"
+
 #include <fcntl.h>
 #include <sys/prctl.h>
 #include <sys/wait.h>
@@ -26,6 +29,7 @@
 
 #include <android-base/logging.h>
 #include <android-base/properties.h>
+#include <utils/Log.h>
 #include <utils/misc.h>
 
 // from LOCAL_C_INCLUDES
@@ -41,10 +45,16 @@
 
 int main(int argc __unused, char** argv)
 {
+
+#if __has_feature(hwaddress_sanitizer)
+    ALOGI("disable media.extractor memory limits (hwasan enabled)");
+#else
+    ALOGI("enable media.extractor memory limits");
     limitProcessMemory(
         "ro.media.maxmem", /* property that defines limit */
         SIZE_MAX, /* upper limit in bytes */
         20 /* upper limit as percentage of physical RAM */);
+#endif
 
     signal(SIGPIPE, SIG_IGN);
 
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index 64def5e..74477a8 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -62,16 +62,18 @@
 
     uid_t callingUid = AIBinder_getCallingUid();
     pid_t callingPid = AIBinder_getCallingPid();
-    int32_t permissionResult;
-    if (APermissionManager_checkPermission("android.permission.DUMP", callingPid, callingUid,
-                                           &permissionResult) != PERMISSION_MANAGER_STATUS_OK ||
-        permissionResult != PERMISSION_MANAGER_PERMISSION_GRANTED) {
-        result.format(
-                "Permission Denial: "
-                "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
-                AIBinder_getCallingPid(), AIBinder_getCallingUid());
-        write(fd, result.string(), result.size());
-        return PERMISSION_DENIED;
+    if (__builtin_available(android 31, *)) {
+        int32_t permissionResult;
+        if (APermissionManager_checkPermission("android.permission.DUMP", callingPid, callingUid,
+                                               &permissionResult) != PERMISSION_MANAGER_STATUS_OK ||
+            permissionResult != PERMISSION_MANAGER_PERMISSION_GRANTED) {
+            result.format(
+                    "Permission Denial: "
+                    "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
+                    AIBinder_getCallingPid(), AIBinder_getCallingUid());
+            write(fd, result.string(), result.size());
+            return PERMISSION_DENIED;
+        }
     }
 
     const size_t SIZE = 256;
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 5327289..edccbf7 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -1,34 +1,16 @@
 filegroup {
     name: "tv_tuner_aidl",
     srcs: [
-        "aidl/android/media/tv/tuner/ITunerFrontend.aidl",
-        "aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl",
-        "aidl/android/media/tv/tuner/ITunerService.aidl",
-        "aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendSettings.aidl",
-        "aidl/android/media/tv/tuner/TunerFrontendStatus.aidl",
-        "aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl",
+        "aidl/android/media/tv/tuner/*.aidl",
+    ],
+    path: "aidl",
+}
+
+filegroup {
+    name: "tv_tuner_frontend_info",
+    srcs: [
+        "aidl/android/media/tv/tuner/TunerFrontendInfo.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontend*Capabilities.aidl",
     ],
     path: "aidl",
 }
@@ -57,6 +39,27 @@
     },
 }
 
+aidl_interface {
+    name: "tv_tuner_frontend_info_aidl_interface",
+    unstable: true,
+    local_include_dir: "aidl",
+    srcs: [
+        ":tv_tuner_frontend_info",
+    ],
+
+    backend: {
+        java: {
+            enabled: true,
+        },
+        cpp: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+        },
+    },
+}
+
 cc_library {
     name: "libtunerservice",
 
@@ -67,6 +70,7 @@
 
     shared_libs: [
         "android.hardware.tv.tuner@1.0",
+        "android.hardware.tv.tuner@1.1",
         "libbase",
         "libbinder_ndk",
         "libcutils",
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index ba4553b..17c60c0 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -19,8 +19,8 @@
 #include "TunerFrontend.h"
 #include "TunerService.h"
 
-using ::aidl::android::media::tv::tuner::TunerAtsc3PlpInfo;
 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
+using ::aidl::android::media::tv::tuner::TunerFrontendScanAtsc3PlpInfo;
 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
 using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
@@ -69,12 +69,13 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
 using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
 using ::android::hardware::tv::tuner::V1_0::Result;
+using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
 
 namespace android {
 
-TunerFrontend::TunerFrontend(sp<ITuner> tuner, int frontendHandle) {
+TunerFrontend::TunerFrontend(sp<ITuner> tuner, int id) {
     mTuner = tuner;
-    mId = TunerService::getResourceIdFromHandle(frontendHandle);
+    mId = id;
 
     if (mTuner != NULL) {
         Result status;
@@ -308,10 +309,14 @@
 }
 
 Status TunerFrontend::getStatus(const std::vector<int32_t>& /*statusTypes*/,
-		std::vector<TunerFrontendStatus>* /*_aidl_return*/) {
+        std::vector<TunerFrontendStatus>* /*_aidl_return*/) {
     return Status::ok();
 }
 
+Status TunerFrontend::getFrontendId(int* _aidl_return) {
+    *_aidl_return = mId;
+    return Status::ok();
+}
 /////////////// FrontendCallback ///////////////////////
 
 Return<void> TunerFrontend::FrontendCallback::onEvent(FrontendEventType frontendEventType) {
@@ -323,59 +328,56 @@
 Return<void> TunerFrontend::FrontendCallback::onScanMessage(
         FrontendScanMessageType type, const FrontendScanMessage& message) {
     ALOGD("FrontendCallback::onScanMessage, type=%d", type);
+    TunerFrontendScanMessage scanMessage;
     switch(type) {
         case FrontendScanMessageType::LOCKED: {
-            if (message.isLocked()) {
-                mTunerFrontendCallback->onLocked();
-            }
+            scanMessage.set<TunerFrontendScanMessage::isLocked>(message.isLocked());
             break;
         }
         case FrontendScanMessageType::END: {
-            if (message.isEnd()) {
-                mTunerFrontendCallback->onScanStopped();
-            }
+            scanMessage.set<TunerFrontendScanMessage::isEnd>(message.isEnd());
             break;
         }
         case FrontendScanMessageType::PROGRESS_PERCENT: {
-            mTunerFrontendCallback->onProgress((int)message.progressPercent());
+            scanMessage.set<TunerFrontendScanMessage::progressPercent>(message.progressPercent());
             break;
         }
         case FrontendScanMessageType::FREQUENCY: {
             auto f = message.frequencies();
-            std::vector<int32_t> frequencies(std::begin(f), std::end(f));
-            mTunerFrontendCallback->onFrequenciesReport(frequencies);
+            std::vector<int> frequencies(std::begin(f), std::end(f));
+            scanMessage.set<TunerFrontendScanMessage::frequencies>(frequencies);
             break;
         }
         case FrontendScanMessageType::SYMBOL_RATE: {
             auto s = message.symbolRates();
-            std::vector<int32_t> symbolRates(std::begin(s), std::end(s));
-            mTunerFrontendCallback->onSymbolRates(symbolRates);
+            std::vector<int> symbolRates(std::begin(s), std::end(s));
+            scanMessage.set<TunerFrontendScanMessage::symbolRates>(symbolRates);
             break;
         }
         case FrontendScanMessageType::HIERARCHY: {
-            mTunerFrontendCallback->onHierarchy((int)message.hierarchy());
+            scanMessage.set<TunerFrontendScanMessage::hierarchy>((int)message.hierarchy());
             break;
         }
         case FrontendScanMessageType::ANALOG_TYPE: {
-            mTunerFrontendCallback->onSignalType((int)message.analogType());
+            scanMessage.set<TunerFrontendScanMessage::analogType>((int)message.analogType());
             break;
         }
         case FrontendScanMessageType::PLP_IDS: {
             auto p = message.plpIds();
-            std::vector<int32_t> plpIds(std::begin(p), std::end(p));
-            mTunerFrontendCallback->onPlpIds(plpIds);
+            std::vector<uint8_t> plpIds(std::begin(p), std::end(p));
+            scanMessage.set<TunerFrontendScanMessage::plpIds>(plpIds);
             break;
         }
         case FrontendScanMessageType::GROUP_IDS: {
             auto g = message.groupIds();
-            std::vector<int32_t> groupIds(std::begin(g), std::end(g));
-            mTunerFrontendCallback->onGroupIds(groupIds);
+            std::vector<uint8_t> groupIds(std::begin(g), std::end(g));
+            scanMessage.set<TunerFrontendScanMessage::groupIds>(groupIds);
             break;
         }
         case FrontendScanMessageType::INPUT_STREAM_IDS: {
             auto i = message.inputStreamIds();
-            std::vector<int32_t> streamIds(std::begin(i), std::end(i));
-            mTunerFrontendCallback->onInputStreamIds(streamIds);
+            std::vector<char16_t> streamIds(std::begin(i), std::end(i));
+            scanMessage.set<TunerFrontendScanMessage::inputStreamIds>(streamIds);
             break;
         }
         case FrontendScanMessageType::STANDARD: {
@@ -383,37 +385,81 @@
             int standard;
             if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
                 standard = (int) std.sStd();
-                mTunerFrontendCallback->onDvbsStandard(standard);
             } else if (std.getDiscriminator() ==
                     FrontendScanMessage::Standard::hidl_discriminator::tStd) {
                 standard = (int) std.tStd();
-                mTunerFrontendCallback->onDvbsStandard(standard);
             } else if (std.getDiscriminator() ==
                     FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
                 standard = (int) std.sifStd();
-                mTunerFrontendCallback->onAnalogSifStandard(standard);
             }
+            scanMessage.set<TunerFrontendScanMessage::std>(standard);
             break;
         }
         case FrontendScanMessageType::ATSC3_PLP_INFO: {
             std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
-            std::vector<TunerAtsc3PlpInfo> tunerPlpInfos;
+            std::vector<TunerFrontendScanAtsc3PlpInfo> tunerPlpInfos;
             for (int i = 0; i < plpInfos.size(); i++) {
                 auto info = plpInfos[i];
                 int plpId = (int) info.plpId;
                 bool lls = (bool) info.bLlsFlag;
-                TunerAtsc3PlpInfo plpInfo{
+                TunerFrontendScanAtsc3PlpInfo plpInfo{
                     .plpId = plpId,
                     .llsFlag = lls,
                 };
                 tunerPlpInfos.push_back(plpInfo);
             }
-            mTunerFrontendCallback->onAtsc3PlpInfos(tunerPlpInfos);
+            scanMessage.set<TunerFrontendScanMessage::atsc3PlpInfos>(tunerPlpInfos);
             break;
         }
         default:
             break;
     }
+    mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
+    return Void();
+}
+
+Return<void> TunerFrontend::FrontendCallback::onScanMessageExt1_1(
+        FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message) {
+    ALOGD("onScanMessageExt1_1::onScanMessage, type=%d", type);
+    TunerFrontendScanMessage scanMessage;
+    switch(type) {
+        case FrontendScanMessageTypeExt1_1::MODULATION: {
+            FrontendModulation m = message.modulation();
+            int modulation;
+            if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbc) {
+                modulation = (int) m.dvbc();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbt) {
+                modulation = (int) m.dvbt();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbs) {
+                modulation = (int) m.dvbs();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbs) {
+                modulation = (int) m.isdbs();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbs3) {
+                modulation = (int) m.isdbs3();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbt) {
+                modulation = (int) m.isdbt();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::atsc) {
+                modulation = (int) m.atsc();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::atsc3) {
+                modulation = (int) m.atsc3();
+            } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dtmb) {
+                modulation = (int) m.dtmb();
+            }
+            scanMessage.set<TunerFrontendScanMessage::modulation>(modulation);
+            break;
+        }
+        case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: {
+            scanMessage.set<TunerFrontendScanMessage::annex>((int)message.annex());
+            break;
+        }
+        case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: {
+            scanMessage.set<TunerFrontendScanMessage::isHighPriority>(message.isHighPriority());
+            break;
+        }
+        default:
+            break;
+    }
+    mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
     return Void();
 }
 
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index c7d3ddd..f1f66e7 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -19,6 +19,7 @@
 
 #include <aidl/android/media/tv/tuner/BnTunerFrontend.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <utils/Log.h>
 
@@ -27,6 +28,7 @@
 using ::aidl::android::media::tv::tuner::ITunerFrontendCallback;
 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Settings;
 using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCodeRate;
+using ::aidl::android::media::tv::tuner::TunerFrontendScanMessage;
 using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
 using ::aidl::android::media::tv::tuner::TunerFrontendStatus;
 using ::android::hardware::Return;
@@ -39,16 +41,17 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
 using ::android::hardware::tv::tuner::V1_0::IFrontend;
-using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
 using ::android::hardware::tv::tuner::V1_0::ITuner;
-
+using ::android::hardware::tv::tuner::V1_1::IFrontendCallback;
+using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
+using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageTypeExt1_1;
 
 namespace android {
 
 class TunerFrontend : public BnTunerFrontend {
 
 public:
-    TunerFrontend(sp<ITuner> tuner, int frontendHandle);
+    TunerFrontend(sp<ITuner> tuner, int id);
     virtual ~TunerFrontend();
     Status setCallback(
             const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) override;
@@ -61,6 +64,7 @@
     Status close() override;
     Status getStatus(const std::vector<int32_t>& statusTypes,
             std::vector<TunerFrontendStatus>* _aidl_return) override;
+    Status getFrontendId(int* _aidl_return) override;
 
     struct FrontendCallback : public IFrontendCallback {
         FrontendCallback(const std::shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
@@ -69,6 +73,8 @@
         virtual Return<void> onEvent(FrontendEventType frontendEventType);
         virtual Return<void> onScanMessage(
                 FrontendScanMessageType type, const FrontendScanMessage& message);
+        virtual Return<void> onScanMessageExt1_1(
+                FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message);
 
         std::shared_ptr<ITunerFrontendCallback> mTunerFrontendCallback;
     };
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 56cb34c..c34ddf6 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -221,7 +221,7 @@
 }
 
 Status TunerService::getFrontendInfo(
-        int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) {
+        int32_t frontendHandle, TunerFrontendInfo* _aidl_return) {
     if (mTuner == nullptr) {
         ALOGE("ITuner service is not init.");
         return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -239,7 +239,7 @@
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
 
-    TunerServiceFrontendInfo tunerInfo = convertToAidlFrontendInfo(feId, info);
+    TunerFrontendInfo tunerInfo = convertToAidlFrontendInfo(info);
     *_aidl_return = tunerInfo;
     return Status::ok();
 }
@@ -252,13 +252,13 @@
                 static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
-    *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(mTuner, frontendHandle);
+    int id = getResourceIdFromHandle(frontendHandle);
+    *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(mTuner, id);
     return Status::ok();
 }
 
-TunerServiceFrontendInfo TunerService::convertToAidlFrontendInfo(int feId, FrontendInfo halInfo) {
-    TunerServiceFrontendInfo info{
-        .id = feId,
+TunerFrontendInfo TunerService::convertToAidlFrontendInfo(FrontendInfo halInfo) {
+    TunerFrontendInfo info{
         .type = (int)halInfo.type,
         .minFrequency = (int)halInfo.minFrequency,
         .maxFrequency = (int)halInfo.maxFrequency,
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 26591ab..021ed26 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -18,7 +18,6 @@
 #define ANDROID_MEDIA_TUNERSERVICE_H
 
 #include <aidl/android/media/tv/tuner/BnTunerService.h>
-#include <aidl/android/media/tv/tuner/TunerServiceFrontendInfo.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
 #include <fmq/AidlMessageQueue.h>
 #include <fmq/EventFlag.h>
@@ -29,7 +28,7 @@
 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::aidl::android::media::tv::tuner::BnTunerService;
 using ::aidl::android::media::tv::tuner::ITunerFrontend;
-using ::aidl::android::media::tv::tuner::TunerServiceFrontendInfo;
+using ::aidl::android::media::tv::tuner::TunerFrontendInfo;
 
 using ::android::hardware::details::logError;
 using ::android::hardware::EventFlag;
@@ -80,12 +79,13 @@
     TunerService();
     virtual ~TunerService();
 
+    // TODO: create a map between resource id and handles.
     static int getResourceIdFromHandle(int resourceHandle) {
         return (resourceHandle & 0x00ff0000) >> 16;
     }
 
     Status getFrontendIds(std::vector<int32_t>* ids, int32_t* _aidl_return) override;
-    Status getFrontendInfo(int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) override;
+    Status getFrontendInfo(int32_t frontendHandle, TunerFrontendInfo* _aidl_return) override;
     Status openFrontend(
             int32_t frontendHandle, std::shared_ptr<ITunerFrontend>* _aidl_return) override;
     Status getFmqSyncReadWrite(
@@ -109,7 +109,7 @@
     MQDescriptorSync<uint8_t> mFilterMQDesc;
     AidlMQDesc mAidlMQDesc;
     EventFlag* mEventFlag;
-    TunerServiceFrontendInfo convertToAidlFrontendInfo(int feId, FrontendInfo halInfo);
+    TunerFrontendInfo convertToAidlFrontendInfo(FrontendInfo halInfo);
 };
 
 } // namespace android
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
index 08d20a9..2a54dc6 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
@@ -19,7 +19,6 @@
 import android.media.tv.tuner.ITunerFrontendCallback;
 import android.media.tv.tuner.TunerFrontendSettings;
 import android.media.tv.tuner.TunerFrontendStatus;
-import android.media.tv.tuner.TunerServiceFrontendInfo;
 
 /**
  * Tuner Frontend interface handles tuner related operations.
@@ -82,4 +81,9 @@
      * Gets the statuses of the frontend.
      */
     TunerFrontendStatus[] getStatus(in int[] statusTypes);
+
+    /**
+     * Gets the id of the frontend.
+     */
+    int getFrontendId();
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
index ae62c15..c92f5ee 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
@@ -16,7 +16,7 @@
 
 package android.media.tv.tuner;
 
-import android.media.tv.tuner.TunerAtsc3PlpInfo;
+import android.media.tv.tuner.TunerFrontendScanMessage;
 
 /**
  * TunerFrontendCallback interface handles tuner frontend related callbacks.
@@ -24,73 +24,13 @@
  * {@hide}
  */
 interface ITunerFrontendCallback {
-    /**
+        /**
      * Notify the client that a new event happened on the frontend.
      */
     void onEvent(in int frontendEventType);
 
     /**
-     * notify locked message to client from the ongoing scan.
+     * notify the client of scan messages.
      */
-    void onLocked();
-
-    /**
-     * notify scan stopped message to client from the ongoing scan.
-     */
-    void onScanStopped();
-
-    /**
-     * notify progress message to client from the ongoing scan.
-     */
-    void onProgress(in int percent);
-
-    /**
-     * notify Frequencies message to client from the ongoing scan.
-     */
-    void onFrequenciesReport(in int[] frequency);
-
-    /**
-     * notify SymbolRates message to client from the ongoing scan.
-     */
-    void onSymbolRates(in int[] rates);
-
-    /**
-     * notify Hierarchy message to client from the ongoing scan.
-     */
-    void onHierarchy(in int hierarchy);
-
-    /**
-     * notify SignalType message to client from the ongoing scan.
-     */
-    void onSignalType(in int signalType);
-
-    /**
-     * notify PlpIds message to client from the ongoing scan.
-     */
-    void onPlpIds(in int[] plpIds);
-
-    /**
-     * notify GroupIds message to client from the ongoing scan.
-     */
-    void onGroupIds(in int[] groupIds);
-
-    /**
-     * notify InputStreamIds message to client from the ongoing scan.
-     */
-    void onInputStreamIds(in int[] inputStreamIds);
-
-    /**
-     * notify DvbsStandard message to client from the ongoing scan.
-     */
-    void onDvbsStandard(in int dvbsStandandard);
-
-    /**
-     * notify AnalogSifStandard message to client from the ongoing scan.
-     */
-    void onAnalogSifStandard(in int sifStandandard);
-
-    /**
-     * notify Atsc3PlpInfos message to client from the ongoing scan.
-     */
-    void onAtsc3PlpInfos(in TunerAtsc3PlpInfo[] atsc3PlpInfos);
+    void onScanMessage(in int messageType, in TunerFrontendScanMessage message);
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index 5c1bce7..205e222 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -20,7 +20,7 @@
 import android.hardware.common.fmq.SynchronizedReadWrite;
 import android.hardware.common.fmq.UnsynchronizedWrite;
 import android.media.tv.tuner.ITunerFrontend;
-import android.media.tv.tuner.TunerServiceFrontendInfo;
+import android.media.tv.tuner.TunerFrontendInfo;
 
 /**
  * TunerService interface handles tuner related operations.
@@ -43,7 +43,7 @@
      * @param frontendHandle the handle of the frontend granted by TRM.
      * @return the information of the frontend.
      */
-    TunerServiceFrontendInfo getFrontendInfo(in int frontendHandle);
+    TunerFrontendInfo getFrontendInfo(in int frontendHandle);
 
     /**
      * Open a Tuner Frontend interface.
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
similarity index 89%
rename from services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
rename to services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
index ddcbcdc..4bccd56 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
@@ -21,13 +21,16 @@
 /**
  * FrontendInfo interface that carries tuner frontend information.
  *
+ * <p>This is used to update the TunerResourceManager and pass Frontend
+ * information from HAL to the client side.
+ *
  * {@hide}
  */
-parcelable TunerServiceFrontendInfo {
+parcelable TunerFrontendInfo {
     /**
-     * Frontend Id
+     * Frontend Handle
      */
-    int id;
+    int handle;
 
     /**
      * Frontend Type
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
similarity index 94%
rename from services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
rename to services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
index a0648a5..ca4a9af 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
@@ -21,7 +21,7 @@
  *
  * {@hide}
  */
-parcelable TunerAtsc3PlpInfo {
+parcelable TunerFrontendScanAtsc3PlpInfo {
     int plpId;
 
     boolean llsFlag;
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl
new file mode 100644
index 0000000..9921ca1
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendScanAtsc3PlpInfo;
+
+/**
+ * Tuner Frontend Scan Message interface.
+ *
+ * {@hide}
+ */
+union TunerFrontendScanMessage {
+    boolean isLocked;
+
+    boolean isEnd;
+
+    byte progressPercent;
+
+    int[] frequencies;
+
+    int[] symbolRates;
+
+    int hierarchy;
+
+    int analogType;
+
+    byte[] plpIds;
+
+    byte[] groupIds;
+
+    char[] inputStreamIds;
+
+    int std;
+
+    TunerFrontendScanAtsc3PlpInfo[] atsc3PlpInfos;
+
+    int modulation;
+
+    int annex;
+
+    boolean isHighPriority;
+}