Android 11.0.0 Release 38 (RQ3A.210605.005)

-----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCYL6V9QAKCRDorT+BmrEO
 eFtBAJ4szCUq6ji0SnBYFvJZNL8PGBkPvgCeP9bsIX0Ha6w7MZXrN9cDGC80ltc=
 =bYy9
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEA2skEMxbPHNb/U7LbZVRKTMRJykFAmC/Y+4ACgkQbZVRKTMR
 JynzIQ//d8DHgbP/jqCKfk5te71I0tVjEOVG9DM6XlhuKOJKTDskA2pLg3CGpRit
 s7H8lJXjVmZi/cY+Yycwnuwz/Nkmt+5X7ZG9er0KnLQiJa4euIwvOGTvEFvMuAby
 WCfAdZY37ND72+k3n0NTU0Qmp9N9/TFsFZFXCm6MrlLqXoOY/7MLl1Abjvmz7VLP
 X9ibhxYl8FMFpG95rYbAs3zKUtDQktEnL/XA3US3YoB4wJ4ro2G7TGWI8Pe368UC
 62iK03EkMQ+M9YuJo9V0SqZ/HVLuOVolDzax0q3uPJDIFV//k21Jeu/+h9Xyuh+i
 sms8tycLy9UHi9daZ8MSvRaDIqPDJxqJxGRjZfz0s8iO3wdIa8G9kVZDNXLMyW8j
 AEBItbibRjjp/KCPk6CjV6qr53OzRq9/tvPg7hDo/eJqwM1+nsUP0R6Kl6tU7WhH
 mGkmqRsF8Jw2UxM+ZqNkxcUFis0Exm48rMkad1ZT39BtziDc/3I7I7h5z+XiZfK1
 tbLCjGkEfdxMjD/ShKmk/N+DwHjkQa9qUc2l02JZLwIGtXhfOWkX2GOwpd/uMLyb
 oXMRi1fJij98UN5TmliwI7xyzZ0vls8awMSJXoK0Dstthp9/7+h9Y+1KluZOj80g
 yOt7ccesO1EQrCn2hECm+4G1tiTKJSrJ80kRMVqqjjv9p4jTWDw=
 =kLB4
 -----END PGP SIGNATURE-----

Merge tag 'android-11.0.0_r38' into staging/lineage-18.1_merge-android-11.0.0_r38

Android 11.0.0 Release 38 (RQ3A.210605.005)

* tag 'android-11.0.0_r38':
  [RESTRICT AUTOMERGE]Fix CryptoPlugin use after free vulnerability.
  [RESTRICT AUTOMERGE] Fix clearkey CryptoPlugin use after free vulnerability.
  cameraserver: Enforce system camera rules for setTorchMode and torch callbacks.
  Modify MediaRecorder stopping process to avoid blocking
  C2SoftAvcEnc: Use dimensions from mSize instead of input buffer
  Revert "CCodecConfig: don't dup input format"
  aaudio: fix race when disconnecting
  aaudio: lock transport methods
  [RESTRICT AUTOMERGE] Fix possible uaf of play policy state
  mediautils : TimeCheck: fix OOB access
  [RESTRICT AUTOMERGE] Fix UAF in clearkey service's MemoryFileSystem
  Fix UAF in clearkey service's MemoryFileSystem
  Fix potential decrypt destPtr overflow.
  [RESTRICT AUTOMERGE] Fix potential decrypt destPtr overflow.
  Prevent read of uninitialized memory
  Prevent read of uninitialized memory
  Prevent read of uninitialized memory
  mp3dec: Changes in the fillMainDataBuf function
  Rephrase to avoid integer overflow
  Fix possible uaf of play policy state
  Fix double free of play policy in a race condition.
  Add a null check in RTSPSource::stop
  Valid pitch value is required to prevent out of bound access
  Fix potential decrypt src pointer overflow.
  mpeg4enc: fix OOB in RasterIntraUpdate
  Improve handling MediaCodec linkToDeath() resource manager
  Codec2: Initialize InputSurfaceWrapper::Config structure fields
  Camera: Fix deadlock in ACameraCaptureSession destructor
  m4v_h263: Add check on the encode dimension
  ACodec: Reduce the TWOmxNode wrapper in GraphicBufferSource

Conflicts:
	drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h

Change-Id: I24a4de763f8f91baddc517491313d6ada6514c79
gugelfrei
Kevin F. Haggerty 3 years ago
commit ec22f455f0

@ -1361,31 +1361,11 @@ CameraDevice::checkAndFireSequenceCompleteLocked() {
it->second.isSequenceCompleted = true;
}
if (it->second.isSequenceCompleted && hasCallback) {
auto cbIt = mSequenceCallbackMap.find(sequenceId);
CallbackHolder cbh = cbIt->second;
// send seq complete callback
sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
msg->setPointer(kContextKey, cbh.mContext);
msg->setObject(kSessionSpKey, cbh.mSession);
msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
msg->setInt32(kSequenceIdKey, sequenceId);
msg->setInt64(kFrameNumberKey, lastFrameNumber);
// Clear the session sp before we send out the message
// This will guarantee the rare case where the message is processed
// before cbh goes out of scope and causing we call the session
// destructor while holding device lock
cbh.mSession.clear();
postSessionMsgAndCleanup(msg);
}
}
if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
mSequenceCallbackMap.erase(sequenceId);
}
sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
} else {
@ -1412,13 +1392,7 @@ CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFr
lastCompletedRegularFrameNumber);
if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
if (it->second.isSequenceCompleted) {
// Check if there is callback for this sequence
// This should not happen because we always register callback (with nullptr inside)
if (mSequenceCallbackMap.count(sequenceId) == 0) {
ALOGW("No callback found for sequenceId %d", sequenceId);
} else {
mSequenceCallbackMap.erase(sequenceId);
}
sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
@ -1709,5 +1683,33 @@ CameraDevice::ServiceCallback::onRepeatingRequestError(
return ret;
}
void
CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
auto cbIt = mSequenceCallbackMap.find(sequenceId);
if (cbIt != mSequenceCallbackMap.end()) {
CallbackHolder cbh = cbIt->second;
mSequenceCallbackMap.erase(cbIt);
// send seq complete callback
sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
msg->setPointer(kContextKey, cbh.mContext);
msg->setObject(kSessionSpKey, cbh.mSession);
msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
msg->setInt32(kSequenceIdKey, sequenceId);
msg->setInt64(kFrameNumberKey, lastFrameNumber);
// Clear the session sp before we send out the message
// This will guarantee the rare case where the message is processed
// before cbh goes out of scope and causing we call the session
// destructor while holding device lock
cbh.mSession.clear();
postSessionMsgAndCleanup(msg);
} else {
// Check if there is callback for this sequence
// This should not happen because we always register callback (with nullptr inside)
ALOGW("No callback found for sequenceId %d", sequenceId);
}
}
} // namespace acam
} // namespace android

@ -354,6 +354,7 @@ class CameraDevice final : public RefBase {
void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
void checkAndFireSequenceCompleteLocked();
void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber);
// Misc variables
int32_t mShadingMapSize[2]; // const after constructor

@ -207,6 +207,7 @@ status_t DrmPlugin::queryKeyStatus(
}
infoMap.clear();
android::Mutex::Autolock lock(mPlayPolicyLock);
for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
infoMap.add(mPlayPolicy.keyAt(i), mPlayPolicy.valueAt(i));
}

@ -262,7 +262,7 @@ private:
void initProperties();
void setPlayPolicy();
android::Mutex mPlayPolicyLock;
mutable android::Mutex mPlayPolicyLock;
android::KeyedVector<String8, String8> mPlayPolicy;
android::KeyedVector<String8, String8> mStringProperties;
android::KeyedVector<String8, Vector<uint8_t>> mByteArrayProperties;

@ -37,7 +37,7 @@ cc_defaults {
relative_install_path: "hw",
cflags: ["-Wall", "-Werror"],
cflags: ["-Wall", "-Werror", "-Wthread-safety"],
shared_libs: [
"android.hardware.drm@1.0",

@ -37,6 +37,8 @@ Return<void> CryptoPlugin::setSharedBufferBase(
sp<IMemory> hidlMemory = mapMemory(base);
ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr");
std::lock_guard<std::mutex> shared_buffer_lock(mSharedBufferLock);
// allow mapMemory to return nullptr
mSharedBufferMap[bufferId] = hidlMemory;
return Void();
@ -94,6 +96,7 @@ Return<void> CryptoPlugin::decrypt_1_2(
return Void();
}
std::unique_lock<std::mutex> shared_buffer_lock(mSharedBufferLock);
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"source decrypt buffer base not set");
@ -142,12 +145,17 @@ Return<void> CryptoPlugin::decrypt_1_2(
base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
totalSize = 0;
if (__builtin_add_overflow(destBuffer.offset, destBuffer.size, &totalSize) ||
totalSize > destBase->getSize()) {
android_errorWriteLog(0x534e4554, "176444622");
_hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
destPtr = static_cast<void*>(base + destination.nonsecureMemory.offset);
// release mSharedBufferLock
shared_buffer_lock.unlock();
// Calculate the output buffer size and determine if any subsamples are
// encrypted.

@ -220,6 +220,7 @@ Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
if (requestString.find(kOfflineLicense) != std::string::npos) {
std::string emptyResponse;
std::string keySetIdString(keySetId.begin(), keySetId.end());
Mutex::Autolock lock(mFileHandleLock);
if (!mFileHandle.StoreLicense(keySetIdString,
DeviceFiles::kLicenseStateReleasing,
emptyResponse)) {
@ -335,6 +336,7 @@ bool DrmPlugin::makeKeySetId(std::string* keySetId) {
}
*keySetId = kKeySetIdPrefix + ByteArrayToHexString(
reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size());
Mutex::Autolock lock(mFileHandleLock);
if (mFileHandle.LicenseExists(*keySetId)) {
// collision, regenerate
ALOGV("Retry generating KeySetId");
@ -392,6 +394,7 @@ Return<void> DrmPlugin::provideKeyResponse(
if (status == Status::OK) {
if (isOfflineLicense) {
if (isRelease) {
Mutex::Autolock lock(mFileHandleLock);
mFileHandle.DeleteLicense(keySetId);
mSessionLibrary->destroySession(session);
} else {
@ -400,6 +403,7 @@ Return<void> DrmPlugin::provideKeyResponse(
return Void();
}
Mutex::Autolock lock(mFileHandleLock);
bool ok = mFileHandle.StoreLicense(
keySetId,
DeviceFiles::kLicenseStateActive,
@ -454,6 +458,7 @@ Return<Status> DrmPlugin::restoreKeys(
DeviceFiles::LicenseState licenseState;
std::string offlineLicense;
Status status = Status::OK;
Mutex::Autolock lock(mFileHandleLock);
if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
&licenseState, &offlineLicense)) {
ALOGE("Failed to restore offline license");
@ -576,7 +581,6 @@ Return<Status> DrmPlugin::setPropertyByteArray(
Return<void> DrmPlugin::queryKeyStatus(
const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) {
if (sessionId.size() == 0) {
// Returns empty key status KeyValue pair
_hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>());
@ -586,12 +590,14 @@ Return<void> DrmPlugin::queryKeyStatus(
std::vector<KeyValue> infoMapVec;
infoMapVec.clear();
mPlayPolicyLock.lock();
KeyValue keyValuePair;
for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
keyValuePair.key = mPlayPolicy[i].key;
keyValuePair.value = mPlayPolicy[i].value;
infoMapVec.push_back(keyValuePair);
}
mPlayPolicyLock.unlock();
_hidl_cb(Status::OK, toHidlVec(infoMapVec));
return Void();
}
@ -704,6 +710,8 @@ Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) {
}
Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) {
Mutex::Autolock lock(mFileHandleLock);
std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
std::vector<KeySetId> keySetIds;
if (mMockError != Status_V1_2::OK) {
@ -724,6 +732,7 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
return toStatus_1_0(mMockError);
}
std::string licenseName(keySetId.begin(), keySetId.end());
Mutex::Autolock lock(mFileHandleLock);
if (mFileHandle.DeleteLicense(licenseName)) {
return Status::OK;
}
@ -732,6 +741,8 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId,
getOfflineLicenseState_cb _hidl_cb) {
Mutex::Autolock lock(mFileHandleLock);
std::string licenseName(keySetId.begin(), keySetId.end());
DeviceFiles::LicenseState state;
std::string license;

@ -24,11 +24,13 @@ std::string MemoryFileSystem::GetFileName(const std::string& path) {
}
bool MemoryFileSystem::FileExists(const std::string& fileName) const {
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
auto result = mMemoryFileSystem.find(fileName);
return result != mMemoryFileSystem.end();
}
ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const {
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
auto result = mMemoryFileSystem.find(fileName);
if (result != mMemoryFileSystem.end()) {
return static_cast<ssize_t>(result->second.getFileSize());
@ -40,6 +42,7 @@ ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const {
std::vector<std::string> MemoryFileSystem::ListFiles() const {
std::vector<std::string> list;
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
for (const auto& filename : mMemoryFileSystem) {
list.push_back(filename.first);
}
@ -48,6 +51,7 @@ std::vector<std::string> MemoryFileSystem::ListFiles() const {
size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) {
std::string key = GetFileName(path);
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
auto result = mMemoryFileSystem.find(key);
if (result != mMemoryFileSystem.end()) {
std::string serializedHashFile = result->second.getContent();
@ -61,6 +65,7 @@ size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) {
size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) {
std::string key = GetFileName(path);
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
auto result = mMemoryFileSystem.find(key);
if (result != mMemoryFileSystem.end()) {
mMemoryFileSystem.erase(key);
@ -70,6 +75,7 @@ size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memory
}
bool MemoryFileSystem::RemoveFile(const std::string& fileName) {
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
auto result = mMemoryFileSystem.find(fileName);
if (result != mMemoryFileSystem.end()) {
mMemoryFileSystem.erase(result);
@ -81,6 +87,7 @@ bool MemoryFileSystem::RemoveFile(const std::string& fileName) {
}
bool MemoryFileSystem::RemoveAllFiles() {
std::lock_guard<std::mutex> lock(mMemoryFileSystemLock);
mMemoryFileSystem.clear();
return mMemoryFileSystem.empty();
}

@ -20,6 +20,8 @@
#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <mutex>
#include "ClearKeyTypes.h"
#include "Session.h"
#include "Utils.h"
@ -93,7 +95,7 @@ struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
decrypt_1_2_cb _hidl_cb);
decrypt_1_2_cb _hidl_cb) NO_THREAD_SAFETY_ANALYSIS; // use unique_lock
Return<void> setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId);
@ -105,7 +107,8 @@ struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
private:
CLEARKEY_DISALLOW_COPY_AND_ASSIGN(CryptoPlugin);
std::map<uint32_t, sp<IMemory> > mSharedBufferMap;
std::mutex mSharedBufferLock;
std::map<uint32_t, sp<IMemory>> mSharedBufferMap GUARDED_BY(mSharedBufferLock);
sp<Session> mSession;
Status mInitStatus;
};

@ -416,7 +416,8 @@ private:
mMockError = Status_V1_2::OK;
}
DeviceFiles mFileHandle;
DeviceFiles mFileHandle GUARDED_BY(mFileHandleLock);
Mutex mFileHandleLock;
Mutex mSecureStopLock;
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);

@ -5,7 +5,9 @@
#ifndef CLEARKEY_MEMORY_FILE_SYSTEM_H_
#define CLEARKEY_MEMORY_FILE_SYSTEM_H_
#include <android-base/thread_annotations.h>
#include <map>
#include <mutex>
#include <string>
#include "ClearKeyTypes.h"
@ -49,10 +51,12 @@ class MemoryFileSystem {
size_t Write(const std::string& pathName, const MemoryFile& memoryFile);
private:
mutable std::mutex mMemoryFileSystemLock;
// License file name is made up of a unique keySetId, therefore,
// the filename can be used as the key to locate licenses in the
// memory file system.
std::map<std::string, MemoryFile> mMemoryFileSystem;
std::map<std::string, MemoryFile> mMemoryFileSystem GUARDED_BY(mMemoryFileSystemLock);
std::string GetFileName(const std::string& path);

@ -1328,13 +1328,13 @@ c2_status_t C2SoftAvcEnc::setEncodeArgs(
ps_inp_raw_buf->apv_bufs[1] = uPlane;
ps_inp_raw_buf->apv_bufs[2] = vPlane;
ps_inp_raw_buf->au4_wd[0] = input->width();
ps_inp_raw_buf->au4_wd[1] = input->width() / 2;
ps_inp_raw_buf->au4_wd[2] = input->width() / 2;
ps_inp_raw_buf->au4_wd[0] = mSize->width;
ps_inp_raw_buf->au4_wd[1] = mSize->width / 2;
ps_inp_raw_buf->au4_wd[2] = mSize->width / 2;
ps_inp_raw_buf->au4_ht[0] = input->height();
ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
ps_inp_raw_buf->au4_ht[2] = input->height() / 2;
ps_inp_raw_buf->au4_ht[0] = mSize->height;
ps_inp_raw_buf->au4_ht[1] = mSize->height / 2;
ps_inp_raw_buf->au4_ht[2] = mSize->height / 2;
ps_inp_raw_buf->au4_strd[0] = yStride;
ps_inp_raw_buf->au4_strd[1] = uStride;
@ -1359,11 +1359,11 @@ c2_status_t C2SoftAvcEnc::setEncodeArgs(
ps_inp_raw_buf->apv_bufs[0] = yPlane;
ps_inp_raw_buf->apv_bufs[1] = uPlane;
ps_inp_raw_buf->au4_wd[0] = input->width();
ps_inp_raw_buf->au4_wd[1] = input->width();
ps_inp_raw_buf->au4_wd[0] = mSize->width;
ps_inp_raw_buf->au4_wd[1] = mSize->width;
ps_inp_raw_buf->au4_ht[0] = input->height();
ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
ps_inp_raw_buf->au4_ht[0] = mSize->height;
ps_inp_raw_buf->au4_ht[1] = mSize->height / 2;
ps_inp_raw_buf->au4_strd[0] = yStride;
ps_inp_raw_buf->au4_strd[1] = uStride;

@ -1151,11 +1151,14 @@ bool CCodecConfig::updateFormats(Domain domain) {
bool changed = false;
if (domain & mInputDomain) {
sp<AMessage> oldFormat = mInputFormat->dup();
sp<AMessage> oldFormat = mInputFormat;
mInputFormat = mInputFormat->dup(); // trigger format changed
mInputFormat->extend(getFormatForDomain(reflected, mInputDomain));
if (mInputFormat->countEntries() != oldFormat->countEntries()
|| mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
changed = true;
} else {
mInputFormat = oldFormat; // no change
}
}
if (domain & mOutputDomain) {

@ -146,7 +146,9 @@ void NuPlayer::RTSPSource::stop() {
}
// Close socket before posting message to RTSPSource message handler.
close(mHandler->getARTSPConnection()->getSocket());
if (mHandler != NULL) {
close(mHandler->getARTSPConnection()->getSocket());
}
sp<AMessage> msg = new AMessage(kWhatDisconnect, this);

@ -7032,10 +7032,9 @@ status_t ACodec::LoadedState::setupInputSurface() {
return err;
}
using hardware::media::omx::V1_0::utils::TWOmxNode;
err = statusFromBinderStatus(
mCodec->mGraphicBufferSource->configure(
new TWOmxNode(mCodec->mOMXNode),
mCodec->mOMXNode->getHalInterface<IOmxNode>(),
static_cast<hardware::graphics::common::V1_0::Dataspace>(dataSpace)));
if (err != OK) {
ALOGE("[%s] Unable to configure for node (err %d)",

@ -168,9 +168,7 @@ status_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
}
status_t MediaCodecSource::Puller::setStopTimeUs(int64_t stopTimeUs) {
sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, this);
msg->setInt64("stop-time-us", stopTimeUs);
return postSynchronouslyAndReturnError(msg);
return mSource->setStopTimeUs(stopTimeUs);
}
status_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
@ -188,19 +186,11 @@ status_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMes
}
void MediaCodecSource::Puller::stop() {
bool interrupt = false;
{
// mark stopping before actually reaching kWhatStop on the looper, so the pulling will
// stop.
Mutexed<Queue>::Locked queue(mQueue);
queue->mPulling = false;
interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000);
queue->flush(); // flush any unprocessed pulled buffers
}
if (interrupt) {
interruptSource();
}
// mark stopping before actually reaching kWhatStop on the looper, so the pulling will
// stop.
Mutexed<Queue>::Locked queue(mQueue);
queue->mPulling = false;
queue->flush(); // flush any unprocessed pulled buffers
}
void MediaCodecSource::Puller::interruptSource() {
@ -660,9 +650,9 @@ void MediaCodecSource::signalEOS(status_t err) {
if (mStopping && reachedEOS) {
ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
if (mPuller != NULL) {
mPuller->stopSource();
mPuller->interruptSource();
}
ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
ALOGI("source (%s) stopped", mIsVideo ? "video" : "audio");
// posting reply to everyone that's waiting
List<sp<AReplyToken>>::iterator it;
for (it = mStopReplyIDQueue.begin();
@ -851,7 +841,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
{
int32_t eos = 0;
if (msg->findInt32("eos", &eos) && eos) {
ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
ALOGI("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
signalEOS();
break;
}
@ -1069,12 +1059,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
if (generation != mGeneration) {
break;
}
if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio");
mPuller->interruptSource();
ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
}
ALOGD("source (%s) stopping stalled", mIsVideo ? "video" : "audio");
signalEOS();
break;
}

@ -570,12 +570,14 @@ static void searchFrac(
Word16 corr[], /* i : normalized correlation */
Word16 flag3, /* i : subsample resolution
(3: =1 / 6: =0) */
Flag *pOverflow
Flag *pOverflow,
enum Mode mode
)
{
Word16 i;
Word16 max;
Word16 corr_int;
Word16 minPitch;
/* Test the fractions around T0 and choose the one which maximizes */
/* the interpolated normalized correlation. */
@ -593,14 +595,22 @@ static void searchFrac(
}
}
minPitch = (mode == MR122) ? PIT_MIN_MR122 : PIT_MIN;
if (flag3 == 0)
{
/* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
if (*frac == -3)
{
*frac = 3;
(*lag)--;
if (*lag > minPitch)
{
*frac = 3;
(*lag)--;
}
else
{
*frac = -2;
}
}
}
else
@ -609,13 +619,27 @@ static void searchFrac(
if (*frac == -2)
{
*frac = 1;
(*lag)--;
if (*lag > minPitch)
{
*frac = 1;
(*lag)--;
}
else
{
*frac = -1;
}
}
if (*frac == 2)
else if (*frac == 2)
{
*frac = -1;
(*lag)++;
if (*lag < PIT_MAX)
{
*frac = -1;
(*lag)++;
}
else
{
*frac = 1;
}
}
}
}
@ -1533,20 +1557,20 @@ Word16 Pitch_fr( /* o : pitch period (integer) */
/* normal search in fractions around T0 */
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
}
else if (lag == (tmp_lag - 2))
{
/* limit search around T0 to the right side */
frac = 0;
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
}
else if (lag == (tmp_lag + 1))
{
/* limit search around T0 to the left side */
last_frac = 0;
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
}
else
{
@ -1556,7 +1580,7 @@ Word16 Pitch_fr( /* o : pitch period (integer) */
}
else
/* test the fractions around T0 */
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
}
/*-----------------------------------------------------------------------*

@ -1576,7 +1576,7 @@ void RasterIntraUpdate(UChar *intraArray, UChar *Mode, Int totalMB, Int numRefre
/* find the last refresh MB */
indx = 0;
while (intraArray[indx] == 1 && indx < totalMB)
while (indx < totalMB && intraArray[indx] == 1)
indx++;
/* add more */

@ -491,6 +491,9 @@ OSCL_EXPORT_REF Bool PVInitVideoEncoder(VideoEncControls *encoderControl, Vid
}
for (i = 0; i < encParams->nLayers; i++)
{
if (encOption->encHeight[i] == 0 || encOption->encWidth[i] == 0 ||
encOption->encHeight[i] % 16 != 0 || encOption->encWidth[i] % 16 != 0)
goto CLEAN_UP;
encParams->LayerHeight[i] = encOption->encHeight[i];
encParams->LayerWidth[i] = encOption->encWidth[i];
}

@ -598,18 +598,10 @@ void fillMainDataBuf(void *pMem, int32 temp)
}
else
{
int32 tmp1 = *(ptr++);
for (int32 nBytes = temp >> 1; nBytes != 0; nBytes--) /* read main data. */
for (int32 nBytes = temp; nBytes != 0; nBytes--) /* read main data. */
{
int32 tmp2 = *(ptr++);
fillDataBuf(&pVars->mainDataStream, tmp1);
fillDataBuf(&pVars->mainDataStream, tmp2);
tmp1 = *(ptr++);
}
if (temp&1)
{
fillDataBuf(&pVars->mainDataStream, tmp1);
int32 tmp = *(ptr++);
fillDataBuf(&pVars->mainDataStream, tmp);
}
/* adjust circular buffer counter */
@ -618,14 +610,9 @@ void fillMainDataBuf(void *pMem, int32 temp)
}
else
{
for (int32 nBytes = temp >> 1; nBytes != 0; nBytes--) /* read main data. */
for (int32 nBytes = temp; nBytes != 0; nBytes--) /* read main data. */
{
fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset++ , BUFSIZE)));
fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset++ , BUFSIZE)));
}
if (temp&1)
{
fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset , BUFSIZE)));
}
}

@ -67,7 +67,7 @@ ABuffer::~ABuffer() {
void ABuffer::setRange(size_t offset, size_t size) {
CHECK_LE(offset, mCapacity);
CHECK_LE(offset + size, mCapacity);
CHECK_LE(size, mCapacity - offset);
mRangeOffset = offset;
mRangeLength = size;

@ -39,10 +39,9 @@ void TimeCheck::accessAudioHalPids(std::vector<pid_t>* pids, bool update) {
static std::atomic<int> curAudioHalPids = 0;
if (update) {
audioHalPids[(curAudioHalPids + 1) % kNumAudioHalPidsVectors] = *pids;
curAudioHalPids++;
audioHalPids[(curAudioHalPids++ + 1) % kNumAudioHalPidsVectors] = *pids;
} else {
*pids = audioHalPids[curAudioHalPids];
*pids = audioHalPids[curAudioHalPids % kNumAudioHalPidsVectors];
}
}

@ -252,10 +252,16 @@ void CameraService::pingCameraServiceProxy() {
proxyBinder->pingForUserUpdate();
}
void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status,
SystemCameraKind systemCameraKind) {
Mutex::Autolock lock(mStatusListenerLock);
for (auto& i : mListenerList) {
if (shouldSkipStatusUpdates(systemCameraKind, i->isVendorListener(), i->getListenerPid(),
i->getListenerUid())) {
ALOGV("Skipping torch callback for system-only camera device %s",
cameraId.c_str());
continue;
}
i->getListener()->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
}
}
@ -341,7 +347,7 @@ void CameraService::addStates(const String8 id) {
Mutex::Autolock al(mTorchStatusMutex);
mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF);
broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF, deviceKind);
}
updateCameraNumAndIds();
@ -502,12 +508,19 @@ void CameraService::disconnectClient(const String8& id, sp<BasicClient> clientTo
void CameraService::onTorchStatusChanged(const String8& cameraId,
TorchModeStatus newStatus) {
SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
if (res != OK) {
ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
cameraId.string());
return;
}
Mutex::Autolock al(mTorchStatusMutex);
onTorchStatusChangedLocked(cameraId, newStatus);
onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
}
void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
TorchModeStatus newStatus) {
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
__FUNCTION__, cameraId.string(), newStatus);
@ -556,8 +569,7 @@ void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
}
}
}
broadcastTorchModeStatus(cameraId, newStatus);
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}
static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
@ -1872,6 +1884,10 @@ Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
String8 id = String8(cameraId.string());
int uid = CameraThreadState::getCallingUid();
if (shouldRejectSystemCameraConnection(id)) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode"
" for system only device %s: ", id.string());
}
// verify id is valid.
auto state = getCameraState(id);
if (state == nullptr) {
@ -2228,6 +2244,11 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen
return shouldSkipStatusUpdates(deviceKind, isVendorListener, clientPid,
clientUid);}), cameraStatuses->end());
//cameraStatuses will have non-eligible camera ids removed.
std::set<String16> idsChosenForCallback;
for (const auto &s : *cameraStatuses) {
idsChosenForCallback.insert(String16(s.cameraId));
}
/*
* Immediately signal current torch status to this listener only
@ -2237,7 +2258,11 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen
Mutex::Autolock al(mTorchStatusMutex);
for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
String16 id = String16(mTorchStatusMap.keyAt(i).string());
listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
// The camera id is visible to the client. Fine to send torch
// callback.
if (idsChosenForCallback.find(id) != idsChosenForCallback.end()) {
listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id);
}
}
}
@ -3781,7 +3806,7 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
TorchModeStatus::AVAILABLE_OFF :
TorchModeStatus::NOT_AVAILABLE;
if (torchStatus != newTorchStatus) {
onTorchStatusChangedLocked(cameraId, newTorchStatus);
onTorchStatusChangedLocked(cameraId, newTorchStatus, deviceKind);
}
}
}

@ -995,7 +995,8 @@ private:
// handle torch mode status change and invoke callbacks. mTorchStatusMutex
// should be locked.
void onTorchStatusChangedLocked(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus);
hardware::camera::common::V1_0::TorchModeStatus newStatus,
SystemCameraKind systemCameraKind);
// get a camera's torch status. mTorchStatusMutex should be locked.
status_t getTorchStatusLocked(const String8 &cameraId,
@ -1084,7 +1085,8 @@ private:
static void pingCameraServiceProxy();
void broadcastTorchModeStatus(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus status);
hardware::camera::common::V1_0::TorchModeStatus status,
SystemCameraKind systemCameraKind);
void disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect);

Loading…
Cancel
Save