Merge "AudioFlinger: allow shared record audio history for fast capture" into sc-dev
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 416884e..b4e4c5d 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -2587,7 +2587,9 @@
case FOURCC("dvcC"):
case FOURCC("dvvC"): {
- CHECK_EQ(chunk_data_size, 24);
+ if (chunk_data_size != 24) {
+ return ERROR_MALFORMED;
+ }
auto buffer = heapbuffer<uint8_t>(chunk_data_size);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9eb7003..4fc60a4 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -828,12 +828,16 @@
if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, ");
if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, ");
if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
- if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
- if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT) s.append("top-side-left, " );
- if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT) s.append("top-side-right, " );
- if (mask & AUDIO_CHANNEL_OUT_HAPTIC_B) s.append("haptic-B, " );
- if (mask & AUDIO_CHANNEL_OUT_HAPTIC_A) s.append("haptic-A, " );
+ if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT) s.append("top-side-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT) s.append("top-side-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_BOTTOM_FRONT_LEFT) s.append("bottom-front-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_BOTTOM_FRONT_CENTER) s.append("bottom-front-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_BOTTOM_FRONT_RIGHT) s.append("bottom-front-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2) s.append("low_frequency_2, ");
+ if (mask & AUDIO_CHANNEL_OUT_HAPTIC_B) s.append("haptic-B, ");
+ if (mask & AUDIO_CHANNEL_OUT_HAPTIC_A) s.append("haptic-A, ");
if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, ");
} else {
if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
@@ -852,8 +856,8 @@
if (mask & AUDIO_CHANNEL_IN_BACK_RIGHT) s.append("back-right, ");
if (mask & AUDIO_CHANNEL_IN_CENTER) s.append("center, ");
if (mask & AUDIO_CHANNEL_IN_LOW_FREQUENCY) s.append("low freq, ");
- if (mask & AUDIO_CHANNEL_IN_TOP_LEFT) s.append("top-left, " );
- if (mask & AUDIO_CHANNEL_IN_TOP_RIGHT) s.append("top-right, " );
+ if (mask & AUDIO_CHANNEL_IN_TOP_LEFT) s.append("top-left, ");
+ if (mask & AUDIO_CHANNEL_IN_TOP_RIGHT) s.append("top-right, ");
if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, ");
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 07c889b..c28c24b 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -82,6 +82,7 @@
"device3/RotateAndCropMapper.cpp",
"device3/Camera3OutputStreamInterface.cpp",
"device3/Camera3OutputUtils.cpp",
+ "device3/Camera3DeviceInjectionMethods.cpp",
"gui/RingBufferConsumer.cpp",
"hidl/AidlCameraDeviceCallbacks.cpp",
"hidl/AidlCameraServiceListener.cpp",
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index d93b9e5..d05a2e1 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -49,6 +49,7 @@
#include <utils/Timers.h>
#include <cutils/properties.h>
+#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
#include "utils/CameraTraces.h"
@@ -358,6 +359,8 @@
}
}
+ mInjectionMethods = new Camera3DeviceInjectionMethods(this);
+
return OK;
}
@@ -431,6 +434,10 @@
mStatusTracker->join();
}
+ if (mInjectionMethods->isInjecting()) {
+ mInjectionMethods->stopInjection();
+ }
+
HalInterface* interface;
{
Mutex::Autolock l(mLock);
@@ -1829,7 +1836,6 @@
return res;
}
-
void Camera3Device::internalUpdateStatusLocked(Status status) {
mStatus = status;
mRecentStatusUpdates.add(mStatus);
@@ -2820,6 +2826,19 @@
mRequestBufferSM.onStreamsConfigured();
}
+ // Since the streams configuration of the injection camera is based on the internal camera, we
+ // must wait until the internal camera configure streams before calling injectCamera() to
+ // configure the injection streams.
+ if (mInjectionMethods->isInjecting()) {
+ ALOGV("%s: Injection camera %s: Start to configure streams.",
+ __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
+ res = mInjectionMethods->injectCamera(config, bufferSizes);
+ if (res != OK) {
+ ALOGE("Can't finish inject camera process!");
+ return res;
+ }
+ }
+
return OK;
}
@@ -3524,6 +3543,146 @@
return res;
}
+status_t Camera3Device::HalInterface::configureInjectedStreams(
+ const camera_metadata_t* sessionParams, camera_stream_configuration* config,
+ const std::vector<uint32_t>& bufferSizes,
+ const CameraMetadata& cameraCharacteristics) {
+ ATRACE_NAME("InjectionCameraHal::configureStreams");
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ if (config->input_is_multi_resolution) {
+ ALOGE("%s: Injection camera device doesn't support multi-resolution input "
+ "stream", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ // Convert stream config to HIDL
+ std::set<int> activeStreams;
+ device::V3_2::StreamConfiguration requestedConfiguration3_2;
+ device::V3_4::StreamConfiguration requestedConfiguration3_4;
+ device::V3_7::StreamConfiguration requestedConfiguration3_7;
+ requestedConfiguration3_2.streams.resize(config->num_streams);
+ requestedConfiguration3_4.streams.resize(config->num_streams);
+ requestedConfiguration3_7.streams.resize(config->num_streams);
+ for (size_t i = 0; i < config->num_streams; i++) {
+ device::V3_2::Stream& dst3_2 = requestedConfiguration3_2.streams[i];
+ device::V3_4::Stream& dst3_4 = requestedConfiguration3_4.streams[i];
+ device::V3_7::Stream& dst3_7 = requestedConfiguration3_7.streams[i];
+ camera3::camera_stream_t* src = config->streams[i];
+
+ Camera3Stream* cam3stream = Camera3Stream::cast(src);
+ cam3stream->setBufferFreedListener(this);
+ int streamId = cam3stream->getId();
+ StreamType streamType;
+ switch (src->stream_type) {
+ case CAMERA_STREAM_OUTPUT:
+ streamType = StreamType::OUTPUT;
+ break;
+ case CAMERA_STREAM_INPUT:
+ streamType = StreamType::INPUT;
+ break;
+ default:
+ ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
+ streamId, config->streams[i]->stream_type);
+ return BAD_VALUE;
+ }
+ dst3_2.id = streamId;
+ dst3_2.streamType = streamType;
+ dst3_2.width = src->width;
+ dst3_2.height = src->height;
+ dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
+ dst3_2.rotation =
+ mapToStreamRotation((camera_stream_rotation_t)src->rotation);
+ // For HidlSession version 3.5 or newer, the format and dataSpace sent
+ // to HAL are original, not the overridden ones.
+ if (mHidlSession_3_5 != nullptr) {
+ dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden()
+ ? cam3stream->getOriginalFormat()
+ : src->format);
+ dst3_2.dataSpace =
+ mapToHidlDataspace(cam3stream->isDataSpaceOverridden()
+ ? cam3stream->getOriginalDataSpace()
+ : src->data_space);
+ } else {
+ dst3_2.format = mapToPixelFormat(src->format);
+ dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
+ }
+ dst3_4.v3_2 = dst3_2;
+ dst3_4.bufferSize = bufferSizes[i];
+ if (src->physical_camera_id != nullptr) {
+ dst3_4.physicalCameraId = src->physical_camera_id;
+ }
+ dst3_7.v3_4 = dst3_4;
+ dst3_7.groupId = cam3stream->getHalStreamGroupId();
+ dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
+ size_t j = 0;
+ for (int mode : src->sensor_pixel_modes_used) {
+ dst3_7.sensorPixelModesUsed[j++] =
+ static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+ }
+ activeStreams.insert(streamId);
+ // Create Buffer ID map if necessary
+ mBufferRecords.tryCreateBufferCache(streamId);
+ }
+ // remove BufferIdMap for deleted streams
+ mBufferRecords.removeInactiveBufferCaches(activeStreams);
+
+ StreamConfigurationMode operationMode;
+ res = mapToStreamConfigurationMode(
+ (camera_stream_configuration_mode_t)config->operation_mode,
+ /*out*/ &operationMode);
+ if (res != OK) {
+ return res;
+ }
+ requestedConfiguration3_7.operationMode = operationMode;
+ size_t sessionParamSize = get_camera_metadata_size(sessionParams);
+ requestedConfiguration3_7.operationMode = operationMode;
+ requestedConfiguration3_7.sessionParams.setToExternal(
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
+ sessionParamSize);
+
+ // See which version of HAL we have
+ if (mHidlSession_3_7 != nullptr) {
+ requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
+ requestedConfiguration3_7.multiResolutionInputImage =
+ config->input_is_multi_resolution;
+
+ const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
+ ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {};
+ hidlChars.setToExternal(
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata)),
+ get_camera_metadata_size(rawMetadata));
+ cameraCharacteristics.unlock(rawMetadata);
+
+ sp<hardware::camera::device::V3_7::ICameraInjectionSession>
+ hidlInjectionSession_3_7;
+ auto castInjectionResult_3_7 =
+ device::V3_7::ICameraInjectionSession::castFrom(mHidlSession_3_7);
+ if (castInjectionResult_3_7.isOk()) {
+ hidlInjectionSession_3_7 = castInjectionResult_3_7;
+ } else {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__,
+ castInjectionResult_3_7.description().c_str());
+ return DEAD_OBJECT;
+ }
+
+ auto err = hidlInjectionSession_3_7->configureInjectionStreams(
+ requestedConfiguration3_7, hidlChars);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__,
+ err.description().c_str());
+ return DEAD_OBJECT;
+ }
+ } else {
+ ALOGE("%s: mHidlSession_3_7 does not exist, the lowest version of injection "
+ "session is 3.7", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ return res;
+}
+
status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera_capture_request_t* request,
/*out*/device::V3_2::CaptureRequest* captureRequest,
/*out*/std::vector<native_handle_t*>* handlesCreated,
@@ -5724,6 +5883,18 @@
return changed;
}
+status_t Camera3Device::RequestThread::setHalInterface(
+ sp<HalInterface> newHalInterface) {
+ if (newHalInterface.get() == nullptr) {
+ ALOGE("%s: The newHalInterface does not exist!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ mInterface = newHalInterface;
+
+ return OK;
+}
+
/**
* PreparerThread inner class methods
*/
@@ -6367,4 +6538,58 @@
return mRequestThread->setCameraMute(enabled);
}
+status_t Camera3Device::injectCamera(const String8& injectedCamId,
+ sp<CameraProviderManager> manager) {
+ ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
+ ATRACE_CALL();
+ Mutex::Autolock il(mInterfaceLock);
+
+ status_t res = NO_ERROR;
+ if (mInjectionMethods->isInjecting()) {
+ if (injectedCamId == mInjectionMethods->getInjectedCamId()) {
+ return OK;
+ } else {
+ res = mInjectionMethods->stopInjection();
+ if (res != OK) {
+ ALOGE("%s: Failed to stop the injection camera! ret != NO_ERROR: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+ }
+ }
+
+ res = mInjectionMethods->injectionInitialize(injectedCamId, manager, this);
+ if (res != OK) {
+ ALOGE("%s: Failed to initialize the injection camera! ret != NO_ERROR: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+
+ camera3::camera_stream_configuration injectionConfig;
+ std::vector<uint32_t> injectionBufferSizes;
+ mInjectionMethods->getInjectionConfig(&injectionConfig, &injectionBufferSizes);
+ // When the second display of android is cast to the remote device, and the opened camera is
+ // also cast to the second display, in this case, because the camera has configured the streams
+ // at this time, we can directly call injectCamera() to replace the internal camera with
+ // injection camera.
+ if (mOperatingMode >= 0 && injectionConfig.num_streams > 0
+ && injectionBufferSizes.size() > 0) {
+ ALOGV("%s: The opened camera is directly cast to the remote device.", __FUNCTION__);
+ res = mInjectionMethods->injectCamera(
+ injectionConfig, injectionBufferSizes);
+ if (res != OK) {
+ ALOGE("Can't finish inject camera process!");
+ return res;
+ }
+ }
+
+ return OK;
+}
+
+status_t Camera3Device::stopInjection() {
+ ALOGI("%s: Injection camera: stopInjection", __FUNCTION__);
+ Mutex::Autolock il(mInterfaceLock);
+ return mInjectionMethods->stopInjection();
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d9e89fd..f962c78 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -263,6 +263,18 @@
wp<camera3::StatusTracker> getStatusTracker() { return mStatusTracker; }
/**
+ * The injection camera session to replace the internal camera
+ * session.
+ */
+ status_t injectCamera(const String8& injectedCamId,
+ sp<CameraProviderManager> manager);
+
+ /**
+ * Stop the injection camera and restore to internal camera session.
+ */
+ status_t stopInjection();
+
+ /**
* Helper functions to map between framework and HIDL values
*/
static hardware::graphics::common::V1_0::PixelFormat mapToPixelFormat(int frameworkFormat);
@@ -363,6 +375,13 @@
/*inout*/ camera_stream_configuration_t *config,
const std::vector<uint32_t>& bufferSizes);
+ // The injection camera configures the streams to hal.
+ status_t configureInjectedStreams(
+ const camera_metadata_t* sessionParams,
+ /*inout*/ camera_stream_configuration_t* config,
+ const std::vector<uint32_t>& bufferSizes,
+ const CameraMetadata& cameraCharacteristics);
+
// When the call succeeds, the ownership of acquire fences in requests is transferred to
// HalInterface. More specifically, the current implementation will send the fence to
// HAL process and close the FD in cameraserver process. When the call fails, the ownership
@@ -900,6 +919,9 @@
camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue);
status_t setCameraMute(bool enabled);
+
+ status_t setHalInterface(sp<HalInterface> newHalInterface);
+
protected:
virtual bool threadLoop();
@@ -1321,6 +1343,75 @@
// Whether the HAL supports camera muting via test pattern
bool mSupportCameraMute = false;
+ // Injection camera related methods.
+ class Camera3DeviceInjectionMethods : public virtual RefBase {
+ public:
+ Camera3DeviceInjectionMethods(wp<Camera3Device> parent);
+
+ ~Camera3DeviceInjectionMethods();
+
+ // Initialize the injection camera and generate an hal interface.
+ status_t injectionInitialize(
+ const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const sp<
+ android::hardware::camera::device::V3_2 ::ICameraDeviceCallback>&
+ callback);
+
+ // Injection camera will replace the internal camera and configure streams
+ // when device is IDLE and request thread is paused.
+ status_t injectCamera(
+ camera3::camera_stream_configuration& injectionConfig,
+ std::vector<uint32_t>& injectionBufferSizes);
+
+ // Stop the injection camera and switch back to backup hal interface.
+ status_t stopInjection();
+
+ bool isInjecting();
+
+ const String8& getInjectedCamId() const;
+
+ void getInjectionConfig(/*out*/ camera3::camera_stream_configuration* injectionConfig,
+ /*out*/ std::vector<uint32_t>* injectionBufferSizes);
+
+ private:
+ // Configure the streams of injection camera, it need wait until the
+ // output streams are created and configured to the original camera before
+ // proceeding.
+ status_t injectionConfigureStreams(
+ camera3::camera_stream_configuration& injectionConfig,
+ std::vector<uint32_t>& injectionBufferSizes);
+
+ // Disconnect the injection camera and delete the hal interface.
+ void injectionDisconnectImpl();
+
+ // Use injection camera hal interface to replace and backup original
+ // camera hal interface.
+ status_t replaceHalInterface(sp<HalInterface> newHalInterface,
+ bool keepBackup);
+
+ wp<Camera3Device> mParent;
+
+ // Backup of the original camera hal interface.
+ sp<HalInterface> mBackupHalInterface;
+
+ // Generated injection camera hal interface.
+ sp<HalInterface> mInjectedCamHalInterface;
+
+ // Copy the configuration of the internal camera.
+ camera3::camera_stream_configuration mInjectionConfig;
+
+ // Copy the bufferSizes of the output streams of the internal camera.
+ std::vector<uint32_t> mInjectionBufferSizes;
+
+ // Synchronizes access to injection camera between initialize and
+ // disconnect.
+ Mutex mInjectionLock;
+
+ // The injection camera ID.
+ String8 mInjectedCamId;
+ };
+ sp<Camera3DeviceInjectionMethods> mInjectionMethods;
+
}; // class Camera3Device
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
new file mode 100644
index 0000000..f145dac
--- /dev/null
+++ b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define LOG_TAG "Camera3DeviceInjectionMethods"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "common/CameraProviderManager.h"
+#include "device3/Camera3Device.h"
+
+namespace android {
+
+using hardware::camera::device::V3_2::ICameraDeviceSession;
+
+Camera3Device::Camera3DeviceInjectionMethods::Camera3DeviceInjectionMethods(
+ wp<Camera3Device> parent)
+ : mParent(parent) {
+ ALOGV("%s: Created injection camera methods", __FUNCTION__);
+}
+
+Camera3Device::Camera3DeviceInjectionMethods::~Camera3DeviceInjectionMethods() {
+ ALOGV("%s: Removed injection camera methods", __FUNCTION__);
+ injectionDisconnectImpl();
+}
+
+status_t Camera3Device::Camera3DeviceInjectionMethods::injectionInitialize(
+ const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const sp<android::hardware::camera::device::V3_2::ICameraDeviceCallback>&
+ callback) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mInjectionLock);
+
+ if (manager == nullptr) {
+ ALOGE("%s: manager does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ mInjectedCamId = injectedCamId;
+ sp<ICameraDeviceSession> session;
+ ATRACE_BEGIN("Injection CameraHal::openSession");
+ status_t res = manager->openSession(injectedCamId.string(), callback,
+ /*out*/ &session);
+ ATRACE_END();
+ if (res != OK) {
+ ALOGE("Injection camera could not open camera session: %s (%d)",
+ strerror(-res), res);
+ return res;
+ }
+
+ std::shared_ptr<RequestMetadataQueue> queue;
+ auto requestQueueRet =
+ session->getCaptureRequestMetadataQueue([&queue](const auto& descriptor) {
+ queue = std::make_shared<RequestMetadataQueue>(descriptor);
+ if (!queue->isValid() || queue->availableToWrite() <= 0) {
+ ALOGE("Injection camera HAL returns empty request metadata fmq, not "
+ "use it");
+ queue = nullptr;
+ // don't use the queue onwards.
+ }
+ });
+ if (!requestQueueRet.isOk()) {
+ ALOGE("Injection camera transaction error when getting request metadata fmq: "
+ "%s, not use it", requestQueueRet.description().c_str());
+ return DEAD_OBJECT;
+ }
+
+ std::unique_ptr<ResultMetadataQueue>& resQueue = parent->mResultMetadataQueue;
+ auto resultQueueRet = session->getCaptureResultMetadataQueue(
+ [&resQueue](const auto& descriptor) {
+ resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
+ if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
+ ALOGE("Injection camera HAL returns empty result metadata fmq, not use "
+ "it");
+ resQueue = nullptr;
+ // Don't use the resQueue onwards.
+ }
+ });
+ if (!resultQueueRet.isOk()) {
+ ALOGE("Injection camera transaction error when getting result metadata queue "
+ "from camera session: %s", resultQueueRet.description().c_str());
+ return DEAD_OBJECT;
+ }
+ IF_ALOGV() {
+ session->interfaceChain(
+ [](::android::hardware::hidl_vec<::android::hardware::hidl_string>
+ interfaceChain) {
+ ALOGV("Injection camera session interface chain:");
+ for (const auto& iface : interfaceChain) {
+ ALOGV(" %s", iface.c_str());
+ }
+ });
+ }
+
+ ALOGV("%s: Injection camera interface = new HalInterface()", __FUNCTION__);
+ mInjectedCamHalInterface =
+ new HalInterface(session, queue, parent->mUseHalBufManager,
+ parent->mSupportOfflineProcessing);
+ if (mInjectedCamHalInterface == nullptr) {
+ ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ return OK;
+}
+
+status_t Camera3Device::Camera3DeviceInjectionMethods::injectCamera(
+ camera3::camera_stream_configuration& injectionConfig,
+ std::vector<uint32_t>& injectionBufferSizes) {
+ status_t res = NO_ERROR;
+ mInjectionConfig = injectionConfig;
+ mInjectionBufferSizes = injectionBufferSizes;
+
+ if (mInjectedCamHalInterface == nullptr) {
+ ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ nsecs_t maxExpectedDuration = parent->getExpectedInFlightDuration();
+ bool wasActive = false;
+ if (parent->mStatus == STATUS_ACTIVE) {
+ ALOGV("%s: Let the device be IDLE and the request thread is paused",
+ __FUNCTION__);
+ parent->mPauseStateNotify = true;
+ res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
+ if (res != OK) {
+ ALOGE("%s: Can't pause captures to inject camera!", __FUNCTION__);
+ return res;
+ }
+ wasActive = true;
+ }
+
+ ALOGV("%s: Injection camera: replaceHalInterface", __FUNCTION__);
+ res = replaceHalInterface(mInjectedCamHalInterface, true);
+ if (res != OK) {
+ ALOGE("%s: Failed to replace the new HalInterface!", __FUNCTION__);
+ injectionDisconnectImpl();
+ return res;
+ }
+
+ res = parent->mRequestThread->setHalInterface(mInjectedCamHalInterface);
+ if (res != OK) {
+ ALOGE("%s: Failed to set new HalInterface in RequestThread!", __FUNCTION__);
+ replaceHalInterface(mBackupHalInterface, false);
+ injectionDisconnectImpl();
+ return res;
+ }
+
+ parent->mNeedConfig = true;
+ res = injectionConfigureStreams(injectionConfig, injectionBufferSizes);
+ parent->mNeedConfig = false;
+ if (res != OK) {
+ ALOGE("Can't injectionConfigureStreams device for streams: %d: %s "
+ "(%d)", parent->mNextStreamId, strerror(-res), res);
+ replaceHalInterface(mBackupHalInterface, false);
+ injectionDisconnectImpl();
+ return res;
+ }
+
+ if (wasActive) {
+ ALOGV("%s: Restarting activity to inject camera", __FUNCTION__);
+ // Reuse current operating mode and session parameters for new stream
+ // config.
+ parent->internalUpdateStatusLocked(STATUS_ACTIVE);
+ }
+
+ return OK;
+}
+
+status_t Camera3Device::Camera3DeviceInjectionMethods::stopInjection() {
+ status_t res = NO_ERROR;
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ nsecs_t maxExpectedDuration = parent->getExpectedInFlightDuration();
+ bool wasActive = false;
+ if (parent->mStatus == STATUS_ACTIVE) {
+ ALOGV("%s: Let the device be IDLE and the request thread is paused",
+ __FUNCTION__);
+ parent->mPauseStateNotify = true;
+ res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
+ if (res != OK) {
+ ALOGE("%s: Can't pause captures to stop injection!", __FUNCTION__);
+ return res;
+ }
+ wasActive = true;
+ }
+
+ res = replaceHalInterface(mBackupHalInterface, false);
+ if (res != OK) {
+ ALOGE("%s: Failed to restore the backup HalInterface!", __FUNCTION__);
+ injectionDisconnectImpl();
+ return res;
+ }
+ injectionDisconnectImpl();
+
+ if (wasActive) {
+ ALOGV("%s: Restarting activity to stop injection", __FUNCTION__);
+ // Reuse current operating mode and session parameters for new stream
+ // config.
+ parent->internalUpdateStatusLocked(STATUS_ACTIVE);
+ }
+
+ return OK;
+}
+
+bool Camera3Device::Camera3DeviceInjectionMethods::isInjecting() {
+ if (mInjectedCamHalInterface == nullptr) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+const String8& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
+ const {
+ return mInjectedCamId;
+}
+
+void Camera3Device::Camera3DeviceInjectionMethods::getInjectionConfig(
+ /*out*/ camera3::camera_stream_configuration* injectionConfig,
+ /*out*/ std::vector<uint32_t>* injectionBufferSizes) {
+ if (injectionConfig == nullptr || injectionBufferSizes == nullptr) {
+ ALOGE("%s: Injection configuration arguments must not be null!", __FUNCTION__);
+ return;
+ }
+
+ *injectionConfig = mInjectionConfig;
+ *injectionBufferSizes = mInjectionBufferSizes;
+}
+
+
+status_t Camera3Device::Camera3DeviceInjectionMethods::injectionConfigureStreams(
+ camera3::camera_stream_configuration& injectionConfig,
+ std::vector<uint32_t>& injectionBufferSizes) {
+ ATRACE_CALL();
+ status_t res = NO_ERROR;
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ if (parent->mOperatingMode < 0) {
+ ALOGE("Invalid operating mode: %d", parent->mOperatingMode);
+ return BAD_VALUE;
+ }
+
+ // Start configuring the streams
+ ALOGV("%s: Injection camera %s: Starting stream configuration", __FUNCTION__,
+ mInjectedCamId.string());
+
+ parent->mPreparerThread->pause();
+
+ // Do the HAL configuration; will potentially touch stream
+ // max_buffers, usage, and priv fields, as well as data_space and format
+ // fields for IMPLEMENTATION_DEFINED formats.
+
+ const camera_metadata_t* sessionBuffer = parent->mSessionParams.getAndLock();
+ res = mInjectedCamHalInterface->configureInjectedStreams(
+ sessionBuffer, &injectionConfig, injectionBufferSizes,
+ parent->mDeviceInfo);
+ parent->mSessionParams.unlock(sessionBuffer);
+
+ if (res == BAD_VALUE) {
+ // HAL rejected this set of streams as unsupported, clean up config
+ // attempt and return to unconfigured state
+ ALOGE("Set of requested outputs not supported by HAL");
+ parent->cancelStreamsConfigurationLocked();
+ return BAD_VALUE;
+ } else if (res != OK) {
+ // Some other kind of error from configure_streams - this is not
+ // expected
+ ALOGE("Unable to configure streams with HAL: %s (%d)", strerror(-res),
+ res);
+ return res;
+ }
+
+ for (size_t i = 0; i < parent->mOutputStreams.size(); i++) {
+ sp<camera3::Camera3OutputStreamInterface> outputStream =
+ parent->mOutputStreams[i];
+ mInjectedCamHalInterface->onStreamReConfigured(outputStream->getId());
+ }
+
+ // Request thread needs to know to avoid using repeat-last-settings protocol
+ // across configure_streams() calls
+ parent->mRequestThread->configurationComplete(
+ parent->mIsConstrainedHighSpeedConfiguration, parent->mSessionParams,
+ parent->mGroupIdPhysicalCameraMap);
+
+ parent->internalUpdateStatusLocked(STATUS_CONFIGURED);
+
+ ALOGV("%s: Injection camera %s: Stream configuration complete", __FUNCTION__,
+ mInjectedCamId.string());
+
+ auto rc = parent->mPreparerThread->resume();
+
+ if (rc != OK) {
+ ALOGE("%s: Injection camera %s: Preparer thread failed to resume!",
+ __FUNCTION__, mInjectedCamId.string());
+ return rc;
+ }
+
+ return OK;
+}
+
+void Camera3Device::Camera3DeviceInjectionMethods::injectionDisconnectImpl() {
+ ATRACE_CALL();
+ ALOGI("%s: Injection camera disconnect", __FUNCTION__);
+
+ mBackupHalInterface = nullptr;
+ HalInterface* interface = nullptr;
+ {
+ Mutex::Autolock lock(mInjectionLock);
+ if (mInjectedCamHalInterface != nullptr) {
+ interface = mInjectedCamHalInterface.get();
+ // Call close without internal mutex held, as the HAL close may need
+ // to wait on assorted callbacks,etc, to complete before it can
+ // return.
+ }
+ }
+
+ if (interface != nullptr) {
+ interface->close();
+ }
+
+ {
+ Mutex::Autolock lock(mInjectionLock);
+ if (mInjectedCamHalInterface != nullptr) {
+ mInjectedCamHalInterface->clear();
+ mInjectedCamHalInterface = nullptr;
+ }
+ }
+}
+
+status_t Camera3Device::Camera3DeviceInjectionMethods::replaceHalInterface(
+ sp<HalInterface> newHalInterface, bool keepBackup) {
+ Mutex::Autolock lock(mInjectionLock);
+ if (newHalInterface.get() == nullptr) {
+ ALOGE("%s: The newHalInterface does not exist, to stop replacing.",
+ __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ if (keepBackup && mBackupHalInterface == nullptr) {
+ mBackupHalInterface = parent->mInterface;
+ } else if (!keepBackup) {
+ mBackupHalInterface = nullptr;
+ }
+ parent->mInterface = newHalInterface;
+
+ return OK;
+}
+
+}; // namespace android
diff --git a/services/mediametrics/statsd_extractor.cpp b/services/mediametrics/statsd_extractor.cpp
index 281a4ce..2378f33 100644
--- a/services/mediametrics/statsd_extractor.cpp
+++ b/services/mediametrics/statsd_extractor.cpp
@@ -52,9 +52,6 @@
//
::android::stats::mediametrics::ExtractorData metrics_proto;
- // flesh out the protobuf we'll hand off with our data
- //
-
std::string format;
if (item->getString("android.media.mediaextractor.fmt", &format)) {
metrics_proto.set_format(format);
@@ -86,7 +83,6 @@
metrics_proto.set_entry_point(entry_point);
}
- // android.media.mediaextractor.logSessionId string
std::string log_session_id;
if (item->getString("android.media.mediaextractor.logSessionId", &log_session_id)) {
metrics_proto.set_log_session_id(log_session_id);
diff --git a/services/mediametrics/statsd_mediaparser.cpp b/services/mediametrics/statsd_mediaparser.cpp
index 6cceb06..af2946b 100644
--- a/services/mediametrics/statsd_mediaparser.cpp
+++ b/services/mediametrics/statsd_mediaparser.cpp
@@ -39,7 +39,6 @@
bool statsd_mediaparser(const std::shared_ptr<const mediametrics::Item>& item,
const std::shared_ptr<mediametrics::StatsdLog>& statsdLog)
{
- static constexpr bool enabled_statsd = true; // TODO: Remove, dup with dump2StatsdInternal().
if (item == nullptr) return false;
const nsecs_t timestamp_nanos = MediaMetricsService::roundTime(item->getTimestamp());
@@ -82,28 +81,25 @@
std::string logSessionId;
item->getString("android.media.mediaparser.logSessionId", &logSessionId);
- if (enabled_statsd) {
- (void) android::util::stats_write(android::util::MEDIAMETRICS_MEDIAPARSER_REPORTED,
- timestamp_nanos,
- package_name.c_str(),
- package_version_code,
- parserName.c_str(),
- createdByName,
- parserPool.c_str(),
- lastException.c_str(),
- resourceByteCount,
- durationMillis,
- trackMimeTypes.c_str(),
- trackCodecs.c_str(),
- alteredParameters.c_str(),
- videoWidth,
- videoHeight,
- logSessionId.c_str());
- } else {
- ALOGV("NOT sending MediaParser media metrics.");
- }
+ int result = android::util::stats_write(android::util::MEDIAMETRICS_MEDIAPARSER_REPORTED,
+ timestamp_nanos,
+ package_name.c_str(),
+ package_version_code,
+ parserName.c_str(),
+ createdByName,
+ parserPool.c_str(),
+ lastException.c_str(),
+ resourceByteCount,
+ durationMillis,
+ trackMimeTypes.c_str(),
+ trackCodecs.c_str(),
+ alteredParameters.c_str(),
+ videoWidth,
+ videoHeight,
+ logSessionId.c_str());
+
std::stringstream log;
- log << "result:" << "(result)" << " {"
+ log << "result:" << result << " {"
<< " mediametrics_mediaparser_reported:"
<< android::util::MEDIAMETRICS_MEDIAPARSER_REPORTED
<< " timestamp_nanos:" << timestamp_nanos