Merge "Camera: Use original format and dataSpace for reconfigure" into qt-dev
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 384d58b..70d1965 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -471,11 +471,11 @@
uint8_t* outPtr = wView.data() + mBytesEncoded;
int encodedBytes =
opus_multistream_encode(mEncoder, mInputBufferPcm16,
- mNumSamplesPerFrame, outPtr, kMaxPayload);
+ mNumSamplesPerFrame, outPtr, kMaxPayload - mBytesEncoded);
ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
processSize);
- if (encodedBytes < 0 || encodedBytes > kMaxPayload) {
+ if (encodedBytes < 0 || encodedBytes > (kMaxPayload - mBytesEncoded)) {
ALOGE("opus_encode failed, encodedBytes : %d", encodedBytes);
mSignalledError = true;
work->result = C2_CORRUPTED;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.h b/media/codec2/components/opus/C2SoftOpusEnc.h
index 69e5240..2b4d8f2 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.h
+++ b/media/codec2/components/opus/C2SoftOpusEnc.h
@@ -47,7 +47,9 @@
private:
/* OPUS_FRAMESIZE_20_MS */
const int kFrameSize = 960;
- const int kMaxPayload = 4000;
+ const int kMaxSampleRate = 48000;
+ const int kMinSampleRate = 8000;
+ const int kMaxPayload = (4000 * kMaxSampleRate) / kMinSampleRate;
const int kMaxNumChannels = 8;
std::shared_ptr<IntfImpl> mIntf;
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index c20ca73..702ad6f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -201,9 +201,10 @@
* \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
* an attempt is made to simply represent the graphic view as a flexible SDK format
* without a memcpy)
+ * \param copy whether the converter is used for copy or not
*/
GraphicView2MediaImageConverter(
- const C2GraphicView &view, int32_t colorFormat)
+ const C2GraphicView &view, int32_t colorFormat, bool copy)
: mInitCheck(NO_INIT),
mView(view),
mWidth(view.width()),
@@ -255,41 +256,44 @@
}
switch (mColorFormat) {
case COLOR_FormatYUV420Flexible:
- { // try to map directly. check if the planes are near one another
- const uint8_t *minPtr = mView.data()[0];
- const uint8_t *maxPtr = mView.data()[0];
- 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);
- 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);
- }
-
- if ((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
+ if (!copy) {
+ // try to map directly. check if the planes are near one another
+ const uint8_t *minPtr = mView.data()[0];
+ const uint8_t *maxPtr = mView.data()[0];
+ int32_t planeSize = 0;
for (uint32_t i = 0; i < layout.numPlanes; ++i) {
const C2PlaneInfo &plane = layout.planes[i];
- mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
- mediaImage->mPlane[i].mColInc = plane.colInc;
- mediaImage->mPlane[i].mRowInc = plane.rowInc;
- mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
- mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+ ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+ 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);
}
- mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
- break;
+
+ if ((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
+ for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+ const C2PlaneInfo &plane = layout.planes[i];
+ mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+ mediaImage->mPlane[i].mColInc = plane.colInc;
+ mediaImage->mPlane[i].mRowInc = plane.rowInc;
+ mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+ mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ }
+ mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
+ maxPtr - minPtr + 1);
+ break;
+ }
}
- }
- [[fallthrough]];
+ [[fallthrough]];
case COLOR_FormatYUV420Planar:
case COLOR_FormatYUV420PackedPlanar:
@@ -503,7 +507,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(view, colorFormat);
+ GraphicView2MediaImageConverter converter(view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -615,7 +619,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(*view, colorFormat);
+ GraphicView2MediaImageConverter converter(*view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -708,7 +712,7 @@
const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
return false;
@@ -730,7 +734,7 @@
format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
return false;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index 1e884ef..bf2a07e 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -137,14 +137,14 @@
int32_t dst_stride_v = img->mPlane[2].mRowInc;
if (IsNV12(view) && IsI420(img)) {
if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
- dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
- view.height())) {
+ dst_u, dst_stride_u, dst_v, dst_stride_v, view.crop().width,
+ view.crop().height)) {
return OK;
}
} else {
if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
- dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
- view.height())) {
+ dst_y, dst_stride_y, dst_u, dst_stride_u, view.crop().width,
+ view.crop().height)) {
return OK;
}
}
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index b1eb301..23022e4 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -2109,8 +2109,10 @@
if (!strcmp("A_AAC", codecID)) {
AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
- CHECK(codecPrivateSize >= 2);
-
+ if (codecPrivateSize < 2) {
+ ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
+ continue;
+ }
addESDSFromCodecPrivate(
meta, true, codecPrivate, codecPrivateSize);
} else if (!strcmp("A_VORBIS", codecID)) {
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 527bb77..9d5890c 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1197,45 +1197,16 @@
AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
}
- // If format type is 'alac', it is necessary to get the parameters
- // from a alac atom spreading behind the frma atom.
- // See 'external/alac/ALACMagicCookieDescription.txt'.
- if (original_fourcc == FOURCC("alac")) {
- // Store ALAC magic cookie (decoder needs it).
- uint8_t alacInfo[12];
- data_offset = *offset;
- if (mDataSource->readAt(
- data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
- return ERROR_IO;
+ if (!mIsQT && original_fourcc == FOURCC("alac")) {
+ off64_t tmpOffset = *offset;
+ status_t err = parseALACSampleEntry(&tmpOffset);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
}
- uint32_t size = U32_AT(&alacInfo[0]);
- if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
- (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
- (U32_AT(&alacInfo[8]) != 0)) {
- return ERROR_MALFORMED;
- }
-
- data_offset += sizeof(alacInfo);
- uint8_t cookie[size - sizeof(alacInfo)];
- if (mDataSource->readAt(
- data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
- return ERROR_IO;
- }
-
- uint8_t bitsPerSample = cookie[5];
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
- AMediaFormat_setBuffer(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
-
- // Add the size of ALAC Specific Info (36 bytes) and terminator
- // atom (8 bytes).
- *offset += (size + 8);
+ *offset = tmpOffset + 8;
}
+
break;
}
@@ -1653,7 +1624,18 @@
case 0x6D730055: // "ms U" mp3 audio
{
if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
+
+ if (chunk_type == FOURCC("alac")) {
+ off64_t offsetTmp = *offset;
+ status_t err = parseALACSampleEntry(&offsetTmp);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
+ }
+ }
+
// Ignore all atoms embedded in QT wave atom
+ ALOGV("Ignore all atoms embedded in QT wave atom");
*offset += chunk_size;
break;
}
@@ -1792,39 +1774,14 @@
CHECK_EQ(*offset, stop_offset);
}
- if (chunk_type == FOURCC("alac")) {
-
- // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
- // Store ALAC magic cookie (decoder needs it).
- uint8_t alacInfo[12];
+ if (!mIsQT && chunk_type == FOURCC("alac")) {
data_offset += sizeof(buffer);
- if (mDataSource->readAt(
- data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
- return ERROR_IO;
- }
- uint32_t size = U32_AT(&alacInfo[0]);
- if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
- (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
- (U32_AT(&alacInfo[8]) != 0)) {
- return ERROR_MALFORMED;
- }
- data_offset += sizeof(alacInfo);
- uint8_t cookie[size - sizeof(alacInfo)];
- if (mDataSource->readAt(
- data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
- return ERROR_IO;
- }
- uint8_t bitsPerSample = cookie[5];
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
- AMediaFormat_setBuffer(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
- data_offset += sizeof(cookie);
+ status_t err = parseALACSampleEntry(&data_offset);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
+ }
*offset = data_offset;
CHECK_EQ(*offset, stop_offset);
}
@@ -3289,6 +3246,45 @@
return OK;
}
+status_t MPEG4Extractor::parseALACSampleEntry(off64_t *offset) {
+ // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
+ // Store ALAC magic cookie (decoder needs it).
+ uint8_t alacInfo[12];
+ off64_t data_offset = *offset;
+
+ if (mDataSource->readAt(
+ data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
+ return ERROR_IO;
+ }
+ uint32_t size = U32_AT(&alacInfo[0]);
+ if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
+ (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
+ (U32_AT(&alacInfo[8]) != 0)) {
+ ALOGV("Size:%u, U32_AT(&alacInfo[4]):%u, U32_AT(&alacInfo[8]):%u",
+ size, U32_AT(&alacInfo[4]), U32_AT(&alacInfo[8]));
+ return ERROR_MALFORMED;
+ }
+ data_offset += sizeof(alacInfo);
+ uint8_t cookie[size - sizeof(alacInfo)];
+ if (mDataSource->readAt(
+ data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
+ return ERROR_IO;
+ }
+
+ uint8_t bitsPerSample = cookie[5];
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
+ AMediaFormat_setBuffer(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
+ data_offset += sizeof(cookie);
+ *offset = data_offset;
+ return OK;
+}
+
status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
ALOGV("MPEG4Extractor::parseSegmentIndex");
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index e10bf8a..fcddbb8 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -179,6 +179,7 @@
status_t parseAC3SpecificBox(off64_t offset);
status_t parseEAC3SpecificBox(off64_t offset);
status_t parseAC4SpecificBox(off64_t offset);
+ status_t parseALACSampleEntry(off64_t *offset);
void adjustRawDefaultFrameSize();
MPEG4Extractor(const MPEG4Extractor &);
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 59265fe..c7e92cd 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -157,6 +157,12 @@
buffer->size() + bufferRemaining);
sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
+ if (copy->data() == NULL) {
+ android_errorWriteLog(0x534e4554, "68399439");
+ ALOGE("not enough memory to download: requesting %zu + %zu",
+ buffer->size(), bufferRemaining);
+ return NO_MEMORY;
+ }
memcpy(copy->data(), buffer->data(), buffer->size());
copy->setRange(0, buffer->size());
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 7ec0e4c..1c1f5e6 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -70,6 +70,7 @@
],
shared_libs: [
+ "libbase",
"libdl",
"libexif",
"libui",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a87ebdf..3e62102 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,6 +33,7 @@
#include <android-base/macros.h>
#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -81,6 +82,7 @@
namespace android {
+using base::StringPrintf;
using binder::Status;
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
using hardware::ICamera;
@@ -2366,6 +2368,13 @@
}
mClientPackageName = packages[0];
}
+ if (hardware::IPCThreadState::self()->isServingCall()) {
+ std::string vendorClient =
+ StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
+ mClientPackageName = String16(vendorClient.c_str());
+ } else {
+ mAppOpsManager = std::make_unique<AppOpsManager>();
+ }
}
CameraService::BasicClient::~BasicClient() {
@@ -2381,8 +2390,7 @@
mDisconnected = true;
sCameraService->removeByClient(this);
- sCameraService->logDisconnected(mCameraIdStr, mClientPid,
- String8(mClientPackageName));
+ sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
mCameraIdStr.c_str());
@@ -2432,31 +2440,31 @@
status_t CameraService::BasicClient::startCameraOps() {
ATRACE_CALL();
- int32_t res;
- // Notify app ops that the camera is not available
- mOpsCallback = new OpsCallback(this);
-
{
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
__FUNCTION__, String8(mClientPackageName).string(), mClientUid);
}
+ if (mAppOpsManager != nullptr) {
+ // Notify app ops that the camera is not available
+ mOpsCallback = new OpsCallback(this);
+ int32_t res;
+ mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
+ mClientPackageName, mOpsCallback);
+ res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
+ mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
- mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
- mClientPackageName, mOpsCallback);
- res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
- mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+ if (res == AppOpsManager::MODE_ERRORED) {
+ ALOGI("Camera %s: Access for \"%s\" has been revoked",
+ mCameraIdStr.string(), String8(mClientPackageName).string());
+ return PERMISSION_DENIED;
+ }
- if (res == AppOpsManager::MODE_ERRORED) {
- ALOGI("Camera %s: Access for \"%s\" has been revoked",
- mCameraIdStr.string(), String8(mClientPackageName).string());
- return PERMISSION_DENIED;
- }
-
- if (res == AppOpsManager::MODE_IGNORED) {
- ALOGI("Camera %s: Access for \"%s\" has been restricted",
- mCameraIdStr.string(), String8(mClientPackageName).string());
- // Return the same error as for device policy manager rejection
- return -EACCES;
+ if (res == AppOpsManager::MODE_IGNORED) {
+ ALOGI("Camera %s: Access for \"%s\" has been restricted",
+ mCameraIdStr.string(), String8(mClientPackageName).string());
+ // Return the same error as for device policy manager rejection
+ return -EACCES;
+ }
}
mOpsActive = true;
@@ -2483,10 +2491,11 @@
// Check if startCameraOps succeeded, and if so, finish the camera op
if (mOpsActive) {
// Notify app ops that the camera is available again
- mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName);
- mOpsActive = false;
-
+ if (mAppOpsManager != nullptr) {
+ mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
+ mClientPackageName);
+ mOpsActive = false;
+ }
// This function is called when a client disconnects. This should
// release the camera, but actually only if it was in a proper
// functional state, i.e. with status NOT_AVAILABLE
@@ -2506,8 +2515,8 @@
mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
}
// Always stop watching, even if no camera op is active
- if (mOpsCallback != NULL) {
- mAppOpsManager.stopWatchingMode(mOpsCallback);
+ if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
+ mAppOpsManager->stopWatchingMode(mOpsCallback);
}
mOpsCallback.clear();
@@ -2516,19 +2525,18 @@
return OK;
}
-void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
+void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
ATRACE_CALL();
-
- String8 name(packageName);
- String8 myName(mClientPackageName);
-
+ if (mAppOpsManager == nullptr) {
+ return;
+ }
if (op != AppOpsManager::OP_CAMERA) {
ALOGW("Unexpected app ops notification received: %d", op);
return;
}
int32_t res;
- res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
+ res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
mClientUid, mClientPackageName);
ALOGV("checkOp returns: %d, %s ", res,
res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
@@ -2538,7 +2546,7 @@
if (res != AppOpsManager::MODE_ALLOWED) {
ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
- myName.string());
+ String8(mClientPackageName).string());
block();
}
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b8cec2c..065157d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -293,7 +293,7 @@
status_t finishCameraOps();
private:
- AppOpsManager mAppOpsManager;
+ std::unique_ptr<AppOpsManager> mAppOpsManager = nullptr;
class OpsCallback : public BnAppOpsCallback {
public: