MediaPlayer2: create MP2AudioOutput in constructor
Move MP2AudioOutput creator from setDataSource() to constructor.
Test: MediaPlayer2Test, RoutingTest
Change-Id: Ibe19c8a259c735ea2b5822f769babaf4d7f2bed0
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 297d11b..cb474f4 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -3524,6 +3524,8 @@
* <p>Some devices may choose to provide a second set of calibration
* information for improved quality, including
* ACAMERA_SENSOR_REFERENCE_ILLUMINANT2 and its corresponding matrices.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM1
* @see ACAMERA_SENSOR_COLOR_TRANSFORM1
@@ -3553,6 +3555,8 @@
* <p>If this key is present, then ACAMERA_SENSOR_COLOR_TRANSFORM2,
* ACAMERA_SENSOR_CALIBRATION_TRANSFORM2, and
* ACAMERA_SENSOR_FORWARD_MATRIX2 will also be present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM2
* @see ACAMERA_SENSOR_COLOR_TRANSFORM2
@@ -3580,6 +3584,8 @@
* colorspace) into this camera device's native sensor color
* space under the first reference illuminant
* (ACAMERA_SENSOR_REFERENCE_ILLUMINANT1).</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
*/
@@ -3607,6 +3613,8 @@
* (ACAMERA_SENSOR_REFERENCE_ILLUMINANT2).</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
*/
@@ -3635,6 +3643,8 @@
* and the CIE XYZ colorspace when calculating this transform will
* match the standard white point for the first reference illuminant
* (i.e. no chromatic adaptation will be applied by this transform).</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
*/
@@ -3665,6 +3675,8 @@
* (i.e. no chromatic adaptation will be applied by this transform).</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
*/
@@ -3691,6 +3703,8 @@
* this matrix is chosen so that the standard white point for this reference
* illuminant in the reference sensor colorspace is mapped to D50 in the
* CIE XYZ colorspace.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
*/
@@ -3719,6 +3733,8 @@
* CIE XYZ colorspace.</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*
* @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
*/
@@ -3751,6 +3767,7 @@
* level values. For raw capture in particular, it is recommended to use
* pixels from ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS to calculate black
* level values for each frame.</p>
+ * <p>For a MONOCHROME camera device, all of the 2x2 channels must have the same values.</p>
*
* @see ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL
* @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -3845,6 +3862,8 @@
* used to interpolate between the provided color transforms when
* processing raw sensor data.</p>
* <p>The order of the values is R, G, B; where R is in the lowest index.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*/
ACAMERA_SENSOR_NEUTRAL_COLOR_POINT = // rational[3]
ACAMERA_SENSOR_START + 18,
@@ -3875,6 +3894,8 @@
* that channel.</p>
* <p>A more detailed description of the noise model can be found in the
* Adobe DNG specification for the NoiseProfile tag.</p>
+ * <p>For a MONOCHROME camera, there is only one color channel. So the noise model coefficients
+ * will only contain one S and one O.</p>
*
* @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
*/
@@ -3920,6 +3941,8 @@
* <li>R > 1.20 will require strong software correction to produce
* a usuable image (>20% divergence).</li>
* </ul>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
*/
ACAMERA_SENSOR_GREEN_SPLIT = // float
ACAMERA_SENSOR_START + 22,
@@ -4072,6 +4095,7 @@
* layout key (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT), i.e. the
* nth value given corresponds to the black level offset for the nth
* color channel listed in the CFA.</p>
+ * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values.</p>
* <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is available or the
* camera device advertises this key via {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS }.</p>
*
@@ -4174,7 +4198,8 @@
/**
* <p>The arrangement of color filters on sensor;
* represents the colors in the top-left 2x2 section of
- * the sensor, in reading order.</p>
+ * the sensor, in reading order, for a Bayer camera, or the
+ * light spectrum it captures for MONOCHROME camera.</p>
*
* <p>Type: byte (acamera_metadata_enum_android_sensor_info_color_filter_arrangement_t)</p>
*
@@ -4643,13 +4668,13 @@
* (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
* pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
* The map is assumed to be bilinearly interpolated between the sample points.</p>
- * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
- * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+ * <p>For a Bayer camera, the channel order is [R, Geven, Godd, B], where Geven is
+ * the green channel for the even rows of a Bayer pattern, and Godd is the odd rows.
* The shading map is stored in a fully interleaved format, and its size
* is provided in the camera static metadata by ACAMERA_LENS_INFO_SHADING_MAP_SIZE.</p>
* <p>The shading map will generally have on the order of 30-40 rows and columns,
* and will be smaller than 64x64.</p>
- * <p>As an example, given a very small map defined as:</p>
+ * <p>As an example, given a very small map for a Bayer camera defined as:</p>
* <pre><code>ACAMERA_LENS_INFO_SHADING_MAP_SIZE = [ 4, 3 ]
* ACAMERA_STATISTICS_LENS_SHADING_MAP =
* [ 1.3, 1.2, 1.15, 1.2, 1.2, 1.2, 1.15, 1.2,
@@ -4669,6 +4694,17 @@
* image of a gray wall (using bicubic interpolation for visual quality)
* as captured by the sensor gives:</p>
* <p><img alt="Image of a uniform white wall (inverse shading map)" src="../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+ * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example
+ * shading map for such a camera is defined as:</p>
+ * <pre><code>ACAMERA_LENS_INFO_SHADING_MAP_SIZE = [ 4, 3 ]
+ * ACAMERA_STATISTICS_LENS_SHADING_MAP =
+ * [ 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.1, 1.1, 1.1, 1.1, 1.3, 1.3, 1.3, 1.3,
+ * 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1,
+ * 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.2, 1.2,
+ * 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.2, 1.2, 1.2, 1.2, 1.3, 1.3, 1.3, 1.3 ]
+ * </code></pre>
* <p>Note that the RAW image data might be subject to lens shading
* correction not reported on this map. Query
* ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED to see if RAW image data has subject
@@ -5012,8 +5048,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* ACAMERA_TONEMAP_MAX_CURVE_POINTS).</p>
- * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
- * are ignored.</p>
+ * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+ * control points.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
@@ -7373,11 +7409,15 @@
/**
* <p>The camera device is a monochrome camera that doesn't contain a color filter array,
- * and the pixel values on U and V planes are all 128.</p>
+ * and for YUV_420_888 stream, the pixel values on U and V planes are all 128.</p>
* <p>A MONOCHROME camera must support the guaranteed stream combinations required for
* its device level and capabilities. Additionally, if the monochrome camera device
* supports Y8 format, all mandatory stream combination requirements related to {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888} apply
- * to {@link AIMAGE_FORMAT_Y8 Y8} as well.</p>
+ * to {@link AIMAGE_FORMAT_Y8 Y8} as well. There are no
+ * mandatory stream combination requirements with regard to
+ * {@link AIMAGE_FORMAT_Y8 Y8} for Bayer camera devices.</p>
+ * <p>Starting from Android Q, the SENSOR_INFO_COLOR_FILTER_ARRANGEMENT of a MONOCHROME
+ * camera will be either MONO or NIR.</p>
*/
ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
@@ -7643,6 +7683,21 @@
*/
ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4,
+ /**
+ * <p>Sensor doesn't have any Bayer color filter.
+ * Such sensor captures visible light in monochrome. The exact weighting and
+ * wavelengths captured is not specified, but generally only includes the visible
+ * frequencies. This value implies a MONOCHROME camera.</p>
+ */
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5,
+
+ /**
+ * <p>Sensor has a near infrared filter capturing light with wavelength between
+ * roughly 750nm and 1400nm, and the same filter covers the whole sensor array. This
+ * value implies a MONOCHROME camera.</p>
+ */
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6,
+
} acamera_metadata_enum_android_sensor_info_color_filter_arrangement_t;
// ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 4991e50..94f9e02 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -32,6 +32,7 @@
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libhidlallocatorutils",
"libhidlbase",
"libhidltransport",
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index ce9dc38..14ff493 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -23,7 +23,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <android/hardware/drm/1.0/types.h>
+#include <android/hardware/drm/1.2/types.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
@@ -43,12 +43,13 @@
using drm::V1_0::KeyStatusType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
-using drm::V1_1::HdcpLevel;;
using drm::V1_0::SecureStop;
-using drm::V1_1::SecureStopRelease;
using drm::V1_0::SecureStopId;
-using drm::V1_1::SecurityLevel;
using drm::V1_0::Status;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::KeySetId;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
@@ -139,6 +140,18 @@
}
}
+static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
+ OfflineLicenseState licenseState) {
+ switch(licenseState) {
+ case OfflineLicenseState::USABLE:
+ return DrmPlugin::kOfflineLicenseStateUsable;
+ case OfflineLicenseState::INACTIVE:
+ return DrmPlugin::kOfflineLicenseStateInactive;
+ default:
+ return DrmPlugin::kOfflineLicenseStateUnknown;
+ }
+}
+
static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
switch(level) {
case HdcpLevel::HDCP_NONE:
@@ -199,6 +212,15 @@
return secureStopIds;
}
+static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
+ hKeySetIds) {
+ List<Vector<uint8_t>> keySetIds;
+ for (size_t i = 0; i < hKeySetIds.size(); i++) {
+ keySetIds.push_back(toVector(hKeySetIds[i]));
+ }
+ return keySetIds;
+}
+
static status_t toStatusT(Status status) {
switch (status) {
case Status::OK:
@@ -305,6 +327,7 @@
}
mPlugin.clear();
mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
@@ -333,6 +356,16 @@
}
}
);
+ manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
+ [&factories](const hidl_vec<hidl_string> ®istered) {
+ for (const auto &instance : registered) {
+ auto factory = drm::V1_2::IDrmFactory::getService(instance);
+ if (factory != NULL) {
+ factories.push_back(factory);
+ }
+ }
+ }
+ );
}
if (factories.size() == 0) {
@@ -525,6 +558,7 @@
mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
if (mPlugin != NULL) {
mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
+ mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
}
}
}
@@ -1063,6 +1097,73 @@
return hResult.isOk() ? err : DEAD_OBJECT;
}
+status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPluginV1_2 == NULL) {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ status_t err = UNKNOWN_ERROR;
+
+ Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
+ [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
+ if (status == Status::OK) {
+ keySetIds = toKeySetIds(hKeySetIds);
+ }
+ err = toStatusT(status);
+ }
+ );
+
+ return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
+status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPluginV1_2 == NULL) {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
+ return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+}
+
+status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ DrmPlugin::OfflineLicenseState *licenseState) const {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPluginV1_2 == NULL) {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
+ *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
+
+ status_t err = UNKNOWN_ERROR;
+
+ Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
+ [&](Status status, OfflineLicenseState hLicenseState) {
+ if (status == Status::OK) {
+ *licenseState = toOfflineLicenseState(hLicenseState);
+ }
+ err = toStatusT(status);
+ }
+ );
+
+ return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
Mutex::Autolock autoLock(mLock);
return getPropertyStringInternal(name, value);
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 509961f..8c26317 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -61,7 +61,10 @@
GET_NUMBER_OF_SESSIONS,
GET_SECURITY_LEVEL,
REMOVE_SECURE_STOP,
- GET_SECURE_STOP_IDS
+ GET_SECURE_STOP_IDS,
+ GET_OFFLINE_LICENSE_KEYSET_IDS,
+ REMOVE_OFFLINE_LICENSE,
+ GET_OFFLINE_LICENSE_STATE
};
struct BpDrm : public BpInterface<IDrm> {
@@ -376,6 +379,52 @@
return reply.readInt32();
}
+ virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t> > &keySetIds) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ status_t status = remote()->transact(GET_OFFLINE_LICENSE_KEYSET_IDS, data, &reply);
+ if (status != OK) {
+ return status;
+ }
+
+ keySetIds.clear();
+ uint32_t count = reply.readInt32();
+ for (size_t i = 0; i < count; i++) {
+ Vector<uint8_t> keySetId;
+ readVector(reply, keySetId);
+ keySetIds.push_back(keySetId);
+ }
+ return reply.readInt32();
+ }
+
+ virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, keySetId);
+ status_t status = remote()->transact(REMOVE_OFFLINE_LICENSE, data, &reply);
+ if (status != OK) {
+ return status;
+ }
+ return reply.readInt32();
+ }
+
+ virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ DrmPlugin::OfflineLicenseState *licenseState) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, keySetId);
+ status_t status = remote()->transact(GET_OFFLINE_LICENSE_STATE, data, &reply);
+ if (status != OK) {
+ *licenseState = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
+ return status;
+ }
+ *licenseState = static_cast<DrmPlugin::OfflineLicenseState>(reply.readInt32());
+ return reply.readInt32();
+ }
+
virtual status_t getPropertyString(String8 const &name, String8 &value) const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -980,6 +1029,45 @@
return OK;
}
+ case GET_OFFLINE_LICENSE_KEYSET_IDS:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ List<Vector<uint8_t> > keySetIds;
+ status_t result = getOfflineLicenseKeySetIds(keySetIds);
+ size_t count = keySetIds.size();
+ reply->writeInt32(count);
+ List<Vector<uint8_t> >::iterator iter = keySetIds.begin();
+ while(iter != keySetIds.end()) {
+ size_t size = iter->size();
+ reply->writeInt32(size);
+ reply->write(iter->array(), iter->size());
+ iter++;
+ }
+ reply->writeInt32(result);
+ return OK;
+ }
+
+ case REMOVE_OFFLINE_LICENSE:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> keySetId;
+ readVector(data, keySetId);
+ reply->writeInt32(removeOfflineLicense(keySetId));
+ return OK;
+ }
+
+ case GET_OFFLINE_LICENSE_STATE:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> keySetId;
+ readVector(data, keySetId);
+ DrmPlugin::OfflineLicenseState state;
+ status_t result = getOfflineLicenseState(keySetId, &state);
+ reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
+ reply->writeInt32(result);
+ return OK;
+ }
+
case GET_PROPERTY_STRING:
{
CHECK_INTERFACE(IDrm, data, reply);
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 66c906f..dcd59b7 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -17,6 +17,7 @@
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libbinder",
"libhidlbase",
"liblog",
diff --git a/include/soundtrigger/ISoundTrigger.h b/include/soundtrigger/ISoundTrigger.h
index ea1aea6..c357caa 100644
--- a/include/soundtrigger/ISoundTrigger.h
+++ b/include/soundtrigger/ISoundTrigger.h
@@ -40,8 +40,7 @@
virtual status_t startRecognition(sound_model_handle_t handle,
const sp<IMemory>& dataMemory) = 0;
virtual status_t stopRecognition(sound_model_handle_t handle) = 0;
- virtual status_t getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory) = 0;
+ virtual status_t getModelState(sound_model_handle_t handle) = 0;
};
diff --git a/include/soundtrigger/SoundTrigger.h b/include/soundtrigger/SoundTrigger.h
index dcf9ce8..2e2ff7a 100644
--- a/include/soundtrigger/SoundTrigger.h
+++ b/include/soundtrigger/SoundTrigger.h
@@ -52,7 +52,7 @@
status_t startRecognition(sound_model_handle_t handle, const sp<IMemory>& dataMemory);
status_t stopRecognition(sound_model_handle_t handle);
- status_t getModelState(sound_model_handle_t handle, sp<IMemory>& eventMemory);
+ status_t getModelState(sound_model_handle_t handle);
// BpSoundTriggerClient
virtual void onRecognitionEvent(const sp<IMemory>& eventMemory);
diff --git a/media/img_utils/include/img_utils/DngUtils.h b/media/img_utils/include/img_utils/DngUtils.h
index de8f120..8819f87 100644
--- a/media/img_utils/include/img_utils/DngUtils.h
+++ b/media/img_utils/include/img_utils/DngUtils.h
@@ -49,6 +49,7 @@
CFA_RGGB,
CFA_BGGR,
CFA_GBRG,
+ CFA_NONE,
};
OpcodeListBuilder();
@@ -89,7 +90,6 @@
CfaLayout cfa,
const float* lensShadingMap);
-
/**
* Add a GainMap opcode with the given fields. The mapGains array
* must have mapPointsV * mapPointsH * mapPlanes elements.
@@ -197,6 +197,33 @@
status_t addOpcodePreamble(uint32_t opcodeId);
+ private:
+ /**
+ * Add Bayer GainMap opcode(s) for the given metadata parameters.
+ * CFA layout must match the layout of the shading map passed into the
+ * lensShadingMap parameter.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ status_t addBayerGainMapsForMetadata(uint32_t lsmWidth,
+ uint32_t lsmHeight,
+ uint32_t activeAreaWidth,
+ uint32_t activeAreaHeight,
+ CfaLayout cfa,
+ const float* lensShadingMap);
+
+ /**
+ * Add Bayer GainMap opcode(s) for the given metadata parameters.
+ * CFA layout must match the layout of the shading map passed into the
+ * lensShadingMap parameter.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ status_t addMonochromeGainMapsForMetadata(uint32_t lsmWidth,
+ uint32_t lsmHeight,
+ uint32_t activeAreaWidth,
+ uint32_t activeAreaHeight,
+ const float* lensShadingMap);
};
} /*namespace img_utils*/
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index 9ac7e2a..9304f53 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -60,34 +60,36 @@
uint32_t activeAreaRight,
CfaLayout cfa,
const float* lensShadingMap) {
+ status_t err = OK;
uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
- double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
- double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
- std::vector<float> redMapVector(lsmWidth * lsmHeight);
- float *redMap = redMapVector.data();
-
- std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
- float *greenEvenMap = greenEvenMapVector.data();
-
- std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
- float *greenOddMap = greenOddMapVector.data();
-
- std::vector<float> blueMapVector(lsmWidth * lsmHeight);
- float *blueMap = blueMapVector.data();
-
- size_t lsmMapSize = lsmWidth * lsmHeight * 4;
-
- // Split lens shading map channels into separate arrays
- size_t j = 0;
- for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
- redMap[j] = lensShadingMap[i + LSM_R_IND];
- greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
- greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
- blueMap[j] = lensShadingMap[i + LSM_B_IND];
+ switch (cfa) {
+ case CFA_RGGB:
+ case CFA_GRBG:
+ case CFA_GBRG:
+ case CFA_BGGR:
+ err = addBayerGainMapsForMetadata(lsmWidth, lsmHeight, activeAreaWidth,
+ activeAreaHeight, cfa, lensShadingMap);
+ break;
+ case CFA_NONE:
+ err = addMonochromeGainMapsForMetadata(lsmWidth, lsmHeight, activeAreaWidth,
+ activeAreaHeight, lensShadingMap);
+ break;
+ default:
+ ALOGE("%s: Unknown CFA layout %d", __FUNCTION__, cfa);
+ err = BAD_VALUE;
+ break;
}
+ return err;
+}
+status_t OpcodeListBuilder::addBayerGainMapsForMetadata(uint32_t lsmWidth,
+ uint32_t lsmHeight,
+ uint32_t activeAreaWidth,
+ uint32_t activeAreaHeight,
+ CfaLayout cfa,
+ const float* lensShadingMap) {
uint32_t redTop = 0;
uint32_t redLeft = 0;
uint32_t greenEvenTop = 0;
@@ -143,6 +145,32 @@
return BAD_VALUE;
}
+ std::vector<float> redMapVector(lsmWidth * lsmHeight);
+ float *redMap = redMapVector.data();
+
+ std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
+ float *greenEvenMap = greenEvenMapVector.data();
+
+ std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
+ float *greenOddMap = greenOddMapVector.data();
+
+ std::vector<float> blueMapVector(lsmWidth * lsmHeight);
+ float *blueMap = blueMapVector.data();
+
+ double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
+ double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
+
+ size_t lsmMapSize = lsmWidth * lsmHeight * 4;
+
+ // Split lens shading map channels into separate arrays
+ size_t j = 0;
+ for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
+ redMap[j] = lensShadingMap[i + LSM_R_IND];
+ greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
+ greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
+ blueMap[j] = lensShadingMap[i + LSM_B_IND];
+ }
+
status_t err = addGainMap(/*top*/redTop,
/*left*/redLeft,
/*bottom*/activeAreaHeight - 1,
@@ -216,6 +244,46 @@
return err;
}
+status_t OpcodeListBuilder::addMonochromeGainMapsForMetadata(uint32_t lsmWidth,
+ uint32_t lsmHeight,
+ uint32_t activeAreaWidth,
+ uint32_t activeAreaHeight,
+ const float* lensShadingMap) {
+ std::vector<float> mapVector(lsmWidth * lsmHeight);
+ float *map = mapVector.data();
+
+ double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
+ double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
+
+ size_t lsmMapSize = lsmWidth * lsmHeight * 4;
+
+ // Split lens shading map channels into separate arrays
+ size_t j = 0;
+ for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
+ map[j] = lensShadingMap[i];
+ }
+
+ status_t err = addGainMap(/*top*/0,
+ /*left*/0,
+ /*bottom*/activeAreaHeight - 1,
+ /*right*/activeAreaWidth - 1,
+ /*plane*/0,
+ /*planes*/1,
+ /*rowPitch*/1,
+ /*colPitch*/1,
+ /*mapPointsV*/lsmHeight,
+ /*mapPointsH*/lsmWidth,
+ /*mapSpacingV*/spacingV,
+ /*mapSpacingH*/spacingH,
+ /*mapOriginV*/0,
+ /*mapOriginH*/0,
+ /*mapPlanes*/1,
+ /*mapGains*/map);
+ if (err != OK) return err;
+
+ return err;
+}
+
status_t OpcodeListBuilder::addGainMap(uint32_t top,
uint32_t left,
uint32_t bottom,
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index f267f76..3302982 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -23,6 +23,8 @@
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@@ -36,6 +38,7 @@
using drm::V1_0::IDrmPlugin;
using drm::V1_0::IDrmPluginListener;
using drm::V1_0::KeyStatus;
+using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
@@ -113,6 +116,11 @@
virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const;
+ virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
+ virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
+ virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ DrmPlugin::OfflineLicenseState *licenseState) const;
+
virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
virtual status_t getPropertyByteArray(String8 const &name,
Vector<uint8_t> &value ) const;
@@ -182,6 +190,7 @@
const Vector<sp<IDrmFactory>> mFactories;
sp<IDrmPlugin> mPlugin;
sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
+ sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
String8 mAppPackageName;
// Mutable to allow modification within GetPropertyByteArray.
diff --git a/media/libmedia/include/media/IDrm.h b/media/libmedia/include/media/IDrm.h
index 8e9eb3a..49166c6 100644
--- a/media/libmedia/include/media/IDrm.h
+++ b/media/libmedia/include/media/IDrm.h
@@ -75,8 +75,8 @@
Vector<uint8_t> &certificate,
Vector<uint8_t> &wrappedKey) = 0;
- virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
- virtual status_t getSecureStopIds(List<Vector<uint8_t> > &secureStopIds) = 0;
+ virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops) = 0;
+ virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) = 0;
virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
@@ -91,6 +91,11 @@
virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const = 0;
+ virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const = 0;
+ virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) = 0;
+ virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ DrmPlugin::OfflineLicenseState *licenseState) const = 0;
+
virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
virtual status_t getPropertyByteArray(String8 const &name,
Vector<uint8_t> &value) const = 0;
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index f7e8a9d..3040c2d 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -60,7 +60,7 @@
}
MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(audio_session_t sessionId, uid_t uid, int pid,
- const jobject attributes, std::vector<jobject>& routingDelegatesBackup)
+ const jobject attributes)
: mCallback(nullptr),
mCallbackCookie(nullptr),
mCallbackData(nullptr),
@@ -77,20 +77,12 @@
mFlags(AUDIO_OUTPUT_FLAG_NONE) {
ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
- if (mAttributes != nullptr) {
- mAttributes->~JObjectHolder();
- }
if (attributes != nullptr) {
mAttributes = new JObjectHolder(attributes);
}
setMinBufferCount();
mRoutingDelegates.clear();
- for (auto routingDelegate : routingDelegatesBackup) {
- mRoutingDelegates.push_back(std::pair<jobject, jobject>(
- JAudioTrack::getListener(routingDelegate), routingDelegate));
- }
- routingDelegatesBackup.clear();
}
MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
@@ -251,11 +243,8 @@
void MediaPlayer2AudioOutput::setAudioAttributes(const jobject attributes) {
Mutex::Autolock lock(mLock);
- if (mAttributes != nullptr) {
- mAttributes->~JObjectHolder();
- }
if (attributes != nullptr) {
- mAttributes = new JObjectHolder(attributes);
+ sp<JObjectHolder> x = new JObjectHolder(attributes);
}
}
@@ -564,15 +553,6 @@
return NO_ERROR;
}
-void MediaPlayer2AudioOutput::copyAudioDeviceCallback(
- std::vector<jobject>& routingDelegateTarget) {
- ALOGV("copyAudioDeviceCallback");
- for (std::vector<std::pair<jobject, jobject>>::iterator it = mRoutingDelegates.begin();
- it != mRoutingDelegates.end(); it++) {
- routingDelegateTarget.push_back(it->second);
- }
-}
-
// static
void MediaPlayer2AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
@@ -650,6 +630,11 @@
return mSessionId;
}
+void MediaPlayer2AudioOutput::setSessionId(const audio_session_t id) {
+ Mutex::Autolock lock(mLock);
+ mSessionId = id;
+}
+
uint32_t MediaPlayer2AudioOutput::getSampleRate() const {
Mutex::Autolock lock(mLock);
if (mJAudioTrack == 0) {
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index decd9f9..fc020ca 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -41,8 +41,7 @@
MediaPlayer2AudioOutput(audio_session_t sessionId,
uid_t uid,
int pid,
- const jobject attributes,
- std::vector<jobject>& routingDelegatesBackup);
+ const jobject attributes);
virtual ~MediaPlayer2AudioOutput();
virtual bool ready() const {
@@ -59,6 +58,7 @@
virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
virtual status_t getFramesWritten(uint32_t *frameswritten) const;
virtual audio_session_t getSessionId() const;
+ virtual void setSessionId(const audio_session_t id);
virtual uint32_t getSampleRate() const;
virtual int64_t getBufferDurationInUs() const;
@@ -99,7 +99,6 @@
virtual jobject getRoutedDevice();
virtual status_t addAudioDeviceCallback(jobject routingDelegate);
virtual status_t removeAudioDeviceCallback(jobject listener);
- virtual void copyAudioDeviceCallback(std::vector<jobject>& routingDelegateTarget);
private:
static void setMinBufferCount();
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index 0aaab7b..d881813 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -26,7 +26,6 @@
#include <mediaplayer2/MediaPlayer2Types.h>
#include <mediaplayer2/JObjectHolder.h>
-#include <vector>
#include <jni.h>
#include <utils/Errors.h>
#include <utils/Mutex.h>
@@ -154,7 +153,6 @@
audio_session_t mAudioSessionId;
sp<JObjectHolder> mAudioAttributes;
float mSendLevel;
- std::vector<jobject> mRoutingDelegates;
sp<ANativeWindowWrapper> mConnectedWindow;
};
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 07442a1..04a6f68 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -258,6 +258,8 @@
// TODO: get pid and uid from JAVA
mPid = IPCThreadState::self()->getCallingPid();
mUid = IPCThreadState::self()->getCallingUid();
+
+ mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid, mPid, NULL /*attributes*/);
}
MediaPlayer2::~MediaPlayer2() {
@@ -352,14 +354,7 @@
clear_l();
- if (mAudioOutput != NULL) {
- mAudioOutput->copyAudioDeviceCallback(mRoutingDelegates);
- }
-
player->setListener(new proxyListener(this));
- mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
- mPid, mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL,
- mRoutingDelegates);
player->setAudioSink(mAudioOutput);
err = player->setDataSource(dsd);
@@ -911,6 +906,9 @@
AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
mAudioSessionId = sessionId;
}
+ if (mAudioOutput != NULL && mAudioSessionId != mAudioOutput->getSessionId()) {
+ mAudioOutput->setSessionId(sessionId);
+ }
return NO_ERROR;
}
@@ -1184,7 +1182,6 @@
Mutex::Autolock _l(mLock);
if (mAudioOutput == NULL) {
ALOGV("addAudioDeviceCallback: player not init");
- mRoutingDelegates.push_back(routingDelegate);
return NO_INIT;
}
return mAudioOutput->addAudioDeviceCallback(routingDelegate);
diff --git a/media/libmediaplayerservice/tests/Android.bp b/media/libmediaplayerservice/tests/Android.bp
index e86b68a..4749a8b 100644
--- a/media/libmediaplayerservice/tests/Android.bp
+++ b/media/libmediaplayerservice/tests/Android.bp
@@ -11,6 +11,7 @@
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
],
compile_multilib: "32",
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 5eb5ba6..17507cd 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -407,7 +407,7 @@
return;
}
mSpeed = speed;
- if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+ if (mMediaPlayer != null && mMediaPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING) {
applySpeed();
}
updatePlaybackState();
@@ -1341,7 +1341,7 @@
if (isRemotePlayback()) {
mRoutePlayer.onPause();
mCurrentState = STATE_PAUSED;
- } else if (mMediaPlayer.isPlaying()) {
+ } else if (mMediaPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING) {
mMediaPlayer.pause();
mCurrentState = STATE_PAUSED;
updatePlaybackState();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index e69ce1f..d45be62 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -209,6 +209,14 @@
proxyBinder->pingForUserUpdate();
}
+void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (auto& i : mListenerList) {
+ i->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
+ }
+}
+
CameraService::~CameraService() {
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
mUidPolicy->unregisterSelf();
@@ -247,6 +255,8 @@
if (mFlashlight->hasFlashUnit(id)) {
Mutex::Autolock al(mTorchStatusMutex);
mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+
+ broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF);
}
updateCameraNumAndIds();
@@ -399,12 +409,7 @@
}
}
- {
- Mutex::Autolock lock(mStatusListenerLock);
- for (auto& i : mListenerList) {
- i->onTorchStatusChanged(mapToInterface(newStatus), String16{cameraId});
- }
- }
+ broadcastTorchModeStatus(cameraId, newStatus);
}
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 80d9ef4..064863f 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -857,6 +857,8 @@
static sp<hardware::ICameraServiceProxy> getCameraServiceProxy();
static void pingCameraServiceProxy();
+ void broadcastTorchModeStatus(const String8& cameraId,
+ hardware::camera::common::V1_0::TorchModeStatus status);
};
} // namespace android
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index a94e886..2542ab2 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -425,6 +425,102 @@
}
}
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
+ status_t res = OK;
+ auto& c = mCameraCharacteristics;
+
+ // Override static metadata for MONOCHROME camera with older device version
+ if (mVersion.get_major() == 3 && mVersion.get_minor() < 5) {
+ camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ for (size_t i = 0; i < cap.count; i++) {
+ if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
+ // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+ uint8_t cfa = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO;
+ res = c.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &cfa, 1);
+ if (res != OK) {
+ ALOGE("%s: Failed to update COLOR_FILTER_ARRANGEMENT: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ // ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
+ const std::vector<uint32_t> sKeys = {
+ ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
+ ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
+ ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
+ ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
+ ANDROID_SENSOR_COLOR_TRANSFORM1,
+ ANDROID_SENSOR_COLOR_TRANSFORM2,
+ ANDROID_SENSOR_FORWARD_MATRIX1,
+ ANDROID_SENSOR_FORWARD_MATRIX2,
+ };
+ res = removeAvailableKeys(c, sKeys,
+ ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+ if (res != OK) {
+ ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ // ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS
+ const std::vector<uint32_t> reqKeys = {
+ ANDROID_COLOR_CORRECTION_MODE,
+ ANDROID_COLOR_CORRECTION_TRANSFORM,
+ ANDROID_COLOR_CORRECTION_GAINS,
+ };
+ res = removeAvailableKeys(c, reqKeys, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+ if (res != OK) {
+ ALOGE("%s: Failed to update REQUEST_AVAILABLE_REQUEST_KEYS: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ // ANDROID_REQUEST_AVAILABLE_RESULT_KEYS
+ const std::vector<uint32_t> resKeys = {
+ ANDROID_SENSOR_GREEN_SPLIT,
+ ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+ ANDROID_COLOR_CORRECTION_MODE,
+ ANDROID_COLOR_CORRECTION_TRANSFORM,
+ ANDROID_COLOR_CORRECTION_GAINS,
+ };
+ res = removeAvailableKeys(c, resKeys, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
+ if (res != OK) {
+ ALOGE("%s: Failed to update REQUEST_AVAILABLE_RESULT_KEYS: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ // ANDROID_SENSOR_BLACK_LEVEL_PATTERN
+ camera_metadata_entry blEntry = c.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
+ for (size_t j = 1; j < blEntry.count; j++) {
+ blEntry.data.i32[j] = blEntry.data.i32[0];
+ }
+ }
+ }
+ }
+ return res;
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
+ CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
+ status_t res = OK;
+
+ camera_metadata_entry keysEntry = c.find(keyTag);
+ if (keysEntry.count == 0) {
+ ALOGE("%s: Failed to find tag %u: %s (%d)", __FUNCTION__, keyTag, strerror(-res), res);
+ return res;
+ }
+ std::vector<int32_t> vKeys;
+ vKeys.reserve(keysEntry.count);
+ for (size_t i = 0; i < keysEntry.count; i++) {
+ if (std::find(keys.begin(), keys.end(), keysEntry.data.i32[i]) == keys.end()) {
+ vKeys.push_back(keysEntry.data.i32[i]);
+ }
+ }
+ res = c.update(keyTag, vKeys.data(), vKeys.size());
+ return res;
+}
+
bool CameraProviderManager::isLogicalCamera(const std::string& id,
std::vector<std::string>* physicalCameraIds) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
@@ -1131,6 +1227,12 @@
__FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
return;
}
+ status_t res = fixupMonochromeTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return;
+ }
camera_metadata_entry flashAvailable =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
if (flashAvailable.count == 1 &&
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 9016747..c506d35 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -385,6 +385,9 @@
CameraMetadata mCameraCharacteristics;
std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics;
void queryPhysicalCameraIds();
+ status_t fixupMonochromeTags();
+ status_t removeAvailableKeys(CameraMetadata& c, const std::vector<uint32_t>& keys,
+ uint32_t keyTag);
};
private:
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 7d41256..58471b9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -79,7 +79,8 @@
mNextReprocessShutterFrameNumber(0),
mListener(NULL),
mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
- mLastTemplateId(-1)
+ mLastTemplateId(-1),
+ mNeedFixupMonochromeTags(false)
{
ATRACE_CALL();
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
@@ -188,6 +189,28 @@
mTagMonitor.parseTagsToMonitor(String8(monitorTags));
}
+ // Metadata tags needs fixup for monochrome camera device version less
+ // than 3.5.
+ hardware::hidl_version maxVersion{0,0};
+ res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
+ if (res != OK) {
+ ALOGE("%s: Error in getting camera device version id: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(
+ maxVersion.get_major(), maxVersion.get_minor());
+
+ bool isMonochrome = false;
+ camera_metadata_entry_t entry = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ for (size_t i = 0; i < entry.count; i++) {
+ uint8_t capability = entry.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
+ isMonochrome = true;
+ }
+ }
+ mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
+
return initializeCommonLocked();
}
@@ -224,6 +247,17 @@
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
}
+ if (mUseHalBufManager) {
+ res = mRequestBufferSM.initialize(mStatusTracker);
+ if (res != OK) {
+ SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
+ strerror(-res), res);
+ mInterface->close();
+ mStatusTracker.clear();
+ return res;
+ }
+ }
+
/** Start up request queue thread */
mRequestThread = new RequestThread(
this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
@@ -951,6 +985,13 @@
return hardware::Void();
}
+ if (bufReqs.size() > mOutputStreams.size()) {
+ ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
+ __FUNCTION__, bufReqs.size(), mOutputStreams.size());
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ return hardware::Void();
+ }
+
// Check for repeated streamId
for (const auto& bufReq : bufReqs) {
if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
@@ -962,19 +1003,10 @@
streamIds.add(bufReq.streamId);
}
- // TODO: check we are not configuring streams. If so return FAILED_CONFIGURING
- // Probably need to hook CameraDeviceClient::beginConfigure and figure something
- // out for API1 client... maybe grab mLock and check mNeedConfig but then we will
- // need to wait until mLock is released...
- // _hidl_cb(BufferRequestStatus::FAILED_CONFIGURING, bufRets);
- // return hardware::Void();
-
- // TODO: here we start accessing mOutputStreams, might need mLock, but that
- // might block incoming API calls. Not sure how bad is it.
- if (bufReqs.size() > mOutputStreams.size()) {
- ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
- __FUNCTION__, bufReqs.size(), mOutputStreams.size());
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ if (!mRequestBufferSM.startRequestBuffer()) {
+ ALOGE("%s: request buffer disallowed while camera service is configuring",
+ __FUNCTION__);
+ _hidl_cb(BufferRequestStatus::FAILED_CONFIGURING, bufRets);
return hardware::Void();
}
@@ -991,6 +1023,7 @@
ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
hardware::hidl_vec<StreamBufferRet> emptyBufRets;
_hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, emptyBufRets);
+ mRequestBufferSM.endRequestBuffer();
return hardware::Void();
}
@@ -1074,15 +1107,20 @@
__FUNCTION__, streamId, strerror(-res), res);
}
}
+ for (size_t b = 0; b < numAllocatedBuffers; b++) {
+ camera3_stream_buffer_t& sb = streamBuffers[b];
+ sb.acquire_fence = -1;
+ sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+ }
returnOutputBuffers(streamBuffers.data(), numAllocatedBuffers, 0);
}
}
- // End of mOutputStreams access
_hidl_cb(allReqsSucceeds ? BufferRequestStatus::OK :
oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
BufferRequestStatus::FAILED_UNKNOWN,
bufRets);
+ mRequestBufferSM.endRequestBuffer();
return hardware::Void();
}
@@ -1734,7 +1772,8 @@
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId);
+ mTimestampOffset, physicalCameraId, streamSetId,
+ mUseHalBufManager);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
@@ -2132,6 +2171,15 @@
mStatusWaiters++;
+ // Notify HAL to start draining. We need to notify the HalInterface layer
+ // even when the device is already IDLE, so HalInterface can reject incoming
+ // requestStreamBuffers call.
+ if (!active && mUseHalBufManager) {
+ auto streamIds = mOutputStreams.getStreamIds();
+ mRequestThread->signalPipelineDrain(streamIds);
+ mRequestBufferSM.onWaitUntilIdle();
+ }
+
bool stateSeen = false;
do {
if (active == (mStatus == STATUS_ACTIVE)) {
@@ -2139,12 +2187,6 @@
break;
}
- // Notify HAL to start draining
- if (!active && mUseHalBufManager) {
- auto streamIds = mOutputStreams.getStreamIds();
- mRequestThread->signalPipelineDrain(streamIds);
- }
-
res = mStatusChanged.waitRelative(mLock, timeout);
if (res != OK) break;
@@ -2889,6 +2931,10 @@
return rc;
}
+ if (mDummyStreamId == NO_STREAM) {
+ mRequestBufferSM.onStreamsConfigured();
+ }
+
return OK;
}
@@ -3013,13 +3059,14 @@
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool hasAppCallback, nsecs_t maxExpectedDuration,
std::set<String8>& physicalCameraIds, bool isStillCapture,
- bool isZslCapture) {
+ bool isZslCapture, const SurfaceMap& outputSurfaces) {
ATRACE_CALL();
Mutex::Autolock l(mInFlightLock);
ssize_t res;
res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
- hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture));
+ hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
+ outputSurfaces));
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
@@ -3037,18 +3084,55 @@
void Camera3Device::returnOutputBuffers(
const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
- nsecs_t timestamp, bool timestampIncreasing) {
+ nsecs_t timestamp, bool timestampIncreasing,
+ const SurfaceMap& outputSurfaces,
+ const CaptureResultExtras &inResultExtras) {
for (size_t i = 0; i < numBuffers; i++)
{
- Camera3Stream *stream = Camera3Stream::cast(outputBuffers[i].stream);
- status_t res = stream->returnBuffer(outputBuffers[i], timestamp, timestampIncreasing);
+ Camera3StreamInterface *stream = Camera3Stream::cast(outputBuffers[i].stream);
+ int streamId = stream->getId();
+ const auto& it = outputSurfaces.find(streamId);
+ status_t res = OK;
+ if (it != outputSurfaces.end()) {
+ res = stream->returnBuffer(
+ outputBuffers[i], timestamp, timestampIncreasing, it->second);
+ } else {
+ res = stream->returnBuffer(
+ outputBuffers[i], timestamp, timestampIncreasing);
+ }
+
// Note: stream may be deallocated at this point, if this buffer was
// the last reference to it.
if (res != OK) {
ALOGE("Can't return buffer to its stream: %s (%d)",
strerror(-res), res);
}
+
+ // Long processing consumers can cause returnBuffer timeout for shared stream
+ // If that happens, cancel the buffer and send a buffer error to client
+ if (it != outputSurfaces.end() && res == TIMED_OUT &&
+ outputBuffers[i].status == CAMERA3_BUFFER_STATUS_OK) {
+ // cancel the buffer
+ camera3_stream_buffer_t sb = outputBuffers[i];
+ sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+ stream->returnBuffer(sb, /*timestamp*/0, timestampIncreasing);
+
+ // notify client buffer error
+ sp<NotificationListener> listener;
+ {
+ Mutex::Autolock l(mOutputLock);
+ listener = mListener.promote();
+ }
+
+ if (listener != nullptr) {
+ CaptureResultExtras extras = inResultExtras;
+ extras.errorStreamId = streamId;
+ listener->notifyError(
+ hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
+ extras);
+ }
+ }
}
}
@@ -3059,6 +3143,7 @@
// Indicate idle inFlightMap to the status tracker
if (mInFlightMap.size() == 0) {
+ mRequestBufferSM.onInflightMapEmpty();
// Hold a separate dedicated tracker lock to prevent race with disconnect and also
// avoid a deadlock during reprocess requests.
Mutex::Autolock l(mTrackerLock);
@@ -3106,7 +3191,8 @@
assert(request.requestStatus != OK ||
request.pendingOutputBuffers.size() == 0);
returnOutputBuffers(request.pendingOutputBuffers.array(),
- request.pendingOutputBuffers.size(), 0);
+ request.pendingOutputBuffers.size(), 0, /*timestampIncreasing*/true,
+ request.outputSurfaces, request.resultExtras);
removeInFlightMapEntryLocked(idx);
ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
@@ -3130,7 +3216,9 @@
for (size_t idx = 0; idx < mInFlightMap.size(); idx++) {
const InFlightRequest &request = mInFlightMap.valueAt(idx);
returnOutputBuffers(request.pendingOutputBuffers.array(),
- request.pendingOutputBuffers.size(), 0);
+ request.pendingOutputBuffers.size(), 0,
+ /*timestampIncreasing*/true, request.outputSurfaces,
+ request.resultExtras);
}
mInFlightMap.clear();
mExpectedInflightDuration = 0;
@@ -3258,6 +3346,13 @@
captureResult.mResultExtras = resultExtras;
captureResult.mMetadata = partialResult;
+ // Fix up result metadata for monochrome camera.
+ status_t res = fixupMonochromeTags(mDeviceInfo, captureResult.mMetadata);
+ if (res != OK) {
+ SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+ return;
+ }
+
insertResultLocked(&captureResult, frameNumber);
}
@@ -3329,6 +3424,21 @@
frameNumber, strerror(res), res);
return;
}
+ // Fix up result metadata for monochrome camera.
+ res = fixupMonochromeTags(mDeviceInfo, captureResult.mMetadata);
+ if (res != OK) {
+ SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+ return;
+ }
+ for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
+ String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+ res = fixupMonochromeTags(mPhysicalDeviceInfoMap.at(cameraId8.c_str()),
+ physicalMetadata.mPhysicalCameraMetadata);
+ if (res != OK) {
+ SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
+ return;
+ }
+ }
mTagMonitor.monitorMetadata(TagMonitor::RESULT,
frameNumber, timestamp.data.i64[0], captureResult.mMetadata);
@@ -3488,7 +3598,8 @@
} else {
bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
returnOutputBuffers(result->output_buffers,
- result->num_output_buffers, shutterTimestamp, timestampIncreasing);
+ result->num_output_buffers, shutterTimestamp, timestampIncreasing,
+ request.outputSurfaces, request.resultExtras);
}
if (result->result != NULL && !isPartialResult) {
@@ -3501,7 +3612,7 @@
if (shutterTimestamp == 0) {
request.pendingMetadata = result->result;
request.collectedPartialResult = collectedPartialResult;
- } else if (request.hasCallback) {
+ } else if (request.hasCallback) {
CameraMetadata metadata;
metadata = result->result;
sendCaptureResult(metadata, request.resultExtras,
@@ -3621,6 +3732,9 @@
// In case of missing result check whether the buffers
// returned. If they returned, then remove inflight
// request.
+ // TODO: should we call this for ERROR_CAMERA_REQUEST as well?
+ // otherwise we are depending on HAL to send the buffers back after
+ // calling notifyError. Not sure if that's in the spec.
removeInFlightRequestIfReadyLocked(idx);
}
} else {
@@ -3696,7 +3810,8 @@
}
bool timestampIncreasing = !(r.zslCapture || r.hasInputBuffer);
returnOutputBuffers(r.pendingOutputBuffers.array(),
- r.pendingOutputBuffers.size(), r.shutterTimestamp, timestampIncreasing);
+ r.pendingOutputBuffers.size(), r.shutterTimestamp, timestampIncreasing,
+ r.outputSurfaces, r.resultExtras);
r.pendingOutputBuffers.clear();
removeInFlightRequestIfReadyLocked(idx);
@@ -5097,6 +5212,13 @@
nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
mRequestLatency.add(tRequestStart, tRequestEnd);
+ if (submitRequestSuccess) {
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent != nullptr) {
+ parent->mRequestBufferSM.onRequestSubmitted();
+ }
+ }
+
if (useFlushLock) {
mFlushLock.unlock();
}
@@ -5241,8 +5363,11 @@
}
nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
+ SurfaceMap uniqueSurfaceIdMap;
for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
- sp<Camera3OutputStreamInterface> outputStream = captureRequest->mOutputStreams.editItemAt(j);
+ sp<Camera3OutputStreamInterface> outputStream =
+ captureRequest->mOutputStreams.editItemAt(j);
+ int streamId = outputStream->getId();
// Prepare video buffers for high speed recording on the first video request.
if (mPrepareVideoStream && outputStream->isVideoStream()) {
@@ -5261,6 +5386,20 @@
}
}
+ std::vector<size_t> uniqueSurfaceIds;
+ res = outputStream->getUniqueSurfaceIds(
+ captureRequest->mOutputSurfaces[streamId],
+ &uniqueSurfaceIds);
+ // INVALID_OPERATION is normal output for streams not supporting surfaceIds
+ if (res != OK && res != INVALID_OPERATION) {
+ ALOGE("%s: failed to query stream %d unique surface IDs",
+ __FUNCTION__, streamId);
+ return res;
+ }
+ if (res == OK) {
+ uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
+ }
+
if (mUseHalBufManager) {
// HAL will request buffer through requestStreamBuffer API
camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
@@ -5272,7 +5411,7 @@
} else {
res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
waitDuration,
- captureRequest->mOutputSurfaces[outputStream->getId()]);
+ captureRequest->mOutputSurfaces[streamId]);
if (res != OK) {
// Can't get output buffer from gralloc queue - this could be due to
// abandoned queue or other consumer misbehavior, so not a fatal
@@ -5326,7 +5465,9 @@
/*hasInput*/halRequest->input_buffer != NULL,
hasCallback,
calculateMaxExpectedDuration(halRequest->settings),
- requestedPhysicalCameras, isStillCapture, isZslCapture);
+ requestedPhysicalCameras, isStillCapture, isZslCapture,
+ (mUseHalBufManager) ? uniqueSurfaceIdMap :
+ SurfaceMap{});
ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
", burstId = %" PRId32 ".",
__FUNCTION__,
@@ -5402,7 +5543,7 @@
if (s.first == streamId) {
const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
if (it != s.second.end()) {
- return true;
+ return true;
}
}
}
@@ -5413,7 +5554,7 @@
if (s.first == streamId) {
const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
if (it != s.second.end()) {
- return true;
+ return true;
}
}
}
@@ -5430,7 +5571,8 @@
Mutex::Autolock pl(mPauseLock);
if (mPaused) {
- return mInterface->signalPipelineDrain(streamIds);
+ mInterface->signalPipelineDrain(streamIds);
+ return;
}
// If request thread is still busy, wait until paused then notify HAL
mNotifyPipelineDrain = true;
@@ -5619,6 +5761,10 @@
mNotifyPipelineDrain = false;
mStreamIdsToBeDrained.clear();
}
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent != nullptr) {
+ parent->mRequestBufferSM.onRequestThreadPaused();
+ }
}
// Stop waiting for now and let thread management happen
return NULL;
@@ -5708,6 +5854,10 @@
mNotifyPipelineDrain = false;
mStreamIdsToBeDrained.clear();
}
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent != nullptr) {
+ parent->mRequestBufferSM.onRequestThreadPaused();
+ }
}
res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
@@ -6163,4 +6313,176 @@
return true;
}
+status_t Camera3Device::RequestBufferStateMachine::initialize(
+ sp<camera3::StatusTracker> statusTracker) {
+ if (statusTracker == nullptr) {
+ ALOGE("%s: statusTracker is null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ std::lock_guard<std::mutex> lock(mLock);
+ mStatusTracker = statusTracker;
+ mRequestBufferStatusId = statusTracker->addComponent();
+ return OK;
+}
+
+bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mStatus == RB_STATUS_READY) {
+ mRequestBufferOngoing = true;
+ return true;
+ }
+ return false;
+}
+
+void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (!mRequestBufferOngoing) {
+ ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
+ return;
+ }
+ mRequestBufferOngoing = false;
+ if (mStatus == RB_STATUS_PENDING_STOP) {
+ checkSwitchToStopLocked();
+ }
+}
+
+void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
+ std::lock_guard<std::mutex> lock(mLock);
+ RequestBufferState oldStatus = mStatus;
+ mStatus = RB_STATUS_READY;
+ if (oldStatus != RB_STATUS_READY) {
+ notifyTrackerLocked(/*active*/true);
+ }
+ return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onRequestSubmitted() {
+ std::lock_guard<std::mutex> lock(mLock);
+ mRequestThreadPaused = false;
+ mInflightMapEmpty = false;
+ if (mStatus == RB_STATUS_STOPPED) {
+ mStatus = RB_STATUS_READY;
+ notifyTrackerLocked(/*active*/true);
+ }
+ return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
+ std::lock_guard<std::mutex> lock(mLock);
+ mRequestThreadPaused = true;
+ if (mStatus == RB_STATUS_PENDING_STOP) {
+ checkSwitchToStopLocked();
+ }
+ return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
+ std::lock_guard<std::mutex> lock(mLock);
+ mInflightMapEmpty = true;
+ if (mStatus == RB_STATUS_PENDING_STOP) {
+ checkSwitchToStopLocked();
+ }
+ return;
+}
+
+void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (!checkSwitchToStopLocked()) {
+ mStatus = RB_STATUS_PENDING_STOP;
+ }
+ return;
+}
+
+void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
+ sp<StatusTracker> statusTracker = mStatusTracker.promote();
+ if (statusTracker != nullptr) {
+ if (active) {
+ statusTracker->markComponentActive(mRequestBufferStatusId);
+ } else {
+ statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
+ }
+ }
+}
+
+bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
+ if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
+ mStatus = RB_STATUS_STOPPED;
+ notifyTrackerLocked(/*active*/false);
+ return true;
+ }
+ return false;
+}
+
+status_t Camera3Device::fixupMonochromeTags(const CameraMetadata& deviceInfo,
+ CameraMetadata& resultMetadata) {
+ status_t res = OK;
+ if (!mNeedFixupMonochromeTags) {
+ return res;
+ }
+
+ // Remove tags that are not applicable to monochrome camera.
+ int32_t tagsToRemove[] = {
+ ANDROID_SENSOR_GREEN_SPLIT,
+ ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+ ANDROID_COLOR_CORRECTION_MODE,
+ ANDROID_COLOR_CORRECTION_TRANSFORM,
+ ANDROID_COLOR_CORRECTION_GAINS,
+ };
+ for (auto tag : tagsToRemove) {
+ res = resultMetadata.erase(tag);
+ if (res != OK) {
+ ALOGE("%s: Failed to remove tag %d for monochrome camera", __FUNCTION__, tag);
+ return res;
+ }
+ }
+
+ // ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
+ camera_metadata_entry blEntry = resultMetadata.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
+ for (size_t i = 1; i < blEntry.count; i++) {
+ blEntry.data.f[i] = blEntry.data.f[0];
+ }
+
+ // ANDROID_SENSOR_NOISE_PROFILE
+ camera_metadata_entry npEntry = resultMetadata.find(ANDROID_SENSOR_NOISE_PROFILE);
+ if (npEntry.count > 0 && npEntry.count % 2 == 0) {
+ double np[] = {npEntry.data.d[0], npEntry.data.d[1]};
+ res = resultMetadata.update(ANDROID_SENSOR_NOISE_PROFILE, np, 2);
+ if (res != OK) {
+ ALOGE("%s: Failed to update SENSOR_NOISE_PROFILE: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
+
+ // ANDROID_STATISTICS_LENS_SHADING_MAP
+ camera_metadata_ro_entry lsSizeEntry = deviceInfo.find(ANDROID_LENS_INFO_SHADING_MAP_SIZE);
+ camera_metadata_entry lsEntry = resultMetadata.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
+ if (lsSizeEntry.count == 2 && lsEntry.count > 0
+ && (int32_t)lsEntry.count == 4 * lsSizeEntry.data.i32[0] * lsSizeEntry.data.i32[1]) {
+ for (int32_t i = 0; i < lsSizeEntry.data.i32[0] * lsSizeEntry.data.i32[1]; i++) {
+ lsEntry.data.f[4*i+1] = lsEntry.data.f[4*i];
+ lsEntry.data.f[4*i+2] = lsEntry.data.f[4*i];
+ lsEntry.data.f[4*i+3] = lsEntry.data.f[4*i];
+ }
+ }
+
+ // ANDROID_TONEMAP_CURVE_BLUE
+ // ANDROID_TONEMAP_CURVE_GREEN
+ // ANDROID_TONEMAP_CURVE_RED
+ camera_metadata_entry tcbEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_BLUE);
+ camera_metadata_entry tcgEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_GREEN);
+ camera_metadata_entry tcrEntry = resultMetadata.find(ANDROID_TONEMAP_CURVE_RED);
+ if (tcbEntry.count > 0
+ && tcbEntry.count == tcgEntry.count
+ && tcbEntry.count == tcrEntry.count) {
+ for (size_t i = 0; i < tcbEntry.count; i++) {
+ tcbEntry.data.f[i] = tcrEntry.data.f[i];
+ tcgEntry.data.f[i] = tcrEntry.data.f[i];
+ }
+ }
+
+ return res;
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 5c0f570..35b9d6d 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1031,6 +1031,9 @@
// Indicates a ZSL capture request
bool zslCapture;
+ // What shared surfaces an output should go to
+ SurfaceMap outputSurfaces;
+
// Default constructor needed by KeyedVector
InFlightRequest() :
shutterTimestamp(0),
@@ -1049,7 +1052,8 @@
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
bool hasAppCallback, nsecs_t maxDuration,
const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
- bool isZslCapture) :
+ bool isZslCapture,
+ const SurfaceMap& outSurfaces = SurfaceMap{}) :
shutterTimestamp(0),
sensorTimestamp(0),
requestStatus(OK),
@@ -1062,7 +1066,8 @@
skipResultMetadata(false),
physicalCameraIds(physicalCameraIdSet),
stillCapture(isStillCapture),
- zslCapture(isZslCapture) {
+ zslCapture(isZslCapture),
+ outputSurfaces(outSurfaces) {
}
};
@@ -1079,7 +1084,8 @@
status_t registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds,
- bool isStillCapture, bool isZslCapture);
+ bool isStillCapture, bool isZslCapture,
+ const SurfaceMap& outputSurfaces);
/**
* Returns the maximum expected time it'll take for all currently in-flight
@@ -1189,7 +1195,11 @@
// helper function to return the output buffers to the streams.
void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers,
- size_t numBuffers, nsecs_t timestamp, bool timestampIncreasing = true);
+ size_t numBuffers, nsecs_t timestamp, bool timestampIncreasing = true,
+ // The following arguments are only meant for surface sharing use case
+ const SurfaceMap& outputSurfaces = SurfaceMap{},
+ // Used to send buffer error callback when failing to return buffer
+ const CaptureResultExtras &resultExtras = CaptureResultExtras{});
// Send a partial capture result.
void sendPartialCaptureResult(const camera_metadata_t * partialResult,
@@ -1249,12 +1259,84 @@
// b/79972865
Mutex mTrackerLock;
- // Whether HAL request buffers through requestStreamBuffer API
+ // Whether HAL request buffers through requestStreamBuffers API
bool mUseHalBufManager = false;
// Lock to ensure requestStreamBuffers() callbacks are serialized
std::mutex mRequestBufferInterfaceLock;
+ // The state machine to control when requestStreamBuffers should allow
+ // HAL to request buffers.
+ enum RequestBufferState {
+ /**
+ * This is the initial state.
+ * requestStreamBuffers call will return FAILED_CONFIGURING in this state.
+ * Will switch to RB_STATUS_READY after a successful configureStreams or
+ * processCaptureRequest call.
+ */
+ RB_STATUS_STOPPED,
+
+ /**
+ * requestStreamBuffers call will proceed in this state.
+ * When device is asked to stay idle via waitUntilStateThenRelock() call:
+ * - Switch to RB_STATUS_STOPPED if there is no inflight requests and
+ * request thread is paused.
+ * - Switch to RB_STATUS_PENDING_STOP otherwise
+ */
+ RB_STATUS_READY,
+
+ /**
+ * requestStreamBuffers call will proceed in this state.
+ * Switch to RB_STATUS_STOPPED when all inflight requests are fulfilled
+ * and request thread is paused
+ */
+ RB_STATUS_PENDING_STOP,
+ };
+
+ class RequestBufferStateMachine {
+ public:
+ status_t initialize(sp<camera3::StatusTracker> statusTracker);
+
+ // Return if the state machine currently allows for requestBuffers
+ // If the state allows for it, mRequestBufferOngoing will be set to true
+ // and caller must call endRequestBuffer() later to unset the flag
+ bool startRequestBuffer();
+ void endRequestBuffer();
+
+ // Events triggered by application API call
+ void onStreamsConfigured();
+ void onWaitUntilIdle();
+
+ // Events usually triggered by hwBinder processCaptureResult callback thread
+ // But can also be triggered on request thread for failed request, or on
+ // hwbinder notify callback thread for shutter/error callbacks
+ void onInflightMapEmpty();
+
+ // Events triggered by RequestThread
+ void onRequestSubmitted();
+ void onRequestThreadPaused();
+
+ private:
+ void notifyTrackerLocked(bool active);
+
+ // Switch to STOPPED state and return true if all conditions allows for it.
+ // Otherwise do nothing and return false.
+ bool checkSwitchToStopLocked();
+
+ std::mutex mLock;
+ RequestBufferState mStatus = RB_STATUS_STOPPED;
+
+ bool mRequestThreadPaused = true;
+ bool mInflightMapEmpty = true;
+ bool mRequestBufferOngoing = false;
+
+ wp<camera3::StatusTracker> mStatusTracker;
+ int mRequestBufferStatusId;
+ } mRequestBufferSM;
+
+ // Fix up result metadata for monochrome camera.
+ bool mNeedFixupMonochromeTags;
+ status_t fixupMonochromeTags(const CameraMetadata& deviceInfo, CameraMetadata& resultMetadata);
}; // class Camera3Device
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index fb1ff77..b637160 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -48,7 +48,7 @@
status_t Camera3DummyStream::returnBufferLocked(
const camera3_stream_buffer &,
- nsecs_t) {
+ nsecs_t, const std::vector<size_t>&) {
ATRACE_CALL();
ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", __FUNCTION__, mId);
return INVALID_OPERATION;
@@ -58,6 +58,7 @@
const camera3_stream_buffer &,
nsecs_t,
bool,
+ const std::vector<size_t>&,
/*out*/
sp<Fence>*) {
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 4627548..4b67ea5 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -87,6 +87,9 @@
*/
virtual ssize_t getSurfaceId(const sp<Surface> &/*surface*/) { return 0; }
+ virtual status_t getUniqueSurfaceIds(const std::vector<size_t>&,
+ /*out*/std::vector<size_t>*) { return INVALID_OPERATION; };
+
/**
* Update the stream output surfaces.
*/
@@ -104,6 +107,7 @@
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>& surface_ids,
/*out*/
sp<Fence> *releaseFenceOut);
@@ -128,7 +132,7 @@
const std::vector<size_t>& surface_ids = std::vector<size_t>());
virtual status_t returnBufferLocked(
const camera3_stream_buffer &buffer,
- nsecs_t timestamp);
+ nsecs_t timestamp, const std::vector<size_t>& surface_ids);
virtual status_t configureQueueLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 18b8c4d..2e909a0 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -219,7 +219,8 @@
status_t Camera3IOStreamBase::returnAnyBufferLocked(
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
- bool output) {
+ bool output,
+ const std::vector<size_t>& surface_ids) {
status_t res;
// returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
@@ -235,7 +236,7 @@
}
sp<Fence> releaseFence;
- res = returnBufferCheckedLocked(buffer, timestamp, output,
+ res = returnBufferCheckedLocked(buffer, timestamp, output, surface_ids,
&releaseFence);
// Res may be an error, but we still want to decrement our owned count
// to enable clean shutdown. So we'll just return the error but otherwise
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 48e9bbf..750f64d 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -66,12 +66,14 @@
status_t returnAnyBufferLocked(
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
- bool output);
+ bool output,
+ const std::vector<size_t>& surface_ids = std::vector<size_t>());
virtual status_t returnBufferCheckedLocked(
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>& surface_ids,
/*out*/
sp<Fence> *releaseFenceOut) = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index 017d7be..fc83684 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -98,6 +98,7 @@
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>&,
/*out*/
sp<Fence> *releaseFenceOut) {
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 0732464..97a627a 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -62,6 +62,7 @@
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>& surface_ids,
/*out*/
sp<Fence> *releaseFenceOut);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index ecbcf76..219cc24 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -187,16 +187,17 @@
}
status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
- ANativeWindowBuffer* buffer, int anwReleaseFence) {
+ ANativeWindowBuffer* buffer, int anwReleaseFence,
+ const std::vector<size_t>&) {
return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
}
status_t Camera3OutputStream::returnBufferLocked(
const camera3_stream_buffer &buffer,
- nsecs_t timestamp) {
+ nsecs_t timestamp, const std::vector<size_t>& surface_ids) {
ATRACE_CALL();
- status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
+ status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true, surface_ids);
if (res != OK) {
return res;
@@ -212,6 +213,7 @@
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>& surface_ids,
/*out*/
sp<Fence> *releaseFenceOut) {
@@ -281,7 +283,7 @@
return res;
}
- res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence);
+ res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence, surface_ids);
if (res != OK) {
ALOGE("%s: Stream %d: Error queueing buffer to native window: "
"%s (%d)", __FUNCTION__, mId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 6f36f92..410905d 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -190,6 +190,9 @@
*/
virtual ssize_t getSurfaceId(const sp<Surface> &/*surface*/) { return 0; }
+ virtual status_t getUniqueSurfaceIds(const std::vector<size_t>&,
+ /*out*/std::vector<size_t>*) { return INVALID_OPERATION; };
+
/**
* Update the stream output surfaces.
*/
@@ -213,6 +216,7 @@
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
+ const std::vector<size_t>& surface_ids,
/*out*/
sp<Fence> *releaseFenceOut);
@@ -285,10 +289,11 @@
virtual status_t returnBufferLocked(
const camera3_stream_buffer &buffer,
- nsecs_t timestamp);
+ nsecs_t timestamp, const std::vector<size_t>& surface_ids);
virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
- ANativeWindowBuffer* buffer, int anwReleaseFence);
+ ANativeWindowBuffer* buffer, int anwReleaseFence,
+ const std::vector<size_t>& surface_ids);
virtual status_t configureQueueLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index a711a6d..2bde949 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -67,6 +67,18 @@
virtual ssize_t getSurfaceId(const sp<Surface> &surface) = 0;
/**
+ * Query the unique surface IDs of current surfaceIds.
+ * When passing unique surface IDs in returnBuffer(), if the
+ * surfaceId has been removed from the stream, the output corresponding to
+ * the unique surface ID will be ignored and not delivered to client.
+ *
+ * Return INVALID_OPERATION if and only if the stream does not support
+ * surface sharing.
+ */
+ virtual status_t getUniqueSurfaceIds(const std::vector<size_t>& surfaceIds,
+ /*out*/std::vector<size_t>* outUniqueIds) = 0;
+
+ /**
* Update the stream output surfaces.
*/
virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 1c13950..e3b74d7 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#define LOG_TAG "Camera3-SharedOuStrm"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
#include "Camera3SharedOutputStream.h"
namespace android {
@@ -28,16 +32,17 @@
uint64_t consumerUsage, android_dataspace dataSpace,
camera3_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
- int setId) :
+ int setId, bool useHalBufManager) :
Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId,
- consumerUsage, timestampOffset, setId) {
+ consumerUsage, timestampOffset, setId),
+ mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
if (surfaces.size() > consumerCount) {
ALOGE("%s: Trying to add more consumers than the maximum ", __func__);
}
for (size_t i = 0; i < consumerCount; i++) {
- mSurfaces[i] = surfaces[i];
+ mSurfaceUniqueIds[i] = std::make_pair(surfaces[i], mNextUniqueSurfaceId++);
}
}
@@ -48,15 +53,15 @@
status_t Camera3SharedOutputStream::connectStreamSplitterLocked() {
status_t res = OK;
- mStreamSplitter = new Camera3StreamSplitter();
+ mStreamSplitter = new Camera3StreamSplitter(mUseHalBufManager);
uint64_t usage;
getEndpointUsage(&usage);
std::unordered_map<size_t, sp<Surface>> initialSurfaces;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaces[i] != nullptr) {
- initialSurfaces.emplace(i, mSurfaces[i]);
+ if (mSurfaceUniqueIds[i].first != nullptr) {
+ initialSurfaces.emplace(i, mSurfaceUniqueIds[i].first);
}
}
@@ -71,6 +76,31 @@
return res;
}
+status_t Camera3SharedOutputStream::attachBufferToSplitterLocked(
+ ANativeWindowBuffer* anb,
+ const std::vector<size_t>& surface_ids) {
+ status_t res = OK;
+
+ // Attach the buffer to the splitter output queues. This could block if
+ // the output queue doesn't have any empty slot. So unlock during the course
+ // of attachBufferToOutputs.
+ sp<Camera3StreamSplitter> splitter = mStreamSplitter;
+ mLock.unlock();
+ res = splitter->attachBufferToOutputs(anb, surface_ids);
+ mLock.lock();
+ if (res != OK) {
+ ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
+ __FUNCTION__, mId, strerror(-res), res);
+ // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
+ // let prepareNextBuffer handle the error.)
+ if (res == NO_INIT && mState == STATE_CONFIGURED) {
+ mState = STATE_ABANDONED;
+ }
+ }
+ return res;
+}
+
+
status_t Camera3SharedOutputStream::notifyBufferReleased(ANativeWindowBuffer *anwBuffer) {
Mutex::Autolock l(mLock);
status_t res = OK;
@@ -89,7 +119,7 @@
return true;
}
- return (mSurfaces[surface_id] == nullptr);
+ return (mSurfaceUniqueIds[surface_id].first == nullptr);
}
status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
@@ -112,7 +142,7 @@
return NO_MEMORY;
}
- mSurfaces[id] = surface;
+ mSurfaceUniqueIds[id] = std::make_pair(surface, mNextUniqueSurfaceId++);
// Only call addOutput if the splitter has been connected.
if (mStreamSplitter != nullptr) {
@@ -128,7 +158,7 @@
}
status_t Camera3SharedOutputStream::getBufferLocked(camera3_stream_buffer *buffer,
- const std::vector<size_t>& surface_ids) {
+ const std::vector<size_t>& surfaceIds) {
ANativeWindowBuffer* anb;
int fenceFd = -1;
@@ -138,27 +168,11 @@
return res;
}
- // TODO: need to refactor this to support requestStreamBuffers API
- // Need to wait until processCaptureResult to decide the source buffer
- // to attach to output...
-
- // Attach the buffer to the splitter output queues. This could block if
- // the output queue doesn't have any empty slot. So unlock during the course
- // of attachBufferToOutputs.
- sp<Camera3StreamSplitter> splitter = mStreamSplitter;
- mLock.unlock();
- res = splitter->attachBufferToOutputs(anb, surface_ids);
- mLock.lock();
- if (res != OK) {
- ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
- __FUNCTION__, mId, strerror(-res), res);
- // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
- // let prepareNextBuffer handle the error.)
- if (res == NO_INIT && mState == STATE_CONFIGURED) {
- mState = STATE_ABANDONED;
+ if (!mUseHalBufManager) {
+ res = attachBufferToSplitterLocked(anb, surfaceIds);
+ if (res != OK) {
+ return res;
}
-
- return res;
}
/**
@@ -172,8 +186,38 @@
}
status_t Camera3SharedOutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
- ANativeWindowBuffer* buffer, int anwReleaseFence) {
- status_t res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
+ ANativeWindowBuffer* buffer, int anwReleaseFence,
+ const std::vector<size_t>& uniqueSurfaceIds) {
+ status_t res = OK;
+ if (mUseHalBufManager) {
+ if (uniqueSurfaceIds.size() == 0) {
+ ALOGE("%s: uniqueSurfaceIds must not be empty!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ Mutex::Autolock l(mLock);
+ std::vector<size_t> surfaceIds;
+ for (const auto& uniqueId : uniqueSurfaceIds) {
+ bool uniqueIdFound = false;
+ for (size_t i = 0; i < kMaxOutputs; i++) {
+ if (mSurfaceUniqueIds[i].second == uniqueId) {
+ surfaceIds.push_back(i);
+ uniqueIdFound = true;
+ break;
+ }
+ }
+ if (!uniqueIdFound) {
+ ALOGV("%s: unknown unique surface ID %zu for stream %d: "
+ "output might have been removed.",
+ __FUNCTION__, uniqueId, mId);
+ }
+ }
+ res = attachBufferToSplitterLocked(buffer, surfaceIds);
+ if (res != OK) {
+ return res;
+ }
+ }
+
+ res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
// After queuing buffer to the internal consumer queue, check whether the buffer is
// successfully queued to the output queues.
@@ -232,8 +276,8 @@
*usage = getPresetConsumerUsage();
for (size_t id = 0; id < kMaxOutputs; id++) {
- if (mSurfaces[id] != nullptr) {
- res = getEndpointUsageForSurface(&u, mSurfaces[id]);
+ if (mSurfaceUniqueIds[id].first != nullptr) {
+ res = getEndpointUsageForSurface(&u, mSurfaceUniqueIds[id].first);
*usage |= u;
}
}
@@ -249,7 +293,7 @@
ssize_t Camera3SharedOutputStream::getNextSurfaceIdLocked() {
ssize_t id = -1;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaces[i] == nullptr) {
+ if (mSurfaceUniqueIds[i].first == nullptr) {
id = i;
break;
}
@@ -262,7 +306,7 @@
Mutex::Autolock l(mLock);
ssize_t id = -1;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaces[i] == surface) {
+ if (mSurfaceUniqueIds[i].first == surface) {
id = i;
break;
}
@@ -271,6 +315,26 @@
return id;
}
+status_t Camera3SharedOutputStream::getUniqueSurfaceIds(
+ const std::vector<size_t>& surfaceIds,
+ /*out*/std::vector<size_t>* outUniqueIds) {
+ Mutex::Autolock l(mLock);
+ if (outUniqueIds == nullptr || surfaceIds.size() > kMaxOutputs) {
+ return BAD_VALUE;
+ }
+
+ outUniqueIds->clear();
+ outUniqueIds->reserve(surfaceIds.size());
+
+ for (const auto& surfaceId : surfaceIds) {
+ if (surfaceId >= kMaxOutputs) {
+ return BAD_VALUE;
+ }
+ outUniqueIds->push_back(mSurfaceUniqueIds[surfaceId].second);
+ }
+ return OK;
+}
+
status_t Camera3SharedOutputStream::revertPartialUpdateLocked(
const KeyedVector<sp<Surface>, size_t> &removedSurfaces,
const KeyedVector<sp<Surface>, size_t> &attachedSurfaces) {
@@ -284,7 +348,7 @@
return UNKNOWN_ERROR;
}
}
- mSurfaces[index] = nullptr;
+ mSurfaceUniqueIds[index] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
}
for (size_t i = 0; i < removedSurfaces.size(); i++) {
@@ -295,7 +359,8 @@
return UNKNOWN_ERROR;
}
}
- mSurfaces[index] = removedSurfaces.keyAt(i);
+ mSurfaceUniqueIds[index] = std::make_pair(
+ removedSurfaces.keyAt(i), mNextUniqueSurfaceId++);
}
return ret;
@@ -347,8 +412,8 @@
}
}
- mSurfaces[it] = nullptr;
- removedSurfaces.add(mSurfaces[it], it);
+ removedSurfaces.add(mSurfaceUniqueIds[it].first, it);
+ mSurfaceUniqueIds[it] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
}
//Next add the new outputs
@@ -373,7 +438,7 @@
return ret;
}
}
- mSurfaces[surfaceId] = it;
+ mSurfaceUniqueIds[surfaceId] = std::make_pair(it, mNextUniqueSurfaceId++);
outputMap->add(it, surfaceId);
}
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 02b1c09..b5e37c2 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SERVERS_CAMERA3_SHARED_OUTPUT_STREAM_H
#define ANDROID_SERVERS_CAMERA3_SHARED_OUTPUT_STREAM_H
+#include <array>
#include "Camera3StreamSplitter.h"
#include "Camera3OutputStream.h"
@@ -37,7 +38,8 @@
uint64_t consumerUsage, android_dataspace dataSpace,
camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
const String8& physicalCameraId,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID,
+ bool useHalBufManager = false);
virtual ~Camera3SharedOutputStream();
@@ -49,6 +51,15 @@
virtual ssize_t getSurfaceId(const sp<Surface> &surface);
+ /**
+ * Query the unique surface IDs of current surfaceIds.
+ * When passing unique surface IDs in returnBuffer(), if the
+ * surfaceId has been removed from the stream, the output corresponding to
+ * the unique surface ID will be ignored and not delivered to client.
+ */
+ virtual status_t getUniqueSurfaceIds(const std::vector<size_t>& surfaceIds,
+ /*out*/std::vector<size_t>* outUniqueIds) override;
+
virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
@@ -58,8 +69,17 @@
static const size_t kMaxOutputs = 4;
- // Map surfaceId -> output surfaces
- sp<Surface> mSurfaces[kMaxOutputs];
+ // Whether HAL is in control for buffer management. Surface sharing behavior
+ // depends on this flag.
+ const bool mUseHalBufManager;
+
+ // Pair of an output Surface and its unique ID
+ typedef std::pair<sp<Surface>, size_t> SurfaceUniqueId;
+
+ // Map surfaceId -> (output surface, unique surface ID)
+ std::array<SurfaceUniqueId, kMaxOutputs> mSurfaceUniqueIds;
+
+ size_t mNextUniqueSurfaceId = 0;
ssize_t getNextSurfaceIdLocked();
@@ -78,13 +98,24 @@
status_t connectStreamSplitterLocked();
/**
+ * Attach the output buffer to stream splitter.
+ * When camera service is doing buffer management, this method will be called
+ * before the buffer is handed out to HAL in request thread.
+ * When HAL is doing buffer management, this method will be called when
+ * the buffer is returned from HAL in hwbinder callback thread.
+ */
+ status_t attachBufferToSplitterLocked(ANativeWindowBuffer* anb,
+ const std::vector<size_t>& surface_ids);
+
+ /**
* Internal Camera3Stream interface
*/
virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
const std::vector<size_t>& surface_ids);
virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
- ANativeWindowBuffer* buffer, int anwReleaseFence);
+ ANativeWindowBuffer* buffer, int anwReleaseFence,
+ const std::vector<size_t>& uniqueSurfaceIds);
virtual status_t configureQueueLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 0a30a97..24d1c1b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -655,7 +655,8 @@
}
status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
- nsecs_t timestamp, bool timestampIncreasing) {
+ nsecs_t timestamp, bool timestampIncreasing,
+ const std::vector<size_t>& surface_ids) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
@@ -684,7 +685,7 @@
*
* Do this for getBuffer as well.
*/
- status_t res = returnBufferLocked(b, timestamp);
+ status_t res = returnBufferLocked(b, timestamp, surface_ids);
if (res == OK) {
fireBufferListenersLocked(b, /*acquired*/false, /*output*/true);
}
@@ -843,7 +844,7 @@
return INVALID_OPERATION;
}
status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
- nsecs_t) {
+ nsecs_t, const std::vector<size_t>&) {
ALOGE("%s: This type of stream does not support output", __FUNCTION__);
return INVALID_OPERATION;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index e29c3e0..ddba9f6 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -322,11 +322,17 @@
/**
* Return a buffer to the stream after use by the HAL.
*
+ * Multiple surfaces could share the same HAL stream, but a request may
+ * be only for a subset of surfaces. In this case, the
+ * Camera3StreamInterface object needs the surface ID information to attach
+ * buffers for those surfaces.
+ *
* This method may only be called for buffers provided by getBuffer().
* For bidirectional streams, this method applies to the output-side buffers
*/
status_t returnBuffer(const camera3_stream_buffer &buffer,
- nsecs_t timestamp, bool timestampIncreasing);
+ nsecs_t timestamp, bool timestampIncreasing,
+ const std::vector<size_t>& surface_ids = std::vector<size_t>());
/**
* Fill in the camera3_stream_buffer with the next valid buffer for this
@@ -478,7 +484,8 @@
virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
const std::vector<size_t>& surface_ids = std::vector<size_t>());
virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
- nsecs_t timestamp);
+ nsecs_t timestamp,
+ const std::vector<size_t>& surface_ids = std::vector<size_t>());
virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
virtual status_t returnInputBufferLocked(
const camera3_stream_buffer &buffer);
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 866b722..a84720b 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -248,11 +248,18 @@
/**
* Return a buffer to the stream after use by the HAL.
*
+ * Multiple surfaces could share the same HAL stream, but a request may
+ * be only for a subset of surfaces. In this case, the
+ * Camera3StreamInterface object needs the surface ID information to attach
+ * buffers for those surfaces. For the case of single surface for a HAL
+ * stream, surface_ids parameter has no effect.
+ *
* This method may only be called for buffers provided by getBuffer().
* For bidirectional streams, this method applies to the output-side buffers
*/
virtual status_t returnBuffer(const camera3_stream_buffer &buffer,
- nsecs_t timestamp, bool timestampIncreasing = true) = 0;
+ nsecs_t timestamp, bool timestampIncreasing = true,
+ const std::vector<size_t>& surface_ids = std::vector<size_t>()) = 0;
/**
* Fill in the camera3_stream_buffer with the next valid buffer for this
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 6d08842..2b5debf 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -152,6 +152,8 @@
SP_LOGV("%s: Disconnected", __FUNCTION__);
}
+Camera3StreamSplitter::Camera3StreamSplitter(bool useHalBufManager) :
+ mUseHalBufManager(useHalBufManager) {}
Camera3StreamSplitter::~Camera3StreamSplitter() {
disconnect();
@@ -241,7 +243,9 @@
uint64_t usage = 0;
res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(outputQueue.get()), &usage);
if (!(usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE))) {
- outputQueue->setDequeueTimeout(kDequeueBufferTimeout);
+ nsecs_t timeout = mUseHalBufManager ?
+ kHalBufMgrDequeueBufferTimeout : kNormalDequeueBufferTimeout;
+ outputQueue->setDequeueTimeout(timeout);
}
res = gbp->allowAllocation(false);
@@ -436,8 +440,9 @@
res = gbp->attachBuffer(&slot, gb);
mMutex.lock();
if (res != OK) {
- SP_LOGE("%s: Cannot acquireBuffer from GraphicBufferProducer %p: %s (%d)",
+ SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)",
__FUNCTION__, gbp.get(), strerror(-res), res);
+ // TODO: might need to detach/cleanup the already attached buffers before return?
return res;
}
if ((slot < 0) || (slot > BufferQueue::NUM_BUFFER_SLOTS)) {
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 1eaf2bd..960f7aa 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -49,7 +49,7 @@
public:
// Constructor
- Camera3StreamSplitter() = default;
+ Camera3StreamSplitter(bool useHalBufManager = false);
// Connect to the stream splitter by creating buffer queue and connecting it
// with output surfaces.
@@ -226,7 +226,10 @@
android::PixelFormat mFormat = android::PIXEL_FORMAT_NONE;
uint64_t mProducerUsage = 0;
- static const nsecs_t kDequeueBufferTimeout = s2ns(1); // 1 sec
+ // The attachBuffer call will happen on different thread according to mUseHalBufManager and have
+ // different timing constraint.
+ static const nsecs_t kNormalDequeueBufferTimeout = s2ns(1); // 1 sec
+ static const nsecs_t kHalBufMgrDequeueBufferTimeout = ms2ns(1); // 1 msec
Mutex mMutex;
@@ -273,6 +276,8 @@
size_t mAcquiredInputBuffers;
String8 mConsumerName;
+
+ const bool mUseHalBufManager;
};
} // namespace android
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index e870965..227a29d 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -29,7 +29,8 @@
libhidlmemory \
libhidltransport \
android.hardware.drm@1.0 \
- android.hardware.drm@1.1
+ android.hardware.drm@1.1 \
+ android.hardware.drm@1.2
LOCAL_CFLAGS += -Wall -Wextra -Werror
diff --git a/services/soundtrigger/SoundTriggerHalHidl.cpp b/services/soundtrigger/SoundTriggerHalHidl.cpp
index 0f9aa15..1d37a8e 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.cpp
+++ b/services/soundtrigger/SoundTriggerHalHidl.cpp
@@ -356,8 +356,7 @@
return hidlReturn;
}
-int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle,
- struct sound_trigger_recognition_event** event)
+int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
{
sp<ISoundTriggerHw> soundtrigger = getService();
if (soundtrigger == 0) {
@@ -377,24 +376,13 @@
}
int ret = NO_ERROR;
- Return<void> hidlReturn;
+ Return<int32_t> hidlReturn(0);
{
AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_2->getModelState(
- model->mHalHandle,
- [&](int r, const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent) {
- ret = r;
- if (ret != 0) {
- ALOGE("getModelState returned error code %d", ret);
- } else {
- *event = convertRecognitionEventFromHal(&halEvent);
- }
- });
+ hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
}
if (!hidlReturn.isOk()) {
ALOGE("getModelState error %s", hidlReturn.description().c_str());
- free(*event);
- *event = nullptr;
ret = FAILED_TRANSACTION;
}
return ret;
diff --git a/services/soundtrigger/SoundTriggerHalHidl.h b/services/soundtrigger/SoundTriggerHalHidl.h
index 3f4bec3..fb9e39e 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.h
+++ b/services/soundtrigger/SoundTriggerHalHidl.h
@@ -96,12 +96,12 @@
virtual int stopAllRecognitions();
/* Get the current state of a given model.
- * Returns 0 or an error code. If successful it also sets indicated the event pointer
- * and expectes that the caller will free the memory.
+ * Returns 0 or an error code. If successful the state will be returned asynchronously
+ * via a recognition event in the callback method that was registered in the
+ * startRecognition() method.
* Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
*/
- virtual int getModelState(sound_model_handle_t handle,
- struct sound_trigger_recognition_event** event);
+ virtual int getModelState(sound_model_handle_t handle);
// ISoundTriggerHwCallback
virtual ::android::hardware::Return<void> recognitionCallback(
diff --git a/services/soundtrigger/SoundTriggerHalInterface.h b/services/soundtrigger/SoundTriggerHalInterface.h
index 076ca23..0183ece 100644
--- a/services/soundtrigger/SoundTriggerHalInterface.h
+++ b/services/soundtrigger/SoundTriggerHalInterface.h
@@ -72,12 +72,12 @@
virtual int stopAllRecognitions() = 0;
/* Get the current state of a given model.
- * Returns 0 or an error code. If successful it also sets indicated the event pointer
- * and expectes that the caller will free the memory.
+ * Returns 0 or an error code. If successful the state will be returned asynchronously
+ * via a recognition event in the callback method that was registered in the
+ * startRecognition() method.
* Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
*/
- virtual int getModelState(sound_model_handle_t handle,
- struct sound_trigger_recognition_event** event) = 0;
+ virtual int getModelState(sound_model_handle_t handle) = 0;
protected:
SoundTriggerHalInterface() {}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 79e9e88..7915068 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -717,8 +717,7 @@
return NO_ERROR;
}
-status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory)
+status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
{
ALOGV("getModelState() model handle %d", handle);
if (mHalInterface == 0) {
@@ -734,21 +733,7 @@
return INVALID_OPERATION;
}
- if (model->mType != SOUND_MODEL_TYPE_GENERIC) {
- return BAD_VALUE;
- }
-
- struct sound_trigger_recognition_event* event = nullptr;
- status_t status = mHalInterface->getModelState(handle, &event);
- if (status == NO_ERROR) {
- sp<SoundTriggerHwService> service;
- service = mService.promote();
- if (service != 0) {
- eventMemory = service->prepareRecognitionEvent(event);
- }
- free(event);
- }
- return status;
+ return mHalInterface->getModelState(handle);
}
void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
@@ -784,7 +769,10 @@
}
recognitionEvent->capture_session = model->mCaptureSession;
- model->mState = Model::STATE_IDLE;
+ // Don't reset the model state if this recognition event is a get-state response
+ if (recognitionEvent->status != RECOGNITION_STATUS_GET_STATE_RESPONSE) {
+ model->mState = Model::STATE_IDLE;
+ }
clients.add(model->mModuleClient);
}
} break;
@@ -1052,8 +1040,7 @@
return module->stopRecognition(handle);
}
-status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory)
+status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
{
ALOGV("getModelState() model handle %d", handle);
if (!captureHotwordAllowed(IPCThreadState::self()->getCallingPid(),
@@ -1065,7 +1052,7 @@
if (module == 0) {
return NO_INIT;
}
- return module->getModelState(handle, eventMemory);
+ return module->getModelState(handle);
}
void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index c222cd9..4258ec0 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -122,8 +122,7 @@
virtual status_t startRecognition(sound_model_handle_t handle,
const sp<IMemory>& dataMemory);
virtual status_t stopRecognition(sound_model_handle_t handle);
- virtual status_t getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory);
+ virtual status_t getModelState(sound_model_handle_t handle);
sp<SoundTriggerHalInterface> halInterface() const { return mHalInterface; }
struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
@@ -171,8 +170,7 @@
virtual status_t startRecognition(sound_model_handle_t handle,
const sp<IMemory>& dataMemory);
virtual status_t stopRecognition(sound_model_handle_t handle);
- virtual status_t getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory);
+ virtual status_t getModelState(sound_model_handle_t handle);
virtual status_t dump(int fd, const Vector<String16>& args);
diff --git a/soundtrigger/ISoundTrigger.cpp b/soundtrigger/ISoundTrigger.cpp
index 32882f1..f5b4b59 100644
--- a/soundtrigger/ISoundTrigger.cpp
+++ b/soundtrigger/ISoundTrigger.cpp
@@ -114,8 +114,7 @@
return status;
}
- virtual status_t getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory)
+ virtual status_t getModelState(sound_model_handle_t handle)
{
Parcel data, reply;
data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
@@ -123,9 +122,6 @@
status_t status = remote()->transact(GET_MODEL_STATE, data, &reply);
if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
- if (status == NO_ERROR) {
- eventMemory = interface_cast<IMemory>(reply.readStrongBinder());
- }
}
return status;
}
@@ -192,14 +188,7 @@
status_t status = UNKNOWN_ERROR;
status_t ret = data.read(&handle, sizeof(sound_model_handle_t));
if (ret == NO_ERROR) {
- sp<IMemory> eventMemory;
- status = getModelState(handle, eventMemory);
- if (eventMemory != NULL) {
- ret = reply->writeStrongBinder(
- IInterface::asBinder(eventMemory));
- } else {
- ret = NO_MEMORY;
- }
+ status = getModelState(handle);
}
reply->writeInt32(status);
return ret;
diff --git a/soundtrigger/SoundTrigger.cpp b/soundtrigger/SoundTrigger.cpp
index bb0650f..d1eb367 100644
--- a/soundtrigger/SoundTrigger.cpp
+++ b/soundtrigger/SoundTrigger.cpp
@@ -188,14 +188,13 @@
return mISoundTrigger->stopRecognition(handle);
}
-status_t SoundTrigger::getModelState(sound_model_handle_t handle,
- sp<IMemory>& eventMemory)
+status_t SoundTrigger::getModelState(sound_model_handle_t handle)
{
Mutex::Autolock _l(mLock);
if (mISoundTrigger == 0) {
return NO_INIT;
}
- return mISoundTrigger->getModelState(handle, eventMemory);
+ return mISoundTrigger->getModelState(handle);
}
// BpSoundTriggerClient