Merge "Fix space in Android.bp to make aidegen -i c frameworks succeed." into sc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index bf91bf7..d8a0b91 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -15,7 +15,10 @@
apex_defaults {
name: "com.android.media-defaults",
updatable: true,
- java_libs: ["updatable-media"],
+ java_libs: [
+ "updatable-media",
+ "service-media-s",
+ ],
multilib: {
first: {
// Extractor process runs only with the primary ABI.
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 1f0c856..72f7c43 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -895,13 +895,12 @@
BufferPoolSender* bufferPoolSender,
std::list<BaseBlock>* baseBlocks,
std::map<const void*, uint32_t>* baseBlockIndices) {
- // TODO: C2InfoBuffer is not implemented.
- (void)d;
- (void)s;
- (void)bufferPoolSender;
- (void)baseBlocks;
- (void)baseBlockIndices;
- LOG(INFO) << "InfoBuffer not implemented.";
+ d->index = static_cast<ParamIndex>(s.index());
+ Buffer& dBuffer = d->buffer;
+ if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+ LOG(ERROR) << "Invalid C2InfoBuffer::data";
+ return false;
+ }
return true;
}
@@ -1336,6 +1335,68 @@
return true;
}
+// InfoBuffer -> C2InfoBuffer
+bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
+ const std::vector<C2BaseBlock>& baseBlocks) {
+
+ // Currently, a non-null C2InfoBufer must contain exactly 1 block.
+ if (s.buffer.blocks.size() == 0) {
+ return true;
+ } else if (s.buffer.blocks.size() != 1) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer "
+ "Currently, a C2InfoBuffer must contain exactly 1 block.";
+ return false;
+ }
+
+ const Block &sBlock = s.buffer.blocks[0];
+ if (sBlock.index >= baseBlocks.size()) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
+ "Array index out of range.";
+ return false;
+ }
+ const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+ // Parse meta.
+ std::vector<C2Param*> sBlockMeta;
+ if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
+ return false;
+ }
+
+ // Copy fence.
+ C2Fence dFence;
+ if (!objcpy(&dFence, sBlock.fence)) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
+ return false;
+ }
+
+ // Construct a block.
+ switch (baseBlock.type) {
+ case C2BaseBlock::LINEAR:
+ if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
+ sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
+ C2Hidl_RangeInfo *rangeInfo =
+ reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
+ d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
+ s.index,
+ baseBlock.linear->share(
+ rangeInfo->offset, rangeInfo->length, dFence)));
+ return true;
+ }
+ LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
+ break;
+ case C2BaseBlock::GRAPHIC:
+ // It's not used now
+ LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
+ break;
+ default:
+ LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
+ break;
+ }
+
+ return false;
+}
+
// FrameData -> C2FrameData
bool objcpy(C2FrameData* d, const FrameData& s,
const std::vector<C2BaseBlock>& baseBlocks) {
@@ -1370,8 +1431,18 @@
}
}
- // TODO: Implement this once C2InfoBuffer has constructors.
d->infoBuffers.clear();
+ if (s.infoBuffers.size() == 0) {
+ // InfoBuffer is optional
+ return true;
+ }
+ d->infoBuffers.reserve(s.infoBuffers.size());
+ for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
+ if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
+ LOG(ERROR) << "Invalid Framedata::infoBuffers.";
+ return false;
+ }
+ }
return true;
}
diff --git a/media/libmediahelper/tests/typeconverter_tests.cpp b/media/libmediahelper/tests/typeconverter_tests.cpp
index d7bfb89..181d636 100644
--- a/media/libmediahelper/tests/typeconverter_tests.cpp
+++ b/media/libmediahelper/tests/typeconverter_tests.cpp
@@ -182,8 +182,9 @@
audio_format_t format;
EXPECT_TRUE(FormatConverter::fromString(stringVal, format))
<< "Conversion of \"" << stringVal << "\" failed";
- EXPECT_TRUE(audio_is_valid_format(format))
- << "Converted format \"" << stringVal << "\" is invalid";
+ EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT,
+ audio_is_valid_format(format))
+ << "Validity of \"" << stringVal << "\" is not as expected";
EXPECT_EQ(stringVal, toString(format));
}
}
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index e3c0b05..994695f 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -238,7 +238,12 @@
int32_t operatingRate = getDefaultOperatingRate(encoderFormat);
if (operatingRate != -1) {
- SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_OPERATING_RATE, encoderFormat, operatingRate);
+ float tmpf;
+ int32_t tmpi;
+ if (!AMediaFormat_getFloat(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpf) &&
+ !AMediaFormat_getInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpi)) {
+ AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, operatingRate);
+ }
}
SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_PRIORITY, encoderFormat, kDefaultCodecPriority);
@@ -260,8 +265,8 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
- // TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
- #define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
+// TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
+#define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
AMediaCodec* encoder;
if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
index e0b2050..42933e6 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -33,6 +33,7 @@
#include <binder/ProcessState.h>
#include <fcntl.h>
#include <media/MediaTranscoder.h>
+#include <media/NdkCommon.h>
#include <iostream>
@@ -87,6 +88,7 @@
AMediaFormat* videoFormat = AMediaFormat_new();
AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
+ AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
return videoFormat;
}
@@ -222,7 +224,7 @@
}
static void SetMaxOperatingRate(AMediaFormat* format) {
- AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
}
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
index 6d781cd..e40a507 100644
--- a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
+++ b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
@@ -24,6 +24,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="{MODULE}" />
+ <option name="native-test-timeout" value="10m" />
</test>
</configuration>
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1f5b8d2..eaf0d10 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2961,7 +2961,10 @@
auto backInserter = std::back_inserter(metadata.tracks);
for (const sp<Track> &track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
- track->copyMetadataTo(backInserter);
+ // Do not forward metadata for PatchTrack with unspecified stream type
+ if (track->streamType() != AUDIO_STREAM_PATCH) {
+ track->copyMetadataTo(backInserter);
+ }
}
sendMetadataToBackend_l(metadata);
}
@@ -8101,6 +8104,10 @@
}
StreamInHalInterface::SinkMetadata metadata;
for (const sp<RecordTrack> &track : mActiveTracks) {
+ // Do not forward PatchRecord metadata to audio HAL
+ if (track->isPatchTrack()) {
+ continue;
+ }
// No track is invalid as this is called after prepareTrack_l in the same critical section
record_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index fed88a4..0ab63cf 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -590,7 +590,14 @@
bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
- return binderStatusFromStatusT(BAD_VALUE);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
+ }
+
+ if (((flags & AUDIO_INPUT_FLAG_HW_HOTWORD) != 0)
+ && !canCaptureHotword) {
+ ALOGE("%s: permission denied: hotword mode not allowed"
+ " for uid %d pid %d", __func__, uid, pid);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
}
sp<AudioPolicyEffects>audioPolicyEffects;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b4c0da3..adf8562 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1686,6 +1686,11 @@
client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
}
+ // Set camera muting behavior
+ if (client->supportsCameraMute()) {
+ client->setCameraMute(mOverrideCameraMuteMode);
+ }
+
if (shimUpdateOnly) {
// If only updating legacy shim parameters, immediately disconnect client
mServiceLock.unlock();
@@ -3887,6 +3892,8 @@
return handleSetImageDumpMask(args);
} else if (args.size() >= 1 && args[0] == String16("get-image-dump-mask")) {
return handleGetImageDumpMask(out);
+ } else if (args.size() >= 2 && args[0] == String16("set-camera-mute")) {
+ return handleSetCameraMute(args);
} else if (args.size() == 1 && args[0] == String16("help")) {
printHelp(out);
return NO_ERROR;
@@ -4009,6 +4016,29 @@
return dprintf(out, "Image dump mask: %d\n", mImageDumpMask);
}
+status_t CameraService::handleSetCameraMute(const Vector<String16>& args) {
+ int muteValue = strtol(String8(args[1]), nullptr, 10);
+ if (errno != 0) return BAD_VALUE;
+
+ if (muteValue < 0 || muteValue > 1) return BAD_VALUE;
+ Mutex::Autolock lock(mServiceLock);
+
+ mOverrideCameraMuteMode = (muteValue == 1);
+
+ const auto clients = mActiveClientManager.getAll();
+ for (auto& current : clients) {
+ if (current != nullptr) {
+ const auto basicClient = current->getValue();
+ if (basicClient.get() != nullptr) {
+ if (basicClient->supportsCameraMute()) {
+ basicClient->setCameraMute(mOverrideCameraMuteMode);
+ }
+ }
+ }
+ }
+
+ return OK;
+}
status_t CameraService::printHelp(int out) {
return dprintf(out, "Camera service commands:\n"
@@ -4021,6 +4051,7 @@
" set-image-dump-mask <MASK> specifies the formats to be saved to disk\n"
" Valid values 0=OFF, 1=ON for JPEG\n"
" get-image-dump-mask returns the current image-dump-mask value\n"
+ " set-camera-mute <0/1> enable or disable camera muting\n"
" help print this message\n");
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 43b03e6..bc6ad35 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -278,6 +278,12 @@
// Override rotate-and-crop AUTO behavior
virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop) = 0;
+ // Whether the client supports camera muting (black only output)
+ virtual bool supportsCameraMute() = 0;
+
+ // Set/reset camera mute
+ virtual status_t setCameraMute(bool enabled) = 0;
+
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
@@ -1044,6 +1050,9 @@
// Get the mask for image dump to disk
status_t handleGetImageDumpMask(int out);
+ // Set the camera mute state
+ status_t handleSetCameraMute(const Vector<String16>& args);
+
// Prints the shell command help
status_t printHelp(int out);
@@ -1088,6 +1097,9 @@
// Current image dump mask
uint8_t mImageDumpMask = 0;
+
+ // Current camera mute mode
+ bool mOverrideCameraMuteMode = false;
};
} // namespace android
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 2494302..1c9e9cf 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -2296,6 +2296,14 @@
static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
}
+bool Camera2Client::supportsCameraMute() {
+ return mDevice->supportsCameraMute();
+}
+
+status_t Camera2Client::setCameraMute(bool enabled) {
+ return mDevice->setCameraMute(enabled);
+}
+
status_t Camera2Client::waitUntilCurrentRequestIdLocked() {
int32_t activeRequestId = mStreamingProcessor->getActiveRequestId();
if (activeRequestId != 0) {
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index f8da0b6..4d667e3 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -87,6 +87,9 @@
virtual int32_t getGlobalAudioRestriction();
virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop);
+ virtual bool supportsCameraMute();
+ virtual status_t setCameraMute(bool enabled);
+
/**
* Interface used by CameraService
*/
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 6e1aba9..d47014e 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1532,6 +1532,14 @@
static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
}
+bool CameraDeviceClient::supportsCameraMute() {
+ return mDevice->supportsCameraMute();
+}
+
+status_t CameraDeviceClient::setCameraMute(bool enabled) {
+ return mDevice->setCameraMute(enabled);
+}
+
binder::Status CameraDeviceClient::switchToOffline(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const std::vector<int>& offlineOutputIds,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 57688a0..5588285 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -189,6 +189,9 @@
virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
+ virtual bool supportsCameraMute();
+ virtual status_t setCameraMute(bool enabled);
+
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t dumpClient(int fd, const Vector<String16>& args);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 62b5479..6765c3b 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -72,6 +72,16 @@
return OK;
}
+bool CameraOfflineSessionClient::supportsCameraMute() {
+ // Offline mode doesn't support muting
+ return false;
+}
+
+status_t CameraOfflineSessionClient::setCameraMute(bool) {
+ return INVALID_OPERATION;
+}
+
+
status_t CameraOfflineSessionClient::dump(int fd, const Vector<String16>& args) {
return BasicClient::dump(fd, args);
}
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 839c435..5c5fcda 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -76,6 +76,9 @@
status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
+ bool supportsCameraMute() override;
+ status_t setCameraMute(bool enabled) override;
+
// permissions management
status_t startCameraOps() override;
status_t finishCameraOps() override;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 5e46f08..1be46d6 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -399,6 +399,21 @@
camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) = 0;
/**
+ * Whether camera muting (producing black-only output) is supported.
+ *
+ * Calling setCameraMute(true) when this returns false will return an
+ * INVALID_OPERATION error.
+ */
+ virtual bool supportsCameraMute() = 0;
+
+ /**
+ * Mute the camera.
+ *
+ * When muted, black image data is output on all output streams.
+ */
+ virtual status_t setCameraMute(bool enabled) = 0;
+
+ /**
* Get the status tracker of the camera device
*/
virtual wp<camera3::StatusTracker> getStatusTracker() = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 385bfd6..7606d7d 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -357,6 +357,15 @@
mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
}
+ camera_metadata_entry_t availableTestPatternModes = mDeviceInfo.find(
+ ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES);
+ for (size_t i = 0; i < availableTestPatternModes.count; i++) {
+ if (availableTestPatternModes.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
+ mSupportCameraMute = true;
+ break;
+ }
+ }
+
return OK;
}
@@ -2388,6 +2397,26 @@
newRequest->mZoomRatioIs1x = false;
}
+ if (mSupportCameraMute) {
+ auto testPatternModeEntry =
+ newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
+ newRequest->mOriginalTestPatternMode = testPatternModeEntry.count > 0 ?
+ testPatternModeEntry.data.i32[0] :
+ ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
+
+ auto testPatternDataEntry =
+ newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
+ if (testPatternDataEntry.count > 0) {
+ memcpy(newRequest->mOriginalTestPatternData, testPatternModeEntry.data.i32,
+ sizeof(newRequest->mOriginalTestPatternData));
+ } else {
+ newRequest->mOriginalTestPatternData[0] = 0;
+ newRequest->mOriginalTestPatternData[1] = 0;
+ newRequest->mOriginalTestPatternData[2] = 0;
+ newRequest->mOriginalTestPatternData[3] = 0;
+ }
+ }
+
return newRequest;
}
@@ -3860,6 +3889,8 @@
mCurrentAfTriggerId(0),
mCurrentPreCaptureTriggerId(0),
mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
+ mCameraMute(false),
+ mCameraMuteChanged(false),
mRepeatingLastFrameNumber(
hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
mPrepareVideoStream(false),
@@ -4484,10 +4515,13 @@
mPrevTriggers = triggerCount;
bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
+ bool testPatternChanged = overrideTestPattern(captureRequest);
- // If the request is the same as last, or we had triggers last time
+ // If the request is the same as last, or we had triggers now or last time or
+ // changing overrides this time
bool newRequest =
- (mPrevRequest != captureRequest || triggersMixedIn || rotateAndCropChanged) &&
+ (mPrevRequest != captureRequest || triggersMixedIn ||
+ rotateAndCropChanged || testPatternChanged) &&
// Request settings are all the same within one batch, so only treat the first
// request in a batch as new
!(batchedRequest && i > 0);
@@ -4952,6 +4986,16 @@
return OK;
}
+status_t Camera3Device::RequestThread::setCameraMute(bool enabled) {
+ ATRACE_CALL();
+ Mutex::Autolock l(mTriggerMutex);
+ if (enabled != mCameraMute) {
+ mCameraMute = enabled;
+ mCameraMuteChanged = true;
+ }
+ return OK;
+}
+
nsecs_t Camera3Device::getExpectedInFlightDuration() {
ATRACE_CALL();
std::lock_guard<std::mutex> l(mInFlightLock);
@@ -5504,6 +5548,61 @@
return false;
}
+bool Camera3Device::RequestThread::overrideTestPattern(
+ const sp<CaptureRequest> &request) {
+ ATRACE_CALL();
+
+ Mutex::Autolock l(mTriggerMutex);
+
+ bool changed = false;
+
+ int32_t testPatternMode = request->mOriginalTestPatternMode;
+ int32_t testPatternData[4] = {
+ request->mOriginalTestPatternData[0],
+ request->mOriginalTestPatternData[1],
+ request->mOriginalTestPatternData[2],
+ request->mOriginalTestPatternData[3]
+ };
+
+ if (mCameraMute) {
+ testPatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR;
+ testPatternData[0] = 0;
+ testPatternData[1] = 0;
+ testPatternData[2] = 0;
+ testPatternData[3] = 0;
+ }
+
+ CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
+
+ auto testPatternEntry = metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
+ if (testPatternEntry.count > 0) {
+ if (testPatternEntry.data.i32[0] != testPatternMode) {
+ testPatternEntry.data.i32[0] = testPatternMode;
+ changed = true;
+ }
+ } else {
+ metadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE,
+ &testPatternMode, 1);
+ changed = true;
+ }
+
+ auto testPatternColor = metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
+ if (testPatternColor.count > 0) {
+ for (size_t i = 0; i < 4; i++) {
+ if (testPatternColor.data.i32[i] != (int32_t)testPatternData[i]) {
+ testPatternColor.data.i32[i] = testPatternData[i];
+ changed = true;
+ }
+ }
+ } else {
+ metadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA,
+ (int32_t*)testPatternData, 4);
+ changed = true;
+ }
+
+ return changed;
+}
+
/**
* PreparerThread inner class methods
*/
@@ -6129,4 +6228,22 @@
return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
}
+bool Camera3Device::supportsCameraMute() {
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ return mSupportCameraMute;
+}
+
+status_t Camera3Device::setCameraMute(bool enabled) {
+ ATRACE_CALL();
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ if (mRequestThread == nullptr || !mSupportCameraMute) {
+ return INVALID_OPERATION;
+ }
+ return mRequestThread->setCameraMute(enabled);
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index b06ce45..567b3ad 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -238,6 +238,21 @@
status_t setRotateAndCropAutoBehavior(
camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue);
+ /**
+ * Whether camera muting (producing black-only output) is supported.
+ *
+ * Calling setCameraMute(true) when this returns false will return an
+ * INVALID_OPERATION error.
+ */
+ bool supportsCameraMute();
+
+ /**
+ * Mute the camera.
+ *
+ * When muted, black image data is output on all output streams.
+ */
+ status_t setCameraMute(bool enabled);
+
// Get the status trackeer for the camera device
wp<camera3::StatusTracker> getStatusTracker() { return mStatusTracker; }
@@ -525,6 +540,11 @@
// overriding of ROTATE_AND_CROP value and adjustment of coordinates
// in several other controls in both the request and the result
bool mRotateAndCropAuto;
+ // Original value of TEST_PATTERN_MODE and DATA so that they can be
+ // restored when sensor muting is turned off
+ int32_t mOriginalTestPatternMode;
+ int32_t mOriginalTestPatternData[4];
+
// Whether this capture request has its zoom ratio set to 1.0x before
// the framework overrides it for camera HAL consumption.
bool mZoomRatioIs1x;
@@ -868,6 +888,7 @@
status_t setRotateAndCropAutoBehavior(
camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue);
+ status_t setCameraMute(bool enabled);
protected:
virtual bool threadLoop();
@@ -889,6 +910,10 @@
// Override rotate_and_crop control if needed; returns true if the current value was changed
bool overrideAutoRotateAndCrop(const sp<CaptureRequest> &request);
+ // Override test_pattern control if needed for camera mute; returns true
+ // if the current value was changed
+ bool overrideTestPattern(const sp<CaptureRequest> &request);
+
static const nsecs_t kRequestTimeout = 50e6; // 50 ms
// TODO: does this need to be adjusted for long exposure requests?
@@ -1011,6 +1036,8 @@
uint32_t mCurrentAfTriggerId;
uint32_t mCurrentPreCaptureTriggerId;
camera_metadata_enum_android_scaler_rotate_and_crop_t mRotateAndCropOverride;
+ bool mCameraMute;
+ bool mCameraMuteChanged;
int64_t mRepeatingLastFrameNumber;
@@ -1276,6 +1303,10 @@
// Whether HAL supports offline processing capability.
bool mSupportOfflineProcessing = false;
+
+ // Whether the HAL supports camera muting via test pattern
+ bool mSupportCameraMute = false;
+
}; // class Camera3Device
}; // namespace android
diff --git a/services/tuner/TunerDemux.cpp b/services/tuner/TunerDemux.cpp
index 0e0cd3b..1f8b70d 100644
--- a/services/tuner/TunerDemux.cpp
+++ b/services/tuner/TunerDemux.cpp
@@ -124,4 +124,17 @@
*_aidl_return = ::ndk::SharedRefBase::make<TunerDvr>(hidlDvr, dvrType);
return Status::ok();
}
+
+Status TunerDemux::close() {
+ if (mDemux == nullptr) {
+ ALOGE("IDemux is not initialized.");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res = mDemux->close();
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
} // namespace android
diff --git a/services/tuner/TunerDemux.h b/services/tuner/TunerDemux.h
index 675bb7c..594fd66 100644
--- a/services/tuner/TunerDemux.h
+++ b/services/tuner/TunerDemux.h
@@ -47,6 +47,7 @@
Status openDvr(
int dvbType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
shared_ptr<ITunerDvr>* _aidl_return) override;
+ Status close() override;
private:
sp<IDemux> mDemux;
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 722d36d..edfc291 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -16,16 +16,19 @@
#define LOG_TAG "TunerFilter"
-#include <aidlcommonsupport/NativeHandle.h>
#include "TunerFilter.h"
+using ::android::hardware::hidl_handle;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using ::android::hardware::tv::tuner::V1_0::Result;
-
namespace android {
-TunerFilter::TunerFilter(sp<IFilter> filter, sp<IFilterCallback> callback) {
+TunerFilter::TunerFilter(
+ sp<IFilter> filter, sp<IFilterCallback> callback) {
mFilter = filter;
mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
mFilterCallback = callback;
@@ -103,6 +106,7 @@
break;
}
}
+ halSettings.ts(ts);
break;
}
}
@@ -113,6 +117,44 @@
return Status::ok();
}
+Status TunerFilter::getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) {
+ if (mFilter_1_1 == nullptr) {
+ ALOGE("IFilter_1_1 is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res;
+ mFilter_1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) {
+ res = r;
+ if (res == Result::SUCCESS) {
+ TunerFilterSharedHandleInfo info{
+ .handle = dupToAidl(hidl_handle(avMemory.getNativeHandle())),
+ .size = static_cast<int64_t>(avMemSize),
+ };
+ *_aidl_return = std::move(info);
+ } else {
+ _aidl_return = NULL;
+ }
+ });
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+}
+
+Status TunerFilter::releaseAvHandle(
+ const ::aidl::android::hardware::common::NativeHandle& handle, int64_t avDataId) {
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res = mFilter->releaseAvHandle(hidl_handle(makeFromAidl(handle)), avDataId);
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
+
+
Status TunerFilter::start() {
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
@@ -149,6 +191,18 @@
return Status::ok();
}
+Status TunerFilter::close() {
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+ Result res = mFilter->close();
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
+
sp<IFilter> TunerFilter::getHalFilter() {
return mFilter;
}
@@ -164,8 +218,8 @@
tunerMedia.streamId = static_cast<int>(mediaEvent.streamId);
tunerMedia.isPtsPresent = mediaEvent.isPtsPresent;
tunerMedia.pts = static_cast<long>(mediaEvent.pts);
- tunerMedia.dataLength = static_cast<long>(mediaEvent.dataLength);
- tunerMedia.offset = static_cast<long>(mediaEvent.offset);
+ tunerMedia.dataLength = static_cast<int>(mediaEvent.dataLength);
+ tunerMedia.offset = static_cast<int>(mediaEvent.offset);
tunerMedia.isSecureMemory = mediaEvent.isSecureMemory;
tunerMedia.avDataId = static_cast<long>(mediaEvent.avDataId);
tunerMedia.mpuSequenceNumber = static_cast<int>(mediaEvent.mpuSequenceNumber);
@@ -187,7 +241,6 @@
}
Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
- ALOGD("FilterCallback::onFilterEvent");
std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
std::vector<TunerFilterEvent> tunerEvent;
@@ -203,7 +256,8 @@
}
}
}
- mTunerFilterCallback->onFilterEvent(&tunerEvent);
+
+ mTunerFilterCallback->onFilterEvent(tunerEvent);
return Void();
}
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index 7f5838c..2f10435 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -19,6 +19,7 @@
#include <aidl/android/media/tv/tuner/BnTunerFilter.h>
#include <aidl/android/media/tv/tuner/ITunerFilterCallback.h>
+#include <aidlcommonsupport/NativeHandle.h>
#include <android/hardware/tv/tuner/1.1/IFilter.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -29,6 +30,7 @@
using ::aidl::android::media::tv::tuner::TunerFilterConfiguration;
using ::aidl::android::media::tv::tuner::TunerFilterEvent;
using ::aidl::android::media::tv::tuner::TunerFilterMediaEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterSharedHandleInfo;
using ::aidl::android::media::tv::tuner::TunerFilterSettings;
using ::android::hardware::Return;
using ::android::hardware::Void;
@@ -39,7 +41,6 @@
using ::android::hardware::tv::tuner::V1_0::IFilter;
using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
-
namespace android {
class TunerFilter : public BnTunerFilter {
@@ -50,9 +51,13 @@
Status getId(int32_t* _aidl_return) override;
Status getId64Bit(int64_t* _aidl_return) override;
Status configure(const TunerFilterConfiguration& config) override;
+ Status getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) override;
+ Status releaseAvHandle(const ::aidl::android::hardware::common::NativeHandle& handle,
+ int64_t avDataId) override;
Status start() override;
Status stop() override;
Status flush() override;
+ Status close() override;
sp<IFilter> getHalFilter();
struct FilterCallback : public IFilterCallback {
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index e92489d..bb8b07d 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -66,7 +66,6 @@
using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
-using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
using ::android::hardware::tv::tuner::V1_0::Result;
using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
@@ -80,6 +79,7 @@
TunerFrontend::~TunerFrontend() {
mFrontend = NULL;
+ mFrontend_1_1 = NULL;
mId = -1;
}
@@ -103,12 +103,33 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
-Status TunerFrontend::tune(const TunerFrontendSettings& /*settings*/) {
- return Status::ok();
+Status TunerFrontend::tune(const TunerFrontendSettings& settings) {
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
+ Result status = mFrontend->tune(frontendSettings);
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::stopTune() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->stopTune();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
@@ -117,165 +138,7 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
}
- // TODO: extend TunerFrontendSettings to use 1.1 types
- FrontendSettings frontendSettings;
- switch (settings.getTag()) {
- case TunerFrontendSettings::analog:
- frontendSettings.analog({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::analog>().frequency),
- .type = static_cast<FrontendAnalogType>(
- settings.get<TunerFrontendSettings::analog>().signalType),
- .sifStandard = static_cast<FrontendAnalogSifStandard>(
- settings.get<TunerFrontendSettings::analog>().sifStandard),
- });
- break;
- case TunerFrontendSettings::atsc:
- frontendSettings.atsc({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::atsc>().frequency),
- .modulation = static_cast<FrontendAtscModulation>(
- settings.get<TunerFrontendSettings::atsc>().modulation),
- });
- break;
- case TunerFrontendSettings::atsc3:
- frontendSettings.atsc3({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::atsc3>().frequency),
- .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
- settings.get<TunerFrontendSettings::atsc3>().bandwidth),
- .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
- settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
- .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
- });
- break;
- case TunerFrontendSettings::cable:
- frontendSettings.dvbc({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::cable>().frequency),
- .modulation = static_cast<FrontendDvbcModulation>(
- settings.get<TunerFrontendSettings::cable>().modulation),
- .fec = static_cast<FrontendInnerFec>(
- settings.get<TunerFrontendSettings::cable>().innerFec),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::cable>().symbolRate),
- .outerFec = static_cast<FrontendDvbcOuterFec>(
- settings.get<TunerFrontendSettings::cable>().outerFec),
- .annex = static_cast<FrontendDvbcAnnex>(
- settings.get<TunerFrontendSettings::cable>().annex),
- .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
- settings.get<TunerFrontendSettings::cable>().spectralInversion),
- });
- break;
- case TunerFrontendSettings::dvbs:
- frontendSettings.dvbs({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().frequency),
- .modulation = static_cast<FrontendDvbsModulation>(
- settings.get<TunerFrontendSettings::dvbs>().modulation),
- .coderate = getDvbsCodeRate(
- settings.get<TunerFrontendSettings::dvbs>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().symbolRate),
- .rolloff = static_cast<FrontendDvbsRolloff>(
- settings.get<TunerFrontendSettings::dvbs>().rolloff),
- .pilot = static_cast<FrontendDvbsPilot>(
- settings.get<TunerFrontendSettings::dvbs>().pilot),
- .inputStreamId = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
- .standard = static_cast<FrontendDvbsStandard>(
- settings.get<TunerFrontendSettings::dvbs>().standard),
- .vcmMode = static_cast<FrontendDvbsVcmMode>(
- settings.get<TunerFrontendSettings::dvbs>().vcm),
- });
- break;
- case TunerFrontendSettings::dvbt:
- frontendSettings.dvbt({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbt>().frequency),
- .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
- settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
- .bandwidth = static_cast<FrontendDvbtBandwidth>(
- settings.get<TunerFrontendSettings::dvbt>().bandwidth),
- .constellation = static_cast<FrontendDvbtConstellation>(
- settings.get<TunerFrontendSettings::dvbt>().constellation),
- .hierarchy = static_cast<FrontendDvbtHierarchy>(
- settings.get<TunerFrontendSettings::dvbt>().hierarchy),
- .hpCoderate = static_cast<FrontendDvbtCoderate>(
- settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
- .lpCoderate = static_cast<FrontendDvbtCoderate>(
- settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
- .guardInterval = static_cast<FrontendDvbtGuardInterval>(
- settings.get<TunerFrontendSettings::dvbt>().guardInterval),
- .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
- .standard = static_cast<FrontendDvbtStandard>(
- settings.get<TunerFrontendSettings::dvbt>().standard),
- .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
- .plpMode = static_cast<FrontendDvbtPlpMode>(
- settings.get<TunerFrontendSettings::dvbt>().plpMode),
- .plpId = static_cast<uint8_t>(
- settings.get<TunerFrontendSettings::dvbt>().plpId),
- .plpGroupId = static_cast<uint8_t>(
- settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
- });
- break;
- case TunerFrontendSettings::isdbs:
- frontendSettings.isdbs({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs>().frequency),
- .streamId = static_cast<uint16_t>(
- settings.get<TunerFrontendSettings::isdbs>().streamId),
- .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
- settings.get<TunerFrontendSettings::isdbs>().streamIdType),
- .modulation = static_cast<FrontendIsdbsModulation>(
- settings.get<TunerFrontendSettings::isdbs>().modulation),
- .coderate = static_cast<FrontendIsdbsCoderate>(
- settings.get<TunerFrontendSettings::isdbs>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs>().symbolRate),
- .rolloff = static_cast<FrontendIsdbsRolloff>(
- settings.get<TunerFrontendSettings::isdbs>().rolloff),
- });
- break;
- case TunerFrontendSettings::isdbs3:
- frontendSettings.isdbs3({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs3>().frequency),
- .streamId = static_cast<uint16_t>(
- settings.get<TunerFrontendSettings::isdbs3>().streamId),
- .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
- settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
- .modulation = static_cast<FrontendIsdbs3Modulation>(
- settings.get<TunerFrontendSettings::isdbs3>().modulation),
- .coderate = static_cast<FrontendIsdbs3Coderate>(
- settings.get<TunerFrontendSettings::isdbs3>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
- .rolloff = static_cast<FrontendIsdbs3Rolloff>(
- settings.get<TunerFrontendSettings::isdbs3>().rolloff),
- });
- break;
- case TunerFrontendSettings::isdbt:
- frontendSettings.isdbt({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbt>().frequency),
- .modulation = static_cast<FrontendIsdbtModulation>(
- settings.get<TunerFrontendSettings::isdbt>().modulation),
- .bandwidth = static_cast<FrontendIsdbtBandwidth>(
- settings.get<TunerFrontendSettings::isdbt>().bandwidth),
- .mode = static_cast<FrontendIsdbtMode>(
- settings.get<TunerFrontendSettings::isdbt>().mode),
- .coderate = static_cast<FrontendIsdbtCoderate>(
- settings.get<TunerFrontendSettings::isdbt>().codeRate),
- .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
- settings.get<TunerFrontendSettings::isdbt>().guardInterval),
- .serviceAreaId = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
- });
- break;
- default:
- break;
- }
+ FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
Result status = mFrontend->scan(
frontendSettings, static_cast<FrontendScanType>(frontendScanType));
if (status == Result::SUCCESS) {
@@ -286,7 +149,17 @@
}
Status TunerFrontend::stopScan() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->stopScan();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::setLnb(int /*lnbHandle*/) {
@@ -298,7 +171,17 @@
}
Status TunerFrontend::close() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->close();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::getStatus(const vector<int32_t>& /*statusTypes*/,
@@ -500,4 +383,167 @@
};
return coderate;
}
+
+FrontendSettings TunerFrontend::getHidlFrontendSettings(const TunerFrontendSettings& settings) {
+ // TODO: extend TunerFrontendSettings to use 1.1 types
+ FrontendSettings frontendSettings;
+ switch (settings.getTag()) {
+ case TunerFrontendSettings::analog:
+ frontendSettings.analog({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::analog>().frequency),
+ .type = static_cast<FrontendAnalogType>(
+ settings.get<TunerFrontendSettings::analog>().signalType),
+ .sifStandard = static_cast<FrontendAnalogSifStandard>(
+ settings.get<TunerFrontendSettings::analog>().sifStandard),
+ });
+ break;
+ case TunerFrontendSettings::atsc:
+ frontendSettings.atsc({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::atsc>().frequency),
+ .modulation = static_cast<FrontendAtscModulation>(
+ settings.get<TunerFrontendSettings::atsc>().modulation),
+ });
+ break;
+ case TunerFrontendSettings::atsc3:
+ frontendSettings.atsc3({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::atsc3>().frequency),
+ .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
+ settings.get<TunerFrontendSettings::atsc3>().bandwidth),
+ .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
+ settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
+ .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
+ });
+ break;
+ case TunerFrontendSettings::cable:
+ frontendSettings.dvbc({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::cable>().frequency),
+ .modulation = static_cast<FrontendDvbcModulation>(
+ settings.get<TunerFrontendSettings::cable>().modulation),
+ .fec = static_cast<FrontendInnerFec>(
+ settings.get<TunerFrontendSettings::cable>().innerFec),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::cable>().symbolRate),
+ .outerFec = static_cast<FrontendDvbcOuterFec>(
+ settings.get<TunerFrontendSettings::cable>().outerFec),
+ .annex = static_cast<FrontendDvbcAnnex>(
+ settings.get<TunerFrontendSettings::cable>().annex),
+ .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
+ settings.get<TunerFrontendSettings::cable>().spectralInversion),
+ });
+ break;
+ case TunerFrontendSettings::dvbs:
+ frontendSettings.dvbs({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().frequency),
+ .modulation = static_cast<FrontendDvbsModulation>(
+ settings.get<TunerFrontendSettings::dvbs>().modulation),
+ .coderate = getDvbsCodeRate(
+ settings.get<TunerFrontendSettings::dvbs>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().symbolRate),
+ .rolloff = static_cast<FrontendDvbsRolloff>(
+ settings.get<TunerFrontendSettings::dvbs>().rolloff),
+ .pilot = static_cast<FrontendDvbsPilot>(
+ settings.get<TunerFrontendSettings::dvbs>().pilot),
+ .inputStreamId = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
+ .standard = static_cast<FrontendDvbsStandard>(
+ settings.get<TunerFrontendSettings::dvbs>().standard),
+ .vcmMode = static_cast<FrontendDvbsVcmMode>(
+ settings.get<TunerFrontendSettings::dvbs>().vcm),
+ });
+ break;
+ case TunerFrontendSettings::dvbt:
+ frontendSettings.dvbt({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbt>().frequency),
+ .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
+ settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
+ .bandwidth = static_cast<FrontendDvbtBandwidth>(
+ settings.get<TunerFrontendSettings::dvbt>().bandwidth),
+ .constellation = static_cast<FrontendDvbtConstellation>(
+ settings.get<TunerFrontendSettings::dvbt>().constellation),
+ .hierarchy = static_cast<FrontendDvbtHierarchy>(
+ settings.get<TunerFrontendSettings::dvbt>().hierarchy),
+ .hpCoderate = static_cast<FrontendDvbtCoderate>(
+ settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
+ .lpCoderate = static_cast<FrontendDvbtCoderate>(
+ settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
+ .guardInterval = static_cast<FrontendDvbtGuardInterval>(
+ settings.get<TunerFrontendSettings::dvbt>().guardInterval),
+ .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
+ .standard = static_cast<FrontendDvbtStandard>(
+ settings.get<TunerFrontendSettings::dvbt>().standard),
+ .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
+ .plpMode = static_cast<FrontendDvbtPlpMode>(
+ settings.get<TunerFrontendSettings::dvbt>().plpMode),
+ .plpId = static_cast<uint8_t>(
+ settings.get<TunerFrontendSettings::dvbt>().plpId),
+ .plpGroupId = static_cast<uint8_t>(
+ settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
+ });
+ break;
+ case TunerFrontendSettings::isdbs:
+ frontendSettings.isdbs({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs>().frequency),
+ .streamId = static_cast<uint16_t>(
+ settings.get<TunerFrontendSettings::isdbs>().streamId),
+ .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+ settings.get<TunerFrontendSettings::isdbs>().streamIdType),
+ .modulation = static_cast<FrontendIsdbsModulation>(
+ settings.get<TunerFrontendSettings::isdbs>().modulation),
+ .coderate = static_cast<FrontendIsdbsCoderate>(
+ settings.get<TunerFrontendSettings::isdbs>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs>().symbolRate),
+ .rolloff = static_cast<FrontendIsdbsRolloff>(
+ settings.get<TunerFrontendSettings::isdbs>().rolloff),
+ });
+ break;
+ case TunerFrontendSettings::isdbs3:
+ frontendSettings.isdbs3({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().frequency),
+ .streamId = static_cast<uint16_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().streamId),
+ .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+ settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
+ .modulation = static_cast<FrontendIsdbs3Modulation>(
+ settings.get<TunerFrontendSettings::isdbs3>().modulation),
+ .coderate = static_cast<FrontendIsdbs3Coderate>(
+ settings.get<TunerFrontendSettings::isdbs3>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
+ .rolloff = static_cast<FrontendIsdbs3Rolloff>(
+ settings.get<TunerFrontendSettings::isdbs3>().rolloff),
+ });
+ break;
+ case TunerFrontendSettings::isdbt:
+ frontendSettings.isdbt({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbt>().frequency),
+ .modulation = static_cast<FrontendIsdbtModulation>(
+ settings.get<TunerFrontendSettings::isdbt>().modulation),
+ .bandwidth = static_cast<FrontendIsdbtBandwidth>(
+ settings.get<TunerFrontendSettings::isdbt>().bandwidth),
+ .mode = static_cast<FrontendIsdbtMode>(
+ settings.get<TunerFrontendSettings::isdbt>().mode),
+ .coderate = static_cast<FrontendIsdbtCoderate>(
+ settings.get<TunerFrontendSettings::isdbt>().codeRate),
+ .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
+ settings.get<TunerFrontendSettings::isdbt>().guardInterval),
+ .serviceAreaId = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
+ });
+ break;
+ default:
+ break;
+ }
+ return frontendSettings;
+}
} // namespace android
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index 99cdcdf..431022d 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -41,6 +41,7 @@
using ::android::hardware::tv::tuner::V1_0::FrontendId;
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
using ::android::hardware::tv::tuner::V1_0::IFrontend;
using ::android::hardware::tv::tuner::V1_1::IFrontendCallback;
using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
@@ -85,6 +86,7 @@
hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
const TunerFrontendAtsc3Settings& settings);
FrontendDvbsCodeRate getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate);
+ FrontendSettings getHidlFrontendSettings(const TunerFrontendSettings& settings);
int mId;
sp<IFrontend> mFrontend;
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
index f6de618..fa2c1ff 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
@@ -44,4 +44,9 @@
* Open a DVR (Digital Video Record) instance in the demux.
*/
ITunerDvr openDvr(in int dvbType, in int bufferSize, in ITunerDvrCallback cb);
+
+ /**
+ * Releases the ITunerDemux instance.
+ */
+ void close();
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
index 37166aa..1d5544f 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
@@ -16,7 +16,9 @@
package android.media.tv.tuner;
+import android.hardware.common.NativeHandle;
import android.media.tv.tuner.TunerFilterConfiguration;
+import android.media.tv.tuner.TunerFilterSharedHandleInfo;
/**
* Tuner Filter interface handles tuner related operations.
@@ -40,6 +42,16 @@
void configure(in TunerFilterConfiguration config);
/**
+ * Get the a/v shared memory handle
+ */
+ TunerFilterSharedHandleInfo getAvSharedHandleInfo();
+
+ /**
+ * Release the handle reported by the HAL for AV memory.
+ */
+ void releaseAvHandle(in NativeHandle handle, in long avDataId);
+
+ /**
* Start the filter.
*/
void start();
@@ -53,4 +65,9 @@
* Flush the filter.
*/
void flush();
+
+ /**
+ * Close the filter.
+ */
+ void close();
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
index f9f86ac..e7a52a7 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
@@ -32,5 +32,5 @@
/**
* Notify the client that a new filter event happened.
*/
- void onFilterEvent(out TunerFilterEvent[] filterEvent);
+ void onFilterEvent(in TunerFilterEvent[] filterEvent);
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
new file mode 100644
index 0000000..122dfc3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Filter Shared Handle Information.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterSharedHandleInfo {
+ NativeHandle handle;
+ long size;
+}
\ No newline at end of file