From cacd8b0430ba25df802deb974ec415c8c8445cc8 Mon Sep 17 00:00:00 2001 From: Andy CrossGate Yan Date: Sun, 14 Mar 2021 05:52:23 +0000 Subject: [PATCH] Sync up to v302 --- ...R10-metadata-at-OutputPortSettingsCh.patch | 88 +++ ...e-InputSurfaceWrapper-Config-structu.patch | 66 +++ ...c-store-flushed-config-as-work-items.patch | 174 ++++++ ...mit-number-of-idle-buffers-in-caches.patch | 121 ++++ ...x-underflow-issue-on-handleImageData.patch | 37 ++ ...oder-omits-sample-rate-channel-count.patch | 139 +++++ ...tra-output-metadata-buffers-if-in-lo.patch | 138 +++++ ...er-Reset-negative-media-time-to-zero.patch | 39 ++ ...elay-from-component-to-determine-buf.patch | 68 +++ ...-max-linear-buffer-size-for-8K-video.patch | 37 ++ ...dePrefix-only-for-components-listed-.patch | 56 ++ ...-C2AllocatorBlob-allow-multiple-maps.patch | 126 ++++ ...029-CCodec-fix-ByteBuffer-mode-image.patch | 546 ++++++++++++++++++ ...fferSourceWrapper-fix-to-apply-nBuff.patch | 44 ++ ...31-CCodec-workaround-for-frame-drops.patch | 53 ++ ...x-AAC-decoder-failing-to-instantiate.patch | 37 ++ ...-for-TestDirectBootEmulated-testcase.patch | 37 ++ ...isplays-lock-screen-black.-Useful-fo.patch | 27 + ...T-MERGE-Correct-physical-orientation.patch | 50 ++ ...4-fix-PlaneLayout-encode-typecasting.patch | 68 +++ ...e-when-there-is-no-hal-but-we-believ.patch | 32 + ...cpu.abilist-to-be-fetched-dynamicall.patch | 104 ++++ ...t-of-mount_all-that-mounted-userdata.patch | 174 ++++++ ...mount_all-for-mounted-userdata-by-me.patch | 33 ++ ...postinstall-root-dir-unconditionally.patch | 45 ++ ...ling-of-vndk-26-remove-liblog.so-fro.patch | 21 +- ...point-only-if-checkpoint-is-supporte.patch | 17 +- 27 files changed, 2349 insertions(+), 28 deletions(-) create mode 100644 patches/platform_frameworks_av/0017-ACodec-Handle-HDR10-metadata-at-OutputPortSettingsCh.patch create mode 100644 patches/platform_frameworks_av/0018-Codec2-Initialize-InputSurfaceWrapper-Config-structu.patch create mode 100644 patches/platform_frameworks_av/0019-CCodec-store-flushed-config-as-work-items.patch create mode 100644 patches/platform_frameworks_av/0020-BufferPool-limit-number-of-idle-buffers-in-caches.patch create mode 100644 patches/platform_frameworks_av/0021-CCodec-fix-underflow-issue-on-handleImageData.patch create mode 100644 patches/platform_frameworks_av/0022-OMX-Opus-decoder-omits-sample-rate-channel-count.patch create mode 100644 patches/platform_frameworks_av/0023-ACodec-submit-extra-output-metadata-buffers-if-in-lo.patch create mode 100644 patches/platform_frameworks_av/0024-NuPlayerRenderer-Reset-negative-media-time-to-zero.patch create mode 100644 patches/platform_frameworks_av/0025-C2OMXNode-read-delay-from-component-to-determine-buf.patch create mode 100644 patches/platform_frameworks_av/0026-CCodec-Increase-max-linear-buffer-size-for-8K-video.patch create mode 100644 patches/platform_frameworks_av/0027-omx-calculate-nodePrefix-only-for-components-listed-.patch create mode 100644 patches/platform_frameworks_av/0028-C2AllocatorBlob-allow-multiple-maps.patch create mode 100644 patches/platform_frameworks_av/0029-CCodec-fix-ByteBuffer-mode-image.patch create mode 100644 patches/platform_frameworks_av/0030-CCodec-GraphicBufferSourceWrapper-fix-to-apply-nBuff.patch create mode 100644 patches/platform_frameworks_av/0031-CCodec-workaround-for-frame-drops.patch create mode 100644 patches/platform_frameworks_av/0032-Fix-AAC-decoder-failing-to-instantiate.patch create mode 100644 patches/platform_frameworks_base/0040-Fix-for-TestDirectBootEmulated-testcase.patch create mode 100644 patches/platform_frameworks_base/0041-Make-secondary-displays-lock-screen-black.-Useful-fo.patch create mode 100644 patches/platform_frameworks_native/0012-DO-NOT-MERGE-Correct-physical-orientation.patch create mode 100644 patches/platform_frameworks_native/0013-gralloc4-fix-PlaneLayout-encode-typecasting.patch create mode 100644 patches/platform_packages_apps_Settings/0001-Act-as-usb-device-when-there-is-no-hal-but-we-believ.patch create mode 100644 patches/platform_system_core/0009-Make-ro.product.cpu.abilist-to-be-fetched-dynamicall.patch create mode 100644 patches/platform_system_core/0010-Only-store-result-of-mount_all-that-mounted-userdata.patch create mode 100644 patches/platform_system_core/0011-Store-result-of-mount_all-for-mounted-userdata-by-me.patch create mode 100644 patches/platform_system_core/0012-Adding-postinstall-root-dir-unconditionally.patch diff --git a/patches/platform_frameworks_av/0017-ACodec-Handle-HDR10-metadata-at-OutputPortSettingsCh.patch b/patches/platform_frameworks_av/0017-ACodec-Handle-HDR10-metadata-at-OutputPortSettingsCh.patch new file mode 100644 index 0000000..9183eb8 --- /dev/null +++ b/patches/platform_frameworks_av/0017-ACodec-Handle-HDR10-metadata-at-OutputPortSettingsCh.patch @@ -0,0 +1,88 @@ +From 8d97b4814211158932b8482888f5b7bcc8a5a21e Mon Sep 17 00:00:00 2001 +From: Houxiang Dai +Date: Thu, 23 Jul 2020 14:07:22 +0800 +Subject: [PATCH 17/30] ACodec: Handle HDR10+ metadata at + OutputPortSettingsChangedState + +[Description] +handle kWhatSetParameters message in OutputPortSettingsChangedState +handle OMX_EventConfigUpdate event in OutputPortSettingsChangedState + +In HDR10+ test, we have to associate each HDR10+ metadata to a particular +frame. If receive a kWhatSetParameters message with "hdr10-plus-info" +buffer, it should not be deferred in OutputPortSettingsChangedState and +adopt OMX_SetConfig to associates this config with the next input buffer +sent in OMX_EmptyThisBuffer. The OMX_EventConfigUpdate event report from +component should be handled also in OutputPortSettingsChangedState, +where is to associate updated "hdr10-plus-info" metadata with the next +output buffer sent via FillBufferDone callback. + +Bug: 157213958 +Bug: 157435393 +Change-Id: I27e4614487414063831fa760b9e9ca96b1c3712c +(cherry picked from commit c111aa4fda9b5b434edb1b46898ff8dd7e51cec6) +--- + media/libstagefright/ACodec.cpp | 36 ++++++++++++++++++++++++++++++--- + 1 file changed, 33 insertions(+), 3 deletions(-) + +diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp +index b9d0f5bb72..f843c7f45f 100644 +--- a/media/libstagefright/ACodec.cpp ++++ b/media/libstagefright/ACodec.cpp +@@ -8296,13 +8296,34 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( + FALLTHROUGH_INTENDED; + } + case kWhatResume: ++ { ++ ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); ++ ++ mCodec->deferMessage(msg); ++ handled = true; ++ break; ++ } ++ + case kWhatSetParameters: + { +- if (msg->what() == kWhatResume) { +- ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); ++ sp params; ++ CHECK(msg->findMessage("params", ¶ms)); ++ ++ sp hdr10PlusInfo; ++ if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) { ++ if (hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) { ++ (void)mCodec->setHdr10PlusInfo(hdr10PlusInfo); ++ } ++ params->removeEntryAt(params->findEntryByName("hdr10-plus-info")); ++ ++ if (params->countEntries() == 0) { ++ msg->removeEntryAt(msg->findEntryByName("params")); ++ } + } + +- mCodec->deferMessage(msg); ++ if (msg->countEntries() > 0) { ++ mCodec->deferMessage(msg); ++ } + handled = true; + break; + } +@@ -8417,6 +8438,15 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( + return false; + } + ++ case OMX_EventConfigUpdate: ++ { ++ CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); ++ ++ mCodec->onConfigUpdate((OMX_INDEXTYPE)data2); ++ ++ return true; ++ } ++ + default: + return BaseState::onOMXEvent(event, data1, data2); + } +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0018-Codec2-Initialize-InputSurfaceWrapper-Config-structu.patch b/patches/platform_frameworks_av/0018-Codec2-Initialize-InputSurfaceWrapper-Config-structu.patch new file mode 100644 index 0000000..c0dbbf5 --- /dev/null +++ b/patches/platform_frameworks_av/0018-Codec2-Initialize-InputSurfaceWrapper-Config-structu.patch @@ -0,0 +1,66 @@ +From f3953cb4a425f0e91b52f5f23d54c0a09162815f Mon Sep 17 00:00:00 2001 +From: wangchenyang +Date: Thu, 24 Dec 2020 16:55:50 +0800 +Subject: [PATCH 18/30] Codec2: Initialize InputSurfaceWrapper::Config + structure fields + +Initialize the fields of Config structure of +InputSurfaceWrapper class. If not initialised, there +is a chance of junk values being used during configure + +Bug: 171763471 +Bug: 175443996 +Test: TH + +Change-Id: Id5ac827df0c2ef6ad761ab5a235162a9358c1704 +(cherry picked from commit a1ab7eb891728b77cc4bf03fedd21574bd8ec586) +--- + media/codec2/sfplugin/InputSurfaceWrapper.h | 28 ++++++++++----------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h +index bb35763f41..479acb109b 100644 +--- a/media/codec2/sfplugin/InputSurfaceWrapper.h ++++ b/media/codec2/sfplugin/InputSurfaceWrapper.h +@@ -61,24 +61,24 @@ public: + /// Input Surface configuration + struct Config { + // IN PARAMS (GBS) +- float mMinFps; // minimum fps (repeat frame to achieve this) +- float mMaxFps; // max fps (via frame drop) +- float mCaptureFps; // capture fps +- float mCodedFps; // coded fps +- bool mSuspended; // suspended +- int64_t mTimeOffsetUs; // time offset (input => codec) +- int64_t mSuspendAtUs; // suspend/resume time +- int64_t mStartAtUs; // start time +- bool mStopped; // stopped +- int64_t mStopAtUs; // stop time ++ float mMinFps = 0.0; // minimum fps (repeat frame to achieve this) ++ float mMaxFps = 0.0; // max fps (via frame drop) ++ float mCaptureFps = 0.0; // capture fps ++ float mCodedFps = 0.0; // coded fps ++ bool mSuspended = false; // suspended ++ int64_t mTimeOffsetUs = 0; // time offset (input => codec) ++ int64_t mSuspendAtUs = 0; // suspend/resume time ++ int64_t mStartAtUs = 0; // start time ++ bool mStopped = false; // stopped ++ int64_t mStopAtUs = 0; // stop time + + // OUT PARAMS (GBS) +- int64_t mInputDelayUs; // delay between encoder input and surface input ++ int64_t mInputDelayUs = 0; // delay between encoder input and surface input + + // IN PARAMS (CODEC WRAPPER) +- float mFixedAdjustedFps; // fixed fps via PTS manipulation +- float mMinAdjustedFps; // minimum fps via PTS manipulation +- uint64_t mUsage; // consumer usage ++ float mFixedAdjustedFps = 0.0; // fixed fps via PTS manipulation ++ float mMinAdjustedFps = 0.0; // minimum fps via PTS manipulation ++ uint64_t mUsage = 0; // consumer usage + }; + + /** +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0019-CCodec-store-flushed-config-as-work-items.patch b/patches/platform_frameworks_av/0019-CCodec-store-flushed-config-as-work-items.patch new file mode 100644 index 0000000..0ebd8e6 --- /dev/null +++ b/patches/platform_frameworks_av/0019-CCodec-store-flushed-config-as-work-items.patch @@ -0,0 +1,174 @@ +From a141c7102252377bc882b982b36980edb60f931e Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Tue, 5 Jan 2021 18:58:15 -0800 +Subject: [PATCH 19/30] CCodec: store flushed config as work items + +Store flushed config as work items and queue them to the component +directly, instead of going through MediaCodecBuffer. + +Bug: 176501678 +Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small +Test: atest CtsMediaTestCases:AdaptivePlaybackTest +Merged-In: I19991101c388eca49226ad2abc37df9cea22dbb8 +Change-Id: I19991101c388eca49226ad2abc37df9cea22dbb8 +(cherry picked from commit 5ebfcb24855e526ec040b9f41d216f7604b8981a) +--- + media/codec2/sfplugin/CCodecBufferChannel.cpp | 119 ++++++++---------- + media/codec2/sfplugin/CCodecBufferChannel.h | 2 +- + 2 files changed, 53 insertions(+), 68 deletions(-) + +diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp +index 1654b11c31..b8ca41b9a8 100644 +--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp ++++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp +@@ -1300,54 +1300,30 @@ status_t CCodecBufferChannel::requestInitialInputBuffers() { + return a.capacity < b.capacity; + }); + +- { +- Mutexed>>::Locked configs(mFlushedConfigs); +- if (!configs->empty()) { +- while (!configs->empty()) { +- sp config = configs->front(); +- configs->pop_front(); +- // Find the smallest input buffer that can fit the config. +- auto i = std::find_if( +- clientInputBuffers.begin(), +- clientInputBuffers.end(), +- [cfgSize = config->size()](const ClientInputBuffer& b) { +- return b.capacity >= cfgSize; +- }); +- if (i == clientInputBuffers.end()) { +- ALOGW("[%s] no input buffer large enough for the config " +- "(%zu bytes)", +- mName, config->size()); +- return NO_MEMORY; +- } +- sp buffer = i->buffer; +- memcpy(buffer->base(), config->data(), config->size()); +- buffer->setRange(0, config->size()); +- buffer->meta()->clear(); +- buffer->meta()->setInt64("timeUs", 0); +- buffer->meta()->setInt32("csd", 1); +- if (queueInputBufferInternal(buffer) != OK) { +- ALOGW("[%s] Error while queueing a flushed config", +- mName); +- return UNKNOWN_ERROR; +- } +- clientInputBuffers.erase(i); +- } +- } else if (oStreamFormat.value == C2BufferData::LINEAR && +- (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) { +- sp buffer = clientInputBuffers.front().buffer; +- // WORKAROUND: Some apps expect CSD available without queueing +- // any input. Queue an empty buffer to get the CSD. +- buffer->setRange(0, 0); +- buffer->meta()->clear(); +- buffer->meta()->setInt64("timeUs", 0); +- if (queueInputBufferInternal(buffer) != OK) { +- ALOGW("[%s] Error while queueing an empty buffer to get CSD", +- mName); +- return UNKNOWN_ERROR; +- } +- clientInputBuffers.pop_front(); ++ std::list> flushedConfigs; ++ mFlushedConfigs.lock()->swap(flushedConfigs); ++ if (!flushedConfigs.empty()) { ++ err = mComponent->queue(&flushedConfigs); ++ if (err != C2_OK) { ++ ALOGW("[%s] Error while queueing a flushed config", mName); ++ return UNKNOWN_ERROR; + } + } ++ if (oStreamFormat.value == C2BufferData::LINEAR && ++ (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) { ++ sp buffer = clientInputBuffers.front().buffer; ++ // WORKAROUND: Some apps expect CSD available without queueing ++ // any input. Queue an empty buffer to get the CSD. ++ buffer->setRange(0, 0); ++ buffer->meta()->clear(); ++ buffer->meta()->setInt64("timeUs", 0); ++ if (queueInputBufferInternal(buffer) != OK) { ++ ALOGW("[%s] Error while queueing an empty buffer to get CSD", ++ mName); ++ return UNKNOWN_ERROR; ++ } ++ clientInputBuffers.pop_front(); ++ } + + for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) { + mCallback->onInputBufferAvailable( +@@ -1396,27 +1372,36 @@ void CCodecBufferChannel::release() { + + void CCodecBufferChannel::flush(const std::list> &flushedWork) { + ALOGV("[%s] flush", mName); +- { +- Mutexed>>::Locked configs(mFlushedConfigs); +- for (const std::unique_ptr &work : flushedWork) { +- if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) { +- continue; +- } +- if (work->input.buffers.empty() +- || work->input.buffers.front()->data().linearBlocks().empty()) { +- ALOGD("[%s] no linear codec config data found", mName); +- continue; +- } +- C2ReadView view = +- work->input.buffers.front()->data().linearBlocks().front().map().get(); +- if (view.error() != C2_OK) { +- ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error()); +- continue; +- } +- configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity())); +- ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity()); +- } +- } ++ std::list> configs; ++ for (const std::unique_ptr &work : flushedWork) { ++ if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) { ++ continue; ++ } ++ if (work->input.buffers.empty() ++ || work->input.buffers.front() == nullptr ++ || work->input.buffers.front()->data().linearBlocks().empty()) { ++ ALOGD("[%s] no linear codec config data found", mName); ++ continue; ++ } ++ std::unique_ptr copy(new C2Work); ++ copy->input.flags = C2FrameData::flags_t(work->input.flags | C2FrameData::FLAG_DROP_FRAME); ++ copy->input.ordinal = work->input.ordinal; ++ copy->input.buffers.insert( ++ copy->input.buffers.begin(), ++ work->input.buffers.begin(), ++ work->input.buffers.end()); ++ for (const std::unique_ptr ¶m : work->input.configUpdate) { ++ copy->input.configUpdate.push_back(C2Param::Copy(*param)); ++ } ++ copy->input.infoBuffers.insert( ++ copy->input.infoBuffers.begin(), ++ work->input.infoBuffers.begin(), ++ work->input.infoBuffers.end()); ++ copy->worklets.emplace_back(new C2Worklet); ++ configs.push_back(std::move(copy)); ++ ALOGV("[%s] stashed flushed codec config data", mName); ++ } ++ mFlushedConfigs.lock()->swap(configs); + { + Mutexed::Locked input(mInput); + input->buffers->flush(); +diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h +index 046c5c3c49..e2c9aaa287 100644 +--- a/media/codec2/sfplugin/CCodecBufferChannel.h ++++ b/media/codec2/sfplugin/CCodecBufferChannel.h +@@ -277,7 +277,7 @@ private: + uint32_t outputDelay; + }; + Mutexed mOutput; +- Mutexed>> mFlushedConfigs; ++ Mutexed>> mFlushedConfigs; + + std::atomic_uint64_t mFrameIndex; + std::atomic_uint64_t mFirstValidFrameIndex; +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0020-BufferPool-limit-number-of-idle-buffers-in-caches.patch b/patches/platform_frameworks_av/0020-BufferPool-limit-number-of-idle-buffers-in-caches.patch new file mode 100644 index 0000000..b52d365 --- /dev/null +++ b/patches/platform_frameworks_av/0020-BufferPool-limit-number-of-idle-buffers-in-caches.patch @@ -0,0 +1,121 @@ +From bfa866666f0fb3e95755e5fb5d22a89c1fdd6767 Mon Sep 17 00:00:00 2001 +From: David Stevens +Date: Tue, 20 Oct 2020 15:00:41 +0900 +Subject: [PATCH 20/30] BufferPool: limit number of idle buffers in caches + +Some systems have limits on the total number of graphics buffers that +can be allocated, not just the total size. When dealing with +particularly small buffers, the caches could end up retaining 1000s of +buffers. This change adds an additional eviction trigger based on the +number of idle cached buffers. + +Bug: 170702290 +Bug: 171553040 +Test: android.video.cts.VideoEncoderDecoderTest on ARCVM +Change-Id: If3f4433ba1794ccb624b864a56619c8613a315f2 +(cherry picked from commit 0f50e523ef1404f9afbaa7b919e2801e5d94012a) +Merged-In: If3f4433ba1794ccb624b864a56619c8613a315f2 +--- + media/bufferpool/2.0/AccessorImpl.cpp | 13 +++++++++---- + media/bufferpool/2.0/AccessorImpl.h | 6 ++++++ + media/bufferpool/2.0/BufferPoolClient.cpp | 12 ++++++++++-- + 3 files changed, 25 insertions(+), 6 deletions(-) + +diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp +index 6111feafb9..1d2562e41d 100644 +--- a/media/bufferpool/2.0/AccessorImpl.cpp ++++ b/media/bufferpool/2.0/AccessorImpl.cpp +@@ -39,6 +39,8 @@ namespace { + + static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15; + static constexpr size_t kMinBufferCountForEviction = 25; ++ static constexpr size_t kMaxUnusedBufferCount = 64; ++ static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16; + + static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec + static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs +@@ -724,9 +726,11 @@ ResultStatus Accessor::Impl::BufferPool::addNewBuffer( + } + + void Accessor::Impl::BufferPool::cleanUp(bool clearCache) { +- if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) { ++ if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs || ++ mStats.buffersNotInUse() > kMaxUnusedBufferCount) { + mLastCleanUpUs = mTimestampUs; +- if (mTimestampUs > mLastLogUs + kLogDurationUs) { ++ if (mTimestampUs > mLastLogUs + kLogDurationUs || ++ mStats.buffersNotInUse() > kMaxUnusedBufferCount) { + mLastLogUs = mTimestampUs; + ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - " + "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - " +@@ -737,8 +741,9 @@ void Accessor::Impl::BufferPool::cleanUp(bool clearCache) { + mStats.mTotalFetches, mStats.mTotalTransfers); + } + for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) { +- if (!clearCache && (mStats.mSizeCached < kMinAllocBytesForEviction +- || mBuffers.size() < kMinBufferCountForEviction)) { ++ if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget && ++ (mStats.mSizeCached < kMinAllocBytesForEviction || ++ mBuffers.size() < kMinBufferCountForEviction)) { + break; + } + auto it = mBuffers.find(*freeIt); +diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h +index cd1b4d08c1..3d39941337 100644 +--- a/media/bufferpool/2.0/AccessorImpl.h ++++ b/media/bufferpool/2.0/AccessorImpl.h +@@ -193,6 +193,12 @@ private: + : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0), + mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {} + ++ /// # of currently unused buffers ++ size_t buffersNotInUse() const { ++ ALOG_ASSERT(mBuffersCached >= mBuffersInUse); ++ return mBuffersCached - mBuffersInUse; ++ } ++ + /// A new buffer is allocated on an allocation request. + void onBufferAllocated(size_t allocSize) { + mSizeCached += allocSize; +diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/bufferpool/2.0/BufferPoolClient.cpp +index 342fef6b9d..9308b8159b 100644 +--- a/media/bufferpool/2.0/BufferPoolClient.cpp ++++ b/media/bufferpool/2.0/BufferPoolClient.cpp +@@ -32,6 +32,8 @@ namespace implementation { + static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms + static constexpr int kPostMaxRetry = 3; + static constexpr int kCacheTtlUs = 1000000; // TODO: tune ++static constexpr size_t kMaxCachedBufferCount = 64; ++static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16; + + class BufferPoolClient::Impl + : public std::enable_shared_from_this { +@@ -136,6 +138,10 @@ private: + --mActive; + mLastChangeUs = getTimestampNow(); + } ++ ++ int cachedBufferCount() const { ++ return mBuffers.size() - mActive; ++ } + } mCache; + + // FMQ - release notifier +@@ -668,10 +674,12 @@ bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) { + // should have mCache.mLock + void BufferPoolClient::Impl::evictCaches(bool clearCache) { + int64_t now = getTimestampNow(); +- if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) { ++ if (now >= mLastEvictCacheUs + kCacheTtlUs || ++ clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) { + size_t evicted = 0; + for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) { +- if (!it->second->hasCache() && (it->second->expire() || clearCache)) { ++ if (!it->second->hasCache() && (it->second->expire() || ++ clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) { + it = mCache.mBuffers.erase(it); + ++evicted; + } else { +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0021-CCodec-fix-underflow-issue-on-handleImageData.patch b/patches/platform_frameworks_av/0021-CCodec-fix-underflow-issue-on-handleImageData.patch new file mode 100644 index 0000000..de4c66b --- /dev/null +++ b/patches/platform_frameworks_av/0021-CCodec-fix-underflow-issue-on-handleImageData.patch @@ -0,0 +1,37 @@ +From 7e08eb2a701487a4b56b449fd5758b8ab5cfce90 Mon Sep 17 00:00:00 2001 +From: Taehwan Kim +Date: Thu, 17 Sep 2020 12:26:40 +0900 +Subject: [PATCH 21/30] CCodec: fix underflow issue on handleImageData + +the logic is assumed that gralloc does assume a contiguous mapping +at GraphicView2MediaImageConverter() in Codec2Buffer. +if it doesn't, underflow could happen because +type of variable is unsigned. + +Bug: 168757280 + +Change-Id: I04e13d0680af74e76d96d3ab10a549f6368205cf +Signed-off-by: Taehwan Kim +(cherry picked from commit fd9b809147b78330d1db7ec17e200071e779fd46) +--- + media/codec2/sfplugin/CCodecBuffers.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp +index bddaa9f22b..692da584ce 100644 +--- a/media/codec2/sfplugin/CCodecBuffers.cpp ++++ b/media/codec2/sfplugin/CCodecBuffers.cpp +@@ -91,7 +91,9 @@ void CCodecBuffers::handleImageData(const sp &buffer) { + newFormat->setInt32(KEY_STRIDE, stride); + ALOGD("[%s] updating stride = %d", mName, stride); + if (img->mNumPlanes > 1 && stride > 0) { +- int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride; ++ int64_t offsetDelta = ++ (int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset; ++ int32_t vstride = int32_t(offsetDelta / stride); + newFormat->setInt32(KEY_SLICE_HEIGHT, vstride); + ALOGD("[%s] updating vstride = %d", mName, vstride); + } +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0022-OMX-Opus-decoder-omits-sample-rate-channel-count.patch b/patches/platform_frameworks_av/0022-OMX-Opus-decoder-omits-sample-rate-channel-count.patch new file mode 100644 index 0000000..6da7fce --- /dev/null +++ b/patches/platform_frameworks_av/0022-OMX-Opus-decoder-omits-sample-rate-channel-count.patch @@ -0,0 +1,139 @@ +From 73517d3e56b2ee0eb171af1e68fa1c729eadd564 Mon Sep 17 00:00:00 2001 +From: Ray Essick +Date: Mon, 14 Sep 2020 17:05:07 -0700 +Subject: [PATCH 22/30] OMX Opus decoder omits sample rate / channel count + +The OMX Opus decoder doesn't signal back the channel/samplerate info to +the framework, leading to a CTS failure when checking required values. + +Based on an AOSP patch provided by denis.hsu@mediatek.com + +Bug: 166695414 +Test: CtsMediaTestCases android.media.cts.DecoderTest#testDecodeOpusChannelsAndRates +Change-Id: If710405caea4be6336b4aec3aa0c051ad3c0fe95 +(cherry picked from commit 74d4b70841b2aa3154b10b82ebcc6737d1d36a6d) +--- + media/libstagefright/ACodec.cpp | 26 +++++++++++++++++++ + .../codecs/opus/dec/SoftOpus.cpp | 11 +++++--- + .../libstagefright/codecs/opus/dec/SoftOpus.h | 2 ++ + .../include/media/stagefright/ACodec.h | 1 + + 4 files changed, 37 insertions(+), 3 deletions(-) + +diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp +index f843c7f45f..7ea444dc77 100644 +--- a/media/libstagefright/ACodec.cpp ++++ b/media/libstagefright/ACodec.cpp +@@ -2247,6 +2247,12 @@ status_t ACodec::configureCodec( + } + err = setupG711Codec(encoder, sampleRate, numChannels); + } ++ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_OPUS)) { ++ int32_t numChannels = 1, sampleRate = 48000; ++ if (msg->findInt32("channel-count", &numChannels) && ++ msg->findInt32("sample-rate", &sampleRate)) { ++ err = setupOpusCodec(encoder, sampleRate, numChannels); ++ } + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { + // numChannels needs to be set to properly communicate PCM values. + int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1; +@@ -3120,6 +3126,26 @@ status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numCha + kPortIndexInput, sampleRate, numChannels); + } + ++status_t ACodec::setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels) { ++ if (encoder) { ++ return INVALID_OPERATION; ++ } ++ OMX_AUDIO_PARAM_ANDROID_OPUSTYPE def; ++ InitOMXParams(&def); ++ def.nPortIndex = kPortIndexInput; ++ status_t err = mOMXNode->getParameter( ++ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def)); ++ if (err != OK) { ++ ALOGE("setupOpusCodec(): Error %d getting OMX_IndexParamAudioAndroidOpus parameter", err); ++ return err; ++ } ++ def.nSampleRate = sampleRate; ++ def.nChannels = numChannels; ++ err = mOMXNode->setParameter( ++ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def)); ++ return err; ++} ++ + status_t ACodec::setupFlacCodec( + bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel, + AudioEncoding encoding) { +diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp +index 4f61aa8be2..5bb1879da1 100644 +--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp ++++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp +@@ -58,6 +58,8 @@ SoftOpus::SoftOpus( + mInputBufferCount(0), + mDecoder(NULL), + mHeader(NULL), ++ mNumChannels(1), ++ mSamplingRate(kRate), + mCodecDelay(0), + mSeekPreRoll(0), + mAnchorTimeUs(0), +@@ -169,11 +171,11 @@ OMX_ERRORTYPE SoftOpus::internalGetParameter( + } + + opusParams->nAudioBandWidth = 0; +- opusParams->nSampleRate = kRate; ++ opusParams->nSampleRate = mSamplingRate; + opusParams->nBitRate = 0; + + if (!isConfigured()) { +- opusParams->nChannels = 1; ++ opusParams->nChannels = mNumChannels; + } else { + opusParams->nChannels = mHeader->channels; + } +@@ -274,7 +276,8 @@ OMX_ERRORTYPE SoftOpus::internalSetParameter( + if (opusParams->nPortIndex != 0) { + return OMX_ErrorUndefined; + } +- ++ mNumChannels = opusParams->nChannels; ++ mSamplingRate = opusParams->nSampleRate; + return OMX_ErrorNone; + } + +@@ -496,6 +499,8 @@ void SoftOpus::onQueueFilled(OMX_U32 /* portIndex */) { + *(reinterpret_cast(inHeader->pBuffer + + inHeader->nOffset)), + kRate); ++ mSamplingRate = kRate; ++ mNumChannels = mHeader->channels; + notify(OMX_EventPortSettingsChanged, 1, 0, NULL); + mOutputPortSettingsChange = AWAITING_DISABLED; + } +diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.h b/media/libstagefright/codecs/opus/dec/SoftOpus.h +index 91cafa14c7..00058c8212 100644 +--- a/media/libstagefright/codecs/opus/dec/SoftOpus.h ++++ b/media/libstagefright/codecs/opus/dec/SoftOpus.h +@@ -70,6 +70,8 @@ private: + OpusMSDecoder *mDecoder; + OpusHeader *mHeader; + ++ int32_t mNumChannels; ++ int32_t mSamplingRate; + int64_t mCodecDelay; + int64_t mSeekPreRoll; + int64_t mSamplesToDiscard; +diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h +index 83e92b9f43..105e7f7f98 100644 +--- a/media/libstagefright/include/media/stagefright/ACodec.h ++++ b/media/libstagefright/include/media/stagefright/ACodec.h +@@ -499,6 +499,7 @@ private: + status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate); + status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels); + ++ status_t setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels); + status_t setupFlacCodec( + bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel, + AudioEncoding encoding); +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0023-ACodec-submit-extra-output-metadata-buffers-if-in-lo.patch b/patches/platform_frameworks_av/0023-ACodec-submit-extra-output-metadata-buffers-if-in-lo.patch new file mode 100644 index 0000000..7a34f77 --- /dev/null +++ b/patches/platform_frameworks_av/0023-ACodec-submit-extra-output-metadata-buffers-if-in-lo.patch @@ -0,0 +1,138 @@ +From bf69673517df3b7c1f90cc07621f8af998310110 Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Tue, 22 Sep 2020 18:44:47 -0700 +Subject: [PATCH 23/30] ACodec: submit extra output metadata buffers if in low + latency mode + +Bug: 166250452 +Test: atest CtsMediaTestCases:DecoderTest +Merged-In: I134a16a70e8ac94dbd4f505c0a5553a3ca0f87a2 +Change-Id: I134a16a70e8ac94dbd4f505c0a5553a3ca0f87a2 +(cherry picked from commit 7e0bb3845b3059c0ee5bd33e506368828cca40fe) +--- + media/libstagefright/ACodec.cpp | 39 ++++++++++++++++++- + .../include/media/stagefright/ACodec.h | 2 + + 2 files changed, 39 insertions(+), 2 deletions(-) + +diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp +index 7ea444dc77..0f8cd39edb 100644 +--- a/media/libstagefright/ACodec.cpp ++++ b/media/libstagefright/ACodec.cpp +@@ -279,6 +279,13 @@ protected: + + void postFillThisBuffer(BufferInfo *info); + ++ void maybePostExtraOutputMetadataBufferRequest() { ++ if (!mPendingExtraOutputMetadataBufferRequest) { ++ (new AMessage(kWhatSubmitExtraOutputMetadataBuffer, mCodec))->post(); ++ mPendingExtraOutputMetadataBufferRequest = true; ++ } ++ } ++ + private: + // Handles an OMX message. Returns true iff message was handled. + bool onOMXMessage(const sp &msg); +@@ -302,6 +309,8 @@ private: + + void getMoreInputDataIfPossible(); + ++ bool mPendingExtraOutputMetadataBufferRequest; ++ + DISALLOW_EVIL_CONSTRUCTORS(BaseState); + }; + +@@ -555,6 +564,7 @@ ACodec::ACodec() + mShutdownInProgress(false), + mExplicitShutdown(false), + mIsLegacyVP9Decoder(false), ++ mIsLowLatency(false), + mEncoderDelay(0), + mEncoderPadding(0), + mRotationDegrees(0), +@@ -2425,6 +2435,7 @@ status_t ACodec::setLowLatency(int32_t lowLatency) { + if (err != OK) { + ALOGE("decoder can not set low-latency to %d (err %d)", lowLatency, err); + } ++ mIsLowLatency = (lowLatency && err == OK); + return err; + } + +@@ -5785,7 +5796,8 @@ status_t ACodec::requestIDRFrame() { + + ACodec::BaseState::BaseState(ACodec *codec, const sp &parentState) + : AState(parentState), +- mCodec(codec) { ++ mCodec(codec), ++ mPendingExtraOutputMetadataBufferRequest(false) { + } + + ACodec::BaseState::PortMode ACodec::BaseState::getPortMode( +@@ -5886,6 +5898,21 @@ bool ACodec::BaseState::onMessageReceived(const sp &msg) { + break; + } + ++ case kWhatSubmitExtraOutputMetadataBuffer: { ++ mPendingExtraOutputMetadataBufferRequest = false; ++ if (getPortMode(kPortIndexOutput) == RESUBMIT_BUFFERS && mCodec->mIsLowLatency) { ++ // Decoders often need more than one output buffer to be ++ // submitted before processing a single input buffer. ++ // For low latency codecs, we don't want to wait for more input ++ // to be queued to get those output buffers submitted. ++ if (mCodec->submitOutputMetadataBuffer() == OK ++ && mCodec->mMetadataBuffersToSubmit > 0) { ++ maybePostExtraOutputMetadataBufferRequest(); ++ } ++ } ++ break; ++ } ++ + default: + return false; + } +@@ -6242,7 +6269,12 @@ void ACodec::BaseState::onInputBufferFilled(const sp &msg) { + (outputMode == FREE_BUFFERS ? "FREE" : + outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT")); + if (outputMode == RESUBMIT_BUFFERS) { +- mCodec->submitOutputMetadataBuffer(); ++ status_t err = mCodec->submitOutputMetadataBuffer(); ++ if (mCodec->mIsLowLatency ++ && err == OK ++ && mCodec->mMetadataBuffersToSubmit > 0) { ++ maybePostExtraOutputMetadataBufferRequest(); ++ } + } + } + info->checkReadFence("onInputBufferFilled"); +@@ -7388,6 +7420,9 @@ void ACodec::ExecutingState::submitOutputMetaBuffers() { + break; + } + } ++ if (mCodec->mIsLowLatency) { ++ maybePostExtraOutputMetadataBufferRequest(); ++ } + + // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED *** + mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround(); +diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h +index 105e7f7f98..8ef92783ec 100644 +--- a/media/libstagefright/include/media/stagefright/ACodec.h ++++ b/media/libstagefright/include/media/stagefright/ACodec.h +@@ -147,6 +147,7 @@ private: + kWhatReleaseCodecInstance = 'relC', + kWhatForceStateTransition = 'fstt', + kWhatCheckIfStuck = 'Cstk', ++ kWhatSubmitExtraOutputMetadataBuffer = 'sbxo', + }; + + enum { +@@ -272,6 +273,7 @@ private: + bool mShutdownInProgress; + bool mExplicitShutdown; + bool mIsLegacyVP9Decoder; ++ bool mIsLowLatency; + + // If "mKeepComponentAllocated" we only transition back to Loaded state + // and do not release the component instance. +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0024-NuPlayerRenderer-Reset-negative-media-time-to-zero.patch b/patches/platform_frameworks_av/0024-NuPlayerRenderer-Reset-negative-media-time-to-zero.patch new file mode 100644 index 0000000..cf3a505 --- /dev/null +++ b/patches/platform_frameworks_av/0024-NuPlayerRenderer-Reset-negative-media-time-to-zero.patch @@ -0,0 +1,39 @@ +From 20517633099c124e1c639fab9b693c32875c7fba Mon Sep 17 00:00:00 2001 +From: Paras Nagda +Date: Tue, 27 Oct 2020 13:01:47 +0530 +Subject: [PATCH 24/30] NuPlayerRenderer: Reset negative media time to zero + +Reset negative media time to zero before call is made to +Mediaclock's setStartingTimeMedia(). + +Test:run android.mediastress.cts.HEVCR1080pAacLongPlayerTest#testPlay00 on gsi + +Bug: 170621757 +Bug: 171945667 +Bug: 170797642 +Bug: 171562715 +Bug: 171850618 +Change-Id: I2c405007b38229038119760423156bd53a2701c0 +--- + media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +index c30f048c2d..7e8fe45121 100644 +--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp ++++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +@@ -922,6 +922,11 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { + firstEntry = false; + int64_t mediaTimeUs; + CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); ++ if (mediaTimeUs < 0) { ++ ALOGD("fillAudioBuffer: reset negative media time %.2f secs to zero", ++ mediaTimeUs / 1E6); ++ mediaTimeUs = 0; ++ } + ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6); + setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs); + } +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0025-C2OMXNode-read-delay-from-component-to-determine-buf.patch b/patches/platform_frameworks_av/0025-C2OMXNode-read-delay-from-component-to-determine-buf.patch new file mode 100644 index 0000000..74cf28b --- /dev/null +++ b/patches/platform_frameworks_av/0025-C2OMXNode-read-delay-from-component-to-determine-buf.patch @@ -0,0 +1,68 @@ +From 3e4bfa2b9f1516d70f117c16abfa7bb7b085faf5 Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Thu, 12 Nov 2020 11:14:42 -0800 +Subject: [PATCH 25/30] C2OMXNode: read delay from component to determine + buffer count + +Bug: 169398817 +Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small +Test: atest CtsMediaTestCases:VideoEncoderTest +Change-Id: I76a3411addd83108d2da2c8f74df55acab03a365 +(cherry picked from commit 414eb15c3c6cd7e1677245508fd23899bef01feb) +--- + media/codec2/sfplugin/C2OMXNode.cpp | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp +index c7588e9a51..dd1f4858a5 100644 +--- a/media/codec2/sfplugin/C2OMXNode.cpp ++++ b/media/codec2/sfplugin/C2OMXNode.cpp +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -44,6 +45,8 @@ namespace android { + + namespace { + ++constexpr OMX_U32 kPortIndexInput = 0; ++ + class Buffer2D : public C2Buffer { + public: + explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {} +@@ -200,11 +203,27 @@ status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) + return BAD_VALUE; + } + OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params; +- // TODO: read these from intf() ++ if (pDef->nPortIndex != kPortIndexInput) { ++ break; ++ } ++ + pDef->nBufferCountActual = 16; ++ ++ std::shared_ptr comp = mComp.lock(); ++ C2PortActualDelayTuning::input inputDelay(0); ++ C2ActualPipelineDelayTuning pipelineDelay(0); ++ c2_status_t c2err = comp->query( ++ {&inputDelay, &pipelineDelay}, {}, C2_DONT_BLOCK, nullptr); ++ if (c2err == C2_OK || c2err == C2_BAD_INDEX) { ++ pDef->nBufferCountActual = 4; ++ pDef->nBufferCountActual += (inputDelay ? inputDelay.value : 0u); ++ pDef->nBufferCountActual += (pipelineDelay ? pipelineDelay.value : 0u); ++ } ++ + pDef->eDomain = OMX_PortDomainVideo; + pDef->format.video.nFrameWidth = mWidth; + pDef->format.video.nFrameHeight = mHeight; ++ pDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque; + err = OK; + break; + } +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0026-CCodec-Increase-max-linear-buffer-size-for-8K-video.patch b/patches/platform_frameworks_av/0026-CCodec-Increase-max-linear-buffer-size-for-8K-video.patch new file mode 100644 index 0000000..0fceeee --- /dev/null +++ b/patches/platform_frameworks_av/0026-CCodec-Increase-max-linear-buffer-size-for-8K-video.patch @@ -0,0 +1,37 @@ +From 9a6c5d750f7060922c4a9675f45df15310e75d5b Mon Sep 17 00:00:00 2001 +From: Sungtak Lee +Date: Sun, 8 Nov 2020 00:07:27 -0800 +Subject: [PATCH 26/30] CCodec: Increase max linear buffer size for 8K video + +Increase max linear buffer size to fit a 8K video frame. + +Bug: 172190459 +Bug: 173683705 +Bug: 173725276 +Bug: 173768931 +Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small + +Change-Id: I47cfc2718447ac51be0f90638d7e7055fd7d95ba +(cherry picked from commit 5692578e0d3ff5eb273a63ee9a4f07b719508973) +--- + media/codec2/sfplugin/CCodecBuffers.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h +index 4772ab53eb..c383a7ce1a 100644 +--- a/media/codec2/sfplugin/CCodecBuffers.h ++++ b/media/codec2/sfplugin/CCodecBuffers.h +@@ -33,8 +33,8 @@ class MemoryDealer; + class SkipCutBuffer; + + constexpr size_t kLinearBufferSize = 1048576; +-// This can fit 4K RGBA frame, and most likely client won't need more than this. +-constexpr size_t kMaxLinearBufferSize = 4096 * 2304 * 4; ++// This can fit an 8K frame. ++constexpr size_t kMaxLinearBufferSize = 7680 * 4320 * 2; + + /** + * Base class for representation of buffers at one port. +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0027-omx-calculate-nodePrefix-only-for-components-listed-.patch b/patches/platform_frameworks_av/0027-omx-calculate-nodePrefix-only-for-components-listed-.patch new file mode 100644 index 0000000..c8be0e8 --- /dev/null +++ b/patches/platform_frameworks_av/0027-omx-calculate-nodePrefix-only-for-components-listed-.patch @@ -0,0 +1,56 @@ +From 55aa1d77e5fa44434fa4ec7976bd3d4ef0bd4629 Mon Sep 17 00:00:00 2001 +From: Lajos Molnar +Date: Wed, 12 Aug 2020 15:56:31 -0700 +Subject: [PATCH 27/30] omx: calculate nodePrefix only for components listed in + IOmx + +Also make common prefix matching case insensitive. + +Bug: 162578527 +Change-Id: Iaf66967fd519e0c3eabb8f0c320b8c7e7fd03497 +(cherry picked from commit 42f653bd87672f3427bdb522f46c55502e6d20d1) +--- + media/libstagefright/omx/1.0/OmxStore.cpp | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/media/libstagefright/omx/1.0/OmxStore.cpp b/media/libstagefright/omx/1.0/OmxStore.cpp +index 67f478ead0..b5c116656f 100644 +--- a/media/libstagefright/omx/1.0/OmxStore.cpp ++++ b/media/libstagefright/omx/1.0/OmxStore.cpp +@@ -54,6 +54,24 @@ OmxStore::OmxStore( + }); + } + ++ if (!nodes.empty()) { ++ auto anyNode = nodes.cbegin(); ++ std::string::const_iterator first = anyNode->cbegin(); ++ std::string::const_iterator last = anyNode->cend(); ++ for (const std::string &name : nodes) { ++ std::string::const_iterator it1 = first; ++ for (std::string::const_iterator it2 = name.cbegin(); ++ it1 != last && it2 != name.cend() && tolower(*it1) == tolower(*it2); ++ ++it1, ++it2) { ++ } ++ last = it1; ++ } ++ mPrefix = std::string(first, last); ++ LOG(INFO) << "omx common prefix: '" << mPrefix.c_str() << "'"; ++ } else { ++ LOG(INFO) << "omx common prefix: no nodes"; ++ } ++ + MediaCodecsXmlParser parser; + parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs); + if (profilingResultsXmlPath != nullptr) { +@@ -112,8 +130,6 @@ OmxStore::OmxStore( + mRoleList[i] = std::move(role); + ++i; + } +- +- mPrefix = parser.getCommonPrefix(); + } + + OmxStore::~OmxStore() { +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0028-C2AllocatorBlob-allow-multiple-maps.patch b/patches/platform_frameworks_av/0028-C2AllocatorBlob-allow-multiple-maps.patch new file mode 100644 index 0000000..650a247 --- /dev/null +++ b/patches/platform_frameworks_av/0028-C2AllocatorBlob-allow-multiple-maps.patch @@ -0,0 +1,126 @@ +From 7fda1fcb614eab32aec99713919c2e915cca1ccd Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Wed, 25 Nov 2020 10:12:32 -0800 +Subject: [PATCH 28/30] C2AllocatorBlob: allow multiple maps + +Test: CtsMediaTestCases:DecoderTest +Test: CtsMediaV2TestCases:CodecDecoderTest +Test: VtsHalMediaC2V1_0TargetVideoDecTest +Test: VtsHalMediaC2V1_0TargetVideoEncTest +Test: VtsHalMediaC2V1_0TargetAudioDecTest +Test: VtsHalMediaC2V1_0TargetAudioEncTest +Bug: 173730101 +Change-Id: Ief24371e19c8e957ea218ffd9bbfd516353b0cc9 +(cherry picked from d04f34cdd8c7ce1a3249a9fbfdd18ca989bb1685) +--- + media/codec2/vndk/C2AllocatorBlob.cpp | 72 ++++++++++++++++++++++++--- + 1 file changed, 66 insertions(+), 6 deletions(-) + +diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp +index 50c9e59af8..aa054998f8 100644 +--- a/media/codec2/vndk/C2AllocatorBlob.cpp ++++ b/media/codec2/vndk/C2AllocatorBlob.cpp +@@ -17,6 +17,8 @@ + // #define LOG_NDEBUG 0 + #define LOG_TAG "C2AllocatorBlob" + ++#include ++ + #include + #include + +@@ -67,6 +69,10 @@ public: + private: + const std::shared_ptr mGraphicAllocation; + const C2Allocator::id_t mAllocatorId; ++ ++ std::mutex mMapLock; ++ std::multiset> mMappedOffsetSize; ++ uint8_t *mMappedAddr; + }; + + C2AllocationBlob::C2AllocationBlob( +@@ -74,20 +80,74 @@ C2AllocationBlob::C2AllocationBlob( + C2Allocator::id_t allocatorId) + : C2LinearAllocation(capacity), + mGraphicAllocation(std::move(graphicAllocation)), +- mAllocatorId(allocatorId) {} ++ mAllocatorId(allocatorId), ++ mMappedAddr(nullptr) {} + +-C2AllocationBlob::~C2AllocationBlob() {} ++C2AllocationBlob::~C2AllocationBlob() { ++ if (mMappedAddr) { ++ C2Rect rect(capacity(), kLinearBufferHeight); ++ mGraphicAllocation->unmap(&mMappedAddr, rect, nullptr); ++ } ++} + + c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage, + C2Fence* fence, void** addr /* nonnull */) { ++ *addr = nullptr; ++ if (size > capacity() || offset > capacity() || offset > capacity() - size) { ++ ALOGV("C2AllocationBlob: map: bad offset / size: offset=%zu size=%zu capacity=%u", ++ offset, size, capacity()); ++ return C2_BAD_VALUE; ++ } ++ std::unique_lock lock(mMapLock); ++ if (mMappedAddr) { ++ *addr = mMappedAddr + offset; ++ mMappedOffsetSize.insert({offset, size}); ++ ALOGV("C2AllocationBlob: mapped from existing mapping: offset=%zu size=%zu capacity=%u", ++ offset, size, capacity()); ++ return C2_OK; ++ } + C2PlanarLayout layout; +- C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u); +- return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast(addr)); ++ C2Rect rect = C2Rect(capacity(), kLinearBufferHeight); ++ c2_status_t err = mGraphicAllocation->map(rect, usage, fence, &layout, &mMappedAddr); ++ if (err != C2_OK) { ++ ALOGV("C2AllocationBlob: map failed: offset=%zu size=%zu capacity=%u err=%d", ++ offset, size, capacity(), err); ++ mMappedAddr = nullptr; ++ return err; ++ } ++ *addr = mMappedAddr + offset; ++ mMappedOffsetSize.insert({offset, size}); ++ ALOGV("C2AllocationBlob: new map succeeded: offset=%zu size=%zu capacity=%u", ++ offset, size, capacity()); ++ return C2_OK; + } + + c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) { +- C2Rect rect(size, kLinearBufferHeight); +- return mGraphicAllocation->unmap(reinterpret_cast(&addr), rect, fenceFd); ++ std::unique_lock lock(mMapLock); ++ uint8_t *u8Addr = static_cast(addr); ++ if (u8Addr < mMappedAddr || mMappedAddr + capacity() < u8Addr + size) { ++ ALOGV("C2AllocationBlob: unmap: Bad addr / size: addr=%p size=%zu capacity=%u", ++ addr, size, capacity()); ++ return C2_BAD_VALUE; ++ } ++ auto it = mMappedOffsetSize.find(std::make_pair(u8Addr - mMappedAddr, size)); ++ if (it == mMappedOffsetSize.end()) { ++ ALOGV("C2AllocationBlob: unrecognized map: addr=%p size=%zu capacity=%u", ++ addr, size, capacity()); ++ return C2_BAD_VALUE; ++ } ++ mMappedOffsetSize.erase(it); ++ if (!mMappedOffsetSize.empty()) { ++ ALOGV("C2AllocationBlob: still maintain mapping: addr=%p size=%zu capacity=%u", ++ addr, size, capacity()); ++ return C2_OK; ++ } ++ C2Rect rect(capacity(), kLinearBufferHeight); ++ c2_status_t err = mGraphicAllocation->unmap(&mMappedAddr, rect, fenceFd); ++ ALOGV("C2AllocationBlob: last unmap: addr=%p size=%zu capacity=%u err=%d", ++ addr, size, capacity(), err); ++ mMappedAddr = nullptr; ++ return err; + } + + /* ====================================== BLOB ALLOCATOR ====================================== */ +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0029-CCodec-fix-ByteBuffer-mode-image.patch b/patches/platform_frameworks_av/0029-CCodec-fix-ByteBuffer-mode-image.patch new file mode 100644 index 0000000..12c6f0f --- /dev/null +++ b/patches/platform_frameworks_av/0029-CCodec-fix-ByteBuffer-mode-image.patch @@ -0,0 +1,546 @@ +From 607c1d606efd9f955ad7545dbfdaf38450c5ce20 Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Thu, 3 Dec 2020 11:07:58 -0800 +Subject: [PATCH 29/30] CCodec: fix ByteBuffer mode image + +- Set offset to (0,0) of Y plane. +- Fix wrapping criteria. + +Bug: 169379476 +Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small +Test: atest ccodec_unit_test +Change-Id: Ic7e074ddaef277833707363b0b9fecfe210bd57f +(cherry picked from commit 2eb063152f67e886472ed42c07f3634a5eb63f19) +--- + media/codec2/sfplugin/CCodecBuffers.cpp | 3 + + media/codec2/sfplugin/Codec2Buffer.cpp | 14 +- + .../sfplugin/tests/CCodecBuffers_test.cpp | 450 +++++++++++++++++- + 3 files changed, 456 insertions(+), 11 deletions(-) + +diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp +index 692da584ce..566a18fbee 100644 +--- a/media/codec2/sfplugin/CCodecBuffers.cpp ++++ b/media/codec2/sfplugin/CCodecBuffers.cpp +@@ -96,6 +96,9 @@ void CCodecBuffers::handleImageData(const sp &buffer) { + int32_t vstride = int32_t(offsetDelta / stride); + newFormat->setInt32(KEY_SLICE_HEIGHT, vstride); + ALOGD("[%s] updating vstride = %d", mName, vstride); ++ buffer->setRange( ++ img->mPlane[0].mOffset, ++ buffer->size() - img->mPlane[0].mOffset); + } + } + setFormat(newFormat); +diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp +index 25e7da9206..19414a0a0c 100644 +--- a/media/codec2/sfplugin/Codec2Buffer.cpp ++++ b/media/codec2/sfplugin/Codec2Buffer.cpp +@@ -276,20 +276,22 @@ public: + int32_t planeSize = 0; + for (uint32_t i = 0; i < layout.numPlanes; ++i) { + const C2PlaneInfo &plane = layout.planes[i]; +- ssize_t minOffset = plane.minOffset(mWidth, mHeight); +- ssize_t maxOffset = plane.maxOffset(mWidth, mHeight); ++ int64_t planeStride = std::abs(plane.rowInc / plane.colInc); ++ ssize_t minOffset = plane.minOffset( ++ mWidth / plane.colSampling, mHeight / plane.rowSampling); ++ ssize_t maxOffset = plane.maxOffset( ++ mWidth / plane.colSampling, mHeight / plane.rowSampling); + if (minPtr > mView.data()[i] + minOffset) { + minPtr = mView.data()[i] + minOffset; + } + if (maxPtr < mView.data()[i] + maxOffset) { + maxPtr = mView.data()[i] + maxOffset; + } +- planeSize += std::abs(plane.rowInc) * align(mHeight, 64) +- / plane.rowSampling / plane.colSampling +- * divUp(mAllocatedDepth, 8u); ++ planeSize += planeStride * divUp(mAllocatedDepth, 8u) ++ * align(mHeight, 64) / plane.rowSampling; + } + +- if ((maxPtr - minPtr + 1) <= planeSize) { ++ if (minPtr == mView.data()[0] && (maxPtr - minPtr + 1) <= planeSize) { + // FIXME: this is risky as reading/writing data out of bound results + // in an undefined behavior, but gralloc does assume a + // contiguous mapping +diff --git a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp +index 5bee605276..ad8f6e555b 100644 +--- a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp ++++ b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp +@@ -18,22 +18,31 @@ + + #include + ++#include + #include + ++#include + #include + + namespace android { + ++static std::shared_ptr GetRawGraphicOutputBuffers( ++ int32_t width, int32_t height) { ++ std::shared_ptr buffers = ++ std::make_shared("test"); ++ sp format{new AMessage}; ++ format->setInt32(KEY_WIDTH, width); ++ format->setInt32(KEY_HEIGHT, height); ++ buffers->setFormat(format); ++ return buffers; ++} ++ + TEST(RawGraphicOutputBuffersTest, ChangeNumSlots) { + constexpr int32_t kWidth = 3840; + constexpr int32_t kHeight = 2160; + + std::shared_ptr buffers = +- std::make_shared("test"); +- sp format{new AMessage}; +- format->setInt32("width", kWidth); +- format->setInt32("height", kHeight); +- buffers->setFormat(format); ++ GetRawGraphicOutputBuffers(kWidth, kHeight); + + std::shared_ptr pool; + ASSERT_EQ(OK, GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, nullptr, &pool)); +@@ -96,4 +105,435 @@ TEST(RawGraphicOutputBuffersTest, ChangeNumSlots) { + } + } + ++class TestGraphicAllocation : public C2GraphicAllocation { ++public: ++ TestGraphicAllocation( ++ uint32_t width, ++ uint32_t height, ++ const C2PlanarLayout &layout, ++ size_t capacity, ++ std::vector offsets) ++ : C2GraphicAllocation(width, height), ++ mLayout(layout), ++ mMemory(capacity, 0xAA), ++ mOffsets(offsets) { ++ } ++ ++ c2_status_t map( ++ C2Rect rect, C2MemoryUsage usage, C2Fence *fence, ++ C2PlanarLayout *layout, uint8_t **addr) override { ++ (void)rect; ++ (void)usage; ++ (void)fence; ++ *layout = mLayout; ++ for (size_t i = 0; i < mLayout.numPlanes; ++i) { ++ addr[i] = mMemory.data() + mOffsets[i]; ++ } ++ return C2_OK; ++ } ++ ++ c2_status_t unmap(uint8_t **, C2Rect, C2Fence *) override { return C2_OK; } ++ ++ C2Allocator::id_t getAllocatorId() const override { return -1; } ++ ++ const C2Handle *handle() const override { return nullptr; } ++ ++ bool equals(const std::shared_ptr &other) const override { ++ return other.get() == this; ++ } ++ ++private: ++ C2PlanarLayout mLayout; ++ std::vector mMemory; ++ std::vector mAddr; ++ std::vector mOffsets; ++}; ++ ++class LayoutTest : public ::testing::TestWithParam> { ++private: ++ static C2PlanarLayout YUVPlanarLayout(int32_t stride) { ++ C2PlanarLayout layout = { ++ C2PlanarLayout::TYPE_YUV, ++ 3, /* numPlanes */ ++ 3, /* rootPlanes */ ++ {}, /* planes --- to be filled below */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_Y] = { ++ C2PlaneInfo::CHANNEL_Y, ++ 1, /* colInc */ ++ stride, /* rowInc */ ++ 1, /* colSampling */ ++ 1, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_Y, /* rootIx */ ++ 0, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_U] = { ++ C2PlaneInfo::CHANNEL_CB, ++ 1, /* colInc */ ++ stride / 2, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_U, /* rootIx */ ++ 0, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_V] = { ++ C2PlaneInfo::CHANNEL_CR, ++ 1, /* colInc */ ++ stride / 2, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_V, /* rootIx */ ++ 0, /* offset */ ++ }; ++ return layout; ++ } ++ ++ static C2PlanarLayout YUVSemiPlanarLayout(int32_t stride) { ++ C2PlanarLayout layout = { ++ C2PlanarLayout::TYPE_YUV, ++ 3, /* numPlanes */ ++ 2, /* rootPlanes */ ++ {}, /* planes --- to be filled below */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_Y] = { ++ C2PlaneInfo::CHANNEL_Y, ++ 1, /* colInc */ ++ stride, /* rowInc */ ++ 1, /* colSampling */ ++ 1, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_Y, /* rootIx */ ++ 0, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_U] = { ++ C2PlaneInfo::CHANNEL_CB, ++ 2, /* colInc */ ++ stride, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_U, /* rootIx */ ++ 0, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_V] = { ++ C2PlaneInfo::CHANNEL_CR, ++ 2, /* colInc */ ++ stride, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_U, /* rootIx */ ++ 1, /* offset */ ++ }; ++ return layout; ++ } ++ ++ static C2PlanarLayout YVUSemiPlanarLayout(int32_t stride) { ++ C2PlanarLayout layout = { ++ C2PlanarLayout::TYPE_YUV, ++ 3, /* numPlanes */ ++ 2, /* rootPlanes */ ++ {}, /* planes --- to be filled below */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_Y] = { ++ C2PlaneInfo::CHANNEL_Y, ++ 1, /* colInc */ ++ stride, /* rowInc */ ++ 1, /* colSampling */ ++ 1, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_Y, /* rootIx */ ++ 0, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_U] = { ++ C2PlaneInfo::CHANNEL_CB, ++ 2, /* colInc */ ++ stride, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_V, /* rootIx */ ++ 1, /* offset */ ++ }; ++ layout.planes[C2PlanarLayout::PLANE_V] = { ++ C2PlaneInfo::CHANNEL_CR, ++ 2, /* colInc */ ++ stride, /* rowInc */ ++ 2, /* colSampling */ ++ 2, /* rowSampling */ ++ 8, /* allocatedDepth */ ++ 8, /* bitDepth */ ++ 0, /* rightShift */ ++ C2PlaneInfo::NATIVE, ++ C2PlanarLayout::PLANE_V, /* rootIx */ ++ 0, /* offset */ ++ }; ++ return layout; ++ } ++ ++ static std::shared_ptr CreateGraphicBlock( ++ uint32_t width, ++ uint32_t height, ++ const C2PlanarLayout &layout, ++ size_t capacity, ++ std::vector offsets) { ++ std::shared_ptr alloc = std::make_shared( ++ width, ++ height, ++ layout, ++ capacity, ++ offsets); ++ ++ return _C2BlockFactory::CreateGraphicBlock(alloc); ++ } ++ ++ static constexpr uint8_t GetPixelValue(uint8_t value, uint32_t row, uint32_t col) { ++ return (uint32_t(value) * row + col) & 0xFF; ++ } ++ ++ static void FillPlane(C2GraphicView &view, size_t index, uint8_t value) { ++ C2PlanarLayout layout = view.layout(); ++ ++ uint8_t *rowPtr = view.data()[index]; ++ C2PlaneInfo plane = layout.planes[index]; ++ for (uint32_t row = 0; row < view.height() / plane.rowSampling; ++row) { ++ uint8_t *colPtr = rowPtr; ++ for (uint32_t col = 0; col < view.width() / plane.colSampling; ++col) { ++ *colPtr = GetPixelValue(value, row, col); ++ colPtr += plane.colInc; ++ } ++ rowPtr += plane.rowInc; ++ } ++ } ++ ++ static void FillBlock(const std::shared_ptr &block) { ++ C2GraphicView view = block->map().get(); ++ ++ FillPlane(view, C2PlanarLayout::PLANE_Y, 'Y'); ++ FillPlane(view, C2PlanarLayout::PLANE_U, 'U'); ++ FillPlane(view, C2PlanarLayout::PLANE_V, 'V'); ++ } ++ ++ static bool VerifyPlane( ++ const MediaImage2 *mediaImage, ++ const uint8_t *base, ++ uint32_t index, ++ uint8_t value, ++ std::string *errorMsg) { ++ *errorMsg = ""; ++ MediaImage2::PlaneInfo plane = mediaImage->mPlane[index]; ++ const uint8_t *rowPtr = base + plane.mOffset; ++ for (uint32_t row = 0; row < mediaImage->mHeight / plane.mVertSubsampling; ++row) { ++ const uint8_t *colPtr = rowPtr; ++ for (uint32_t col = 0; col < mediaImage->mWidth / plane.mHorizSubsampling; ++col) { ++ if (GetPixelValue(value, row, col) != *colPtr) { ++ *errorMsg = AStringPrintf("row=%u col=%u expected=%02x actual=%02x", ++ row, col, GetPixelValue(value, row, col), *colPtr).c_str(); ++ return false; ++ } ++ colPtr += plane.mColInc; ++ } ++ rowPtr += plane.mRowInc; ++ } ++ return true; ++ } ++ ++public: ++ static constexpr int32_t kWidth = 320; ++ static constexpr int32_t kHeight = 240; ++ static constexpr int32_t kGapLength = kWidth * kHeight * 10; ++ ++ static std::shared_ptr CreateAndFillBufferFromParam(const ParamType ¶m) { ++ bool contiguous = std::get<0>(param); ++ std::string planeOrderStr = std::get<1>(param); ++ bool planar = std::get<2>(param); ++ int32_t stride = std::get<3>(param); ++ ++ C2PlanarLayout::plane_index_t planeOrder[3]; ++ C2PlanarLayout layout; ++ ++ if (planeOrderStr.size() != 3) { ++ return nullptr; ++ } ++ for (size_t i = 0; i < 3; ++i) { ++ C2PlanarLayout::plane_index_t planeIndex; ++ switch (planeOrderStr[i]) { ++ case 'Y': planeIndex = C2PlanarLayout::PLANE_Y; break; ++ case 'U': planeIndex = C2PlanarLayout::PLANE_U; break; ++ case 'V': planeIndex = C2PlanarLayout::PLANE_V; break; ++ default: return nullptr; ++ } ++ planeOrder[i] = planeIndex; ++ } ++ ++ if (planar) { ++ layout = YUVPlanarLayout(stride); ++ } else { // semi-planar ++ for (size_t i = 0; i < 3; ++i) { ++ if (planeOrder[i] == C2PlanarLayout::PLANE_U) { ++ layout = YUVSemiPlanarLayout(stride); ++ break; ++ } ++ if (planeOrder[i] == C2PlanarLayout::PLANE_V) { ++ layout = YVUSemiPlanarLayout(stride); ++ break; ++ } ++ } ++ } ++ ++ size_t yPlaneSize = stride * kHeight; ++ size_t uvPlaneSize = stride * kHeight / 4; ++ size_t capacity = yPlaneSize + uvPlaneSize * 2; ++ std::vector offsets(3); ++ ++ if (!contiguous) { ++ if (planar) { ++ capacity += kGapLength * 2; ++ } else { // semi-planar ++ capacity += kGapLength; ++ } ++ } ++ ++ offsets[planeOrder[0]] = 0; ++ size_t planeSize = (planeOrder[0] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize; ++ for (size_t i = 1; i < 3; ++i) { ++ offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + planeSize; ++ if (!contiguous) { ++ offsets[planeOrder[i]] += kGapLength; ++ } ++ planeSize = (planeOrder[i] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize; ++ if (!planar // semi-planar ++ && planeOrder[i - 1] != C2PlanarLayout::PLANE_Y ++ && planeOrder[i] != C2PlanarLayout::PLANE_Y) { ++ offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + 1; ++ planeSize = uvPlaneSize * 2 - 1; ++ } ++ } ++ ++ std::shared_ptr block = CreateGraphicBlock( ++ kWidth, ++ kHeight, ++ layout, ++ capacity, ++ offsets); ++ FillBlock(block); ++ return C2Buffer::CreateGraphicBuffer( ++ block->share(block->crop(), C2Fence())); ++ } ++ ++ static bool VerifyClientBuffer( ++ const sp &buffer, std::string *errorMsg) { ++ *errorMsg = ""; ++ sp imageData; ++ if (!buffer->format()->findBuffer("image-data", &imageData)) { ++ *errorMsg = "Missing image data"; ++ return false; ++ } ++ MediaImage2 *mediaImage = (MediaImage2 *)imageData->data(); ++ if (mediaImage->mType != MediaImage2::MEDIA_IMAGE_TYPE_YUV) { ++ *errorMsg = AStringPrintf("Unexpected type: %d", mediaImage->mType).c_str(); ++ return false; ++ } ++ std::string planeErrorMsg; ++ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::Y, 'Y', &planeErrorMsg)) { ++ *errorMsg = "Y plane does not match: " + planeErrorMsg; ++ return false; ++ } ++ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::U, 'U', &planeErrorMsg)) { ++ *errorMsg = "U plane does not match: " + planeErrorMsg; ++ return false; ++ } ++ if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::V, 'V', &planeErrorMsg)) { ++ *errorMsg = "V plane does not match: " + planeErrorMsg; ++ return false; ++ } ++ ++ int32_t width, height, stride; ++ buffer->format()->findInt32(KEY_WIDTH, &width); ++ buffer->format()->findInt32(KEY_HEIGHT, &height); ++ buffer->format()->findInt32(KEY_STRIDE, &stride); ++ ++ MediaImage2 legacyYLayout = { ++ MediaImage2::MEDIA_IMAGE_TYPE_Y, ++ 1, // mNumPlanes ++ uint32_t(width), ++ uint32_t(height), ++ 8, ++ 8, ++ {}, // mPlane ++ }; ++ legacyYLayout.mPlane[MediaImage2::Y] = { ++ 0, // mOffset ++ 1, // mColInc ++ stride, // mRowInc ++ 1, // mHorizSubsampling ++ 1, // mVertSubsampling ++ }; ++ if (!VerifyPlane(&legacyYLayout, buffer->data(), MediaImage2::Y, 'Y', &planeErrorMsg)) { ++ *errorMsg = "Y plane by legacy layout does not match: " + planeErrorMsg; ++ return false; ++ } ++ return true; ++ } ++ ++}; ++ ++TEST_P(LayoutTest, VerifyLayout) { ++ std::shared_ptr buffers = ++ GetRawGraphicOutputBuffers(kWidth, kHeight); ++ ++ std::shared_ptr c2Buffer = CreateAndFillBufferFromParam(GetParam()); ++ ASSERT_NE(nullptr, c2Buffer); ++ sp clientBuffer; ++ size_t index; ++ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer)); ++ ASSERT_NE(nullptr, clientBuffer); ++ std::string errorMsg; ++ ASSERT_TRUE(VerifyClientBuffer(clientBuffer, &errorMsg)) << errorMsg; ++} ++ ++INSTANTIATE_TEST_SUITE_P( ++ RawGraphicOutputBuffersTest, ++ LayoutTest, ++ ::testing::Combine( ++ ::testing::Bool(), /* contiguous */ ++ ::testing::Values("YUV", "YVU", "UVY", "VUY"), ++ ::testing::Bool(), /* planar */ ++ ::testing::Values(320, 512)), ++ [](const ::testing::TestParamInfo &info) { ++ std::string contiguous = std::get<0>(info.param) ? "Contiguous" : "Noncontiguous"; ++ std::string planar = std::get<2>(info.param) ? "Planar" : "SemiPlanar"; ++ return contiguous ++ + std::get<1>(info.param) ++ + planar ++ + std::to_string(std::get<3>(info.param)); ++ }); ++ + } // namespace android +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0030-CCodec-GraphicBufferSourceWrapper-fix-to-apply-nBuff.patch b/patches/platform_frameworks_av/0030-CCodec-GraphicBufferSourceWrapper-fix-to-apply-nBuff.patch new file mode 100644 index 0000000..a947686 --- /dev/null +++ b/patches/platform_frameworks_av/0030-CCodec-GraphicBufferSourceWrapper-fix-to-apply-nBuff.patch @@ -0,0 +1,44 @@ +From 9a240b125c01838dcd7be395354cd8d740b0923b Mon Sep 17 00:00:00 2001 +From: Taehwan Kim +Date: Thu, 26 Nov 2020 22:40:40 +0900 +Subject: [PATCH 30/30] CCodec: GraphicBufferSourceWrapper: fix to apply + nBufferCountActual for deciding number of inputs + +Bug: 169398817 + +Change-Id: I58cd7da35a3ddc4abdb58df954307acf329c7ee7 +Signed-off-by: Taehwan Kim +(cherry picked from commit 8b3bcddbc98af38d64a1ffefd5932b498f9d4c36) +--- + media/codec2/sfplugin/CCodec.cpp | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp +index 54107bd852..2f16ca1104 100644 +--- a/media/codec2/sfplugin/CCodec.cpp ++++ b/media/codec2/sfplugin/CCodec.cpp +@@ -246,8 +246,19 @@ public: + if (source == nullptr) { + return NO_INIT; + } +- constexpr size_t kNumSlots = 16; +- for (size_t i = 0; i < kNumSlots; ++i) { ++ ++ size_t numSlots = 4; ++ constexpr OMX_U32 kPortIndexInput = 0; ++ ++ OMX_PARAM_PORTDEFINITIONTYPE param; ++ param.nPortIndex = kPortIndexInput; ++ status_t err = mNode->getParameter(OMX_IndexParamPortDefinition, ++ ¶m, sizeof(param)); ++ if (err == OK) { ++ numSlots = param.nBufferCountActual; ++ } ++ ++ for (size_t i = 0; i < numSlots; ++i) { + source->onInputBufferAdded(i); + } + +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0031-CCodec-workaround-for-frame-drops.patch b/patches/platform_frameworks_av/0031-CCodec-workaround-for-frame-drops.patch new file mode 100644 index 0000000..6b2d6da --- /dev/null +++ b/patches/platform_frameworks_av/0031-CCodec-workaround-for-frame-drops.patch @@ -0,0 +1,53 @@ +From c833b08d188dbb1294e164958c51ac2afb0e3e2e Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Tue, 5 Jan 2021 18:55:22 -0800 +Subject: [PATCH 31/32] CCodec: workaround for frame drops + +Retain old behavior for lower resolution (<=4K) to workaround +possible frame drops. + +Bug: 175354926 +Bug: 175182085 +Test: atest CtsCameraTestCases:RecordingTest +Change-Id: I170102e928714c5b48817bf7915f55ce8a6280f0 +--- + media/codec2/sfplugin/CCodec.cpp | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp +index 2f16ca1104..55ff18f4a2 100644 +--- a/media/codec2/sfplugin/CCodec.cpp ++++ b/media/codec2/sfplugin/CCodec.cpp +@@ -247,15 +247,20 @@ public: + return NO_INIT; + } + +- size_t numSlots = 4; +- constexpr OMX_U32 kPortIndexInput = 0; +- +- OMX_PARAM_PORTDEFINITIONTYPE param; +- param.nPortIndex = kPortIndexInput; +- status_t err = mNode->getParameter(OMX_IndexParamPortDefinition, +- ¶m, sizeof(param)); +- if (err == OK) { +- numSlots = param.nBufferCountActual; ++ size_t numSlots = 16; ++ // WORKAROUND: having more slots improve performance while consuming ++ // more memory. This is a temporary workaround to reduce memory for ++ // larger-than-4K scenario. ++ if (mWidth * mHeight > 4096 * 2340) { ++ constexpr OMX_U32 kPortIndexInput = 0; ++ ++ OMX_PARAM_PORTDEFINITIONTYPE param; ++ param.nPortIndex = kPortIndexInput; ++ status_t err = mNode->getParameter(OMX_IndexParamPortDefinition, ++ ¶m, sizeof(param)); ++ if (err == OK) { ++ numSlots = param.nBufferCountActual; ++ } + } + + for (size_t i = 0; i < numSlots; ++i) { +-- +2.25.1 + diff --git a/patches/platform_frameworks_av/0032-Fix-AAC-decoder-failing-to-instantiate.patch b/patches/platform_frameworks_av/0032-Fix-AAC-decoder-failing-to-instantiate.patch new file mode 100644 index 0000000..5f00d25 --- /dev/null +++ b/patches/platform_frameworks_av/0032-Fix-AAC-decoder-failing-to-instantiate.patch @@ -0,0 +1,37 @@ +From 624cfc90b8bedb024f289772960f3cd7072fa940 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Sat, 6 Mar 2021 19:15:24 -0500 +Subject: [PATCH 32/32] Fix AAC decoder failing to instantiate + +This has been caused by I50fcc5ef35cb7e96592c2267652228b5fa074ba9 +Non-Android 11 vendors won't provide those calls, and will thus fail. +--- + media/libstagefright/ACodec.cpp | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp +index 0f8cd39edb..35cdf86319 100644 +--- a/media/libstagefright/ACodec.cpp ++++ b/media/libstagefright/ACodec.cpp +@@ -5340,9 +5340,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { + 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); +@@ -5355,6 +5353,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { + notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode); + notify->setInt32("aac-drc-output-loudness", + presentation.nDrcOutputLoudness); ++ } + } + } + break; +-- +2.25.1 + diff --git a/patches/platform_frameworks_base/0040-Fix-for-TestDirectBootEmulated-testcase.patch b/patches/platform_frameworks_base/0040-Fix-for-TestDirectBootEmulated-testcase.patch new file mode 100644 index 0000000..dbc936c --- /dev/null +++ b/patches/platform_frameworks_base/0040-Fix-for-TestDirectBootEmulated-testcase.patch @@ -0,0 +1,37 @@ +From 109bc691f314f18f923c5c72fc82ff072c77eca3 Mon Sep 17 00:00:00 2001 +From: N Harish +Date: Mon, 25 Jan 2021 17:22:33 +0530 +Subject: [PATCH 40/40] Fix for TestDirectBootEmulated testcase + +In case of emulated FBE the secrets are empty hence add this +exception to prevent from unlocking userkey. + +Bug: 177617301 +Test: android.appsecurity.cts.DirectBootHostTest#testDirectBootEmulated + +Change-Id: I5be2ceb61d9ef47219862e75cc8ec03ab5513426 +(cherry picked from commit 2912b101aaa34abfa9637f2f00c992e7d129b994) +--- + .../core/java/com/android/server/StorageManagerService.java | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java +index 87afdac45dae..179899ee6067 100644 +--- a/services/core/java/com/android/server/StorageManagerService.java ++++ b/services/core/java/com/android/server/StorageManagerService.java +@@ -3295,6 +3295,12 @@ class StorageManagerService extends IStorageManager.Stub + enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); + + if (isFsEncrypted) { ++ // When a user has secure lock screen, require secret to actually unlock. ++ // This check is mostly in place for emulation mode. ++ if (StorageManager.isFileEncryptedEmulatedOnly() && ++ mLockPatternUtils.isSecure(userId) && ArrayUtils.isEmpty(secret)) { ++ throw new IllegalStateException("Secret required to unlock secure user " + userId); ++ } + try { + mVold.unlockUserKey(userId, serialNumber, encodeBytes(token), + encodeBytes(secret)); +-- +2.25.1 + diff --git a/patches/platform_frameworks_base/0041-Make-secondary-displays-lock-screen-black.-Useful-fo.patch b/patches/platform_frameworks_base/0041-Make-secondary-displays-lock-screen-black.-Useful-fo.patch new file mode 100644 index 0000000..d7be9b4 --- /dev/null +++ b/patches/platform_frameworks_base/0041-Make-secondary-displays-lock-screen-black.-Useful-fo.patch @@ -0,0 +1,27 @@ +From 8b9a1e5df3dd1b25b2cf9d83eca1353327697796 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Sat, 6 Mar 2021 18:39:15 -0500 +Subject: [PATCH 41/41] Make secondary displays' lock screen black. Useful for + Moto Razr AOD + +--- + .../SystemUI/res-keyguard/layout/keyguard_presentation.xml | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml +index f4d34f4ca141..58650b26ceaf 100644 +--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml ++++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml +@@ -22,7 +22,8 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/presentation" + android:layout_width="match_parent" +- android:layout_height="match_parent"> ++ android:layout_height="match_parent" ++ android:background="@android:color/black"> + + +Date: Sat, 10 Oct 2020 17:08:47 +0800 +Subject: [PATCH 12/13] DO NOT MERGE Correct physical orientation + +setProjection already includes the physical orientation when updating +the DisplayDevice orientation. Therefore applying the physical +orientation when capturing a screenshot applies the rotation twice +which is incorrect. + +Bug: 170512822 +Test: run cts-on-gsi -m CtsInputMethodServiceHostTestCases -t android.inputmethodservice.cts.hostside.InputMethodServiceLifecycleTest#testImeVisibilityAfterImeSwitchingFull +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.FocusHandlingTest#testNonFocusablePopupWindowDoesNotAffectImeVisibility +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.ImeInsetsVisibilityTest#testEditTextPositionAndPersistWhenAboveImeWindowShown +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.ImeInsetsVisibilityTest#testImeVisibilityWhenImeFocusableChildPopup" /> +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.InputMethodServiceTest#testRequestHideSelf +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.InputMethodServiceTest#testRequestShowSelf +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testBasicShowHideSoftInput +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testFloatingImeHideKeyboardAfterBackPressed +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testImeVisibilityWhenDismisingDialogWithImeFocused +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.KeyboardVisibilityControlTest#testToggleSoftInput +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testShowImeWhenSearchViewFocusInListView +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testShowImeWithSearchViewFocus +run cts-on-gsi -m CtsInputMethodTestCases -t android.view.inputmethod.cts.SearchViewTest#testTapThenSetQuery +run cts-on-gsi -m CtsWindowManagerDeviceTestCases -t android.server.wm.WindowInsetsAnimationSynchronicityTests#testControl_rendersSynchronouslyBetweenImeWindowAndAppContent +run cts-on-gsi -m CtsWindowManagerDeviceTestCases -t android.server.wm.WindowInsetsAnimationSynchronicityTests#testShowAndHide_renderSynchronouslyBetweenImeWindowAndAppContent + +Change-Id: I72aba3cdbae1075dcf9d99661bfd13fe5fd74c72 +(cherry picked from commit d4d89976ea3f98248064fd755505ee5dc9b35c2f) +--- + services/surfaceflinger/DisplayDevice.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h +index cb467ea29..ca7119e2c 100644 +--- a/services/surfaceflinger/DisplayDevice.h ++++ b/services/surfaceflinger/DisplayDevice.h +@@ -313,7 +313,7 @@ private: + logicalOrientation = ui::Rotation::Rotation90; + } + +- const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation; ++ const ui::Rotation orientation = logicalOrientation; + + switch (orientation) { + case ui::ROTATION_0: +-- +2.25.1 + diff --git a/patches/platform_frameworks_native/0013-gralloc4-fix-PlaneLayout-encode-typecasting.patch b/patches/platform_frameworks_native/0013-gralloc4-fix-PlaneLayout-encode-typecasting.patch new file mode 100644 index 0000000..6db6c79 --- /dev/null +++ b/patches/platform_frameworks_native/0013-gralloc4-fix-PlaneLayout-encode-typecasting.patch @@ -0,0 +1,68 @@ +From 54a80ed3e7039548d565c4e40e2fa7a45c89bce8 Mon Sep 17 00:00:00 2001 +From: SeYeong Byeon +Date: Tue, 15 Sep 2020 15:02:40 +0900 +Subject: [PATCH 13/13] gralloc4: fix PlaneLayout encode typecasting + +Fixes a bug where planeLayout members were being downcasted +to int32_t during the encoding step. + +Bug: 168564125 + +Signed-off-by: SeYeong Byeon +Change-Id: I8d5139dbd253278193775380ca387d45bfe2589d +(cherry picked from commit 389ee53332904b49c8f9fb35ef4e9e624e1ee3d2) +--- + libs/gralloc/types/Gralloc4.cpp | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp +index 53c68b723..e2f072a7a 100644 +--- a/libs/gralloc/types/Gralloc4.cpp ++++ b/libs/gralloc/types/Gralloc4.cpp +@@ -706,35 +706,35 @@ status_t encodePlaneLayout(const PlaneLayout& input, OutputHidlVec* output) { + return err; + } + +- err = encodeInteger(static_cast(input.offsetInBytes), output); ++ err = encodeInteger(static_cast(input.offsetInBytes), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.sampleIncrementInBits), output); ++ err = encodeInteger(static_cast(input.sampleIncrementInBits), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.strideInBytes), output); ++ err = encodeInteger(static_cast(input.strideInBytes), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.widthInSamples), output); ++ err = encodeInteger(static_cast(input.widthInSamples), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.heightInSamples), output); ++ err = encodeInteger(static_cast(input.heightInSamples), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.totalSizeInBytes), output); ++ err = encodeInteger(static_cast(input.totalSizeInBytes), output); + if (err) { + return err; + } +- err = encodeInteger(static_cast(input.horizontalSubsampling), output); ++ err = encodeInteger(static_cast(input.horizontalSubsampling), output); + if (err) { + return err; + } +- return encodeInteger(static_cast(input.verticalSubsampling), output); ++ return encodeInteger(static_cast(input.verticalSubsampling), output); + } + + status_t decodePlaneLayout(InputHidlVec* input, PlaneLayout* output) { +-- +2.25.1 + diff --git a/patches/platform_packages_apps_Settings/0001-Act-as-usb-device-when-there-is-no-hal-but-we-believ.patch b/patches/platform_packages_apps_Settings/0001-Act-as-usb-device-when-there-is-no-hal-but-we-believ.patch new file mode 100644 index 0000000..f26989c --- /dev/null +++ b/patches/platform_packages_apps_Settings/0001-Act-as-usb-device-when-there-is-no-hal-but-we-believ.patch @@ -0,0 +1,32 @@ +From 28d9ac16f35106b40dd183dfc697023e056f3cae Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Tue, 14 Aug 2018 21:48:19 +0200 +Subject: [PATCH] Act as usb device when there is no hal, but we believe we are + a device + +Change-Id: I036090738525fd8cc63534d52d02ab1852950a7d +--- + .../usb/UsbConnectionBroadcastReceiver.java | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java +index a203534dde..86c8564bed 100644 +--- a/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java ++++ b/src/com/android/settings/connecteddevice/usb/UsbConnectionBroadcastReceiver.java +@@ -78,6 +78,13 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements + mFunctions = functions; + mDataRole = mUsbBackend.getDataRole(); + mPowerRole = mUsbBackend.getPowerRole(); ++ //If we have no USB HAL, mDataRole is invalid ++ //But we can't be connected AND have none data_role, so it's safe. ++ //It would be better to fix UsbManager when no HAL is available, but that's more work ++ if(mDataRole == UsbPortStatus.DATA_ROLE_NONE && ++ intent.getExtras().getBoolean(UsbManager.USB_CONNECTED) && ++ !intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED)) ++ mDataRole = UsbPortStatus.DATA_ROLE_DEVICE; + } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) { + UsbPortStatus portStatus = intent.getExtras() + .getParcelable(UsbManager.EXTRA_PORT_STATUS); +-- +2.25.1 + diff --git a/patches/platform_system_core/0009-Make-ro.product.cpu.abilist-to-be-fetched-dynamicall.patch b/patches/platform_system_core/0009-Make-ro.product.cpu.abilist-to-be-fetched-dynamicall.patch new file mode 100644 index 0000000..16cb5c7 --- /dev/null +++ b/patches/platform_system_core/0009-Make-ro.product.cpu.abilist-to-be-fetched-dynamicall.patch @@ -0,0 +1,104 @@ +From e9288c036c55b8d7cc1c3ba9e1b20a3ca4fb29e3 Mon Sep 17 00:00:00 2001 +From: SzuWei Lin +Date: Thu, 31 Dec 2020 16:52:39 +0800 +Subject: [PATCH] Make ro.product.cpu.abilist* to be fetched dynamically + +Basically, ro.product.cpu.abilist* are defined by +ro.vendor.cpu.abilist*. And they can be overried by +ro.odm.cpu.abilist* and ro.product.cpu.abilist*. +ro.system.cpu.abilist* are for fallback if others are no defined. + +Bug: 176520383 +Test: check the result by flashing aosp_arm64-userdebug on +Test: aosp_blueline-user and aosp_blueline-user hacked by +Test: 64-bits-only +Change-Id: I01ae01af099a4ec8fe3d4525edecc233a477ff60 +--- + init/property_service.cpp | 64 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/init/property_service.cpp b/init/property_service.cpp +index 42dd5afcb..44b51c2cf 100644 +--- a/init/property_service.cpp ++++ b/init/property_service.cpp +@@ -874,6 +874,69 @@ static void property_derive_build_fingerprint() { + } + } + ++// If the ro.product.cpu.abilist* properties have not been explicitly ++// set, derive them from ro.${partition}.product.cpu.abilist* properties. ++static void property_initialize_ro_cpu_abilist() { ++ // From high to low priority. ++ const char* kAbilistSources[] = { ++ "product", ++ "odm", ++ "vendor", ++ "system", ++ }; ++ const std::string EMPTY = ""; ++ const char* kAbilistProp = "ro.product.cpu.abilist"; ++ const char* kAbilist32Prop = "ro.product.cpu.abilist32"; ++ const char* kAbilist64Prop = "ro.product.cpu.abilist64"; ++ ++ // If the properties are defined explicitly, just use them. ++ if (GetProperty(kAbilistProp, EMPTY) != EMPTY) { ++ return; ++ } ++ ++ // Find the first source defining these properties by order. ++ std::string abilist32_prop_val; ++ std::string abilist64_prop_val; ++ for (const auto& source : kAbilistSources) { ++ const auto abilist32_prop = std::string("ro.") + source + ".product.cpu.abilist32"; ++ const auto abilist64_prop = std::string("ro.") + source + ".product.cpu.abilist64"; ++ abilist32_prop_val = GetProperty(abilist32_prop, EMPTY); ++ abilist64_prop_val = GetProperty(abilist64_prop, EMPTY); ++ // The properties could be empty on 32-bit-only or 64-bit-only devices, ++ // but we cannot identify a property is empty or undefined by GetProperty(). ++ // So, we assume both of these 2 properties are empty as undefined. ++ if (abilist32_prop_val != EMPTY || abilist64_prop_val != EMPTY) { ++ break; ++ } ++ } ++ ++ // Merge ABI lists for ro.product.cpu.abilist ++ auto abilist_prop_val = abilist64_prop_val; ++ if (abilist32_prop_val != EMPTY) { ++ if (abilist_prop_val != EMPTY) { ++ abilist_prop_val += ","; ++ } ++ abilist_prop_val += abilist32_prop_val; ++ } ++ ++ // Set these properties ++ const std::pair set_prop_list[] = { ++ {kAbilistProp, abilist_prop_val}, ++ {kAbilist32Prop, abilist32_prop_val}, ++ {kAbilist64Prop, abilist64_prop_val}, ++ }; ++ for (const auto& [prop, prop_val] : set_prop_list) { ++ LOG(INFO) << "Setting property '" << prop << "' to '" << prop_val << "'"; ++ ++ std::string error; ++ uint32_t res = PropertySet(prop, prop_val, &error); ++ if (res != PROP_SUCCESS) { ++ LOG(ERROR) << "Error setting property '" << prop << "': err=" << res << " (" << error ++ << ")"; ++ } ++ } ++} ++ + void PropertyLoadBootDefaults() { + // TODO(b/117892318): merge prop.default and build.prop files into one + // We read the properties and their values into a map, in order to always allow properties +@@ -918,6 +981,7 @@ void PropertyLoadBootDefaults() { + + property_initialize_ro_product_props(); + property_derive_build_fingerprint(); ++ property_initialize_ro_cpu_abilist(); + + if (android::base::GetBoolProperty("ro.persistent_properties.ready", false)) { + update_sys_usb_config(); +-- +2.25.1 + diff --git a/patches/platform_system_core/0010-Only-store-result-of-mount_all-that-mounted-userdata.patch b/patches/platform_system_core/0010-Only-store-result-of-mount_all-that-mounted-userdata.patch new file mode 100644 index 0000000..b641b45 --- /dev/null +++ b/patches/platform_system_core/0010-Only-store-result-of-mount_all-that-mounted-userdata.patch @@ -0,0 +1,174 @@ +From d3debf43a576aebfc505803eeb95b099c9129ae3 Mon Sep 17 00:00:00 2001 +From: Nikita Ioffe +Date: Mon, 7 Sep 2020 10:27:25 +0100 +Subject: [PATCH 10/12] Only store result of mount_all that mounted userdata + +During boot sequence there can be multiple calls to mount_all. For the +userspace reboot to correctly remount userdata, we need to store the +return code of the one that was responsible in mounting userdata. + +Test: adb root +Test: adb shell setprop init.userspace_reboot.is_supported 1 +Test: adb reboot userspace +Test: checked dmsg +Bug: 166353152 +Change-Id: Id0ae15f3bcf65fa54e4e72b76f64716c053af7fb +Merged-In: Id0ae15f3bcf65fa54e4e72b76f64716c053af7fb +(cherry picked from commit 9ede7ec273539d7ad6820bdf3f1f2f28433a9fb3) +--- + fs_mgr/fs_mgr.cpp | 24 ++++++++++++++---------- + fs_mgr/include/fs_mgr.h | 14 +++++++++++++- + init/builtins.cpp | 14 +++++++++++--- + 3 files changed, 38 insertions(+), 14 deletions(-) + +diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp +index 30db652ed..bc2d8a475 100644 +--- a/fs_mgr/fs_mgr.cpp ++++ b/fs_mgr/fs_mgr.cpp +@@ -1305,14 +1305,15 @@ static bool IsMountPointMounted(const std::string& mount_point) { + // When multiple fstab records share the same mount_point, it will try to mount each + // one in turn, and ignore any duplicates after a first successful mount. + // Returns -1 on error, and FS_MGR_MNTALL_* otherwise. +-int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { ++MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; + int error_count = 0; + CheckpointManager checkpoint_manager; + AvbUniquePtr avb_handle(nullptr); + ++ bool userdata_mounted = false; + if (fstab->empty()) { +- return FS_MGR_MNTALL_FAIL; ++ return {FS_MGR_MNTALL_FAIL, userdata_mounted}; + } + + // Keep i int to prevent unsigned integer overflow from (i = top_idx - 1), +@@ -1352,7 +1353,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + } + + // Terrible hack to make it possible to remount /data. +- // TODO: refact fs_mgr_mount_all and get rid of this. ++ // TODO: refactor fs_mgr_mount_all and get rid of this. + if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") { + continue; + } +@@ -1388,7 +1389,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + avb_handle = AvbHandle::Open(); + if (!avb_handle) { + LERROR << "Failed to open AvbHandle"; +- return FS_MGR_MNTALL_FAIL; ++ return {FS_MGR_MNTALL_FAIL, userdata_mounted}; + } + } + if (avb_handle->SetUpAvbHashtree(¤t_entry, true /* wait_for_verity_dev */) == +@@ -1430,7 +1431,7 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + + if (status == FS_MGR_MNTALL_FAIL) { + // Fatal error - no point continuing. +- return status; ++ return {status, userdata_mounted}; + } + + if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { +@@ -1444,11 +1445,14 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + attempted_entry.mount_point}, + nullptr)) { + LERROR << "Encryption failed"; +- return FS_MGR_MNTALL_FAIL; ++ return {FS_MGR_MNTALL_FAIL, userdata_mounted}; + } + } + } + ++ if (current_entry.mount_point == "/data") { ++ userdata_mounted = true; ++ } + // Success! Go get the next one. + continue; + } +@@ -1546,9 +1550,9 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + #endif + + if (error_count) { +- return FS_MGR_MNTALL_FAIL; ++ return {FS_MGR_MNTALL_FAIL, userdata_mounted}; + } else { +- return encryptable; ++ return {encryptable, userdata_mounted}; + } + } + +@@ -1770,8 +1774,8 @@ int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) { + } + LINFO << "Remounting /data"; + // TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored. +- int result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA); +- return result == FS_MGR_MNTALL_FAIL ? -1 : 0; ++ auto result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA); ++ return result.code == FS_MGR_MNTALL_FAIL ? -1 : 0; + } + return 0; + } +diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h +index 2a67b8c9f..11e36645e 100644 +--- a/fs_mgr/include/fs_mgr.h ++++ b/fs_mgr/include/fs_mgr.h +@@ -60,8 +60,20 @@ enum mount_mode { + #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1 + #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0 + #define FS_MGR_MNTALL_FAIL (-1) ++ ++struct MountAllResult { ++ // One of the FS_MGR_MNTALL_* returned code defined above. ++ int code; ++ // Whether userdata was mounted as a result of |fs_mgr_mount_all| call. ++ bool userdata_mounted; ++}; ++ + // fs_mgr_mount_all() updates fstab entries that reference device-mapper. +-int fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); ++// Returns a |MountAllResult|. The first element is one of the FS_MNG_MNTALL_* return codes ++// defined above, and the second element tells whether this call to fs_mgr_mount_all was responsible ++// for mounting userdata. Later is required for init to correctly enqueue fs-related events as part ++// of userdata remount during userspace reboot. ++MountAllResult fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode); + + #define FS_MGR_DOMNT_FAILED (-1) + #define FS_MGR_DOMNT_BUSY (-2) +diff --git a/init/builtins.cpp b/init/builtins.cpp +index 0ac66f272..789316621 100644 +--- a/init/builtins.cpp ++++ b/init/builtins.cpp +@@ -666,18 +666,26 @@ static Result do_mount_all(const BuiltinArguments& args) { + } + } + +- auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode); ++ auto mount_fstab_result = fs_mgr_mount_all(&fstab, mount_all->mode); + SetProperty(prop_name, std::to_string(t.duration().count())); + + if (mount_all->import_rc) { + import_late(mount_all->rc_paths); + } + ++ if (mount_fstab_result.userdata_mounted) { ++ // This call to fs_mgr_mount_all mounted userdata. Keep the result in ++ // order for userspace reboot to correctly remount userdata. ++ LOG(INFO) << "Userdata mounted using " ++ << (mount_all->fstab_path.empty() ? "(default fstab)" : mount_all->fstab_path) ++ << " result : " << mount_fstab_result.code; ++ initial_mount_fstab_return_code = mount_fstab_result.code; ++ } ++ + if (queue_event) { + /* queue_fs_event will queue event based on mount_fstab return code + * and return processed return code*/ +- initial_mount_fstab_return_code = mount_fstab_return_code; +- auto queue_fs_result = queue_fs_event(mount_fstab_return_code, false); ++ auto queue_fs_result = queue_fs_event(mount_fstab_result.code, false); + if (!queue_fs_result.ok()) { + return Error() << "queue_fs_event() failed: " << queue_fs_result.error(); + } +-- +2.25.1 + diff --git a/patches/platform_system_core/0011-Store-result-of-mount_all-for-mounted-userdata-by-me.patch b/patches/platform_system_core/0011-Store-result-of-mount_all-for-mounted-userdata-by-me.patch new file mode 100644 index 0000000..c1c9a91 --- /dev/null +++ b/patches/platform_system_core/0011-Store-result-of-mount_all-for-mounted-userdata-by-me.patch @@ -0,0 +1,33 @@ +From 60cf1d694c1550c0b9b8139e70d0627c54b44d6b Mon Sep 17 00:00:00 2001 +From: Qilin Tan +Date: Mon, 2 Nov 2020 11:25:09 +0800 +Subject: [PATCH 11/12] Store result of mount_all for mounted userdata by + metadata encryption + +When the userdata is mounted, its result will be stored and return. +But the result is not stored when the userdata is mounted with +metadata encryption. Store the result of metadata encryption mount. + +Bug: 172180818 +Test: run cts-on-gsi -m CtsUserspaceRebootHostSideTestCases +Change-Id: I88b1b4f6a2b1ed81773e18243cb6c46244dc1ba5 +--- + fs_mgr/fs_mgr.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp +index bc2d8a475..b20086e5d 100644 +--- a/fs_mgr/fs_mgr.cpp ++++ b/fs_mgr/fs_mgr.cpp +@@ -1521,6 +1521,8 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) { + attempted_entry.mount_point}, + nullptr)) { + ++error_count; ++ } else if (current_entry.mount_point == "/data") { ++ userdata_mounted = true; + } + encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; + continue; +-- +2.25.1 + diff --git a/patches/platform_system_core/0012-Adding-postinstall-root-dir-unconditionally.patch b/patches/platform_system_core/0012-Adding-postinstall-root-dir-unconditionally.patch new file mode 100644 index 0000000..64ab6f7 --- /dev/null +++ b/patches/platform_system_core/0012-Adding-postinstall-root-dir-unconditionally.patch @@ -0,0 +1,45 @@ +From 26478551e8a20d3abf1c302e58ee8fee97cab728 Mon Sep 17 00:00:00 2001 +From: Bowgo Tsai +Date: Fri, 4 Dec 2020 17:04:34 +0800 +Subject: [PATCH 12/12] Adding 'postinstall' root dir unconditionally. + +It is required to pass update_engine_unittests in GSI +compliance test. And it's clean to just add this mount +dir unconditionally. + +Bug: 172696594 +Test: `m init.environ.rc` and checks that $OUT/root/postinstall exists +Change-Id: Ib340a78af442ea66c45cecb373a9eb3c428f8dda +Merged-In: Ib340a78af442ea66c45cecb373a9eb3c428f8dda +--- + rootdir/Android.mk | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/rootdir/Android.mk b/rootdir/Android.mk +index a9d0ed08a..7d383f522 100644 +--- a/rootdir/Android.mk ++++ b/rootdir/Android.mk +@@ -78,7 +78,7 @@ endif + # create some directories (some are mount points) and symlinks + LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \ + dev proc sys system data data_mirror odm oem acct config storage mnt apex debug_ramdisk \ +- linkerconfig $(BOARD_ROOT_EXTRA_FOLDERS)); \ ++ linkerconfig postinstall $(BOARD_ROOT_EXTRA_FOLDERS)); \ + ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \ + ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \ + ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \ +@@ -132,11 +132,6 @@ ifdef BOARD_ROOT_EXTRA_SYMLINKS + ; mkdir -p $(dir $(TARGET_ROOT_OUT)/$(word 2,$(p))) \ + ; ln -sf $(word 1,$(p)) $(TARGET_ROOT_OUT)/$(word 2,$(p))) + endif +-# The A/B updater uses a top-level /postinstall directory to mount the new +-# system before reboot. +-ifeq ($(AB_OTA_UPDATER),true) +- LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/postinstall +-endif + + # The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT. + # Since init.environ.rc is required for init and satisfies that requirement, we hijack it to create the symlink. +-- +2.25.1 + diff --git a/patches/platform_system_linkerconfig/0002-Add-special-handling-of-vndk-26-remove-liblog.so-fro.patch b/patches/platform_system_linkerconfig/0002-Add-special-handling-of-vndk-26-remove-liblog.so-fro.patch index 31e5a1f..c8870d1 100644 --- a/patches/platform_system_linkerconfig/0002-Add-special-handling-of-vndk-26-remove-liblog.so-fro.patch +++ b/patches/platform_system_linkerconfig/0002-Add-special-handling-of-vndk-26-remove-liblog.so-fro.patch @@ -1,4 +1,4 @@ -From d4880eec8fa830f6c8fe68fe1ebbb05adc5bbbb1 Mon Sep 17 00:00:00 2001 +From 99e0657c0215e9ce9ba55aba5c41fbfe438c82e6 Mon Sep 17 00:00:00 2001 From: Pierre-Hugues Husson Date: Mon, 28 Sep 2020 21:02:19 +0200 Subject: [PATCH 2/2] Add special handling of vndk 26 (remove liblog.so from @@ -6,12 +6,12 @@ Subject: [PATCH 2/2] Add special handling of vndk 26 (remove liblog.so from Change-Id: I29b0bb6087ba58f69ee6406e003513bceb6785d8 --- - contents/namespace/vendordefault.cc | 16 ++++++++++++++-- + contents/namespace/vendordefault.cc | 14 +++++++++++++- contents/namespace/vndk.cc | 5 +++++ - 2 files changed, 19 insertions(+), 2 deletions(-) + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/contents/namespace/vendordefault.cc b/contents/namespace/vendordefault.cc -index 6d56904..c93c489 100644 +index b3be200..af53602 100644 --- a/contents/namespace/vendordefault.cc +++ b/contents/namespace/vendordefault.cc @@ -17,6 +17,7 @@ @@ -22,16 +22,7 @@ index 6d56904..c93c489 100644 #include "linkerconfig/namespacebuilder.h" #include "linkerconfig/common.h" -@@ -92,7 +93,7 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) { - AsanPath::SAME_PATH); - } - -- if (ctx.IsDefaultConfig() && GetVendorVndkVersion() == "27") { -+ if (ctx.IsDefaultConfig() && (GetVendorVndkVersion() == "27" || GetVendorVndkVersion()== "26")) { - ns.AddSearchPath("/vendor/${LIB}/hw", AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/vendor/${LIB}/egl", AsanPath::WITH_DATA_ASAN); - } -@@ -107,9 +108,20 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) { +@@ -105,9 +106,20 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) { ns.AddRequires(kVndkLiteVendorRequires); ns.AddProvides(GetSystemStubLibraries()); } else { @@ -77,5 +68,5 @@ index a95db80..589f745 100644 } } // namespace contents -- -2.17.1 +2.25.1 diff --git a/patches/platform_system_vold/0003-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch b/patches/platform_system_vold/0003-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch index 72d69fb..3a73cd6 100644 --- a/patches/platform_system_vold/0003-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch +++ b/patches/platform_system_vold/0003-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch @@ -1,4 +1,4 @@ -From d6f033bfbd7c03b30a23b287e84b1608c35d6038 Mon Sep 17 00:00:00 2001 +From d69f9a1231d08fd6508e7219b3298cdbc3158796 Mon Sep 17 00:00:00 2001 From: Pierre-Hugues Husson Date: Mon, 16 Sep 2019 13:49:05 +0200 Subject: [PATCH] Check needsCheckpoint only if checkpoint is supported @@ -9,22 +9,13 @@ vold will then hang in needsCheckpoint waiting for bootctrl Change-Id: I2dafcbca7e994d7a3ac36ef3698590db2ab482fa --- - cryptfs.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) + cryptfs.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cryptfs.cpp b/cryptfs.cpp -index 063c5be..df48b15 100644 +index 33f0913..7db1ef6 100644 --- a/cryptfs.cpp +++ b/cryptfs.cpp -@@ -1363,7 +1363,7 @@ static int create_crypto_blk_dev_hw(struct crypt_mnt_ftr* crypt_ftr, const unsig - load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, fd, - extra_params); - } -- -+ - if (load_count < 0) { - SLOGE("Cannot load dm-crypt mapping table.\n"); - goto errout; @@ -1963,7 +1963,9 @@ static int cryptfs_restart_internal(int restart_main) { SLOGE("Failed to setexeccon"); return -1;