Merge "codec2 hal: type conversion refactoring, step 2" into main am: d758be4c3f am: 5419864e7c am: deeb938092 am: 45d19b7c75 am: 54ed5919f6
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2620618
Change-Id: Id1fae4d944fcedecb6720c4e7682e8b43028bcff
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 2244682..35b8e21 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -19,7 +19,6 @@
#define LOG_TAG "Camera"
#include <utils/Log.h>
#include <utils/threads.h>
-#include <utils/String16.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
@@ -70,7 +69,7 @@
// deadlock if we call any method of ICamera here.
}
-sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
+sp<Camera> Camera::connect(int cameraId, const std::string& clientPackageName,
int clientUid, int clientPid, int targetSdkVersion, bool overrideToPortrait,
bool forceSlowJpegMode)
{
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 9ae4607..2a102d0 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -31,6 +31,7 @@
#include <camera/CameraBase.h>
#include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
// needed to instantiate
#include <camera/Camera.h>
@@ -58,7 +59,7 @@
}
status_t CameraStatus::writeToParcel(android::Parcel* parcel) const {
- auto res = parcel->writeString16(String16(cameraId));
+ auto res = parcel->writeString16(toString16(cameraId));
if (res != OK) return res;
res = parcel->writeInt32(status);
@@ -66,12 +67,12 @@
std::vector<String16> unavailablePhysicalIds16;
for (auto& id8 : unavailablePhysicalIds) {
- unavailablePhysicalIds16.push_back(String16(id8));
+ unavailablePhysicalIds16.push_back(toString16(id8));
}
res = parcel->writeString16Vector(unavailablePhysicalIds16);
if (res != OK) return res;
- res = parcel->writeString16(String16(clientPackage));
+ res = parcel->writeString16(toString16(clientPackage));
return res;
}
@@ -79,7 +80,7 @@
String16 tempCameraId;
auto res = parcel->readString16(&tempCameraId);
if (res != OK) return res;
- cameraId = String8(tempCameraId);
+ cameraId = toString8(tempCameraId);
res = parcel->readInt32(&status);
if (res != OK) return res;
@@ -88,13 +89,13 @@
res = parcel->readString16Vector(&unavailablePhysicalIds16);
if (res != OK) return res;
for (auto& id16 : unavailablePhysicalIds16) {
- unavailablePhysicalIds.push_back(String8(id16));
+ unavailablePhysicalIds.push_back(toStdString(id16));
}
String16 tempClientPackage;
res = parcel->readString16(&tempClientPackage);
if (res != OK) return res;
- clientPackage = String8(tempClientPackage);
+ clientPackage = toStdString(tempClientPackage);
return res;
}
@@ -103,7 +104,6 @@
namespace {
sp<::android::hardware::ICameraService> gCameraService;
- const int kCameraServicePollDelay = 500000; // 0.5s
const char* kCameraServiceName = "media.camera";
Mutex gLock;
@@ -141,14 +141,10 @@
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
- do {
- binder = sm->getService(String16(kCameraServiceName));
- if (binder != 0) {
- break;
- }
- ALOGW("CameraService not published, waiting...");
- usleep(kCameraServicePollDelay);
- } while(true);
+ binder = sm->waitForService(toString16(kCameraServiceName));
+ if (binder == nullptr) {
+ return nullptr;
+ }
if (gDeathNotifier == NULL) {
gDeathNotifier = new DeathNotifier();
}
@@ -161,7 +157,7 @@
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
int clientUid, int clientPid, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode)
{
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 9e9793d..36bf24c 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -20,6 +20,7 @@
#include <utils/String16.h>
#include <camera/CameraSessionStats.h>
+#include <camera/StringUtils.h>
#include <binder/Parcel.h>
@@ -282,8 +283,8 @@
mSessionIndex(0),
mCameraExtensionSessionStats() {}
-CameraSessionStats::CameraSessionStats(const String16& cameraId,
- int facing, int newCameraState, const String16& clientName,
+CameraSessionStats::CameraSessionStats(const std::string& cameraId,
+ int facing, int newCameraState, const std::string& clientName,
int apiLevel, bool isNdk, int32_t latencyMs, int64_t logId) :
mCameraId(cameraId),
mFacing(facing),
@@ -425,10 +426,10 @@
return err;
}
- mCameraId = id;
+ mCameraId = toStdString(id);
mFacing = facing;
mNewCameraState = newCameraState;
- mClientName = clientName;
+ mClientName = toStdString(clientName);
mApiLevel = apiLevel;
mIsNdk = isNdk;
mLatencyMs = latencyMs;
@@ -440,7 +441,7 @@
mResultErrorCount = resultErrorCount;
mDeviceError = deviceError;
mStreamStats = std::move(streamStats);
- mUserTag = userTag;
+ mUserTag = toStdString(userTag);
mVideoStabilizationMode = videoStabilizationMode;
mSessionIndex = sessionIdx;
mCameraExtensionSessionStats = extStats;
@@ -456,7 +457,7 @@
status_t err = OK;
- if ((err = parcel->writeString16(mCameraId)) != OK) {
+ if ((err = parcel->writeString16(toString16(mCameraId))) != OK) {
ALOGE("%s: Failed to write camera id!", __FUNCTION__);
return err;
}
@@ -471,7 +472,7 @@
return err;
}
- if ((err = parcel->writeString16(mClientName)) != OK) {
+ if ((err = parcel->writeString16(toString16(mClientName))) != OK) {
ALOGE("%s: Failed to write client name!", __FUNCTION__);
return err;
}
@@ -531,7 +532,7 @@
return err;
}
- if ((err = parcel->writeString16(mUserTag)) != OK) {
+ if ((err = parcel->writeString16(toString16(mUserTag))) != OK) {
ALOGE("%s: Failed to write user tag!", __FUNCTION__);
return err;
}
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index bb880d1..9ff2578 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -18,6 +18,7 @@
#include <utils/Log.h>
#include <camera/CaptureResult.h>
+#include <camera/StringUtils.h>
#include <binder/Parcel.h>
namespace android {
@@ -47,7 +48,7 @@
ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
return res;
}
- errorPhysicalCameraId = cameraId;
+ errorPhysicalCameraId = toStdString(cameraId);
}
parcel->readInt64(&lastCompletedRegularFrameNumber);
parcel->readInt64(&lastCompletedReprocessFrameNumber);
@@ -75,7 +76,7 @@
if (errorPhysicalCameraId.size() > 0) {
parcel->writeBool(true);
status_t res = OK;
- if ((res = parcel->writeString16(errorPhysicalCameraId)) != OK) {
+ if ((res = parcel->writeString16(toString16(errorPhysicalCameraId))) != OK) {
ALOGE("%s: Failed to write physical camera ID to parcel: %d", __FUNCTION__, res);
return res;
}
@@ -96,13 +97,15 @@
status_t PhysicalCaptureResultInfo::readFromParcel(const android::Parcel* parcel) {
status_t res;
- mPhysicalCameraId.setTo(u"");
+ mPhysicalCameraId = "";
mPhysicalCameraMetadata.clear();
- if ((res = parcel->readString16(&mPhysicalCameraId)) != OK) {
+ String16 physicalCameraId;
+ if ((res = parcel->readString16(&physicalCameraId)) != OK) {
ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
return res;
}
+ mPhysicalCameraId = toStdString(physicalCameraId);
if ((res = mPhysicalCameraMetadata.readFromParcel(parcel)) != OK) {
ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
@@ -113,7 +116,7 @@
status_t PhysicalCaptureResultInfo::writeToParcel(android::Parcel* parcel) const {
status_t res;
- if ((res = parcel->writeString16(mPhysicalCameraId)) != OK) {
+ if ((res = parcel->writeString16(toString16(mPhysicalCameraId))) != OK) {
ALOGE("%s: Failed to write physical camera ID to parcel: %d",
__FUNCTION__, res);
return res;
@@ -187,7 +190,8 @@
return res;
}
- mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), cameraId, physicalMetadata);
+ mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), toStdString(cameraId),
+ physicalMetadata);
}
ALOGV("%s: Read physical metadata from parcel", __FUNCTION__);
@@ -228,7 +232,7 @@
return BAD_VALUE;
}
for (const auto& physicalMetadata : mPhysicalMetadatas) {
- if ((res = parcel->writeString16(physicalMetadata.mPhysicalCameraId)) != OK) {
+ if ((res = parcel->writeString16(toString16(physicalMetadata.mPhysicalCameraId))) != OK) {
ALOGE("%s: Failed to write physical camera ID to parcel: %d",
__FUNCTION__, res);
return res;
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index f8e1631..ed37b2d 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -82,7 +82,7 @@
*/
ICamera connect(ICameraClient client,
int cameraId,
- String opPackageName,
+ @utf8InCpp String opPackageName,
int clientUid, int clientPid,
int targetSdkVersion,
boolean overrideToPortrait,
@@ -93,9 +93,9 @@
* Only supported for device HAL versions >= 3.2
*/
ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,
- String cameraId,
- String opPackageName,
- @nullable String featureId,
+ @utf8InCpp String cameraId,
+ @utf8InCpp String opPackageName,
+ @nullable @utf8InCpp String featureId,
int clientUid, int oomScoreOffset,
int targetSdkVersion,
boolean overrideToPortrait);
@@ -139,7 +139,7 @@
* Read the static camera metadata for a camera device.
* Only supported for device HAL versions >= 3.2
*/
- CameraMetadataNative getCameraCharacteristics(String cameraId, int targetSdkVersion,
+ CameraMetadataNative getCameraCharacteristics(@utf8InCpp String cameraId, int targetSdkVersion,
boolean overrideToPortrait);
/**
@@ -160,7 +160,7 @@
/**
* Read the legacy camera1 parameters into a String
*/
- String getLegacyParameters(int cameraId);
+ @utf8InCpp String getLegacyParameters(int cameraId);
/**
* apiVersion constants for supportsCameraApi
@@ -169,21 +169,21 @@
const int API_VERSION_2 = 2;
// Determines if a particular API version is supported directly for a cameraId.
- boolean supportsCameraApi(String cameraId, int apiVersion);
+ boolean supportsCameraApi(@utf8InCpp String cameraId, int apiVersion);
// Determines if a cameraId is a hidden physical camera of a logical multi-camera.
- boolean isHiddenPhysicalCamera(String cameraId);
+ boolean isHiddenPhysicalCamera(@utf8InCpp String cameraId);
// Inject the external camera to replace the internal camera session.
- ICameraInjectionSession injectCamera(String packageName, String internalCamId,
- String externalCamId, in ICameraInjectionCallback CameraInjectionCallback);
+ ICameraInjectionSession injectCamera(@utf8InCpp String packageName, @utf8InCpp String internalCamId,
+ @utf8InCpp String externalCamId, in ICameraInjectionCallback CameraInjectionCallback);
- void setTorchMode(String cameraId, boolean enabled, IBinder clientBinder);
+ void setTorchMode(@utf8InCpp String cameraId, boolean enabled, IBinder clientBinder);
// Change the brightness level of the flash unit associated with cameraId to strengthLevel.
// If the torch is in OFF state and strengthLevel > 0 then the torch will also be turned ON.
- void turnOnTorchWithStrengthLevel(String cameraId, int strengthLevel, IBinder clientBinder);
+ void turnOnTorchWithStrengthLevel(@utf8InCpp String cameraId, int strengthLevel, IBinder clientBinder);
// Get the brightness level of the flash unit associated with cameraId.
- int getTorchStrengthLevel(String cameraId);
+ int getTorchStrengthLevel(@utf8InCpp String cameraId);
/**
* Notify the camera service of a system event. Should only be called from system_server.
@@ -233,7 +233,7 @@
*
* @return the key that must be used to report updates to previously reported stats.
*/
- String reportExtensionSessionStats(in CameraExtensionSessionStats stats);
+ @utf8InCpp String reportExtensionSessionStats(in CameraExtensionSessionStats stats);
// Bitfield constants for notifyDeviceStateChange
// All bits >= 32 are for custom vendor states
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index 5f17f5b..23a87d3 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -51,13 +51,14 @@
// Use to initialize variables only
const int STATUS_UNKNOWN = -1;
- oneway void onStatusChanged(int status, String cameraId);
+ oneway void onStatusChanged(int status, @utf8InCpp String cameraId);
/**
* Notify registered client about status changes for a physical camera backing
* a logical camera.
*/
- oneway void onPhysicalCameraStatusChanged(int status, String cameraId, String physicalCameraId);
+ oneway void onPhysicalCameraStatusChanged(int status, @utf8InCpp String cameraId,
+ @utf8InCpp String physicalCameraId);
/**
* The torch mode status of a camera.
@@ -81,9 +82,9 @@
// Use to initialize variables only
const int TORCH_STATUS_UNKNOWN = -1;
- oneway void onTorchStatusChanged(int status, String cameraId);
+ oneway void onTorchStatusChanged(int status, @utf8InCpp String cameraId);
- oneway void onTorchStrengthLevelChanged(String cameraId, int newTorchStrength);
+ oneway void onTorchStrengthLevelChanged(@utf8InCpp String cameraId, int newTorchStrength);
/**
* Notify registered clients about camera access priority changes.
@@ -97,6 +98,6 @@
* Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission
* will receive such callbacks.
*/
- oneway void onCameraOpened(String cameraId, String clientPackageId);
- oneway void onCameraClosed(String cameraId);
+ oneway void onCameraOpened(@utf8InCpp String cameraId, @utf8InCpp String clientPackageId);
+ oneway void onCameraClosed(@utf8InCpp String cameraId);
}
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 4faa6b4..dcd69b0 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -44,14 +44,14 @@
* {@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_180},
* {@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_270}).
*/
- int getRotateAndCropOverride(String packageName, int lensFacing, int userId);
+ int getRotateAndCropOverride(@utf8InCpp String packageName, int lensFacing, int userId);
/**
* Returns the necessary autoframing override for the top activity which
* will be one of ({@link android.hardware.camera2.CameraMetadata#AUTOFRAMING_FALSE},
* {@link android.hardware.camera2.CameraMetadata#AUTOFRAMING_TRUE}).
*/
- int getAutoframingOverride(String packageName);
+ int getAutoframingOverride(@utf8InCpp String packageName);
/**
* Checks if the camera has been disabled via device policy.
diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp
index 7a8a4ba..071f34e 100644
--- a/camera/camera2/CaptureRequest.cpp
+++ b/camera/camera2/CaptureRequest.cpp
@@ -21,6 +21,7 @@
#include <utils/String16.h>
#include <camera/camera2/CaptureRequest.h>
+#include <camera/StringUtils.h>
#include <binder/Parcel.h>
#include <gui/Surface.h>
@@ -74,7 +75,7 @@
return err;
}
ALOGV("%s: Read metadata from parcel", __FUNCTION__);
- mPhysicalCameraSettings.push_back({std::string(String8(id).string()), settings});
+ mPhysicalCameraSettings.push_back({toStdString(id), settings});
}
int isReprocess = 0;
@@ -157,7 +158,7 @@
ALOGE("%s: Failed to read user tag!", __FUNCTION__);
return BAD_VALUE;
}
- mUserTag = String8(userTag).c_str();
+ mUserTag = toStdString(userTag);
}
return OK;
@@ -179,7 +180,7 @@
}
for (const auto &it : mPhysicalCameraSettings) {
- if ((err = parcel->writeString16(String16(it.id.c_str()))) != OK) {
+ if ((err = parcel->writeString16(toString16(it.id))) != OK) {
ALOGE("%s: Failed to camera id!", __FUNCTION__);
return err;
}
@@ -232,7 +233,7 @@
parcel->writeInt32(0);
} else {
parcel->writeInt32(1);
- parcel->writeString16(String16(mUserTag.c_str()));
+ parcel->writeString16(toString16(mUserTag));
}
return OK;
diff --git a/camera/camera2/ConcurrentCamera.cpp b/camera/camera2/ConcurrentCamera.cpp
index 01a695c..67aa876 100644
--- a/camera/camera2/ConcurrentCamera.cpp
+++ b/camera/camera2/ConcurrentCamera.cpp
@@ -20,6 +20,7 @@
#include <utils/String16.h>
#include <camera/camera2/ConcurrentCamera.h>
+#include <camera/StringUtils.h>
#include <binder/Parcel.h>
@@ -53,7 +54,7 @@
ALOGE("%s: Failed to read camera id!", __FUNCTION__);
return err;
}
- mConcurrentCameraIds.push_back(std::string(String8(id).string()));
+ mConcurrentCameraIds.push_back(toStdString(id));
}
return OK;
}
@@ -73,7 +74,7 @@
}
for (const auto &it : mConcurrentCameraIds) {
- if ((err = parcel->writeString16(String16(it.c_str()))) != OK) {
+ if ((err = parcel->writeString16(toString16(it))) != OK) {
ALOGE("%s: Failed to write the camera id string to parcel: %d", __FUNCTION__, err);
return err;
}
@@ -99,7 +100,7 @@
ALOGE("%s: Failed to read sessionConfiguration!", __FUNCTION__);
return err;
}
- mCameraId = std::string(String8(id).string());
+ mCameraId = toStdString(id);
return OK;
}
@@ -111,7 +112,7 @@
}
status_t err = OK;
- if ((err = parcel->writeString16(String16(mCameraId.c_str()))) != OK) {
+ if ((err = parcel->writeString16(toString16(mCameraId))) != OK) {
ALOGE("%s: Failed to write camera id!", __FUNCTION__);
return err;
}
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index da4484a..33220ce 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <camera/camera2/OutputConfiguration.h>
+#include <camera/StringUtils.h>
#include <binder/Parcel.h>
#include <gui/view/Surface.h>
#include <system/camera_metadata.h>
@@ -65,7 +66,7 @@
return mIsShared;
}
-String16 OutputConfiguration::getPhysicalCameraId() const {
+std::string OutputConfiguration::getPhysicalCameraId() const {
return mPhysicalCameraId;
}
@@ -183,7 +184,9 @@
return err;
}
- parcel->readString16(&mPhysicalCameraId);
+ String16 physicalCameraId;
+ parcel->readString16(&physicalCameraId);
+ mPhysicalCameraId = toStdString(physicalCameraId);
int isMultiResolution = 0;
if ((err = parcel->readInt32(&isMultiResolution)) != OK) {
@@ -246,7 +249,7 @@
for (auto& surface : surfaceShims) {
ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
surface.graphicBufferProducer.get(),
- String8(surface.name).string());
+ toString8(surface.name).string());
mGbps.push_back(surface.graphicBufferProducer);
}
@@ -258,14 +261,14 @@
" physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %" PRId64
", timestampBase = %d, mirrorMode = %d, useReadoutTimestamp = %d",
__FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType,
- String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase,
+ mPhysicalCameraId.c_str(), mIsMultiResolution, mStreamUseCase, timestampBase,
mMirrorMode, mUseReadoutTimestamp);
return err;
}
OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
- const String16& physicalId,
+ const std::string& physicalId,
int surfaceSetID, bool isShared) {
mGbps.push_back(gbp);
mRotation = rotation;
@@ -284,7 +287,7 @@
OutputConfiguration::OutputConfiguration(
const std::vector<sp<IGraphicBufferProducer>>& gbps,
- int rotation, const String16& physicalCameraId, int surfaceSetID, int surfaceType,
+ int rotation, const std::string& physicalCameraId, int surfaceSetID, int surfaceType,
int width, int height, bool isShared)
: mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType),
mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
@@ -331,7 +334,8 @@
err = parcel->writeParcelableVector(surfaceShims);
if (err != OK) return err;
- err = parcel->writeString16(mPhysicalCameraId);
+ String16 physicalCameraId = toString16(mPhysicalCameraId);
+ err = parcel->writeString16(physicalCameraId);
if (err != OK) return err;
err = parcel->writeInt32(mIsMultiResolution ? 1 : 0);
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 8472562..13b705c 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -26,12 +26,15 @@
srcs: ["main_cameraserver.cpp"],
+ defaults: [
+ "libcameraservice_deps",
+ ],
+
header_libs: [
"libmedia_headers",
],
shared_libs: [
- "libcameraservice",
"liblog",
"libutils",
"libui",
@@ -40,15 +43,13 @@
"libbinder_ndk",
"libhidlbase",
"android.hardware.camera.common@1.0",
- "android.hardware.camera.provider@2.4",
- "android.hardware.camera.provider@2.5",
- "android.hardware.camera.provider@2.6",
- "android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
],
+ static_libs: [
+ "libcameraservice",
+ ],
compile_multilib: "first",
cflags: [
"-Wall",
diff --git a/camera/include/camera/Camera.h b/camera/include/camera/Camera.h
index 21b57af..6655f82 100644
--- a/camera/include/camera/Camera.h
+++ b/camera/include/camera/Camera.h
@@ -56,9 +56,9 @@
typedef CameraListener TCamListener;
typedef ::android::hardware::ICamera TCamUser;
typedef ::android::hardware::ICameraClient TCamCallbacks;
- typedef ::android::binder::Status(::android::hardware::ICameraService::*TCamConnectService)
+ typedef ::android::binder::Status (::android::hardware::ICameraService::*TCamConnectService)
(const sp<::android::hardware::ICameraClient>&,
- int, const String16&, int, int, int, bool, bool,
+ int, const std::string&, int, int, int, bool, bool,
/*out*/
sp<::android::hardware::ICamera>*);
static TCamConnectService fnConnectService;
@@ -80,7 +80,7 @@
// construct a camera client from an existing remote
static sp<Camera> create(const sp<::android::hardware::ICamera>& camera);
static sp<Camera> connect(int cameraId,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
int clientUid, int clientPid, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode);
diff --git a/camera/include/camera/CameraBase.h b/camera/include/camera/CameraBase.h
index b20dc1b..6af7f2a 100644
--- a/camera/include/camera/CameraBase.h
+++ b/camera/include/camera/CameraBase.h
@@ -73,7 +73,7 @@
/**
* The name of the camera device
*/
- String8 cameraId;
+ std::string cameraId;
/**
* Its current status, one of the ICameraService::STATUS_* fields
@@ -83,18 +83,18 @@
/**
* Unavailable physical camera names for a multi-camera device
*/
- std::vector<String8> unavailablePhysicalIds;
+ std::vector<std::string> unavailablePhysicalIds;
/**
* Client package name if camera is open, otherwise not applicable
*/
- String8 clientPackage;
+ std::string clientPackage;
virtual status_t writeToParcel(android::Parcel* parcel) const;
virtual status_t readFromParcel(const android::Parcel* parcel);
- CameraStatus(String8 id, int32_t s, const std::vector<String8>& unavailSubIds,
- const String8& clientPkg) : cameraId(id), status(s),
+ CameraStatus(std::string id, int32_t s, const std::vector<std::string>& unavailSubIds,
+ const std::string& clientPkg) : cameraId(id), status(s),
unavailablePhysicalIds(unavailSubIds), clientPackage(clientPkg) {}
CameraStatus() : status(ICameraServiceListener::STATUS_PRESENT) {}
};
@@ -118,7 +118,7 @@
typedef typename TCamTraits::TCamConnectService TCamConnectService;
static sp<TCam> connect(int cameraId,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
int clientUid, int clientPid, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode);
virtual void disconnect();
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 071bc736..70ca0b3 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
#define ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
+#include <string>
+
#include <binder/Parcelable.h>
#include <camera/CameraMetadata.h>
@@ -121,10 +123,10 @@
static const int CAMERA_API_LEVEL_1;
static const int CAMERA_API_LEVEL_2;
- String16 mCameraId;
+ std::string mCameraId;
int mFacing;
int mNewCameraState;
- String16 mClientName;
+ std::string mClientName;
int mApiLevel;
bool mIsNdk;
// latency in ms for camera open, close, or session creation.
@@ -157,7 +159,7 @@
// Whether the device runs into an error state
bool mDeviceError;
std::vector<CameraStreamStats> mStreamStats;
- String16 mUserTag;
+ std::string mUserTag;
int mVideoStabilizationMode;
int mSessionIndex;
@@ -165,8 +167,8 @@
// Constructors
CameraSessionStats();
- CameraSessionStats(const String16& cameraId, int facing, int newCameraState,
- const String16& clientName, int apiLevel, bool isNdk, int32_t latencyMs,
+ CameraSessionStats(const std::string& cameraId, int facing, int newCameraState,
+ const std::string& clientName, int apiLevel, bool isNdk, int32_t latencyMs,
int64_t logId);
virtual status_t readFromParcel(const android::Parcel* parcel) override;
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index de534ab..e08c9ca 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -74,7 +74,7 @@
* a reference to physical camera device.
* Empty otherwise.
*/
- String16 errorPhysicalCameraId;
+ std::string errorPhysicalCameraId;
// The last completed frame numbers shouldn't be checked in onResultReceived() and notifyError()
// because the output buffers could be arriving after onResultReceived() and
@@ -150,13 +150,13 @@
: mPhysicalCameraId(),
mPhysicalCameraMetadata() {
}
- PhysicalCaptureResultInfo(const String16& cameraId,
+ PhysicalCaptureResultInfo(const std::string& cameraId,
const CameraMetadata& cameraMetadata)
: mPhysicalCameraId(cameraId),
mPhysicalCameraMetadata(cameraMetadata) {
}
- String16 mPhysicalCameraId;
+ std::string mPhysicalCameraId;
CameraMetadata mPhysicalCameraMetadata;
virtual status_t readFromParcel(const android::Parcel* parcel) override;
diff --git a/camera/include/camera/StringUtils.h b/camera/include/camera/StringUtils.h
new file mode 100644
index 0000000..b9dfbfc
--- /dev/null
+++ b/camera/include/camera/StringUtils.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_STRINGUTILS_H
+#define ANDROID_SERVERS_CAMERA_STRINGUTILS_H
+
+#include <codecvt>
+#include <locale>
+#include <memory>
+#include <optional>
+#include <string>
+
+#include <fmt/printf.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+ inline String8 toString8(const std::string &str) {
+ return String8(str.c_str());
+ }
+
+ inline String8 toString8(const String16 &str) {
+ return String8(str);
+ }
+
+ inline String8 toString8(const char *str) {
+ return String8(str);
+ }
+
+ inline String16 toString16(const std::string &str) {
+ return String16(str.c_str());
+ }
+
+ inline String16 toString16(const String8 &str) {
+ return String16(str);
+ }
+
+ inline String16 toString16(const char *str) {
+ return String16(str);
+ }
+
+ inline std::optional<String16> toString16(std::optional<std::string> str) {
+ if (str.has_value()) {
+ return std::optional<String16>(toString16(str.value()));
+ }
+
+ return std::nullopt;
+ }
+
+ inline std::string toStdString(const String8 &str) {
+ return std::string(str.string());
+ }
+
+ inline std::string toStdString(const String16 &str) {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ return convert.to_bytes(str.string());
+ }
+
+ /**
+ * Convert a non-null-terminated UTF16 string to a UTF8 string (i.e. in jni functions)
+ * len is the number of characters.
+ */
+ inline std::string toStdString(const char16_t *str, size_t len) {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ return convert.to_bytes(str, str + len);
+ }
+} // namespace android
+
+#endif // ANDROID_SERVERS_CAMERA_STRINGUTILS_H
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index 16fddb5..3f74b4a 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
#define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
+#include <string>
+
#include <gui/IGraphicBufferProducer.h>
#include <binder/Parcelable.h>
@@ -63,7 +65,7 @@
int32_t getColorSpace() const;
bool isDeferred() const;
bool isShared() const;
- String16 getPhysicalCameraId() const;
+ std::string getPhysicalCameraId() const;
bool isMultiResolution() const;
int64_t getStreamUseCase() const;
int getTimestampBase() const;
@@ -90,11 +92,11 @@
OutputConfiguration(const android::Parcel& parcel);
OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
- const String16& physicalCameraId,
+ const std::string& physicalCameraId,
int surfaceSetID = INVALID_SET_ID, bool isShared = false);
OutputConfiguration(const std::vector<sp<IGraphicBufferProducer>>& gbps,
- int rotation, const String16& physicalCameraId,
+ int rotation, const std::string& physicalCameraId,
int surfaceSetID = INVALID_SET_ID,
int surfaceType = OutputConfiguration::SURFACE_TYPE_UNKNOWN, int width = 0,
int height = 0, bool isShared = false);
@@ -192,7 +194,7 @@
int mHeight;
bool mIsDeferred;
bool mIsShared;
- String16 mPhysicalCameraId;
+ std::string mPhysicalCameraId;
bool mIsMultiResolution;
std::vector<int32_t> mSensorPixelModesUsed;
int64_t mDynamicRangeProfile;
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index bfd02b3..866dc72 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -182,6 +182,7 @@
shared_libs: [
"libcamera2ndk_vendor",
"libcamera_metadata",
+ "libhidlbase",
"libmediandk",
"libnativewindow",
"libutils",
@@ -191,6 +192,7 @@
],
static_libs: [
"android.hardware.camera.common@1.0-helper",
+ "android.hidl.token@1.0",
],
cflags: [
"-D__ANDROID_VNDK__",
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 1dae0f9..8bdb6d4 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -21,6 +21,7 @@
#include <inttypes.h>
#include <android/hardware/ICameraService.h>
#include <gui/Surface.h>
+#include <camera/StringUtils.h>
#include "ACameraDevice.h"
#include "ACameraMetadata.h"
#include "ACaptureRequest.h"
@@ -234,8 +235,7 @@
return ret;
}
- String16 physicalId16(output.mPhysicalCameraId.c_str());
- OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
+ OutputConfiguration outConfig(iGBP, output.mRotation, output.mPhysicalCameraId,
OutputConfiguration::INVALID_SET_ID, true);
for (auto& anw : output.mSharedWindows) {
@@ -299,8 +299,7 @@
return ret;
}
- String16 physicalId16(output->mPhysicalCameraId.c_str());
- OutputConfiguration outConfig(iGBP, output->mRotation, physicalId16,
+ OutputConfiguration outConfig(iGBP, output->mRotation, output->mPhysicalCameraId,
OutputConfiguration::INVALID_SET_ID, true);
for (auto& anw : output->mSharedWindows) {
@@ -683,9 +682,8 @@
if (ret != ACAMERA_OK) {
return ret;
}
- String16 physicalId16(outConfig.mPhysicalCameraId.c_str());
outputSet.insert(std::make_pair(
- anw, OutputConfiguration(iGBP, outConfig.mRotation, physicalId16,
+ anw, OutputConfiguration(iGBP, outConfig.mRotation, outConfig.mPhysicalCameraId,
OutputConfiguration::INVALID_SET_ID, outConfig.mIsShared)));
}
auto addSet = outputSet;
@@ -919,7 +917,7 @@
msg->setObject(kSessionSpKey, session);
if (cbh.mIsLogicalCameraCallback) {
if (resultExtras.errorPhysicalCameraId.size() > 0) {
- String8 cameraId(resultExtras.errorPhysicalCameraId);
+ String8 cameraId = toString8(resultExtras.errorPhysicalCameraId);
msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
}
msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
@@ -1215,7 +1213,7 @@
std::vector<std::string> physicalCameraIds;
std::vector<sp<ACameraMetadata>> physicalMetadataCopy;
for (size_t i = 0; i < physicalResultInfo.size(); i++) {
- String8 physicalId8(physicalResultInfo[i].mPhysicalCameraId);
+ String8 physicalId8 = toString8(physicalResultInfo[i].mPhysicalCameraId);
physicalCameraIds.push_back(physicalId8.c_str());
CameraMetadata clone = physicalResultInfo[i].mPhysicalCameraMetadata;
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 837b5be..299ffc0 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -25,6 +25,7 @@
#include <cutils/properties.h>
#include <stdlib.h>
#include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
#include <camera/VendorTagDescriptor.h>
using namespace android::acam;
@@ -84,7 +85,7 @@
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
- binder = sm->getService(String16(kCameraServiceName));
+ binder = sm->getService(toString16(kCameraServiceName));
if (binder != nullptr) {
break;
}
@@ -188,12 +189,12 @@
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
AutoMutex lock(cm->mLock);
- std::vector<String8> cameraIdList;
+ std::vector<std::string> cameraIdList;
for (auto& pair : cm->mDeviceStatusMap) {
cameraIdList.push_back(pair.first);
}
- for (String8 cameraId : cameraIdList) {
+ for (const std::string& cameraId : cameraIdList) {
cm->onStatusChangedLocked(
CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
}
@@ -259,7 +260,7 @@
// Send initial callbacks if callback is newly registered
if (pair.second) {
for (auto& pair : mDeviceStatusMap) {
- const String8& cameraId = pair.first;
+ const std::string& cameraId = pair.first;
int32_t status = pair.second.getStatus();
// Don't send initial callbacks for camera ids which don't support
// camera2
@@ -273,12 +274,12 @@
cb.mAvailable : cb.mUnavailable;
msg->setPointer(kCallbackFpKey, (void *) cbFunc);
msg->setPointer(kContextKey, cb.mContext);
- msg->setString(kCameraIdKey, AString(cameraId));
+ msg->setString(kCameraIdKey, AString(cameraId.c_str()));
mPendingCallbackCnt++;
msg->post();
// Physical camera unavailable callback
- std::set<String8> unavailablePhysicalCameras =
+ std::set<std::string> unavailablePhysicalCameras =
pair.second.getUnavailablePhysicalIds();
for (const auto& physicalCameraId : unavailablePhysicalCameras) {
sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
@@ -286,8 +287,8 @@
cb.mPhysicalCamUnavailable;
msg->setPointer(kCallbackFpKey, (void *) cbFunc);
msg->setPointer(kContextKey, cb.mContext);
- msg->setString(kCameraIdKey, AString(cameraId));
- msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+ msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+ msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
mPendingCallbackCnt++;
msg->post();
}
@@ -295,11 +296,11 @@
}
}
-bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
+bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
bool camera2Support = false;
auto cs = getCameraServiceLocked();
binder::Status serviceRet =
- cs->supportsCameraApi(String16(cameraId),
+ cs->supportsCameraApi(cameraId,
hardware::ICameraService::API_VERSION_2, &camera2Support);
if (!serviceRet.isOk()) {
ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
@@ -309,7 +310,7 @@
return camera2Support;
}
-void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
+void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) {
// Ensure that we have initialized/refreshed the list of available devices
Mutex::Autolock _l(mLock);
// Needed to make sure we're connected to cameraservice
@@ -459,10 +460,10 @@
}
binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
- int32_t status, const String16& cameraId) {
+ int32_t status, const std::string& cameraId) {
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
- cm->onStatusChanged(status, String8(cameraId));
+ cm->onStatusChanged(status, cameraId);
} else {
ALOGE("Cannot deliver status change. Global camera manager died");
}
@@ -470,10 +471,10 @@
}
binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
- int32_t status, const String16& cameraId, const String16& physicalCameraId) {
+ int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
- cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
+ cm->onStatusChanged(status, cameraId, physicalCameraId);
} else {
ALOGE("Cannot deliver physical camera status change. Global camera manager died");
}
@@ -495,13 +496,13 @@
}
void CameraManagerGlobal::onStatusChanged(
- int32_t status, const String8& cameraId) {
+ int32_t status, const std::string& cameraId) {
Mutex::Autolock _l(mLock);
onStatusChangedLocked(status, cameraId);
}
void CameraManagerGlobal::onStatusChangedLocked(
- int32_t status, const String8& cameraId) {
+ int32_t status, const std::string& cameraId) {
if (!validStatus(status)) {
ALOGE("%s: Invalid status %d", __FUNCTION__, status);
return;
@@ -534,7 +535,7 @@
cb.mAvailable : cb.mUnavailable;
msg->setPointer(kCallbackFpKey, (void *) cbFp);
msg->setPointer(kContextKey, cb.mContext);
- msg->setString(kCameraIdKey, AString(cameraId));
+ msg->setString(kCameraIdKey, AString(cameraId.c_str()));
mPendingCallbackCnt++;
msg->post();
}
@@ -545,13 +546,13 @@
}
void CameraManagerGlobal::onStatusChanged(
- int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+ int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
Mutex::Autolock _l(mLock);
onStatusChangedLocked(status, cameraId, physicalCameraId);
}
void CameraManagerGlobal::onStatusChangedLocked(
- int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+ int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
if (!validStatus(status)) {
ALOGE("%s: Invalid status %d", __FUNCTION__, status);
return;
@@ -567,7 +568,7 @@
if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
- __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
+ __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
return;
}
@@ -588,8 +589,8 @@
cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
msg->setPointer(kCallbackFpKey, (void *) cbFp);
msg->setPointer(kContextKey, cb.mContext);
- msg->setString(kCameraIdKey, AString(cameraId));
- msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+ msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+ msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
mPendingCallbackCnt++;
msg->post();
}
@@ -607,20 +608,20 @@
}
bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
- const String8& physicalCameraId) {
+ const std::string& physicalCameraId) {
std::lock_guard<std::mutex> lock(mLock);
auto result = unavailablePhysicalIds.insert(physicalCameraId);
return result.second;
}
bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
- const String8& physicalCameraId) {
+ const std::string& physicalCameraId) {
std::lock_guard<std::mutex> lock(mLock);
auto count = unavailablePhysicalIds.erase(physicalCameraId);
return count > 0;
}
-std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
+std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
std::lock_guard<std::mutex> lock(mLock);
return unavailablePhysicalIds;
}
@@ -635,7 +636,7 @@
ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
Mutex::Autolock _l(mLock);
- std::vector<String8> idList;
+ std::vector<std::string> idList;
CameraManagerGlobal::getInstance()->getCameraIdList(&idList);
int numCameras = idList.size();
@@ -652,7 +653,7 @@
return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
}
for (int i = 0; i < numCameras; i++) {
- const char* src = idList[i].string();
+ const char* src = idList[i].c_str();
size_t dstSize = strlen(src) + 1;
char* dst = new char[dstSize];
if (!dst) {
@@ -694,7 +695,7 @@
CameraMetadata rawMetadata;
int targetSdkVersion = android_get_application_target_sdk_version();
- binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr),
+ binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
targetSdkVersion, /*overrideToPortrait*/false, &rawMetadata);
if (!serviceRet.isOk()) {
switch(serviceRet.serviceSpecificErrorCode()) {
@@ -745,7 +746,7 @@
// No way to get package name from native.
// Send a zero length package name and let camera service figure it out from UID
binder::Status serviceRet = cs->connectDevice(
- callbacks, String16(cameraId), String16(""), {},
+ callbacks, cameraId, "", {},
hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
targetSdkVersion, /*overrideToPortrait*/false, /*out*/&deviceRemote);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 0dd79da..c135d0f 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -62,7 +62,7 @@
/**
* Return camera IDs that support camera2
*/
- void getCameraIdList(std::vector<String8> *cameraIds);
+ void getCameraIdList(std::vector<std::string> *cameraIds);
private:
sp<hardware::ICameraService> mCameraService;
@@ -87,23 +87,23 @@
class CameraServiceListener final : public hardware::BnCameraServiceListener {
public:
explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
- virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId);
+ virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId);
virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
- const String16& cameraId, const String16& physicalCameraId);
+ const std::string& cameraId, const std::string& physicalCameraId);
// Torch API not implemented yet
- virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
+ virtual binder::Status onTorchStatusChanged(int32_t, const std::string&) {
return binder::Status::ok();
}
- virtual binder::Status onTorchStrengthLevelChanged(const String16&, int32_t) {
+ virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t) {
return binder::Status::ok();
}
virtual binder::Status onCameraAccessPrioritiesChanged();
- virtual binder::Status onCameraOpened(const String16&, const String16&) {
+ virtual binder::Status onCameraOpened(const std::string&, const std::string&) {
return binder::Status::ok();
}
- virtual binder::Status onCameraClosed(const String16&) {
+ virtual binder::Status onCameraClosed(const std::string&) {
return binder::Status::ok();
}
@@ -203,20 +203,20 @@
sp<hardware::ICameraService> getCameraServiceLocked();
void onCameraAccessPrioritiesChanged();
- void onStatusChanged(int32_t status, const String8& cameraId);
- void onStatusChangedLocked(int32_t status, const String8& cameraId);
- void onStatusChanged(int32_t status, const String8& cameraId, const String8& physicalCameraId);
- void onStatusChangedLocked(int32_t status, const String8& cameraId,
- const String8& physicalCameraId);
+ void onStatusChanged(int32_t status, const std::string& cameraId);
+ void onStatusChangedLocked(int32_t status, const std::string& cameraId);
+ void onStatusChanged(int32_t status, const std::string& cameraId, const std::string& physicalCameraId);
+ void onStatusChangedLocked(int32_t status, const std::string& cameraId,
+ const std::string& physicalCameraId);
// Utils for status
static bool validStatus(int32_t status);
static bool isStatusAvailable(int32_t status);
- bool supportsCamera2ApiLocked(const String8 &cameraId);
+ bool supportsCamera2ApiLocked(const std::string &cameraId);
// The sort logic must match the logic in
// libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
struct CameraIdComparator {
- bool operator()(const String8& a, const String8& b) const {
+ bool operator()(const std::string& a, const std::string& b) const {
uint32_t aUint = 0, bUint = 0;
bool aIsUint = base::ParseUint(a.c_str(), &aUint);
bool bIsUint = base::ParseUint(b.c_str(), &bUint);
@@ -238,22 +238,22 @@
private:
int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
mutable std::mutex mLock;
- std::set<String8> unavailablePhysicalIds;
+ std::set<std::string> unavailablePhysicalIds;
public:
const bool supportsHAL3 = false;
StatusAndHAL3Support(int32_t st, bool HAL3support):
status(st), supportsHAL3(HAL3support) { };
StatusAndHAL3Support() = default;
- bool addUnavailablePhysicalId(const String8& physicalCameraId);
- bool removeUnavailablePhysicalId(const String8& physicalCameraId);
+ bool addUnavailablePhysicalId(const std::string& physicalCameraId);
+ bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
int32_t getStatus();
void updateStatus(int32_t newStatus);
- std::set<String8> getUnavailablePhysicalIds();
+ std::set<std::string> getUnavailablePhysicalIds();
};
// Map camera_id -> status
- std::map<String8, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
+ std::map<std::string, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
// For the singleton instance
static Mutex sLock;
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7f6ea9d..74c6cad 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -31,10 +31,13 @@
#include <stdio.h>
#include <android/log.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/hidl/token/1.0/ITokenManager.h>
#include <camera/NdkCameraError.h>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraCaptureSession.h>
+#include <hidl/ServiceManagement.h>
#include <media/NdkImage.h>
#include <media/NdkImageReader.h>
#include <cutils/native_handle.h>
@@ -50,6 +53,8 @@
static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+using android::hidl::manager::V1_0::IServiceManager;
+using android::hidl::token::V1_0::ITokenManager;
using ConfiguredWindows = std::set<const native_handle_t *>;
class CameraHelper {
@@ -981,11 +986,19 @@
TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+ auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+ if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+ GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+ }
testBasicTakePictures(/*prepareSurfaces*/ false);
testBasicTakePictures(/*prepareSurfaces*/ true);
}
TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+ auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+ if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+ GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+ }
for (auto & v2 : {true, false}) {
testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 1af5637..bb963ab 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -43,6 +43,7 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
+#include <camera/StringUtils.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IGraphicBufferProducer.h>
@@ -68,15 +69,15 @@
// Stub listener implementation
class TestCameraServiceListener : public hardware::BnCameraServiceListener {
- std::map<String16, int32_t> mCameraTorchStatuses;
- std::map<String16, int32_t> mCameraStatuses;
+ std::map<std::string, int32_t> mCameraTorchStatuses;
+ std::map<std::string, int32_t> mCameraStatuses;
mutable Mutex mLock;
mutable Condition mCondition;
mutable Condition mTorchCondition;
public:
virtual ~TestCameraServiceListener() {};
- virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId) {
+ virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId) override {
Mutex::Autolock l(mLock);
mCameraStatuses[cameraId] = status;
mCondition.broadcast();
@@ -84,36 +85,37 @@
};
virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
- const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+ const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) override {
// No op
return binder::Status::ok();
};
- virtual binder::Status onTorchStatusChanged(int32_t status, const String16& cameraId) {
+ virtual binder::Status onTorchStatusChanged(int32_t status,
+ const std::string& cameraId) override {
Mutex::Autolock l(mLock);
mCameraTorchStatuses[cameraId] = status;
mTorchCondition.broadcast();
return binder::Status::ok();
};
- virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
- int32_t /*torchStrength*/) {
+ virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
+ int32_t /*torchStrength*/) override {
// No op
return binder::Status::ok();
}
- virtual binder::Status onCameraAccessPrioritiesChanged() {
+ virtual binder::Status onCameraAccessPrioritiesChanged() override {
// No op
return binder::Status::ok();
}
- virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
- const String16& /*clientPackageName*/) {
+ virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageName*/) {
// No op
return binder::Status::ok();
}
- virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+ virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) override {
// No op
return binder::Status::ok();
}
@@ -136,7 +138,7 @@
bool waitForTorchState(int32_t status, int32_t cameraId) const {
Mutex::Autolock l(mLock);
- const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+ const auto& iter = mCameraTorchStatuses.find(std::to_string(cameraId));
if (iter != mCameraTorchStatuses.end() && iter->second == status) {
return true;
}
@@ -147,7 +149,7 @@
return false;
}
const auto& iter =
- mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+ mCameraTorchStatuses.find(std::to_string(cameraId));
foundStatus = (iter != mCameraTorchStatuses.end() && iter->second == status);
}
return true;
@@ -155,14 +157,14 @@
int32_t getTorchStatus(int32_t cameraId) const {
Mutex::Autolock l(mLock);
- const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
+ const auto& iter = mCameraTorchStatuses.find(std::to_string(cameraId));
if (iter == mCameraTorchStatuses.end()) {
return hardware::ICameraServiceListener::TORCH_STATUS_UNKNOWN;
}
return iter->second;
};
- int32_t getStatus(const String16& cameraId) const {
+ int32_t getStatus(const std::string& cameraId) const {
Mutex::Autolock l(mLock);
const auto& iter = mCameraStatuses.find(cameraId);
if (iter == mCameraStatuses.end()) {
@@ -352,11 +354,11 @@
EXPECT_EQ(numCameras, static_cast<const int>(statuses.size()));
for (const auto &it : statuses) {
- listener->onStatusChanged(it.status, String16(it.cameraId));
+ listener->onStatusChanged(it.status, it.cameraId);
}
for (int32_t i = 0; i < numCameras; i++) {
- String16 cameraId = String16(String8::format("%d", i));
+ std::string cameraId = std::to_string(i);
bool isSupported = false;
res = service->supportsCameraApi(cameraId,
hardware::ICameraService::API_VERSION_2, &isSupported);
@@ -384,7 +386,7 @@
// Check connect binder calls
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
- res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
+ res = service->connectDevice(callbacks, cameraId, "meeeeeeeee!",
{}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
/*overrideToPortrait*/false, /*out*/&device);
@@ -423,12 +425,12 @@
sp<TestCameraServiceListener> serviceListener;
std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>
- openNewDevice(const String16& deviceId) {
+ openNewDevice(const std::string& deviceId) {
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
{
SCOPED_TRACE("openNewDevice");
- binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
+ binder::Status res = service->connectDevice(callbacks, deviceId, "meeeeeeeee!",
{}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
/*overrideToPortrait*/false, /*out*/&device);
@@ -464,7 +466,7 @@
std::vector<hardware::CameraStatus> statuses;
service->addListener(serviceListener, &statuses);
for (const auto &it : statuses) {
- serviceListener->onStatusChanged(it.status, String16(it.cameraId));
+ serviceListener->onStatusChanged(it.status, it.cameraId);
}
service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
&numCameras);
@@ -484,9 +486,8 @@
ASSERT_NOT_NULL(service);
EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras));
for (int32_t i = 0; i < numCameras; i++) {
- String8 cameraId8 = String8::format("%d", i);
+ std::string cameraId = std::to_string(i);
// Make sure we're available, or skip device tests otherwise
- String16 cameraId(cameraId8);
int32_t s = serviceListener->getStatus(cameraId);
EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s);
if (s != hardware::ICameraServiceListener::STATUS_PRESENT) {
@@ -513,7 +514,7 @@
sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
- String16 noPhysicalId;
+ std::string noPhysicalId;
OutputConfiguration output(gbProducer, /*rotation*/0, noPhysicalId);
// Can we configure?
@@ -550,7 +551,7 @@
EXPECT_TRUE(res.isOk()) << res;
hardware::camera2::CaptureRequest request;
- request.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+ request.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
request.mSurfaceList.add(surface);
request.mIsReprocess = false;
int64_t lastFrameNumber = 0;
@@ -577,7 +578,7 @@
/*out*/&requestTemplate);
EXPECT_TRUE(res.isOk()) << res;
hardware::camera2::CaptureRequest request2;
- request2.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+ request2.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
request2.mSurfaceList.add(surface);
request2.mIsReprocess = false;
callbacks->clearStatus();
@@ -610,10 +611,10 @@
EXPECT_TRUE(res.isOk()) << res;
android::hardware::camera2::CaptureRequest request3;
android::hardware::camera2::CaptureRequest request4;
- request3.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
+ request3.mPhysicalCameraSettings.push_back({cameraId, requestTemplate});
request3.mSurfaceList.add(surface);
request3.mIsReprocess = false;
- request4.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate2});
+ request4.mPhysicalCameraSettings.push_back({cameraId, requestTemplate2});
request4.mSurfaceList.add(surface);
request4.mIsReprocess = false;
std::vector<hardware::camera2::CaptureRequest> requestList;
diff --git a/camera/tests/CameraCharacteristicsPermission.cpp b/camera/tests/CameraCharacteristicsPermission.cpp
index f2fa48c..1de7cb4 100644
--- a/camera/tests/CameraCharacteristicsPermission.cpp
+++ b/camera/tests/CameraCharacteristicsPermission.cpp
@@ -62,7 +62,7 @@
TEST_F(CameraCharacteristicsPermission, TestCameraPermission) {
for (int32_t cameraId = 0; cameraId < numCameras; cameraId++) {
- String16 cameraIdStr = String16(String8::format("%d", cameraId));
+ std::string cameraIdStr = std::to_string(cameraId);
bool isSupported = false;
auto rc = mCameraService->supportsCameraApi(cameraIdStr,
hardware::ICameraService::API_VERSION_2, &isSupported);
diff --git a/camera/tests/CameraZSLTests.cpp b/camera/tests/CameraZSLTests.cpp
index 6423709..3ae7659 100644
--- a/camera/tests/CameraZSLTests.cpp
+++ b/camera/tests/CameraZSLTests.cpp
@@ -27,6 +27,7 @@
#include <camera/CameraParameters.h>
#include <camera/CameraMetadata.h>
#include <camera/Camera.h>
+#include <camera/StringUtils.h>
#include <android/hardware/ICameraService.h>
using namespace android;
@@ -169,7 +170,7 @@
sp<SurfaceControl> surfaceControl;
sp<ICamera> cameraDevice;
- String16 cameraIdStr = String16(String8::format("%d", cameraId));
+ std::string cameraIdStr = std::to_string(cameraId);
bool isSupported = false;
rc = mCameraService->supportsCameraApi(cameraIdStr,
hardware::ICameraService::API_VERSION_1, &isSupported);
@@ -208,7 +209,7 @@
}
rc = mCameraService->connect(this, cameraId,
- String16("ZSLTest"), hardware::ICameraService::USE_CALLING_UID,
+ "ZSLTest", hardware::ICameraService::USE_CALLING_UID,
hardware::ICameraService::USE_CALLING_PID,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
/*overrideToPortrait*/false, /*forceSlowJpegMode*/false, &cameraDevice);
diff --git a/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp b/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
index 45b3526..07efc20 100644
--- a/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_Parameters_fuzzer.cpp
@@ -19,6 +19,7 @@
#include <fcntl.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <utils/String16.h>
+#include <camera/StringUtils.h>
using namespace std;
using namespace android;
@@ -77,7 +78,7 @@
} else {
params = mFDP->ConsumeRandomLengthString();
}
- *obj = new type(String8(params.c_str()));
+ *obj = new type(toString8(params));
}
}
diff --git a/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp b/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
index 2f2ad77..c9bb20c 100644
--- a/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_SessionStats_fuzzer.cpp
@@ -17,6 +17,7 @@
#include <CameraSessionStats.h>
#include <binder/Parcel.h>
#include <fuzzer/FuzzedDataProvider.h>
+#include <camera/StringUtils.h>
#include "camera2common.h"
using namespace std;
@@ -100,10 +101,9 @@
if (fdp.ConsumeBool()) {
cameraSessionStats = new CameraSessionStats();
} else {
- string camId = fdp.ConsumeRandomLengthString();
- String16 cameraId(camId.c_str());
+ string cameraId = fdp.ConsumeRandomLengthString();
if (fdp.ConsumeBool()) {
- parcelCamSessionStats.writeString16(cameraId);
+ parcelCamSessionStats.writeString16(toString16(cameraId));
}
int32_t facing = fdp.ConsumeIntegral<int32_t>();
if (fdp.ConsumeBool()) {
@@ -113,10 +113,9 @@
if (fdp.ConsumeBool()) {
parcelCamSessionStats.writeInt32(newCameraState);
}
- string name = fdp.ConsumeRandomLengthString();
- String16 clientName(name.c_str());
+ string clientName = fdp.ConsumeRandomLengthString();
if (fdp.ConsumeBool()) {
- parcelCamSessionStats.writeString16(clientName);
+ parcelCamSessionStats.writeString16(toString16(clientName));
}
int32_t apiLevel = fdp.ConsumeIntegral<int32_t>();
if (fdp.ConsumeBool()) {
diff --git a/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp b/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
index 06215a5..494ec1b 100644
--- a/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2CaptureRequest_fuzzer.cpp
@@ -15,6 +15,7 @@
*/
#include <CameraMetadata.h>
+#include <camera/StringUtils.h>
#include <camera2/CaptureRequest.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <gui/Surface.h>
@@ -45,7 +46,7 @@
for (size_t idx = 0; idx < physicalCameraSettingsSize; ++idx) {
string id = fdp.ConsumeRandomLengthString();
if (fdp.ConsumeBool()) {
- parcelCamCaptureReq.writeString16(String16(id.c_str()));
+ parcelCamCaptureReq.writeString16(toString16(id));
}
CameraMetadata cameraMetadata;
if (fdp.ConsumeBool()) {
diff --git a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
index 51ac4e8..2fe9a94 100644
--- a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
@@ -38,8 +38,7 @@
outputConfiguration = new OutputConfiguration();
} else {
int32_t rotation = fdp.ConsumeIntegral<int32_t>();
- string phyCameraId = fdp.ConsumeRandomLengthString();
- String16 physicalCameraId(phyCameraId.c_str());
+ string physicalCameraId = fdp.ConsumeRandomLengthString();
int32_t surfaceSetID = fdp.ConsumeIntegral<int32_t>();
bool isShared = fdp.ConsumeBool();
diff --git a/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp b/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
index b2de95d..7cd0e59 100644
--- a/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2SessionConfiguration_fuzzer.cpp
@@ -65,8 +65,7 @@
surface.clear();
}
int32_t rotation = fdp.ConsumeIntegral<int32_t>();
- string phyCameraId = fdp.ConsumeRandomLengthString();
- String16 physicalCameraId(phyCameraId.c_str());
+ string physicalCameraId = fdp.ConsumeRandomLengthString();
int32_t surfaceSetID = fdp.ConsumeIntegral<int32_t>();
bool isShared = fdp.ConsumeBool();
outputConfiguration =
diff --git a/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp b/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
index 1396431..dd857d4 100644
--- a/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_captureResult_fuzzer.cpp
@@ -32,8 +32,7 @@
if (fdp.ConsumeBool()) {
physicalCaptureResultInfo = new PhysicalCaptureResultInfo();
} else {
- string camId = fdp.ConsumeRandomLengthString();
- String16 cameraId(camId.c_str());
+ string cameraId = fdp.ConsumeRandomLengthString();
CameraMetadata cameraMetadata = CameraMetadata();
physicalCaptureResultInfo = new PhysicalCaptureResultInfo(cameraId, cameraMetadata);
}
@@ -47,9 +46,7 @@
}
if (fdp.ConsumeBool()) {
captureResult->mResultExtras = CaptureResultExtras();
- string errCamId = fdp.ConsumeRandomLengthString();
- String16 errCameraId(errCamId.c_str());
- captureResult->mResultExtras.errorPhysicalCameraId = errCameraId;
+ captureResult->mResultExtras.errorPhysicalCameraId = fdp.ConsumeRandomLengthString();
captureResult->mResultExtras.isValid();
invokeReadWriteNullParcel<CaptureResultExtras>(&(captureResult->mResultExtras));
}
diff --git a/camera/tests/fuzzer/camera_fuzzer.cpp b/camera/tests/fuzzer/camera_fuzzer.cpp
index f9ef98e..d09a6dd 100644
--- a/camera/tests/fuzzer/camera_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_fuzzer.cpp
@@ -149,7 +149,7 @@
sp<IBinder> binder = sm->getService(String16("media.camera"));
mCameraService = interface_cast<ICameraService>(binder);
mCameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
- String16("CAMERAFUZZ"), hardware::ICameraService::USE_CALLING_UID,
+ "CAMERAFUZZ", hardware::ICameraService::USE_CALLING_UID,
hardware::ICameraService::USE_CALLING_PID,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__,
/*overrideToPortrait*/false, /*forceSlowJpegMode*/false, &cameraDevice);
@@ -294,18 +294,15 @@
cameraStatus = new CameraStatus();
} else {
string cid = mFDP->ConsumeRandomLengthString();
- String8 id(cid.c_str());
int32_t status = mFDP->ConsumeIntegral<int32_t>();
size_t unavailSubIdsSize = mFDP->ConsumeIntegralInRange<size_t>(kSizeMin, kSizeMax);
- vector<String8> unavailSubIds;
+ vector<std::string> unavailSubIds;
for (size_t idx = 0; idx < unavailSubIdsSize; ++idx) {
string subId = mFDP->ConsumeRandomLengthString();
- String8 unavailSubId(subId.c_str());
- unavailSubIds.push_back(unavailSubId);
+ unavailSubIds.push_back(subId);
}
- string clientPkg = mFDP->ConsumeRandomLengthString();
- String8 clientPackage(clientPkg.c_str());
- cameraStatus = new CameraStatus(id, status, unavailSubIds, clientPackage);
+ string clientPackage = mFDP->ConsumeRandomLengthString();
+ cameraStatus = new CameraStatus(cid, status, unavailSubIds, clientPackage);
}
invokeReadWriteParcel<CameraStatus>(cameraStatus);
diff --git a/media/audioserver/Android.bp b/media/audioserver/Android.bp
index 828d861..2030dc7 100644
--- a/media/audioserver/Android.bp
+++ b/media/audioserver/Android.bp
@@ -25,21 +25,31 @@
"libmediametrics_headers",
],
- shared_libs: [
- "packagemanager_aidl-cpp",
+ defaults: [
+ "libaaudioservice_dependencies",
+ "libaudioflinger_dependencies",
+ "libaudiopolicyservice_dependencies",
+ "latest_android_media_audio_common_types_cpp_shared",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
+ ],
+
+ static_libs: [
"libaaudioservice",
- "libaudioclient",
"libaudioflinger",
"libaudiopolicyservice",
+ "libmedialogservice",
+ "libnbaio",
+ ],
+
+ shared_libs: [
+ "libaudioclient",
"libaudioprocessing",
"libbinder",
"libcutils",
"libhidlbase",
"liblog",
"libmedia",
- "libmedialogservice",
"libmediautils",
- "libnbaio",
"libnblog",
"libpowermanager",
"libutils",
@@ -59,9 +69,9 @@
"frameworks/av/services/audiopolicy/engine/interface",
"frameworks/av/services/audiopolicy/service",
"frameworks/av/services/medialog",
+ "frameworks/av/services/oboeservice", // TODO oboeservice is the old folder name for aaudioservice. It will be changed.
- // TODO oboeservice is the old folder name for aaudioservice. It will be changed.
- "frameworks/av/services/oboeservice",
+
],
init_rc: ["audioserver.rc"],
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 1e3bfe0..c7a1bfd 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -184,7 +184,7 @@
// attempting to call audio flinger on a null pointer could make the process crash
// and attract attentions.
std::vector<AudioMMapPolicyInfo> policyInfos;
- status_t status = af->getMmapPolicyInfos(
+ status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos(
AudioMMapPolicyType::DEFAULT, &policyInfos);
// Initialize aaudio service when querying mmap policy succeeds and
// any of the policy supports MMAP.
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index d865ab2..721a12a 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -69,7 +69,7 @@
addParameter(
DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
.withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 6)})
+ .withFields({C2F(mChannelCount, value).inRange(1, kMaxChannelCount)})
.withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
.build());
@@ -198,10 +198,17 @@
}
c2_status_t C2SoftAacEnc::onFlush_sm() {
+ if (mAACEncoder != nullptr) {
+ /* encoder's internal input buffer needs to be reset during flush */
+ if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CONTROL_STATE, AACENC_INIT_ALL)) {
+ ALOGE("Failed to reset AAC encoder");
+ }
+ }
mSentCodecSpecificData = false;
mInputSize = 0u;
mNextFrameTimestampUs.reset();
mLastFrameEndTimestampUs.reset();
+ mRemainderLen = 0;
return C2_OK;
}
@@ -562,6 +569,11 @@
inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
inargs.numInSamples -= outargs.numInSamples;
}
+ } else {
+ // In case of error in encode call, discard remaining input bytes.
+ inBuffer[0] = nullptr;
+ inBufferSize[0] = 0;
+ inargs.numInSamples = 0;
}
ALOGV("encoderErr = %d mInputSize = %zu "
"inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
@@ -597,10 +609,19 @@
&outBufDesc,
&inargs,
&outargs);
+
+ // after flush, discard remaining input bytes.
+ inBuffer[0] = nullptr;
inBufferSize[0] = 0;
}
if (inBufferSize[0] > 0) {
+ if (inBufferSize[0] > kRemainderBufSize) {
+ ALOGE("Remaining bytes %d greater than remainder buffer size %zu", inBufferSize[0],
+ kRemainderBufSize);
+ work->result = C2_CORRUPTED;
+ return;
+ }
for (size_t i = 0; i < inBufferSize[0]; ++i) {
mRemainder[i] = static_cast<uint8_t *>(inBuffer[0])[i];
}
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
index 9a28280..c79526c 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.h
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -47,6 +47,9 @@
const std::shared_ptr<C2BlockPool> &pool) override;
private:
+ static constexpr size_t kMaxChannelCount = 6;
+ static constexpr size_t kRemainderBufSize = kMaxChannelCount * sizeof(int16_t);
+
std::shared_ptr<IntfImpl> mIntf;
HANDLE_AACENCODER mAACEncoder;
@@ -63,7 +66,7 @@
std::atomic_uint64_t mOutIndex;
// We support max 6 channels
- uint8_t mRemainder[6 * sizeof(int16_t)];
+ uint8_t mRemainder[kRemainderBufSize];
size_t mRemainderLen;
status_t initEncoder();
diff --git a/media/codec2/components/dav1d/Android.bp b/media/codec2/components/dav1d/Android.bp
new file mode 100644
index 0000000..f7850ad
--- /dev/null
+++ b/media/codec2/components/dav1d/Android.bp
@@ -0,0 +1,37 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library {
+ name: "libcodec2_soft_av1dec_dav1d",
+ // TODO: b/277797541 - enable once ready
+ enabled: false,
+
+ defaults: [
+ "libcodec2_soft-defaults",
+ "libcodec2_soft_sanitize_all-defaults",
+ ],
+
+ cflags: [
+ "-DCODECNAME=\"c2.android.dav1d-av1.decoder\"",
+ "-Wno-unused-variable",
+ ],
+
+ srcs: ["C2SoftDav1dDec.cpp"],
+ static_libs: [
+ "libyuv_static",
+ "libdav1d_8bit",
+ "libdav1d_16bit",
+ ],
+
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ ],
+
+}
diff --git a/media/codec2/components/dav1d/C2SoftDav1dDec.cpp b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp
new file mode 100644
index 0000000..b0cef41
--- /dev/null
+++ b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp
@@ -0,0 +1,1493 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "C2SoftDav1dDec"
+#include <android-base/properties.h>
+#include <cutils/properties.h>
+#include <thread>
+
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
+#include <Codec2CommonUtils.h>
+#include <Codec2Mapper.h>
+#include <SimpleC2Interface.h>
+#include <libyuv.h>
+#include <log/log.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include "C2SoftDav1dDec.h"
+
+// libyuv version required for I410ToAB30Matrix and I210ToAB30Matrix.
+#if LIBYUV_VERSION >= 1780
+#include <algorithm>
+#define HAVE_LIBYUV_I410_I210_TO_AB30 1
+#else
+#define HAVE_LIBYUV_I410_I210_TO_AB30 0
+#endif
+
+namespace android {
+
+// Flag to enable dumping the bitsteram and the decoded pictures to files.
+static const bool ENABLE_DUMPING_FILES_DEFAULT = false;
+static const char ENABLE_DUMPING_FILES_PROPERTY[] = "debug.dav1d.enabledumping";
+
+// The number of frames to dump to a file
+static const int NUM_FRAMES_TO_DUMP_DEFAULT = INT_MAX;
+static const char NUM_FRAMES_TO_DUMP_PROPERTY[] = "debug.dav1d.numframestodump";
+
+// The number of threads used for the dav1d decoder.
+static const int NUM_THREADS_DAV1D_DEFAULT = 0;
+static const char NUM_THREADS_DAV1D_PROPERTY[] = "debug.dav1d.numthreads";
+
+// codecname set and passed in as a compile flag from Android.bp
+constexpr char COMPONENT_NAME[] = CODECNAME;
+
+constexpr size_t kMinInputBufferSize = 2 * 1024 * 1024;
+
+class C2SoftDav1dDec::IntfImpl : public SimpleInterface<void>::BaseParams {
+ public:
+ explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
+ : SimpleInterface<void>::BaseParams(helper, COMPONENT_NAME, C2Component::KIND_DECODER,
+ C2Component::DOMAIN_VIDEO, MEDIA_MIMETYPE_VIDEO_AV1) {
+ noPrivateBuffers();
+ noInputReferences();
+ noOutputReferences();
+ noInputLatency();
+ noTimeStretch();
+
+ addParameter(DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+ .withConstValue(new C2ComponentAttributesSetting(
+ C2Component::ATTRIB_IS_TEMPORAL))
+ .build());
+
+ addParameter(DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+ .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
+ .withFields({
+ C2F(mSize, width).inRange(2, 4096),
+ C2F(mSize, height).inRange(2, 4096),
+ })
+ .withSetter(SizeSetter)
+ .build());
+
+ addParameter(DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+ .withDefault(new C2StreamProfileLevelInfo::input(
+ 0u, C2Config::PROFILE_AV1_0, C2Config::LEVEL_AV1_2_1))
+ .withFields({C2F(mProfileLevel, profile)
+ .oneOf({C2Config::PROFILE_AV1_0,
+ C2Config::PROFILE_AV1_1}),
+ C2F(mProfileLevel, level)
+ .oneOf({
+ C2Config::LEVEL_AV1_2,
+ C2Config::LEVEL_AV1_2_1,
+ C2Config::LEVEL_AV1_2_2,
+ C2Config::LEVEL_AV1_2_3,
+ C2Config::LEVEL_AV1_3,
+ C2Config::LEVEL_AV1_3_1,
+ C2Config::LEVEL_AV1_3_2,
+ C2Config::LEVEL_AV1_3_3,
+ C2Config::LEVEL_AV1_4,
+ C2Config::LEVEL_AV1_4_1,
+ C2Config::LEVEL_AV1_4_2,
+ C2Config::LEVEL_AV1_4_3,
+ C2Config::LEVEL_AV1_5,
+ C2Config::LEVEL_AV1_5_1,
+ C2Config::LEVEL_AV1_5_2,
+ C2Config::LEVEL_AV1_5_3,
+ })})
+ .withSetter(ProfileLevelSetter, mSize)
+ .build());
+
+ mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
+ addParameter(DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
+ .withDefault(mHdr10PlusInfoInput)
+ .withFields({
+ C2F(mHdr10PlusInfoInput, m.value).any(),
+ })
+ .withSetter(Hdr10PlusInfoInputSetter)
+ .build());
+
+ mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
+ addParameter(DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
+ .withDefault(mHdr10PlusInfoOutput)
+ .withFields({
+ C2F(mHdr10PlusInfoOutput, m.value).any(),
+ })
+ .withSetter(Hdr10PlusInfoOutputSetter)
+ .build());
+
+ // default static info
+ C2HdrStaticMetadataStruct defaultStaticInfo{};
+ helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
+ addParameter(
+ DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
+ .withDefault(new C2StreamHdrStaticInfo::output(0u, defaultStaticInfo))
+ .withFields({C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.red.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.maxLuminance).inRange(0, 65535),
+ C2F(mHdrStaticInfo, mastering.minLuminance).inRange(0, 6.5535),
+ C2F(mHdrStaticInfo, maxCll).inRange(0, 0XFFFF),
+ C2F(mHdrStaticInfo, maxFall).inRange(0, 0XFFFF)})
+ .withSetter(HdrStaticInfoSetter)
+ .build());
+
+ addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
+ .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
+ .withFields({
+ C2F(mSize, width).inRange(2, 2048, 2),
+ C2F(mSize, height).inRange(2, 2048, 2),
+ })
+ .withSetter(MaxPictureSizeSetter, mSize)
+ .build());
+
+ addParameter(
+ DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
+ .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, kMinInputBufferSize))
+ .withFields({
+ C2F(mMaxInputSize, value).any(),
+ })
+ .calculatedAs(MaxInputSizeSetter, mMaxSize)
+ .build());
+
+ C2ChromaOffsetStruct locations[1] = {C2ChromaOffsetStruct::ITU_YUV_420_0()};
+ std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
+ C2StreamColorInfo::output::AllocShared(1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+ memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
+
+ defaultColorInfo = C2StreamColorInfo::output::AllocShared(
+ {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */, C2Color::YUV_420);
+ helper->addStructDescriptors<C2ChromaOffsetStruct>();
+
+ addParameter(DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
+ .withConstValue(defaultColorInfo)
+ .build());
+
+ addParameter(DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsTuning::output(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({C2F(mDefaultColorAspects, range)
+ .inRange(C2Color::RANGE_UNSPECIFIED,
+ C2Color::RANGE_OTHER),
+ C2F(mDefaultColorAspects, primaries)
+ .inRange(C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::PRIMARIES_OTHER),
+ C2F(mDefaultColorAspects, transfer)
+ .inRange(C2Color::TRANSFER_UNSPECIFIED,
+ C2Color::TRANSFER_OTHER),
+ C2F(mDefaultColorAspects, matrix)
+ .inRange(C2Color::MATRIX_UNSPECIFIED,
+ C2Color::MATRIX_OTHER)})
+ .withSetter(DefaultColorAspectsSetter)
+ .build());
+
+ addParameter(DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({C2F(mCodedColorAspects, range)
+ .inRange(C2Color::RANGE_UNSPECIFIED,
+ C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries)
+ .inRange(C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer)
+ .inRange(C2Color::TRANSFER_UNSPECIFIED,
+ C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix)
+ .inRange(C2Color::MATRIX_UNSPECIFIED,
+ C2Color::MATRIX_OTHER)})
+ .withSetter(CodedColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields(
+ {C2F(mColorAspects, range)
+ .inRange(C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries)
+ .inRange(C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer)
+ .inRange(C2Color::TRANSFER_UNSPECIFIED,
+ C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix)
+ .inRange(C2Color::MATRIX_UNSPECIFIED,
+ C2Color::MATRIX_OTHER)})
+ .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
+ .build());
+
+ std::vector<uint32_t> pixelFormats = {HAL_PIXEL_FORMAT_YCBCR_420_888};
+ if (isHalPixelFormatSupported((AHardwareBuffer_Format)HAL_PIXEL_FORMAT_YCBCR_P010)) {
+ pixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
+ }
+ // If color format surface isn't added to supported formats, there is no way to know
+ // when the color-format is configured to surface. This is necessary to be able to
+ // choose 10-bit format while decoding 10-bit clips in surface mode.
+ pixelFormats.push_back(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+
+ // TODO: support more formats?
+ addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+ .withDefault(new C2StreamPixelFormatInfo::output(
+ 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+ .withFields({C2F(mPixelFormat, value).oneOf(pixelFormats)})
+ .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps))
+ .build());
+ }
+
+ static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output>& oldMe,
+ C2P<C2StreamPictureSizeInfo::output>& me) {
+ (void)mayBlock;
+ C2R res = C2R::Ok();
+ if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+ res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+ me.set().width = oldMe.v.width;
+ }
+ if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+ res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+ me.set().height = oldMe.v.height;
+ }
+ return res;
+ }
+
+ static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output>& me,
+ const C2P<C2StreamPictureSizeInfo::output>& size) {
+ (void)mayBlock;
+ // TODO: get max width/height from the size's field helpers vs.
+ // hardcoding
+ me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
+ me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
+ return C2R::Ok();
+ }
+
+ static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& me,
+ const C2P<C2StreamMaxPictureSizeTuning::output>& maxSize) {
+ (void)mayBlock;
+ // assume compression ratio of 2, but enforce a floor
+ me.set().value =
+ c2_max((((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072),
+ kMinInputBufferSize);
+ return C2R::Ok();
+ }
+
+ static C2R DefaultColorAspectsSetter(bool mayBlock,
+ C2P<C2StreamColorAspectsTuning::output>& me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+
+ static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input>& me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
+ const C2P<C2StreamColorAspectsTuning::output>& def,
+ const C2P<C2StreamColorAspectsInfo::input>& coded) {
+ (void)mayBlock;
+ // take default values for all unspecified fields, and coded values for specified ones
+ me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+ me.set().primaries =
+ coded.v.primaries == PRIMARIES_UNSPECIFIED ? def.v.primaries : coded.v.primaries;
+ me.set().transfer =
+ coded.v.transfer == TRANSFER_UNSPECIFIED ? def.v.transfer : coded.v.transfer;
+ me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
+ return C2R::Ok();
+ }
+
+ static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input>& me,
+ const C2P<C2StreamPictureSizeInfo::output>& size) {
+ (void)mayBlock;
+ (void)size;
+ (void)me; // TODO: validate
+ return C2R::Ok();
+ }
+
+ std::shared_ptr<C2StreamColorAspectsTuning::output> getDefaultColorAspects_l() {
+ return mDefaultColorAspects;
+ }
+
+ std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() { return mColorAspects; }
+
+ static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input>& me) {
+ (void)mayBlock;
+ (void)me; // TODO: validate
+ return C2R::Ok();
+ }
+
+ static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output>& me) {
+ (void)mayBlock;
+ (void)me; // TODO: validate
+ return C2R::Ok();
+ }
+
+ // unsafe getters
+ std::shared_ptr<C2StreamPixelFormatInfo::output> getPixelFormat_l() const {
+ return mPixelFormat;
+ }
+
+ static C2R HdrStaticInfoSetter(bool mayBlock, C2P<C2StreamHdrStaticInfo::output>& me) {
+ (void)mayBlock;
+ if (me.v.mastering.red.x > 1) {
+ me.set().mastering.red.x = 1;
+ }
+ if (me.v.mastering.red.y > 1) {
+ me.set().mastering.red.y = 1;
+ }
+ if (me.v.mastering.green.x > 1) {
+ me.set().mastering.green.x = 1;
+ }
+ if (me.v.mastering.green.y > 1) {
+ me.set().mastering.green.y = 1;
+ }
+ if (me.v.mastering.blue.x > 1) {
+ me.set().mastering.blue.x = 1;
+ }
+ if (me.v.mastering.blue.y > 1) {
+ me.set().mastering.blue.y = 1;
+ }
+ if (me.v.mastering.white.x > 1) {
+ me.set().mastering.white.x = 1;
+ }
+ if (me.v.mastering.white.y > 1) {
+ me.set().mastering.white.y = 1;
+ }
+ if (me.v.mastering.maxLuminance > 65535.0) {
+ me.set().mastering.maxLuminance = 65535.0;
+ }
+ if (me.v.mastering.minLuminance > 6.5535) {
+ me.set().mastering.minLuminance = 6.5535;
+ }
+ if (me.v.maxCll > 65535.0) {
+ me.set().maxCll = 65535.0;
+ }
+ if (me.v.maxFall > 65535.0) {
+ me.set().maxFall = 65535.0;
+ }
+ return C2R::Ok();
+ }
+
+ private:
+ std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+ std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
+ std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
+ std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
+ std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
+ std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
+ std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
+ std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
+ std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+ std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
+};
+
+C2SoftDav1dDec::C2SoftDav1dDec(const char* name, c2_node_id_t id,
+ const std::shared_ptr<IntfImpl>& intfImpl)
+ : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
+ mIntf(intfImpl) {
+ mTimeStart = mTimeEnd = systemTime();
+}
+
+C2SoftDav1dDec::~C2SoftDav1dDec() {
+ onRelease();
+}
+
+c2_status_t C2SoftDav1dDec::onInit() {
+ return initDecoder() ? C2_OK : C2_CORRUPTED;
+}
+
+c2_status_t C2SoftDav1dDec::onStop() {
+ // TODO: b/277797541 - investigate if the decoder needs to be flushed.
+ mSignalledError = false;
+ mSignalledOutputEos = false;
+ return C2_OK;
+}
+
+void C2SoftDav1dDec::onReset() {
+ (void)onStop();
+ c2_status_t err = onFlush_sm();
+ if (err != C2_OK) {
+ ALOGW("Failed to flush the av1 decoder. Trying to hard reset.");
+ destroyDecoder();
+ if (!initDecoder()) {
+ ALOGE("Hard reset failed.");
+ }
+ }
+}
+
+void C2SoftDav1dDec::flushDav1d() {
+ if (mDav1dCtx) {
+ Dav1dPicture p;
+
+ while (mDecodedPictures.size() > 0) {
+ p = mDecodedPictures.front();
+ mDecodedPictures.pop_front();
+
+ dav1d_picture_unref(&p);
+ }
+
+ int res = 0;
+ while (true) {
+ memset(&p, 0, sizeof(p));
+
+ if ((res = dav1d_get_picture(mDav1dCtx, &p)) < 0) {
+ if (res != DAV1D_ERR(EAGAIN)) {
+ ALOGE("Error decoding frame: %s\n", strerror(DAV1D_ERR(res)));
+ break;
+ } else {
+ res = 0;
+ break;
+ }
+ } else {
+ dav1d_picture_unref(&p);
+ }
+ }
+
+ dav1d_flush(mDav1dCtx);
+ }
+}
+
+void C2SoftDav1dDec::onRelease() {
+ destroyDecoder();
+}
+
+c2_status_t C2SoftDav1dDec::onFlush_sm() {
+ flushDav1d();
+
+ mSignalledError = false;
+ mSignalledOutputEos = false;
+
+ return C2_OK;
+}
+
+static int GetCPUCoreCount() {
+ int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+ cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ // _SC_NPROC_ONLN must be defined...
+ cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+ CHECK(cpuCoreCount >= 1);
+ ALOGV("Number of CPU cores: %d", cpuCoreCount);
+ return cpuCoreCount;
+}
+
+bool C2SoftDav1dDec::initDecoder() {
+ nsecs_t now = systemTime();
+#ifdef FILE_DUMP_ENABLE
+ snprintf(mInDataFileName, 256, "%s_%" PRId64 "d.%s", DUMP_FILE_PATH, now, INPUT_DATA_DUMP_EXT);
+ snprintf(mInSizeFileName, 256, "%s_%" PRId64 "d.%s", DUMP_FILE_PATH, now, INPUT_SIZE_DUMP_EXT);
+ snprintf(mDav1dOutYuvFileName, 256, "%s_%" PRId64 "dx.%s", DUMP_FILE_PATH, now,
+ OUTPUT_YUV_DUMP_EXT);
+
+ bool enableDumping = android::base::GetBoolProperty(ENABLE_DUMPING_FILES_PROPERTY,
+ ENABLE_DUMPING_FILES_DEFAULT);
+
+ num_frames_to_dump =
+ android::base::GetIntProperty(NUM_FRAMES_TO_DUMP_PROPERTY, NUM_FRAMES_TO_DUMP_DEFAULT);
+
+ if (enableDumping) {
+ ALOGD("enableDumping = %d, num_frames_to_dump = %d", enableDumping, num_frames_to_dump);
+
+ mInDataFile = fopen(mInDataFileName, "wb");
+ if (mInDataFile == nullptr) {
+ ALOGD("Could not open file %s", mInDataFileName);
+ }
+
+ mInSizeFile = fopen(mInSizeFileName, "wb");
+ if (mInSizeFile == nullptr) {
+ ALOGD("Could not open file %s", mInSizeFileName);
+ }
+
+ mDav1dOutYuvFile = fopen(mDav1dOutYuvFileName, "wb");
+ if (mDav1dOutYuvFile == nullptr) {
+ ALOGD("Could not open file %s", mDav1dOutYuvFileName);
+ }
+ }
+#endif
+ mSignalledError = false;
+ mSignalledOutputEos = false;
+ mHalPixelFormat = HAL_PIXEL_FORMAT_YV12;
+ {
+ IntfImpl::Lock lock = mIntf->lock();
+ mPixelFormatInfo = mIntf->getPixelFormat_l();
+ }
+
+ const char* version = dav1d_version();
+
+ Dav1dSettings lib_settings;
+ dav1d_default_settings(&lib_settings);
+ int cpu_count = GetCPUCoreCount();
+ lib_settings.n_threads = std::max(cpu_count / 2, 1); // use up to half the cores by default.
+
+ int32_t numThreads =
+ android::base::GetIntProperty(NUM_THREADS_DAV1D_PROPERTY, NUM_THREADS_DAV1D_DEFAULT);
+ if (numThreads > 0) lib_settings.n_threads = numThreads;
+
+ int res = 0;
+ if ((res = dav1d_open(&mDav1dCtx, &lib_settings))) {
+ ALOGE("dav1d_open failed. status: %d.", res);
+ return false;
+ } else {
+ ALOGD("dav1d_open succeeded(n_threads=%d,version=%s).", lib_settings.n_threads, version);
+ }
+
+ return true;
+}
+
+void C2SoftDav1dDec::destroyDecoder() {
+ if (mDav1dCtx) {
+ Dav1dPicture p;
+ while (mDecodedPictures.size() > 0) {
+ memset(&p, 0, sizeof(p));
+ p = mDecodedPictures.front();
+ mDecodedPictures.pop_front();
+
+ dav1d_picture_unref(&p);
+ }
+
+ dav1d_close(&mDav1dCtx);
+ mDav1dCtx = nullptr;
+ mOutputBufferIndex = 0;
+ mInputBufferIndex = 0;
+ }
+#ifdef FILE_DUMP_ENABLE
+ if (mInDataFile != nullptr) {
+ fclose(mInDataFile);
+ mInDataFile = nullptr;
+ }
+
+ if (mInSizeFile != nullptr) {
+ fclose(mInSizeFile);
+ mInSizeFile = nullptr;
+ }
+
+ if (mDav1dOutYuvFile != nullptr) {
+ fclose(mDav1dOutYuvFile);
+ mDav1dOutYuvFile = nullptr;
+ }
+#endif
+}
+
+void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
+ uint32_t flags = 0;
+ if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
+ flags |= C2FrameData::FLAG_END_OF_STREAM;
+ ALOGV("signalling end_of_stream.");
+ }
+ work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+ work->worklets.front()->output.buffers.clear();
+ work->worklets.front()->output.ordinal = work->input.ordinal;
+ work->workletsProcessed = 1u;
+}
+
+void C2SoftDav1dDec::finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
+ const std::shared_ptr<C2GraphicBlock>& block) {
+ std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block, C2Rect(mWidth, mHeight));
+ {
+ IntfImpl::Lock lock = mIntf->lock();
+ buffer->setInfo(mIntf->getColorAspects_l());
+ }
+ auto fillWork = [buffer, index](const std::unique_ptr<C2Work>& work) {
+ uint32_t flags = 0;
+ if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
+ (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
+ flags |= C2FrameData::FLAG_END_OF_STREAM;
+ ALOGV("signalling end_of_stream.");
+ }
+ work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
+ work->worklets.front()->output.buffers.clear();
+ work->worklets.front()->output.buffers.push_back(buffer);
+ work->worklets.front()->output.ordinal = work->input.ordinal;
+ work->workletsProcessed = 1u;
+ };
+ if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
+ fillWork(work);
+ } else {
+ finish(index, fillWork);
+ }
+}
+
+void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work,
+ const std::shared_ptr<C2BlockPool>& pool) {
+ work->result = C2_OK;
+ work->workletsProcessed = 0u;
+ work->worklets.front()->output.configUpdate.clear();
+ work->worklets.front()->output.flags = work->input.flags;
+ if (mSignalledError || mSignalledOutputEos) {
+ work->result = C2_BAD_VALUE;
+ return;
+ }
+
+ size_t inOffset = 0u;
+ size_t inSize = 0u;
+ C2ReadView rView = mDummyReadView;
+ if (!work->input.buffers.empty()) {
+ rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
+ inSize = rView.capacity();
+ if (inSize && rView.error()) {
+ ALOGE("read view map failed %d", rView.error());
+ work->result = C2_CORRUPTED;
+ return;
+ }
+ }
+
+ bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0);
+ bool end_of_stream = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
+
+ if (codecConfig) {
+ fillEmptyWork(work);
+ return;
+ }
+
+ int64_t in_frameIndex = work->input.ordinal.frameIndex.peekll();
+ if (inSize) {
+ mInputBufferIndex = in_frameIndex;
+
+ uint8_t* bitstream = const_cast<uint8_t*>(rView.data() + inOffset);
+
+ mTimeStart = systemTime();
+ nsecs_t delay = mTimeStart - mTimeEnd;
+
+ // Send the bitstream data (inputBuffer) to dav1d.
+ if (mDav1dCtx) {
+ int i_ret = 0;
+
+ Dav1dSequenceHeader seq;
+ int res = dav1d_parse_sequence_header(&seq, bitstream, inSize);
+ if (res == 0) {
+ ALOGV("dav1d found a sequenceHeader (%dx%d) for in_frameIndex=%ld.", seq.max_width,
+ seq.max_height, (long)in_frameIndex);
+ }
+
+ // insert OBU TD if it is not present.
+ // TODO: b/286852962
+ uint8_t obu_type = (bitstream[0] >> 3) & 0xf;
+ Dav1dData data;
+
+ uint8_t* ptr = (obu_type == DAV1D_OBU_TD) ? dav1d_data_create(&data, inSize)
+ : dav1d_data_create(&data, inSize + 2);
+ if (ptr == nullptr) {
+ ALOGE("dav1d_data_create failed!");
+ i_ret = -1;
+
+ } else {
+ data.m.timestamp = in_frameIndex;
+
+ int new_Size;
+ if (obu_type != DAV1D_OBU_TD) {
+ new_Size = (int)(inSize + 2);
+
+ // OBU TD
+ ptr[0] = 0x12;
+ ptr[1] = 0;
+
+ memcpy(ptr + 2, bitstream, inSize);
+ } else {
+ new_Size = (int)(inSize);
+ // TODO: b/277797541 - investigate how to wrap this pointer in Dav1dData to
+ // avoid memcopy operations.
+ memcpy(ptr, bitstream, new_Size);
+ }
+
+ // ALOGV("memcpy(ptr,bitstream,inSize=%ld,new_Size=%d,in_frameIndex=%ld,timestamp=%ld,"
+ // "ptr[0,1,2,3,4]=%x,%x,%x,%x,%x)",
+ // inSize, new_Size, frameIndex, data.m.timestamp, ptr[0], ptr[1], ptr[2],
+ // ptr[3], ptr[4]);
+
+ // Dump the bitstream data (inputBuffer) if dumping is enabled.
+#ifdef FILE_DUMP_ENABLE
+ if (mInDataFile) {
+ int ret = fwrite(ptr, 1, new_Size, mInDataFile);
+
+ if (ret != new_Size) {
+ ALOGE("Error in fwrite %s, requested %d, returned %d", mInDataFileName,
+ new_Size, ret);
+ }
+ }
+
+ // Dump the size per inputBuffer if dumping is enabled.
+ if (mInSizeFile) {
+ int ret = fwrite(&new_Size, 1, 4, mInSizeFile);
+
+ if (ret != 4) {
+ ALOGE("Error in fwrite %s, requested %d, returned %d", mInSizeFileName, 4,
+ ret);
+ }
+ }
+#endif
+
+ bool b_draining = false;
+ int res;
+
+ do {
+ res = dav1d_send_data(mDav1dCtx, &data);
+ if (res < 0 && res != DAV1D_ERR(EAGAIN)) {
+ ALOGE("Decoder feed error %s!", strerror(DAV1D_ERR(res)));
+ /* bitstream decoding errors (typically DAV1D_ERR(EINVAL), are assumed
+ * to be recoverable. Other errors returned from this function are
+ * either unexpected, or considered critical failures.
+ */
+ i_ret = res == DAV1D_ERR(EINVAL) ? 0 : -1;
+ break;
+ }
+
+ bool b_output_error = false;
+
+ do {
+ Dav1dPicture img;
+ memset(&img, 0, sizeof(img));
+
+ res = dav1d_get_picture(mDav1dCtx, &img);
+ if (res == 0) {
+ mDecodedPictures.push_back(img);
+
+ if (!end_of_stream) break;
+ } else if (res == DAV1D_ERR(EAGAIN)) {
+ /* the decoder needs more data to be able to output something.
+ * if there is more data pending, continue the loop below or
+ * otherwise break */
+ if (data.sz != 0) res = 0;
+ break;
+ } else {
+ ALOGE("warning! Decoder error %d!", res);
+ b_output_error = true;
+ break;
+ }
+ } while (res == 0);
+
+ if (b_output_error) break;
+
+ /* on drain, we must ignore the 1st EAGAIN */
+ if (!b_draining && (res == DAV1D_ERR(EAGAIN) || res == 0) &&
+ (end_of_stream)) {
+ b_draining = true;
+ res = 0;
+ }
+ } while (res == 0 && ((data.sz != 0) || b_draining));
+
+ if (data.sz > 0) {
+ ALOGE("unexpected data.sz=%zu after dav1d_send_data", data.sz);
+ dav1d_data_unref(&data);
+ }
+ }
+
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ // ALOGV("decodeTime=%4" PRId64 " delay=%4" PRId64 "\n", decodeTime, delay);
+
+ if (i_ret != 0) {
+ ALOGE("av1 decoder failed to decode frame. status: %d.", i_ret);
+ work->result = C2_CORRUPTED;
+ work->workletsProcessed = 1u;
+ mSignalledError = true;
+ return;
+ }
+ }
+ }
+
+ (void)outputBuffer(pool, work);
+
+ if (end_of_stream) {
+ drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
+ mSignalledOutputEos = true;
+ } else if (!inSize) {
+ fillEmptyWork(work);
+ }
+}
+
+void C2SoftDav1dDec::getHDRStaticParams(Dav1dPicture* picture,
+ const std::unique_ptr<C2Work>& work) {
+ C2StreamHdrStaticMetadataInfo::output hdrStaticMetadataInfo{};
+ bool infoPresent = false;
+
+ if (picture != nullptr) {
+ if (picture->mastering_display != nullptr) {
+ hdrStaticMetadataInfo.mastering.red.x =
+ picture->mastering_display->primaries[0][0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.red.y =
+ picture->mastering_display->primaries[0][1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.green.x =
+ picture->mastering_display->primaries[1][0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.green.y =
+ picture->mastering_display->primaries[1][1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.blue.x =
+ picture->mastering_display->primaries[2][0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.blue.y =
+ picture->mastering_display->primaries[2][1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.white.x =
+ picture->mastering_display->white_point[0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.white.y =
+ picture->mastering_display->white_point[1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.maxLuminance =
+ picture->mastering_display->max_luminance / 256.0;
+ hdrStaticMetadataInfo.mastering.minLuminance =
+ picture->mastering_display->min_luminance / 16384.0;
+
+ infoPresent = true;
+ }
+
+ if (picture->content_light != nullptr) {
+ hdrStaticMetadataInfo.maxCll = picture->content_light->max_content_light_level;
+ hdrStaticMetadataInfo.maxFall = picture->content_light->max_frame_average_light_level;
+ infoPresent = true;
+ }
+ }
+
+ // if (infoPresent) {
+ // ALOGD("received a hdrStaticMetadataInfo (mastering.red=%f,%f mastering.green=%f,%f
+ // mastering.blue=%f,%f mastering.white=%f,%f mastering.maxLuminance=%f
+ // mastering.minLuminance=%f maxCll=%f maxFall=%f) at mOutputBufferIndex=%d.",
+ // hdrStaticMetadataInfo.mastering.red.x,hdrStaticMetadataInfo.mastering.red.y,
+ // hdrStaticMetadataInfo.mastering.green.x,hdrStaticMetadataInfo.mastering.green.y,
+ // hdrStaticMetadataInfo.mastering.blue.x,hdrStaticMetadataInfo.mastering.blue.y,
+ // hdrStaticMetadataInfo.mastering.white.x,hdrStaticMetadataInfo.mastering.white.y,
+ // hdrStaticMetadataInfo.mastering.maxLuminance,hdrStaticMetadataInfo.mastering.minLuminance,
+ // hdrStaticMetadataInfo.maxCll,
+ // hdrStaticMetadataInfo.maxFall,
+ // mOutputBufferIndex);
+ // }
+
+ // config if static info has changed
+ if (infoPresent && !(hdrStaticMetadataInfo == mHdrStaticMetadataInfo)) {
+ mHdrStaticMetadataInfo = hdrStaticMetadataInfo;
+ work->worklets.front()->output.configUpdate.push_back(
+ C2Param::Copy(mHdrStaticMetadataInfo));
+ }
+}
+
+void C2SoftDav1dDec::getHDR10PlusInfoData(Dav1dPicture* picture,
+ const std::unique_ptr<C2Work>& work) {
+ if (picture != nullptr) {
+ if (picture->itut_t35 != nullptr) {
+ std::vector<uint8_t> payload;
+ size_t payloadSize = picture->itut_t35->payload_size;
+ if (payloadSize > 0) {
+ payload.push_back(picture->itut_t35->country_code);
+ if (picture->itut_t35->country_code == 0xFF) {
+ payload.push_back(picture->itut_t35->country_code_extension_byte);
+ }
+ payload.insert(payload.end(), picture->itut_t35->payload,
+ picture->itut_t35->payload + picture->itut_t35->payload_size);
+ }
+
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
+ C2StreamHdr10PlusInfo::output::AllocUnique(payload.size());
+ if (!hdr10PlusInfo) {
+ ALOGE("Hdr10PlusInfo allocation failed");
+ mSignalledError = true;
+ work->result = C2_NO_MEMORY;
+ return;
+ }
+ memcpy(hdr10PlusInfo->m.value, payload.data(), payload.size());
+
+ // ALOGD("Received a hdr10PlusInfo from picture->itut_t32
+ // (payload_size=%ld,country_code=%d) at mOutputBufferIndex=%d.",
+ // picture->itut_t35->payload_size,
+ // picture->itut_t35->country_code,
+ // mOutputBufferIndex);
+
+ // config if hdr10Plus info has changed
+ if (nullptr == mHdr10PlusInfo || !(*hdr10PlusInfo == *mHdr10PlusInfo)) {
+ mHdr10PlusInfo = std::move(hdr10PlusInfo);
+ work->worklets.front()->output.configUpdate.push_back(std::move(mHdr10PlusInfo));
+ }
+ }
+ }
+}
+
+void C2SoftDav1dDec::getVuiParams(Dav1dPicture* picture) {
+ VuiColorAspects vuiColorAspects;
+
+ if (picture) {
+ vuiColorAspects.primaries = picture->seq_hdr->pri;
+ vuiColorAspects.transfer = picture->seq_hdr->trc;
+ vuiColorAspects.coeffs = picture->seq_hdr->mtrx;
+ vuiColorAspects.fullRange = picture->seq_hdr->color_range;
+
+ // ALOGD("Received a vuiColorAspects from dav1d
+ // (primaries = % d, transfer = % d, coeffs = % d, fullRange = % d)
+ // at mOutputBufferIndex = % d,
+ // out_frameIndex = % ld.",
+ // vuiColorAspects.primaries,
+ // vuiColorAspects.transfer, vuiColorAspects.coeffs, vuiColorAspects.fullRange,
+ // mOutputBufferIndex, picture->m.timestamp);
+ }
+
+ // convert vui aspects to C2 values if changed
+ if (!(vuiColorAspects == mBitstreamColorAspects)) {
+ mBitstreamColorAspects = vuiColorAspects;
+ ColorAspects sfAspects;
+ C2StreamColorAspectsInfo::input codedAspects = {0u};
+ ColorUtils::convertIsoColorAspectsToCodecAspects(
+ vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
+ vuiColorAspects.fullRange, sfAspects);
+ if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+ codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+ codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+ codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+ codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+ }
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+ }
+}
+
+void C2SoftDav1dDec::setError(const std::unique_ptr<C2Work>& work, c2_status_t error) {
+ mSignalledError = true;
+ work->result = error;
+ work->workletsProcessed = 1u;
+}
+
+bool C2SoftDav1dDec::allocTmpFrameBuffer(size_t size) {
+ if (size > mTmpFrameBufferSize) {
+ mTmpFrameBuffer = std::make_unique<uint16_t[]>(size);
+ if (mTmpFrameBuffer == nullptr) {
+ mTmpFrameBufferSize = 0;
+ return false;
+ }
+ mTmpFrameBufferSize = size;
+ }
+ return true;
+}
+
+#ifdef FILE_DUMP_ENABLE
+void C2SoftDav1dDec::writeDav1dOutYuvFile(const Dav1dPicture& p) {
+ if (mDav1dOutYuvFile != NULL) {
+ uint8_t* ptr;
+ const int hbd = p.p.bpc > 8;
+
+ ptr = (uint8_t*)p.data[0];
+ for (int y = 0; y < p.p.h; y++) {
+ int iSize = p.p.w << hbd;
+ int ret = fwrite(ptr, 1, iSize, mDav1dOutYuvFile);
+ if (ret != iSize) {
+ ALOGE("Error in fwrite %s, requested %d, returned %d", mDav1dOutYuvFileName, iSize,
+ ret);
+ break;
+ }
+
+ ptr += p.stride[0];
+ }
+
+ if (p.p.layout != DAV1D_PIXEL_LAYOUT_I400) {
+ // u/v
+ const int ss_ver = p.p.layout == DAV1D_PIXEL_LAYOUT_I420;
+ const int ss_hor = p.p.layout != DAV1D_PIXEL_LAYOUT_I444;
+ const int cw = (p.p.w + ss_hor) >> ss_hor;
+ const int ch = (p.p.h + ss_ver) >> ss_ver;
+ for (int pl = 1; pl <= 2; pl++) {
+ ptr = (uint8_t*)p.data[pl];
+ for (int y = 0; y < ch; y++) {
+ int iSize = cw << hbd;
+ int ret = fwrite(ptr, 1, cw << hbd, mDav1dOutYuvFile);
+ if (ret != iSize) {
+ ALOGE("Error in fwrite %s, requested %d, returned %d", mDav1dOutYuvFileName,
+ iSize, ret);
+ break;
+ }
+ ptr += p.stride[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
+ const std::unique_ptr<C2Work>& work) {
+ if (!(work && pool)) return false;
+ if (mDav1dCtx == nullptr) return false;
+
+ // Get a decoded picture from dav1d if it is enabled.
+ Dav1dPicture img;
+ memset(&img, 0, sizeof(img));
+
+ int res = 0;
+ if (mDecodedPictures.size() > 0) {
+ img = mDecodedPictures.front();
+ mDecodedPictures.pop_front();
+ // ALOGD("Got a picture(out_frameIndex=%ld,timestamp=%ld) from the deque for
+ // outputBuffer.",img.m.timestamp,img.m.timestamp);
+ } else {
+ res = dav1d_get_picture(mDav1dCtx, &img);
+ if (res == 0) {
+ // ALOGD("Got a picture(out_frameIndex=%ld,timestamp=%ld) from dav1d for
+ // outputBuffer.",img.m.timestamp,img.m.timestamp);
+ } else {
+ ALOGE("failed to get a picture from dav1d for outputBuffer.");
+ }
+ }
+
+ if (res == DAV1D_ERR(EAGAIN)) {
+ ALOGD("Not enough data to output a picture.");
+ return false;
+ }
+ if (res != 0) {
+ ALOGE("The AV1 decoder failed to get a picture (res=%s).", strerror(DAV1D_ERR(res)));
+ return false;
+ }
+
+ const int width = img.p.w;
+ const int height = img.p.h;
+ if (width != mWidth || height != mHeight) {
+ mWidth = width;
+ mHeight = height;
+
+ C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+ if (err == C2_OK) {
+ work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(size));
+ } else {
+ ALOGE("Config update size failed");
+ mSignalledError = true;
+ work->result = C2_CORRUPTED;
+ work->workletsProcessed = 1u;
+ return false;
+ }
+ }
+
+ getVuiParams(&img);
+ getHDRStaticParams(&img, work);
+ getHDR10PlusInfoData(&img, work);
+
+ // out_frameIndex that the decoded picture returns from dav1d.
+ int64_t out_frameIndex = img.m.timestamp;
+
+#if LIBYUV_VERSION < 1779
+ if (!(img.p.layout != DAV1D_PIXEL_LAYOUT_I400 || img.p.layout != DAV1D_PIXEL_LAYOUT_I420)) {
+ ALOGE("image_format %d not supported", img.p.layout);
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return false;
+ }
+#endif
+
+ const bool isMonochrome = img.p.layout == DAV1D_PIXEL_LAYOUT_I400;
+
+ int bitdepth = img.p.bpc;
+
+ std::shared_ptr<C2GraphicBlock> block;
+ uint32_t format = HAL_PIXEL_FORMAT_YV12;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects;
+ if (bitdepth == 10 && mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
+ IntfImpl::Lock lock = mIntf->lock();
+ codedColorAspects = mIntf->getColorAspects_l();
+ bool allowRGBA1010102 = false;
+ if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+ codedColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+ codedColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+ allowRGBA1010102 = true;
+ }
+ format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
+#if !HAVE_LIBYUV_I410_I210_TO_AB30
+ if ((format == HAL_PIXEL_FORMAT_RGBA_1010102) &&
+ (is_img_ready ? img.p.layout == DAV1D_PIXEL_LAYOUT_I420
+ : buffer->image_format != libgav1::kImageFormatYuv420)) {
+ ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
+ mSignalledError = true;
+ work->result = C2_OMITTED;
+ work->workletsProcessed = 1u;
+ return false;
+ }
+#endif
+ }
+
+ if (mHalPixelFormat != format) {
+ C2StreamPixelFormatInfo::output pixelFormat(0u, format);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&pixelFormat}, C2_MAY_BLOCK, &failures);
+ if (err == C2_OK) {
+ work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(pixelFormat));
+ } else {
+ ALOGE("Config update pixelFormat failed");
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return UNKNOWN_ERROR;
+ }
+ mHalPixelFormat = format;
+ }
+
+ C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+
+ // We always create a graphic block that is width aligned to 16 and height
+ // aligned to 2. We set the correct "crop" value of the image in the call to
+ // createGraphicBuffer() by setting the correct image dimensions.
+ c2_status_t err =
+ pool->fetchGraphicBlock(align(mWidth, 16), align(mHeight, 2), format, usage, &block);
+
+ if (err != C2_OK) {
+ ALOGE("fetchGraphicBlock for Output failed with status %d", err);
+ work->result = err;
+ return false;
+ }
+
+ C2GraphicView wView = block->map().get();
+
+ if (wView.error()) {
+ ALOGE("graphic view map failed %d", wView.error());
+ work->result = C2_CORRUPTED;
+ return false;
+ }
+
+ // ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d", block->width(),
+ // block->height(), mWidth, mHeight, (int)out_frameIndex);
+
+ mOutputBufferIndex = out_frameIndex;
+
+ uint8_t* dstY = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t* dstU = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_U]);
+ uint8_t* dstV = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_V]);
+
+ C2PlanarLayout layout = wView.layout();
+ size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+ size_t dstUStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+ size_t dstVStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
+
+ if (bitdepth == 10) {
+ // TODO: b/277797541 - Investigate if we can ask DAV1D to output the required format during
+ // decompression to avoid color conversion.
+ const uint16_t* srcY = (const uint16_t*)img.data[0];
+ const uint16_t* srcU = (const uint16_t*)img.data[1];
+ const uint16_t* srcV = (const uint16_t*)img.data[2];
+ size_t srcYStride = img.stride[0] / 2;
+ size_t srcUStride = img.stride[1] / 2;
+ size_t srcVStride = img.stride[1] / 2;
+
+ if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+ bool processed = false;
+#if HAVE_LIBYUV_I410_I210_TO_AB30
+ if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
+ libyuv::I410ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
+ dstYStride, &libyuv::kYuvV2020Constants, mWidth, mHeight);
+ processed = true;
+ } else if (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
+ libyuv::I210ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
+ dstYStride, &libyuv::kYuvV2020Constants, mWidth, mHeight);
+ processed = true;
+ }
+#endif // HAVE_LIBYUV_I410_I210_TO_AB30
+ if (!processed) {
+ if (isMonochrome) {
+ const size_t tmpSize = mWidth;
+ const bool needFill = tmpSize > mTmpFrameBufferSize;
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ srcU = srcV = mTmpFrameBuffer.get();
+ srcUStride = srcVStride = 0;
+ if (needFill) {
+ std::fill_n(mTmpFrameBuffer.get(), tmpSize, 512);
+ }
+ }
+ convertYUV420Planar16ToY410OrRGBA1010102(
+ (uint32_t*)dstY, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
+ dstYStride / sizeof(uint32_t), mWidth, mHeight,
+ std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects));
+ }
+ } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
+ dstYStride /= 2;
+ dstUStride /= 2;
+ dstVStride /= 2;
+#if LIBYUV_VERSION >= 1779
+ if ((img.p.layout == DAV1D_PIXEL_LAYOUT_I444) ||
+ (img.p.layout == DAV1D_PIXEL_LAYOUT_I422)) {
+ // TODO(https://crbug.com/libyuv/952): replace this block with libyuv::I410ToP010
+ // and libyuv::I210ToP010 when they are available. Note it may be safe to alias dstY
+ // in I010ToP010, but the libyuv API doesn't make any guarantees.
+ const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ uint16_t* const tmpY = mTmpFrameBuffer.get();
+ uint16_t* const tmpU = tmpY + dstYStride * mHeight;
+ uint16_t* const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
+ if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
+ libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY,
+ dstYStride, tmpU, dstUStride, tmpV, dstUStride, mWidth,
+ mHeight);
+ } else {
+ libyuv::I210ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY,
+ dstYStride, tmpU, dstUStride, tmpV, dstUStride, mWidth,
+ mHeight);
+ }
+ libyuv::I010ToP010(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
+ (uint16_t*)dstY, dstYStride, (uint16_t*)dstU, dstUStride, mWidth,
+ mHeight);
+ } else {
+ convertYUV420Planar16ToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcV,
+ srcYStride, srcUStride, srcVStride, dstYStride,
+ dstUStride, mWidth, mHeight, isMonochrome);
+ }
+#else // LIBYUV_VERSION < 1779
+ convertYUV420Planar16ToP010((uint16_t*)dstY, (uint16_t*)dstU, srcY, srcU, srcV,
+ srcYStride, srcUStride, srcVStride, dstYStride, dstUStride,
+ mWidth, mHeight, isMonochrome);
+#endif // LIBYUV_VERSION >= 1779
+ } else {
+#if LIBYUV_VERSION >= 1779
+ if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
+ // TODO(https://crbug.com/libyuv/950): replace this block with libyuv::I410ToI420
+ // when it's available.
+ const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ uint16_t* const tmpY = mTmpFrameBuffer.get();
+ uint16_t* const tmpU = tmpY + dstYStride * mHeight;
+ uint16_t* const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
+ libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, tmpY,
+ dstYStride, tmpU, dstUStride, tmpV, dstVStride, mWidth, mHeight);
+ libyuv::I010ToI420(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride, dstY,
+ dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
+ } else if (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
+ libyuv::I210ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
+ dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
+ } else {
+ convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride,
+ srcUStride, srcVStride, dstYStride, dstUStride, mWidth,
+ mHeight, isMonochrome);
+ }
+#else // LIBYUV_VERSION < 1779
+ convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
+ srcVStride, dstYStride, dstUStride, mWidth, mHeight,
+ isMonochrome);
+#endif // LIBYUV_VERSION >= 1779
+ }
+
+ // Dump the output buffer if dumping is enabled (debug only).
+#ifdef FILE_DUMP_ENABLE
+ FILE* fp_out = mDav1dOutYuvFile;
+
+ // if(mOutputBufferIndex % 100 == 0)
+ ALOGV("output a 10bit picture %dx%d from dav1d "
+ "(mInputBufferIndex=%d,mOutputBufferIndex=%d,format=%d).",
+ mWidth, mHeight, mInputBufferIndex, mOutputBufferIndex, format);
+
+ if (fp_out && mOutputBufferIndex <= num_frames_to_dump) {
+ for (int i = 0; i < mHeight; i++) {
+ int ret = fwrite((uint8_t*)srcY + i * srcYStride * 2, 1, mWidth * 2, fp_out);
+ if (ret != mWidth * 2) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth * 2, ret);
+ break;
+ }
+ }
+
+ for (int i = 0; i < mHeight / 2; i++) {
+ int ret = fwrite((uint8_t*)srcU + i * srcUStride * 2, 1, mWidth, fp_out);
+ if (ret != mWidth) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth, ret);
+ break;
+ }
+ }
+
+ for (int i = 0; i < mHeight / 2; i++) {
+ int ret = fwrite((uint8_t*)srcV + i * srcVStride * 2, 1, mWidth, fp_out);
+ if (ret != mWidth) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth, ret);
+ break;
+ }
+ }
+ }
+#endif
+ } else {
+ const uint8_t* srcY = (const uint8_t*)img.data[0];
+ const uint8_t* srcU = (const uint8_t*)img.data[1];
+ const uint8_t* srcV = (const uint8_t*)img.data[2];
+
+ size_t srcYStride = img.stride[0];
+ size_t srcUStride = img.stride[1];
+ size_t srcVStride = img.stride[1];
+
+ // Dump the output buffer is dumping is enabled (debug only)
+#ifdef FILE_DUMP_ENABLE
+ FILE* fp_out = mDav1dOutYuvFile;
+ // if(mOutputBufferIndex % 100 == 0)
+ ALOGV("output a 8bit picture %dx%d from dav1d "
+ "(mInputBufferIndex=%d,mOutputBufferIndex=%d,format=%d).",
+ mWidth, mHeight, mInputBufferIndex, mOutputBufferIndex, format);
+
+ if (fp_out && mOutputBufferIndex <= num_frames_to_dump) {
+ for (int i = 0; i < mHeight; i++) {
+ int ret = fwrite((uint8_t*)srcY + i * srcYStride, 1, mWidth, fp_out);
+ if (ret != mWidth) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth, ret);
+ break;
+ }
+ }
+
+ for (int i = 0; i < mHeight / 2; i++) {
+ int ret = fwrite((uint8_t*)srcU + i * srcUStride, 1, mWidth / 2, fp_out);
+ if (ret != mWidth / 2) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth / 2, ret);
+ break;
+ }
+ }
+
+ for (int i = 0; i < mHeight / 2; i++) {
+ int ret = fwrite((uint8_t*)srcV + i * srcVStride, 1, mWidth / 2, fp_out);
+ if (ret != mWidth / 2) {
+ ALOGE("Error in fwrite, requested %d, returned %d", mWidth / 2, ret);
+ break;
+ }
+ }
+ }
+#endif
+ if (img.p.layout == DAV1D_PIXEL_LAYOUT_I444) {
+ libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
+ dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
+ } else if (img.p.layout == DAV1D_PIXEL_LAYOUT_I422) {
+ libyuv::I422ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride, dstY,
+ dstYStride, dstU, dstUStride, dstV, dstVStride, mWidth, mHeight);
+ } else {
+ convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
+ srcVStride, dstYStride, dstUStride, dstVStride, mWidth,
+ mHeight, isMonochrome);
+ }
+ }
+
+ dav1d_picture_unref(&img);
+
+ finishWork(out_frameIndex, work, std::move(block));
+ block = nullptr;
+ return true;
+}
+
+c2_status_t C2SoftDav1dDec::drainInternal(uint32_t drainMode,
+ const std::shared_ptr<C2BlockPool>& pool,
+ const std::unique_ptr<C2Work>& work) {
+ if (drainMode == NO_DRAIN) {
+ ALOGW("drain with NO_DRAIN: no-op");
+ return C2_OK;
+ }
+ if (drainMode == DRAIN_CHAIN) {
+ ALOGW("DRAIN_CHAIN not supported");
+ return C2_OMITTED;
+ }
+
+ while (outputBuffer(pool, work)) {
+ }
+
+ if (drainMode == DRAIN_COMPONENT_WITH_EOS && work && work->workletsProcessed == 0u) {
+ fillEmptyWork(work);
+ }
+
+ return C2_OK;
+}
+
+c2_status_t C2SoftDav1dDec::drain(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool) {
+ return drainInternal(drainMode, pool, nullptr);
+}
+
+class C2SoftDav1dFactory : public C2ComponentFactory {
+ public:
+ C2SoftDav1dFactory()
+ : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+ GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+ virtual c2_status_t createComponent(c2_node_id_t id,
+ std::shared_ptr<C2Component>* const component,
+ std::function<void(C2Component*)> deleter) override {
+ *component = std::shared_ptr<C2Component>(
+ new C2SoftDav1dDec(COMPONENT_NAME, id,
+ std::make_shared<C2SoftDav1dDec::IntfImpl>(mHelper)),
+ deleter);
+ return C2_OK;
+ }
+
+ virtual c2_status_t createInterface(
+ c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+ std::function<void(C2ComponentInterface*)> deleter) override {
+ *interface = std::shared_ptr<C2ComponentInterface>(
+ new SimpleInterface<C2SoftDav1dDec::IntfImpl>(
+ COMPONENT_NAME, id, std::make_shared<C2SoftDav1dDec::IntfImpl>(mHelper)),
+ deleter);
+ return C2_OK;
+ }
+
+ virtual ~C2SoftDav1dFactory() override = default;
+
+ private:
+ std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
+} // namespace android
+
+__attribute__((cfi_canonical_jump_table)) extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+ ALOGV("in %s", __func__);
+ return new ::android::C2SoftDav1dFactory();
+}
+
+__attribute__((cfi_canonical_jump_table)) extern "C" void DestroyCodec2Factory(
+ ::C2ComponentFactory* factory) {
+ ALOGV("in %s", __func__);
+ delete factory;
+}
diff --git a/media/codec2/components/dav1d/C2SoftDav1dDec.h b/media/codec2/components/dav1d/C2SoftDav1dDec.h
new file mode 100644
index 0000000..5201456
--- /dev/null
+++ b/media/codec2/components/dav1d/C2SoftDav1dDec.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_C2_SOFT_DAV1D_DEC_H_
+#define ANDROID_C2_SOFT_DAV1D_DEC_H_
+
+#include <inttypes.h>
+
+#include <memory>
+
+#include <media/stagefright/foundation/ColorUtils.h>
+
+#include <C2Config.h>
+#include <SimpleC2Component.h>
+
+#include <dav1d/dav1d.h>
+#include <deque>
+
+//#define FILE_DUMP_ENABLE 1
+#define DUMP_FILE_PATH "/data/local/tmp/dump"
+#define INPUT_DATA_DUMP_EXT "av1"
+#define INPUT_SIZE_DUMP_EXT "size"
+#define OUTPUT_YUV_DUMP_EXT "yuv"
+
+namespace android {
+
+struct C2SoftDav1dDec : public SimpleC2Component {
+ class IntfImpl;
+
+ C2SoftDav1dDec(const char* name, c2_node_id_t id, const std::shared_ptr<IntfImpl>& intfImpl);
+ ~C2SoftDav1dDec();
+
+ // Begin SimpleC2Component overrides.
+ c2_status_t onInit() override;
+ c2_status_t onStop() override;
+ void onReset() override;
+ void onRelease() override;
+ c2_status_t onFlush_sm() override;
+ void process(const std::unique_ptr<C2Work>& work,
+ const std::shared_ptr<C2BlockPool>& pool) override;
+ c2_status_t drain(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool) override;
+ // End SimpleC2Component overrides.
+
+ private:
+ std::shared_ptr<IntfImpl> mIntf;
+
+ int mInputBufferIndex = 0;
+ int mOutputBufferIndex = 0;
+
+ Dav1dContext* mDav1dCtx = nullptr;
+ std::deque<Dav1dPicture> mDecodedPictures;
+
+ // configurations used by component in process
+ // (TODO: keep this in intf but make them internal only)
+ std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormatInfo;
+
+ uint32_t mHalPixelFormat;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ bool mSignalledOutputEos;
+ bool mSignalledError;
+ // Used during 10-bit I444/I422 to 10-bit P010 & 8-bit I420 conversions.
+ std::unique_ptr<uint16_t[]> mTmpFrameBuffer;
+ size_t mTmpFrameBufferSize = 0;
+
+ C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
+
+ // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
+ // converting them to C2 values for each frame
+ struct VuiColorAspects {
+ uint8_t primaries;
+ uint8_t transfer;
+ uint8_t coeffs;
+ uint8_t fullRange;
+
+ // default color aspects
+ VuiColorAspects()
+ : primaries(C2Color::PRIMARIES_UNSPECIFIED),
+ transfer(C2Color::TRANSFER_UNSPECIFIED),
+ coeffs(C2Color::MATRIX_UNSPECIFIED),
+ fullRange(C2Color::RANGE_UNSPECIFIED) {}
+
+ bool operator==(const VuiColorAspects& o) {
+ return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs &&
+ fullRange == o.fullRange;
+ }
+ } mBitstreamColorAspects;
+
+ nsecs_t mTimeStart = 0; // Time at the start of decode()
+ nsecs_t mTimeEnd = 0; // Time at the end of decode()
+
+ bool initDecoder();
+ void getHDRStaticParams(Dav1dPicture* picture, const std::unique_ptr<C2Work>& work);
+ void getHDR10PlusInfoData(Dav1dPicture* picture, const std::unique_ptr<C2Work>& work);
+ void getVuiParams(Dav1dPicture* picture);
+ void destroyDecoder();
+ void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
+ const std::shared_ptr<C2GraphicBlock>& block);
+ // Sets |work->result| and mSignalledError. Returns false.
+ void setError(const std::unique_ptr<C2Work>& work, c2_status_t error);
+ bool allocTmpFrameBuffer(size_t size);
+ bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
+ const std::unique_ptr<C2Work>& work);
+
+ c2_status_t drainInternal(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool,
+ const std::unique_ptr<C2Work>& work);
+
+ void flushDav1d();
+
+#ifdef FILE_DUMP_ENABLE
+ char mInDataFileName[256];
+ char mInSizeFileName[256];
+ char mDav1dOutYuvFileName[256];
+
+ FILE* mInDataFile = nullptr;
+ FILE* mInSizeFile = nullptr;
+ FILE* mDav1dOutYuvFile = nullptr;
+
+ void writeDav1dOutYuvFile(const Dav1dPicture& p);
+
+ int num_frames_to_dump = 0;
+#endif
+
+ C2_DO_NOT_COPY(C2SoftDav1dDec);
+};
+
+} // namespace android
+
+#endif // ANDROID_C2_SOFT_DAV1D_DEC_H_
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 3e4247b..5f5f05d 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -752,6 +752,19 @@
return true;
}
+bool C2SoftGav1Dec::fillMonochromeRow(int value) {
+ const size_t tmpSize = mWidth;
+ const bool needFill = tmpSize > mTmpFrameBufferSize;
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ return false;
+ }
+ if (needFill) {
+ std::fill_n(mTmpFrameBuffer.get(), tmpSize, value);
+ }
+ return true;
+}
+
bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
const std::unique_ptr<C2Work> &work) {
if (!(work && pool)) return false;
@@ -773,6 +786,16 @@
return false;
}
+#if LIBYUV_VERSION < 1871
+ if (buffer->bitdepth > 10) {
+ ALOGE("bitdepth %d is not supported", buffer->bitdepth);
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return false;
+ }
+#endif
+
const int width = buffer->displayed_width[0];
const int height = buffer->displayed_height[0];
if (width != mWidth || height != mHeight) {
@@ -816,7 +839,7 @@
std::shared_ptr<C2GraphicBlock> block;
uint32_t format = HAL_PIXEL_FORMAT_YV12;
std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects;
- if (buffer->bitdepth == 10 && mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
+ if (buffer->bitdepth >= 10 && mPixelFormatInfo->value != HAL_PIXEL_FORMAT_YCBCR_420_888) {
IntfImpl::Lock lock = mIntf->lock();
codedColorAspects = mIntf->getColorAspects_l();
bool allowRGBA1010102 = false;
@@ -828,8 +851,9 @@
format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
#if !HAVE_LIBYUV_I410_I210_TO_AB30
if ((format == HAL_PIXEL_FORMAT_RGBA_1010102) &&
- (buffer->image_format != libgav1::kImageFormatYuv420)) {
- ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
+ (buffer->image_format != libgav1::kImageFormatYuv420) &&
+ (buffer->bitdepth == 10)) {
+ ALOGE("Only YUV420 output is supported for 10-bit when targeting RGBA_1010102");
mSignalledError = true;
work->result = C2_OMITTED;
work->workletsProcessed = 1u;
@@ -837,6 +861,18 @@
}
#endif
}
+ if (buffer->bitdepth == 12 && format == HAL_PIXEL_FORMAT_RGBA_1010102 &&
+ (buffer->image_format == libgav1::kImageFormatYuv422 ||
+ buffer->image_format == libgav1::kImageFormatYuv444)) {
+ // There are no 12-bit color conversion functions from YUV422/YUV444 to
+ // RGBA_1010102. Use 8-bit YV12 in this case.
+ format = HAL_PIXEL_FORMAT_YV12;
+ }
+ if (buffer->bitdepth == 12 && format == HAL_PIXEL_FORMAT_YCBCR_P010) {
+ // There are no 12-bit color conversion functions to P010. Use 8-bit YV12
+ // in this case.
+ format = HAL_PIXEL_FORMAT_YV12;
+ }
if (mHalPixelFormat != format) {
C2StreamPixelFormatInfo::output pixelFormat(0u, format);
@@ -890,7 +926,41 @@
size_t dstUStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
size_t dstVStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
- if (buffer->bitdepth == 10) {
+ if (buffer->bitdepth == 12) {
+#if LIBYUV_VERSION >= 1871
+ const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
+ const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
+ const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
+ size_t srcYStride = buffer->stride[0] / 2;
+ size_t srcUStride = buffer->stride[1] / 2;
+ size_t srcVStride = buffer->stride[2] / 2;
+ if (isMonochrome) {
+ if (!fillMonochromeRow(2048)) {
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ srcU = srcV = mTmpFrameBuffer.get();
+ srcUStride = srcVStride = 0;
+ }
+ if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
+ libyuv::I012ToAB30Matrix(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, &libyuv::kYuvV2020Constants,
+ mWidth, mHeight);
+ } else if (isMonochrome || buffer->image_format == libgav1::kImageFormatYuv420) {
+ libyuv::I012ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else if (buffer->image_format == libgav1::kImageFormatYuv444) {
+ libyuv::I412ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else {
+ libyuv::I212ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ }
+#endif // LIBYUV_VERSION >= 1871
+ } else if (buffer->bitdepth == 10) {
const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
@@ -915,18 +985,12 @@
#endif // HAVE_LIBYUV_I410_I210_TO_AB30
if (!processed) {
if (isMonochrome) {
- const size_t tmpSize = mWidth;
- const bool needFill = tmpSize > mTmpFrameBufferSize;
- if (!allocTmpFrameBuffer(tmpSize)) {
- ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ if (!fillMonochromeRow(512)) {
setError(work, C2_NO_MEMORY);
return false;
}
srcU = srcV = mTmpFrameBuffer.get();
srcUStride = srcVStride = 0;
- if (needFill) {
- std::fill_n(mTmpFrameBuffer.get(), tmpSize, 512);
- }
}
convertYUV420Planar16ToY410OrRGBA1010102(
(uint32_t *)dstY, srcY, srcU, srcV, srcYStride,
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index c3b27ea..0e09fcc 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -105,6 +105,7 @@
// Sets |work->result| and mSignalledError. Returns false.
void setError(const std::unique_ptr<C2Work> &work, c2_status_t error);
bool allocTmpFrameBuffer(size_t size);
+ bool fillMonochromeRow(int value);
bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
const std::unique_ptr<C2Work>& work);
c2_status_t drainInternal(uint32_t drainMode,
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index f272499..0803dc3 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -23,6 +23,7 @@
#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <cutils/native_handle.h>
+#include <drm/drm_fourcc.h>
#include <gralloctypes/Gralloc4.h>
#include <hardware/gralloc.h>
#include <ui/GraphicBufferAllocator.h>
@@ -478,7 +479,25 @@
// 'NATIVE' on Android means LITTLE_ENDIAN
constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
- switch (mFormat) {
+ // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
+ // possible.
+ uint32_t format = mFormat;
+ uint32_t fourCc;
+ if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+ !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) {
+ switch (fourCc) {
+ case DRM_FORMAT_XBGR8888:
+ format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
+ break;
+ case DRM_FORMAT_ABGR8888:
+ format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (format) {
case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
// TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
// Surface. In all other cases it is RGBA. We don't know which case it is here, so
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
index 5444565..b7e0ae6 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.cpp
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -39,18 +39,21 @@
aaudio_result_t AAudioFlowGraph::configure(audio_format_t sourceFormat,
int32_t sourceChannelCount,
+ int32_t sourceSampleRate,
audio_format_t sinkFormat,
int32_t sinkChannelCount,
+ int32_t sinkSampleRate,
bool useMonoBlend,
+ bool useVolumeRamps,
float audioBalance,
- bool isExclusive) {
+ aaudio::resampler::MultiChannelResampler::Quality resamplerQuality) {
FlowGraphPortFloatOutput *lastOutput = nullptr;
- // TODO change back to ALOGD
- ALOGI("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d, "
- "useMonoBlend = %d, audioBalance = %f, isExclusive %d",
- __func__, sourceFormat, sourceChannelCount, sinkFormat, sinkChannelCount,
- useMonoBlend, audioBalance, isExclusive);
+ ALOGD("%s() source format = 0x%08x, channels = %d, sample rate = %d, "
+ "sink format = 0x%08x, channels = %d, sample rate = %d, "
+ "useMonoBlend = %d, audioBalance = %f, useVolumeRamps %d",
+ __func__, sourceFormat, sourceChannelCount, sourceSampleRate, sinkFormat,
+ sinkChannelCount, sinkSampleRate, useMonoBlend, audioBalance, useVolumeRamps);
switch (sourceFormat) {
case AUDIO_FORMAT_PCM_FLOAT:
@@ -85,6 +88,15 @@
lastOutput = &mLimiter->output;
}
+ if (sourceSampleRate != sinkSampleRate) {
+ mResampler.reset(aaudio::resampler::MultiChannelResampler::make(sourceChannelCount,
+ sourceSampleRate, sinkSampleRate, resamplerQuality));
+ mRateConverter = std::make_unique<SampleRateConverter>(sourceChannelCount,
+ *mResampler);
+ lastOutput->connect(&mRateConverter->input);
+ lastOutput = &mRateConverter->output;
+ }
+
// Expand the number of channels if required.
if (sourceChannelCount == 1 && sinkChannelCount > 1) {
mChannelConverter = std::make_unique<MonoToMultiConverter>(sinkChannelCount);
@@ -95,8 +107,7 @@
return AAUDIO_ERROR_UNIMPLEMENTED;
}
- // Apply volume ramps for only exclusive streams.
- if (isExclusive) {
+ if (useVolumeRamps) {
// Apply volume ramps to set the left/right audio balance and target volumes.
// The signals will be decoupled, volume ramps will be applied, before the signals are
// combined again.
@@ -137,9 +148,14 @@
return AAUDIO_OK;
}
-void AAudioFlowGraph::process(const void *source, void *destination, int32_t numFrames) {
- mSource->setData(source, numFrames);
- mSink->read(destination, numFrames);
+int32_t AAudioFlowGraph::pull(void *destination, int32_t targetFramesToRead) {
+ return mSink->read(destination, targetFramesToRead);
+}
+
+int32_t AAudioFlowGraph::process(const void *source, int32_t numFramesToWrite, void *destination,
+ int32_t targetFramesToRead) {
+ mSource->setData(source, numFramesToWrite);
+ return mSink->read(destination, targetFramesToRead);
}
/**
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.h b/media/libaaudio/src/client/AAudioFlowGraph.h
index 35fef37..e1d517e 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.h
+++ b/media/libaaudio/src/client/AAudioFlowGraph.h
@@ -30,6 +30,7 @@
#include <flowgraph/MonoToMultiConverter.h>
#include <flowgraph/MultiToManyConverter.h>
#include <flowgraph/RampLinear.h>
+#include <flowgraph/SampleRateConverter.h>
class AAudioFlowGraph {
public:
@@ -38,23 +39,57 @@
*
* @param sourceFormat
* @param sourceChannelCount
+ * @param sourceSampleRate
* @param sinkFormat
* @param sinkChannelCount
+ * @param sinkSampleRate
* @param useMonoBlend
+ * @param useVolumeRamps
* @param audioBalance
- * @param channelMask
- * @param isExclusive
+ * @param resamplerQuality
* @return
*/
aaudio_result_t configure(audio_format_t sourceFormat,
int32_t sourceChannelCount,
+ int32_t sourceSampleRate,
audio_format_t sinkFormat,
int32_t sinkChannelCount,
+ int32_t sinkSampleRate,
bool useMonoBlend,
+ bool useVolumeRamps,
float audioBalance,
- bool isExclusive);
+ aaudio::resampler::MultiChannelResampler::Quality resamplerQuality);
- void process(const void *source, void *destination, int32_t numFrames);
+ /**
+ * Attempt to read targetFramesToRead from the flowgraph.
+ * This function returns the number of frames actually read.
+ *
+ * This function does nothing if process() was not called before.
+ *
+ * @param destination
+ * @param targetFramesToRead
+ * @return numFramesRead
+ */
+ int32_t pull(void *destination, int32_t targetFramesToRead);
+
+ /**
+ * Set numFramesToWrite frames from the source into the flowgraph.
+ * Then, attempt to read targetFramesToRead from the flowgraph.
+ * This function returns the number of frames actually read.
+ *
+ * There may be data still in the flowgraph if targetFramesToRead is not large enough.
+ * Before calling process() again, pull() must be called until until all the data is consumed.
+ *
+ * TODO: b/289510598 - Calculate the exact number of input frames needed for Y output frames.
+ *
+ * @param source
+ * @param numFramesToWrite
+ * @param destination
+ * @param targetFramesToRead
+ * @return numFramesRead
+ */
+ int32_t process(const void *source, int32_t numFramesToWrite, void *destination,
+ int32_t targetFramesToRead);
/**
* @param volume between 0.0 and 1.0
@@ -73,6 +108,8 @@
private:
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSourceBuffered> mSource;
+ std::unique_ptr<RESAMPLER_OUTER_NAMESPACE::resampler::MultiChannelResampler> mResampler;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::SampleRateConverter> mRateConverter;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoBlend> mMonoBlend;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::Limiter> mLimiter;
std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoToMultiConverter> mChannelConverter;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 84c715f..9b1ad72 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -63,6 +63,8 @@
#define LOG_TIMESTAMPS 0
+#define ENABLE_SAMPLE_RATE_CONVERTER 1
+
AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface &serviceInterface, bool inService)
: AudioStream()
, mClockModel()
@@ -132,12 +134,6 @@
request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());
- request.getConfiguration().setHardwareSamplesPerFrame(builder.getHardwareSamplesPerFrame());
- request.getConfiguration().setHardwareSampleRate(builder.getHardwareSampleRate());
- request.getConfiguration().setHardwareFormat(builder.getHardwareFormat());
-
- mDeviceChannelCount = getSamplesPerFrame(); // Assume it will be the same. Update if not.
-
mServiceStreamHandleInfo = mServiceInterface.openStream(request, configurationOutput);
if (getServiceHandle() < 0
&& (request.getConfiguration().getSamplesPerFrame() == 1
@@ -181,9 +177,6 @@
setChannelMask(configurationOutput.getChannelMask());
}
- mDeviceChannelCount = configurationOutput.getSamplesPerFrame();
-
- setSampleRate(configurationOutput.getSampleRate());
setDeviceId(configurationOutput.getDeviceId());
setSessionId(configurationOutput.getSessionId());
setSharingMode(configurationOutput.getSharingMode());
@@ -194,8 +187,21 @@
setIsContentSpatialized(configurationOutput.isContentSpatialized());
setInputPreset(configurationOutput.getInputPreset());
+ setDeviceSampleRate(configurationOutput.getSampleRate());
+
+ if (getSampleRate() == AAUDIO_UNSPECIFIED) {
+ setSampleRate(configurationOutput.getSampleRate());
+ }
+
+#if !ENABLE_SAMPLE_RATE_CONVERTER
+ if (getSampleRate() != getDeviceSampleRate()) {
+ goto error;
+ }
+#endif
+
// Save device format so we can do format conversion and volume scaling together.
setDeviceFormat(configurationOutput.getFormat());
+ setDeviceSamplesPerFrame(configurationOutput.getSamplesPerFrame());
setHardwareSamplesPerFrame(configurationOutput.getHardwareSamplesPerFrame());
setHardwareSampleRate(configurationOutput.getHardwareSampleRate());
@@ -233,39 +239,46 @@
}
aaudio_result_t AudioStreamInternal::configureDataInformation(int32_t callbackFrames) {
- int32_t framesPerHardwareBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
+ int32_t deviceFramesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst;
// Scale up the burst size to meet the minimum equivalent in microseconds.
// This is to avoid waking the CPU too often when the HW burst is very small
- // or at high sample rates.
- int32_t framesPerBurst = framesPerHardwareBurst;
+ // or at high sample rates. The actual number of frames that we call back to
+ // the app with will be 0 < N <= framesPerBurst so round up the division.
+ int32_t framesPerBurst = (static_cast<int64_t>(deviceFramesPerBurst) * getSampleRate() +
+ getDeviceSampleRate() - 1) / getDeviceSampleRate();
int32_t burstMicros = 0;
const int32_t burstMinMicros = android::AudioSystem::getAAudioHardwareBurstMinUsec();
do {
if (burstMicros > 0) { // skip first loop
+ deviceFramesPerBurst *= 2;
framesPerBurst *= 2;
}
burstMicros = framesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
} while (burstMicros < burstMinMicros);
ALOGD("%s() original HW burst = %d, minMicros = %d => SW burst = %d\n",
- __func__, framesPerHardwareBurst, burstMinMicros, framesPerBurst);
+ __func__, deviceFramesPerBurst, burstMinMicros, framesPerBurst);
// Validate final burst size.
if (framesPerBurst < MIN_FRAMES_PER_BURST || framesPerBurst > MAX_FRAMES_PER_BURST) {
ALOGE("%s - framesPerBurst out of range = %d", __func__, framesPerBurst);
return AAUDIO_ERROR_OUT_OF_RANGE;
}
+ setDeviceFramesPerBurst(deviceFramesPerBurst);
setFramesPerBurst(framesPerBurst); // only save good value
- mBufferCapacityInFrames = mEndpointDescriptor.dataQueueDescriptor.capacityInFrames;
+ mDeviceBufferCapacityInFrames = mEndpointDescriptor.dataQueueDescriptor.capacityInFrames;
+
+ mBufferCapacityInFrames = static_cast<int64_t>(mDeviceBufferCapacityInFrames)
+ * getSampleRate() / getDeviceSampleRate();
if (mBufferCapacityInFrames < getFramesPerBurst()
|| mBufferCapacityInFrames > MAX_BUFFER_CAPACITY_IN_FRAMES) {
ALOGE("%s - bufferCapacity out of range = %d", __func__, mBufferCapacityInFrames);
return AAUDIO_ERROR_OUT_OF_RANGE;
}
- mClockModel.setSampleRate(getSampleRate());
- mClockModel.setFramesPerBurst(framesPerHardwareBurst);
+ mClockModel.setSampleRate(getDeviceSampleRate());
+ mClockModel.setFramesPerBurst(deviceFramesPerBurst);
if (isDataCallbackSet()) {
mCallbackFrames = callbackFrames;
@@ -315,7 +328,8 @@
mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND;
}
- setBufferSize(mBufferCapacityInFrames / 2); // Default buffer size to match Q
+ // Default buffer size to match Q
+ setBufferSize(mBufferCapacityInFrames / 2);
return AAUDIO_OK;
}
@@ -374,9 +388,9 @@
// Cache the buffer size which may be from client.
const int32_t previousBufferSize = mBufferSizeInFrames;
// Copy all available data from current data queue.
- uint8_t buffer[getBufferCapacity() * getBytesPerFrame()];
- android::fifo_frames_t fullFramesAvailable =
- mAudioEndpoint->read(buffer, getBufferCapacity());
+ uint8_t buffer[getDeviceBufferCapacity() * getBytesPerFrame()];
+ android::fifo_frames_t fullFramesAvailable = mAudioEndpoint->read(buffer,
+ getDeviceBufferCapacity());
mEndPointParcelable.closeDataFileDescriptor();
aaudio_result_t result = mServiceInterface.exitStandby(
mServiceStreamHandleInfo, endpointParcelable);
@@ -408,7 +422,7 @@
goto exit;
}
// Write data from previous data buffer to new endpoint.
- if (android::fifo_frames_t framesWritten =
+ if (const android::fifo_frames_t framesWritten =
mAudioEndpoint->write(buffer, fullFramesAvailable);
framesWritten != fullFramesAvailable) {
ALOGW("Some data lost after exiting standby, frames written: %d, "
@@ -448,7 +462,7 @@
ALOGD("requestStart() but DISCONNECTED");
return AAUDIO_ERROR_DISCONNECTED;
}
- aaudio_stream_state_t originalState = getState();
+ const aaudio_stream_state_t originalState = getState();
setState(AAUDIO_STREAM_STATE_STARTING);
// Clear any stale timestamps from the previous run.
@@ -605,7 +619,11 @@
// Generated in server and passed to client. Return latest.
if (mAtomicInternalTimestamp.isValid()) {
Timestamp timestamp = mAtomicInternalTimestamp.read();
- int64_t position = timestamp.getPosition() + mFramesOffsetFromService;
+ // This should not overflow as timestamp.getPosition() should be a position in a buffer and
+ // not the actual timestamp. timestamp.getNanoseconds() below uses the actual timestamp.
+ // At 48000 Hz we can run for over 100 years before overflowing the int64_t.
+ int64_t position = (timestamp.getPosition() + mFramesOffsetFromService) * getSampleRate() /
+ getDeviceSampleRate();
if (position >= 0) {
*framePosition = position;
*timeNanoseconds = timestamp.getNanoseconds();
@@ -889,7 +907,8 @@
adjustedFrames = maximumSize;
} else {
// Round to the next highest burst size.
- int32_t numBursts = (adjustedFrames + getFramesPerBurst() - 1) / getFramesPerBurst();
+ int32_t numBursts = (static_cast<int64_t>(adjustedFrames) + getFramesPerBurst() - 1) /
+ getFramesPerBurst();
adjustedFrames = numBursts * getFramesPerBurst();
// Clip just in case maximumSize is not a multiple of getFramesPerBurst().
adjustedFrames = std::min(maximumSize, adjustedFrames);
@@ -897,23 +916,32 @@
if (mAudioEndpoint) {
// Clip against the actual size from the endpoint.
- int32_t actualFrames = 0;
+ int32_t actualFramesDevice = 0;
+ int32_t maximumFramesDevice = (static_cast<int64_t>(maximumSize) * getDeviceSampleRate()
+ + getSampleRate() - 1) / getSampleRate();
// Set to maximum size so we can write extra data when ready in order to reduce glitches.
// The amount we keep in the buffer is controlled by mBufferSizeInFrames.
- mAudioEndpoint->setBufferSizeInFrames(maximumSize, &actualFrames);
+ mAudioEndpoint->setBufferSizeInFrames(maximumFramesDevice, &actualFramesDevice);
+ int32_t actualFrames = (static_cast<int64_t>(actualFramesDevice) * getSampleRate() +
+ getDeviceSampleRate() - 1) / getDeviceSampleRate();
// actualFrames should be <= actual maximum size of endpoint
adjustedFrames = std::min(actualFrames, adjustedFrames);
}
- if (adjustedFrames != mBufferSizeInFrames) {
+ const int32_t bufferSizeInFrames = adjustedFrames;
+ const int32_t deviceBufferSizeInFrames = static_cast<int64_t>(bufferSizeInFrames) *
+ getDeviceSampleRate() / getSampleRate();
+
+ if (deviceBufferSizeInFrames != mDeviceBufferSizeInFrames) {
android::mediametrics::LogItem(mMetricsId)
.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETBUFFERSIZE)
- .set(AMEDIAMETRICS_PROP_BUFFERSIZEFRAMES, adjustedFrames)
+ .set(AMEDIAMETRICS_PROP_BUFFERSIZEFRAMES, deviceBufferSizeInFrames)
.set(AMEDIAMETRICS_PROP_UNDERRUN, (int32_t) getXRunCount())
.record();
}
- mBufferSizeInFrames = adjustedFrames;
+ mBufferSizeInFrames = bufferSizeInFrames;
+ mDeviceBufferSizeInFrames = deviceBufferSizeInFrames;
ALOGV("%s(%d) returns %d", __func__, requestedFrames, adjustedFrames);
return (aaudio_result_t) adjustedFrames;
}
@@ -922,10 +950,18 @@
return mBufferSizeInFrames;
}
+int32_t AudioStreamInternal::getDeviceBufferSize() const {
+ return mDeviceBufferSizeInFrames;
+}
+
int32_t AudioStreamInternal::getBufferCapacity() const {
return mBufferCapacityInFrames;
}
+int32_t AudioStreamInternal::getDeviceBufferCapacity() const {
+ return mDeviceBufferCapacityInFrames;
+}
+
bool AudioStreamInternal::isClockModelInControl() const {
return isActive() && mAudioEndpoint->isFreeRunning() && mClockModel.isRunning();
}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 9c06121..a5981b1 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -22,8 +22,9 @@
#include "binding/AudioEndpointParcelable.h"
#include "binding/AAudioServiceInterface.h"
-#include "client/IsochronousClockModel.h"
+#include "client/AAudioFlowGraph.h"
#include "client/AudioEndpoint.h"
+#include "client/IsochronousClockModel.h"
#include "core/AudioStream.h"
#include "utility/AudioClock.h"
@@ -56,8 +57,12 @@
int32_t getBufferSize() const override;
+ int32_t getDeviceBufferSize() const;
+
int32_t getBufferCapacity() const override;
+ int32_t getDeviceBufferCapacity() const override;
+
int32_t getXRunCount() const override {
return mXRunCount;
}
@@ -133,8 +138,6 @@
// Calculate timeout for an operation involving framesPerOperation.
int64_t calculateReasonableTimeout(int32_t framesPerOperation);
- int32_t getDeviceChannelCount() const { return mDeviceChannelCount; }
-
/**
* @return true if running in audio service, versus in app process
*/
@@ -177,6 +180,8 @@
int64_t mLastFramesWritten = 0;
int64_t mLastFramesRead = 0;
+ AAudioFlowGraph mFlowGraph;
+
private:
/*
* Asynchronous write with data conversion.
@@ -206,13 +211,10 @@
int64_t mServiceLatencyNanos = 0;
- // Sometimes the hardware is operating with a different channel count from the app.
- // Then we require conversion in AAudio.
- int32_t mDeviceChannelCount = 0;
-
int32_t mBufferSizeInFrames = 0; // local threshold to control latency
+ int32_t mDeviceBufferSizeInFrames = 0;
int32_t mBufferCapacityInFrames = 0;
-
+ int32_t mDeviceBufferCapacityInFrames = 0;
};
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index f5cc2be..7d7b4ef 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -47,6 +47,27 @@
}
+aaudio_result_t AudioStreamInternalCapture::open(const AudioStreamBuilder &builder) {
+ aaudio_result_t result = AudioStreamInternal::open(builder);
+ if (result == AAUDIO_OK) {
+ result = mFlowGraph.configure(getDeviceFormat(),
+ getDeviceSamplesPerFrame(),
+ getDeviceSampleRate(),
+ getFormat(),
+ getSamplesPerFrame(),
+ getSampleRate(),
+ getRequireMonoBlend(),
+ false /* useVolumeRamps */,
+ getAudioBalance(),
+ aaudio::resampler::MultiChannelResampler::Quality::Medium);
+
+ if (result != AAUDIO_OK) {
+ safeReleaseClose();
+ }
+ }
+ return result;
+}
+
void AudioStreamInternalCapture::advanceClientToMatchServerPosition(int32_t serverMargin) {
int64_t readCounter = mAudioEndpoint->getDataReadCounter();
int64_t writeCounter = mAudioEndpoint->getDataWriteCounter() + serverMargin;
@@ -149,7 +170,8 @@
// Calculate frame position based off of the readCounter because
// the writeCounter might have just advanced in the background,
// causing us to sleep until a later burst.
- int64_t nextPosition = mAudioEndpoint->getDataReadCounter() + getFramesPerBurst();
+ const int64_t nextPosition = mAudioEndpoint->getDataReadCounter() +
+ getDeviceFramesPerBurst();
wakeTime = mClockModel.convertPositionToLatestTime(nextPosition);
}
break;
@@ -166,42 +188,73 @@
aaudio_result_t AudioStreamInternalCapture::readNowWithConversion(void *buffer,
int32_t numFrames) {
- // ALOGD("readNowWithConversion(%p, %d)",
- // buffer, numFrames);
WrappingBuffer wrappingBuffer;
- uint8_t *destination = (uint8_t *) buffer;
- int32_t framesLeft = numFrames;
+ uint8_t *byteBuffer = (uint8_t *) buffer;
+ int32_t framesLeftInByteBuffer = numFrames;
+
+ if (framesLeftInByteBuffer > 0) {
+ // Pull data from the flowgraph in case there is residual data.
+ const int32_t framesActuallyWrittenToByteBuffer = mFlowGraph.pull(
+ (void *)byteBuffer,
+ framesLeftInByteBuffer);
+
+ const int32_t numBytesActuallyWrittenToByteBuffer =
+ framesActuallyWrittenToByteBuffer * getBytesPerFrame();
+ byteBuffer += numBytesActuallyWrittenToByteBuffer;
+ framesLeftInByteBuffer -= framesActuallyWrittenToByteBuffer;
+ }
mAudioEndpoint->getFullFramesAvailable(&wrappingBuffer);
- // Read data in one or two parts.
- for (int partIndex = 0; framesLeft > 0 && partIndex < WrappingBuffer::SIZE; partIndex++) {
- int32_t framesToProcess = framesLeft;
- const int32_t framesAvailable = wrappingBuffer.numFrames[partIndex];
- if (framesAvailable <= 0) break;
+ // Write data in one or two parts.
+ int partIndex = 0;
+ int framesReadFromAudioEndpoint = 0;
+ while (framesLeftInByteBuffer > 0 && partIndex < WrappingBuffer::SIZE) {
+ const int32_t totalFramesInWrappingBuffer = wrappingBuffer.numFrames[partIndex];
+ int32_t framesAvailableInWrappingBuffer = totalFramesInWrappingBuffer;
+ uint8_t *currentWrappingBuffer = (uint8_t *) wrappingBuffer.data[partIndex];
- if (framesToProcess > framesAvailable) {
- framesToProcess = framesAvailable;
+ // Put data from the wrapping buffer into the flowgraph 8 frames at a time.
+ // Continuously pull as much data as possible from the flowgraph into the byte buffer.
+ // The return value of mFlowGraph.process is the number of frames actually pulled.
+ while (framesAvailableInWrappingBuffer > 0 && framesLeftInByteBuffer > 0) {
+ const int32_t framesToReadFromWrappingBuffer = std::min(flowgraph::kDefaultBufferSize,
+ framesAvailableInWrappingBuffer);
+
+ const int32_t numBytesToReadFromWrappingBuffer = getBytesPerDeviceFrame() *
+ framesToReadFromWrappingBuffer;
+
+ // If framesActuallyWrittenToByteBuffer < framesLeftInByteBuffer, it is guaranteed
+ // that all the data is pulled. If there is no more space in the byteBuffer, the
+ // remaining data will be pulled in the following readNowWithConversion().
+ const int32_t framesActuallyWrittenToByteBuffer = mFlowGraph.process(
+ (void *)currentWrappingBuffer,
+ framesToReadFromWrappingBuffer,
+ (void *)byteBuffer,
+ framesLeftInByteBuffer);
+
+ const int32_t numBytesActuallyWrittenToByteBuffer =
+ framesActuallyWrittenToByteBuffer * getBytesPerFrame();
+ byteBuffer += numBytesActuallyWrittenToByteBuffer;
+ framesLeftInByteBuffer -= framesActuallyWrittenToByteBuffer;
+ currentWrappingBuffer += numBytesToReadFromWrappingBuffer;
+ framesAvailableInWrappingBuffer -= framesToReadFromWrappingBuffer;
+
+ //ALOGD("%s() numBytesActuallyWrittenToByteBuffer %d, framesLeftInByteBuffer %d"
+ // "framesAvailableInWrappingBuffer %d, framesReadFromAudioEndpoint %d"
+ // , __func__, numBytesActuallyWrittenToByteBuffer, framesLeftInByteBuffer,
+ // framesAvailableInWrappingBuffer, framesReadFromAudioEndpoint);
}
-
- const int32_t numBytes = getBytesPerFrame() * framesToProcess;
- const int32_t numSamples = framesToProcess * getSamplesPerFrame();
-
- const audio_format_t sourceFormat = getDeviceFormat();
- const audio_format_t destinationFormat = getFormat();
-
- memcpy_by_audio_format(destination, destinationFormat,
- wrappingBuffer.data[partIndex], sourceFormat, numSamples);
-
- destination += numBytes;
- framesLeft -= framesToProcess;
+ framesReadFromAudioEndpoint += totalFramesInWrappingBuffer -
+ framesAvailableInWrappingBuffer;
+ partIndex++;
}
- int32_t framesProcessed = numFrames - framesLeft;
- mAudioEndpoint->advanceReadIndex(framesProcessed);
+ // The audio endpoint should reference the number of frames written to the wrapping buffer.
+ mAudioEndpoint->advanceReadIndex(framesReadFromAudioEndpoint);
- //ALOGD("readNowWithConversion() returns %d", framesProcessed);
- return framesProcessed;
+ // The internal code should use the number of frames read from the app.
+ return numFrames - framesLeftInByteBuffer;
}
int64_t AudioStreamInternalCapture::getFramesWritten() {
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.h b/media/libaaudio/src/client/AudioStreamInternalCapture.h
index 87017de..10e247d 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.h
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.h
@@ -32,6 +32,8 @@
bool inService = false);
virtual ~AudioStreamInternalCapture() = default;
+ aaudio_result_t open(const AudioStreamBuilder &builder) override;
+
aaudio_result_t read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) override;
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 89dd8ff..ac927ae 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -48,14 +48,18 @@
aaudio_result_t AudioStreamInternalPlay::open(const AudioStreamBuilder &builder) {
aaudio_result_t result = AudioStreamInternal::open(builder);
+ const bool useVolumeRamps = (getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE);
if (result == AAUDIO_OK) {
result = mFlowGraph.configure(getFormat(),
getSamplesPerFrame(),
+ getSampleRate(),
getDeviceFormat(),
- getDeviceChannelCount(),
+ getDeviceSamplesPerFrame(),
+ getDeviceSampleRate(),
getRequireMonoBlend(),
+ useVolumeRamps,
getAudioBalance(),
- (getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE));
+ aaudio::resampler::MultiChannelResampler::Quality::Medium);
if (result != AAUDIO_OK) {
safeReleaseClose();
@@ -186,7 +190,7 @@
// Sleep if there is too much data in the buffer.
// Calculate an ideal time to wake up.
if (wakeTimePtr != nullptr
- && (mAudioEndpoint->getFullFramesAvailable() >= getBufferSize())) {
+ && (mAudioEndpoint->getFullFramesAvailable() >= getDeviceBufferSize())) {
// By default wake up a few milliseconds from now. // TODO review
int64_t wakeTime = currentNanoTime + (1 * AAUDIO_NANOS_PER_MILLISECOND);
aaudio_stream_state_t state = getState();
@@ -206,12 +210,12 @@
// If the appBufferSize is smaller than the endpointBufferSize then
// we will have room to write data beyond the appBufferSize.
// That is a technique used to reduce glitches without adding latency.
- const int32_t appBufferSize = getBufferSize();
+ const int64_t appBufferSize = getDeviceBufferSize();
// The endpoint buffer size is set to the maximum that can be written.
// If we use it then we must carve out some room to write data when we wake up.
- const int32_t endBufferSize = mAudioEndpoint->getBufferSizeInFrames()
- - getFramesPerBurst();
- const int32_t bestBufferSize = std::min(appBufferSize, endBufferSize);
+ const int64_t endBufferSize = mAudioEndpoint->getBufferSizeInFrames()
+ - getDeviceFramesPerBurst();
+ const int64_t bestBufferSize = std::min(appBufferSize, endBufferSize);
int64_t targetReadPosition = mAudioEndpoint->getDataWriteCounter() - bestBufferSize;
wakeTime = mClockModel.convertPositionToTime(targetReadPosition);
}
@@ -232,37 +236,78 @@
int32_t numFrames) {
WrappingBuffer wrappingBuffer;
uint8_t *byteBuffer = (uint8_t *) buffer;
- int32_t framesLeft = numFrames;
+ int32_t framesLeftInByteBuffer = numFrames;
mAudioEndpoint->getEmptyFramesAvailable(&wrappingBuffer);
// Write data in one or two parts.
int partIndex = 0;
- while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
- int32_t framesToWrite = framesLeft;
- int32_t framesAvailable = wrappingBuffer.numFrames[partIndex];
- if (framesAvailable > 0) {
- if (framesToWrite > framesAvailable) {
- framesToWrite = framesAvailable;
- }
+ int framesWrittenToAudioEndpoint = 0;
+ while (framesLeftInByteBuffer > 0 && partIndex < WrappingBuffer::SIZE) {
+ int32_t framesAvailableInWrappingBuffer = wrappingBuffer.numFrames[partIndex];
+ uint8_t *currentWrappingBuffer = (uint8_t *) wrappingBuffer.data[partIndex];
- int32_t numBytes = getBytesPerFrame() * framesToWrite;
+ if (framesAvailableInWrappingBuffer > 0) {
+ // Pull data from the flowgraph in case there is residual data.
+ const int32_t framesActuallyWrittenToWrappingBuffer = mFlowGraph.pull(
+ (void*) currentWrappingBuffer,
+ framesAvailableInWrappingBuffer);
- mFlowGraph.process((void *)byteBuffer,
- wrappingBuffer.data[partIndex],
- framesToWrite);
+ const int32_t numBytesActuallyWrittenToWrappingBuffer =
+ framesActuallyWrittenToWrappingBuffer * getBytesPerDeviceFrame();
+ currentWrappingBuffer += numBytesActuallyWrittenToWrappingBuffer;
+ framesAvailableInWrappingBuffer -= framesActuallyWrittenToWrappingBuffer;
+ framesWrittenToAudioEndpoint += framesActuallyWrittenToWrappingBuffer;
+ }
- byteBuffer += numBytes;
- framesLeft -= framesToWrite;
- } else {
- break;
+ // Put data from byteBuffer into the flowgraph one buffer (8 frames) at a time.
+ // Continuously pull as much data as possible from the flowgraph into the wrapping buffer.
+ // The return value of mFlowGraph.process is the number of frames actually pulled.
+ while (framesAvailableInWrappingBuffer > 0 && framesLeftInByteBuffer > 0) {
+ const int32_t framesToWriteFromByteBuffer = std::min(flowgraph::kDefaultBufferSize,
+ framesLeftInByteBuffer);
+
+ const int32_t numBytesToWriteFromByteBuffer = getBytesPerFrame() *
+ framesToWriteFromByteBuffer;
+
+ //ALOGD("%s() framesLeftInByteBuffer %d, framesAvailableInWrappingBuffer %d"
+ // "framesToWriteFromByteBuffer %d, numBytesToWriteFromByteBuffer %d"
+ // , __func__, framesLeftInByteBuffer, framesAvailableInWrappingBuffer,
+ // framesToWriteFromByteBuffer, numBytesToWriteFromByteBuffer);
+
+ const int32_t framesActuallyWrittenToWrappingBuffer = mFlowGraph.process(
+ (void *)byteBuffer,
+ framesToWriteFromByteBuffer,
+ (void *)currentWrappingBuffer,
+ framesAvailableInWrappingBuffer);
+
+ byteBuffer += numBytesToWriteFromByteBuffer;
+ framesLeftInByteBuffer -= framesToWriteFromByteBuffer;
+ const int32_t numBytesActuallyWrittenToWrappingBuffer =
+ framesActuallyWrittenToWrappingBuffer * getBytesPerDeviceFrame();
+ currentWrappingBuffer += numBytesActuallyWrittenToWrappingBuffer;
+ framesAvailableInWrappingBuffer -= framesActuallyWrittenToWrappingBuffer;
+ framesWrittenToAudioEndpoint += framesActuallyWrittenToWrappingBuffer;
+
+ //ALOGD("%s() numBytesActuallyWrittenToWrappingBuffer %d, framesLeftInByteBuffer %d"
+ // "framesActuallyWrittenToWrappingBuffer %d, numBytesToWriteFromByteBuffer %d"
+ // "framesWrittenToAudioEndpoint %d"
+ // , __func__, numBytesActuallyWrittenToWrappingBuffer, framesLeftInByteBuffer,
+ // framesActuallyWrittenToWrappingBuffer, numBytesToWriteFromByteBuffer,
+ // framesWrittenToAudioEndpoint);
}
partIndex++;
}
- int32_t framesWritten = numFrames - framesLeft;
- mAudioEndpoint->advanceWriteIndex(framesWritten);
+ //ALOGD("%s() framesWrittenToAudioEndpoint %d, numFrames %d"
+ // "framesLeftInByteBuffer %d"
+ // , __func__, framesWrittenToAudioEndpoint, numFrames,
+ // framesLeftInByteBuffer);
- return framesWritten;
+ // The audio endpoint should reference the number of frames written to the wrapping buffer.
+ mAudioEndpoint->advanceWriteIndex(framesWrittenToAudioEndpoint);
+
+ // The internal code should use the number of frames read from the app.
+ return numFrames - framesLeftInByteBuffer;
}
int64_t AudioStreamInternalPlay::getFramesRead() {
@@ -284,7 +329,6 @@
return mLastFramesWritten;
}
-
// Render audio in the application callback and then write the data to the stream.
void *AudioStreamInternalPlay::callbackLoop() {
ALOGD("%s() entering >>>>>>>>>>>>>>>", __func__);
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.h b/media/libaaudio/src/client/AudioStreamInternalPlay.h
index e761807..b51b5d0 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.h
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.h
@@ -21,7 +21,6 @@
#include <aaudio/AAudio.h>
#include "binding/AAudioServiceInterface.h"
-#include "client/AAudioFlowGraph.h"
#include "client/AudioStreamInternal.h"
using android::sp;
@@ -89,13 +88,11 @@
* Asynchronous write with data conversion.
* @param buffer
* @param numFrames
- * @return fdrames written or negative error
+ * @return frames written or negative error
*/
aaudio_result_t writeNowWithConversion(const void *buffer,
int32_t numFrames);
- AAudioFlowGraph mFlowGraph;
-
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 8a13a6f..1e27a81 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -571,13 +571,15 @@
AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
- return audioStream->getFramesWritten();
+ return audioStream->getFramesWritten() * audioStream->getSampleRate() /
+ audioStream->getDeviceSampleRate();
}
AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
- return audioStream->getFramesRead();
+ return audioStream->getFramesRead() * audioStream->getSampleRate() /
+ audioStream->getDeviceSampleRate();
}
AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 56ef1e6..e0fd325 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -134,7 +134,8 @@
.set(AMEDIAMETRICS_PROP_ENCODINGHARDWARE,
android::toString(getHardwareFormat()).c_str())
.set(AMEDIAMETRICS_PROP_CHANNELCOUNTHARDWARE, (int32_t)getHardwareSamplesPerFrame())
- .set(AMEDIAMETRICS_PROP_SAMPLERATEHARDWARE, (int32_t)getHardwareSampleRate());
+ .set(AMEDIAMETRICS_PROP_SAMPLERATEHARDWARE, (int32_t)getHardwareSampleRate())
+ .set(AMEDIAMETRICS_PROP_SAMPLERATECLIENT, (int32_t)getSampleRate());
if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
item.set(AMEDIAMETRICS_PROP_PLAYERIID, mPlayerBase->getPlayerIId());
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 9b4b734..f2f5cac 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -204,10 +204,18 @@
return mBufferCapacity;
}
+ virtual int32_t getDeviceBufferCapacity() const {
+ return mDeviceBufferCapacity;
+ }
+
virtual int32_t getFramesPerBurst() const {
return mFramesPerBurst;
}
+ virtual int32_t getDeviceFramesPerBurst() const {
+ return mDeviceFramesPerBurst;
+ }
+
virtual int32_t getXRunCount() const {
return AAUDIO_ERROR_UNIMPLEMENTED;
}
@@ -224,6 +232,10 @@
return mSampleRate;
}
+ aaudio_result_t getDeviceSampleRate() const {
+ return mDeviceSampleRate;
+ }
+
aaudio_result_t getHardwareSampleRate() const {
return mHardwareSampleRate;
}
@@ -240,6 +252,10 @@
return mSamplesPerFrame;
}
+ aaudio_result_t getDeviceSamplesPerFrame() const {
+ return mDeviceSamplesPerFrame;
+ }
+
aaudio_result_t getHardwareSamplesPerFrame() const {
return mHardwareSamplesPerFrame;
}
@@ -322,10 +338,10 @@
}
/**
- * This is only valid after setChannelMask() and setDeviceFormat() have been called.
+ * This is only valid after setDeviceSamplesPerFrame() and setDeviceFormat() have been called.
*/
int32_t getBytesPerDeviceFrame() const {
- return getSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
+ return getDeviceSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
}
virtual int64_t getFramesWritten() = 0;
@@ -365,6 +381,11 @@
mSamplesPerFrame = AAudioConvert_channelMaskToCount(channelMask);
}
+ void setDeviceSamplesPerFrame(int32_t deviceSamplesPerFrame) {
+ mDeviceSamplesPerFrame = deviceSamplesPerFrame;
+ }
+
+
/**
* @return true if data callback has been specified
*/
@@ -542,6 +563,11 @@
}
// This should not be called after the open() call.
+ void setDeviceSampleRate(int32_t deviceSampleRate) {
+ mDeviceSampleRate = deviceSampleRate;
+ }
+
+ // This should not be called after the open() call.
void setHardwareSampleRate(int32_t hardwareSampleRate) {
mHardwareSampleRate = hardwareSampleRate;
}
@@ -552,11 +578,21 @@
}
// This should not be called after the open() call.
+ void setDeviceFramesPerBurst(int32_t deviceFramesPerBurst) {
+ mDeviceFramesPerBurst = deviceFramesPerBurst;
+ }
+
+ // This should not be called after the open() call.
void setBufferCapacity(int32_t bufferCapacity) {
mBufferCapacity = bufferCapacity;
}
// This should not be called after the open() call.
+ void setDeviceBufferCapacity(int32_t deviceBufferCapacity) {
+ mDeviceBufferCapacity = deviceBufferCapacity;
+ }
+
+ // This should not be called after the open() call.
void setSharingMode(aaudio_sharing_mode_t sharingMode) {
mSharingMode = sharingMode;
}
@@ -721,9 +757,11 @@
// These do not change after open().
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
+ int32_t mDeviceSamplesPerFrame = AAUDIO_UNSPECIFIED;
int32_t mHardwareSamplesPerFrame = AAUDIO_UNSPECIFIED;
aaudio_channel_mask_t mChannelMask = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
+ int32_t mDeviceSampleRate = AAUDIO_UNSPECIFIED;
int32_t mHardwareSampleRate = AAUDIO_UNSPECIFIED;
int32_t mDeviceId = AAUDIO_UNSPECIFIED;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
@@ -732,7 +770,9 @@
audio_format_t mHardwareFormat = AUDIO_FORMAT_DEFAULT;
aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
int32_t mFramesPerBurst = 0;
+ int32_t mDeviceFramesPerBurst = 0;
int32_t mBufferCapacity = 0;
+ int32_t mDeviceBufferCapacity = 0;
aaudio_usage_t mUsage = AAUDIO_UNSPECIFIED;
aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED;
diff --git a/media/libaaudio/src/core/VersionExperiment.txt b/media/libaaudio/src/core/VersionExperiment.txt
deleted file mode 100644
index 071239b..0000000
--- a/media/libaaudio/src/core/VersionExperiment.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-
-// TODO Experiment with versioning. This may be removed or changed dramatically.
-// Please ignore for now. Do not review.
-#define OBOE_VERSION_EXPERIMENT 0
-#if OBOE_VERSION_EXPERIMENT
-
-#define OBOE_EARLIEST_SUPPORTED_VERSION 1
-#define OBOE_CURRENT_VERSION 2
-
-typedef struct OboeInterface_s {
- int32_t size; // do not use size_t because its size can vary
- int32_t version;
- int32_t reserved1;
- void * reserved2;
- oboe_result_t (*createStreamBuilder)(OboeStreamBuilder *);
-} OboeInterface_t;
-
-OboeInterface_t s_oboe_template = {
- .size = sizeof(OboeInterface_t),
- .version = OBOE_CURRENT_VERSION,
- .reserved1 = 0,
- .reserved2 = NULL,
- .createStreamBuilder = Oboe_createStreamBuilder
-};
-
-oboe_result_t Oboe_Unimplemented(OboeInterface_t *oboe) {
- (void) oboe;
- return OBOE_ERROR_UNIMPLEMENTED;
-}
-
-typedef oboe_result_t (*OboeFunction_t)(OboeInterface_t *oboe);
-
-int32_t Oboe_Initialize(OboeInterface_t *oboe, uint32_t flags) {
- if (oboe->version < OBOE_EARLIEST_SUPPORTED_VERSION) {
- return OBOE_ERROR_INCOMPATIBLE;
- }
- // Fill in callers vector table.
- uint8_t *start = (uint8_t*)&oboe->reserved1;
- uint8_t *end;
- if (oboe->size <= s_oboe_template.size) {
- end = ((uint8_t *)oboe) + oboe->size;
- } else {
- end = ((uint8_t *)oboe) + s_oboe_template.size;
- // Assume the rest of the structure is vectors.
- // Point them all to OboeInternal_Unimplemented()
- // Point to first vector past end of the known structure.
- OboeFunction_t *next = (OboeFunction_t*)end;
- while ((((uint8_t *)next) - ((uint8_t *)oboe)) < oboe->size) {
- *next++ = Oboe_Unimplemented;
- }
- }
- memcpy(&oboe->reserved1, &s_oboe_template.reserved1, end - start);
- return OBOE_OK;
-}
-#endif /* OBOE_VERSION_EXPERIMENT -------------------------- */
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index ad6d041..e79bf96 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -21,7 +21,8 @@
#include <stdint.h>
#include "FifoControllerBase.h"
-using namespace android; // TODO just import names needed
+using android::FifoControllerBase;
+using android::fifo_frames_t;
FifoControllerBase::FifoControllerBase(fifo_frames_t capacity, fifo_frames_t threshold)
: mCapacity(capacity)
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
index a3ce58c..611ddcd 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
@@ -135,10 +135,9 @@
int coefficientIndex = 0;
double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples
// Stretch the sinc function for low pass filtering.
- const float cutoffScaler = normalizedCutoff *
- ((outputRate < inputRate)
- ? ((float)outputRate / inputRate)
- : ((float)inputRate / outputRate));
+ const float cutoffScaler = (outputRate < inputRate)
+ ? (normalizedCutoff * (float)outputRate / inputRate)
+ : 1.0f; // Do not filter when upsampling.
const int numTapsHalf = getNumTaps() / 2; // numTaps must be even.
const float numTapsHalfInverse = 1.0f / numTapsHalf;
for (int i = 0; i < numRows; i++) {
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
index 717f3fd..9e47335 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
@@ -111,6 +111,9 @@
* Set lower to reduce aliasing.
* Default is 0.70.
*
+ * Note that this value is ignored when upsampling, which is when
+ * the outputRate is higher than the inputRate.
+ *
* @param normalizedCutoff anti-aliasing filter cutoff
* @return address of this builder for chaining calls
*/
@@ -227,6 +230,10 @@
/**
* Generate the filter coefficients in optimal order.
+ *
+ * Note that normalizedCutoff is ignored when upsampling, which is when
+ * the outputRate is higher than the inputRate.
+ *
* @param inputRate sample rate of the input stream
* @param outputRate sample rate of the output stream
* @param numRows number of rows in the array that contain a set of tap coefficients
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index e760dab..fe4bf2c 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -208,6 +208,12 @@
setBufferCapacity(getBufferCapacityFromDevice());
setFramesPerBurst(getFramesPerBurstFromDevice());
+ // Use the same values for device values.
+ setDeviceSamplesPerFrame(getSamplesPerFrame());
+ setDeviceSampleRate(mAudioRecord->getSampleRate());
+ setDeviceBufferCapacity(getBufferCapacityFromDevice());
+ setDeviceFramesPerBurst(getFramesPerBurstFromDevice());
+
setHardwareSamplesPerFrame(mAudioRecord->getHalChannelCount());
setHardwareSampleRate(mAudioRecord->getHalSampleRate());
setHardwareFormat(mAudioRecord->getHalFormat());
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 67ee42e..59fdabc 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -203,6 +203,12 @@
setBufferCapacity(getBufferCapacityFromDevice());
setFramesPerBurst(getFramesPerBurstFromDevice());
+ // Use the same values for device values.
+ setDeviceSamplesPerFrame(getSamplesPerFrame());
+ setDeviceSampleRate(mAudioTrack->getSampleRate());
+ setDeviceBufferCapacity(getBufferCapacityFromDevice());
+ setDeviceFramesPerBurst(getFramesPerBurstFromDevice());
+
setHardwareSamplesPerFrame(mAudioTrack->getHalChannelCount());
setHardwareSampleRate(mAudioTrack->getHalSampleRate());
setHardwareFormat(mAudioTrack->getHalFormat());
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index e8324a8..0cbf79d 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -383,11 +383,10 @@
return AUDIO_CHANNEL_OUT_7POINT1POINT2;
case AAUDIO_CHANNEL_7POINT1POINT4:
return AUDIO_CHANNEL_OUT_7POINT1POINT4;
- // TODO: add 9point1point4 and 9point1point6 when they are added in audio-hal-enums.h
- // case AAUDIO_CHANNEL_9POINT1POINT4:
- // return AUDIO_CHANNEL_OUT_9POINT1POINT4;
- // case AAUDIO_CHANNEL_9POINT1POINT6:
- // return AUDIO_CHANNEL_OUT_9POINT1POINT6;
+ case AAUDIO_CHANNEL_9POINT1POINT4:
+ return AUDIO_CHANNEL_OUT_9POINT1POINT4;
+ case AAUDIO_CHANNEL_9POINT1POINT6:
+ return AUDIO_CHANNEL_OUT_9POINT1POINT6;
default:
ALOGE("%s() %#x unrecognized", __func__, channelMask);
return AUDIO_CHANNEL_INVALID;
@@ -465,11 +464,10 @@
return AAUDIO_CHANNEL_7POINT1POINT2;
case AUDIO_CHANNEL_OUT_7POINT1POINT4:
return AAUDIO_CHANNEL_7POINT1POINT4;
- // TODO: add 9point1point4 and 9point1point6 when they are added in audio-hal-enums.h
- // case AUDIO_CHANNEL_OUT_9POINT1POINT4:
- // return AAUDIO_CHANNEL_9POINT1POINT4;
- // case AUDIO_CHANNEL_OUT_9POINT1POINT6:
- // return AAUDIO_CHANNEL_9POINT1POINT6;
+ case AUDIO_CHANNEL_OUT_9POINT1POINT4:
+ return AAUDIO_CHANNEL_9POINT1POINT4;
+ case AUDIO_CHANNEL_OUT_9POINT1POINT6:
+ return AAUDIO_CHANNEL_9POINT1POINT6;
default:
ALOGE("%s() %#x unrecognized", __func__, channelMask);
return AAUDIO_CHANNEL_INVALID;
diff --git a/media/libaaudio/src/utility/AudioClock.h b/media/libaaudio/src/utility/AudioClock.h
index d5d4ef4..37f5b39 100644
--- a/media/libaaudio/src/utility/AudioClock.h
+++ b/media/libaaudio/src/utility/AudioClock.h
@@ -33,7 +33,7 @@
public:
static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) {
struct timespec time;
- int result = clock_gettime(clockId, &time);
+ const int result = clock_gettime(clockId, &time);
if (result < 0) {
return -errno;
}
@@ -56,7 +56,7 @@
time.tv_sec = nanoTime / AAUDIO_NANOS_PER_SECOND;
// Calculate the fractional nanoseconds. Avoids expensive % operation.
time.tv_nsec = nanoTime - (time.tv_sec * AAUDIO_NANOS_PER_SECOND);
- int err = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
+ const int err = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
switch (err) {
case EINTR:
return 1;
@@ -86,7 +86,7 @@
// Calculate the fractional nanoseconds. Avoids expensive % operation.
time.tv_nsec = nanoseconds - (time.tv_sec * AAUDIO_NANOS_PER_SECOND);
const int flags = 0; // documented as relative sleep
- int err = clock_nanosleep(clockId, flags, &time, nullptr);
+ const int err = clock_nanosleep(clockId, flags, &time, nullptr);
switch (err) {
case EINTR:
return 1;
diff --git a/media/libaaudio/src/utility/MonotonicCounter.h b/media/libaaudio/src/utility/MonotonicCounter.h
index 51eb69b..b58634f 100644
--- a/media/libaaudio/src/utility/MonotonicCounter.h
+++ b/media/libaaudio/src/utility/MonotonicCounter.h
@@ -104,7 +104,7 @@
*/
void roundUp64(int32_t period) {
if (period > 0) {
- int64_t numPeriods = (mCounter64 + period - 1) / period;
+ const int64_t numPeriods = (mCounter64 + period - 1) / period;
mCounter64 = numPeriods * period;
}
}
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 24041bc..0cfdfb2 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -145,6 +145,7 @@
srcs: ["test_flowgraph.cpp"],
shared_libs: [
"libaaudio_internal",
+ "libaudioutils",
"libbinder",
"libcutils",
"libutils",
diff --git a/media/libaaudio/tests/test_flowgraph.cpp b/media/libaaudio/tests/test_flowgraph.cpp
index 6f75f5a..7eb8b0d 100644
--- a/media/libaaudio/tests/test_flowgraph.cpp
+++ b/media/libaaudio/tests/test_flowgraph.cpp
@@ -25,6 +25,8 @@
#include <gtest/gtest.h>
+#include <aaudio/AAudio.h>
+#include "client/AAudioFlowGraph.h"
#include "flowgraph/ClipToRange.h"
#include "flowgraph/Limiter.h"
#include "flowgraph/MonoBlend.h"
@@ -37,8 +39,18 @@
#include "flowgraph/SinkI32.h"
#include "flowgraph/SourceI16.h"
#include "flowgraph/SourceI24.h"
+#include "flowgraph/resampler/IntegerRatio.h"
using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
+
+using TestFlowgraphResamplerParams = std::tuple<int32_t, int32_t, MultiChannelResampler::Quality>;
+
+enum {
+ PARAM_SOURCE_SAMPLE_RATE = 0,
+ PARAM_SINK_SAMPLE_RATE,
+ PARAM_RESAMPLER_QUALITY
+};
constexpr int kBytesPerI24Packed = 3;
@@ -394,3 +406,240 @@
EXPECT_NEAR(expected[i], output[i], tolerance);
}
}
+
+TEST(test_flowgraph, module_sinki16_multiple_reads) {
+ static constexpr int kNumSamples = 8;
+ std::array<int16_t, kNumSamples + 10> output; // larger than input
+
+ SourceFloat sourceFloat{1};
+ SinkI16 sinkI16{1};
+
+ sourceFloat.setData(kInputFloat.data(), kNumSamples);
+ sourceFloat.output.connect(&sinkI16.input);
+
+ output.fill(777);
+
+ // Read the first half of the data
+ int32_t numRead = sinkI16.read(output.data(), kNumSamples / 2);
+ ASSERT_EQ(kNumSamples / 2, numRead);
+ for (int i = 0; i < numRead; i++) {
+ EXPECT_EQ(kExpectedI16.at(i), output.at(i)) << ", i = " << i;
+ }
+
+ // Read the rest of the data
+ numRead = sinkI16.read(output.data(), output.size());
+ ASSERT_EQ(kNumSamples / 2, numRead);
+ for (int i = 0; i < numRead; i++) {
+ EXPECT_EQ(kExpectedI16.at(i + kNumSamples / 2), output.at(i)) << ", i = " << i;
+ }
+}
+
+void checkSampleRateConversionVariedSizes(int32_t sourceSampleRate,
+ int32_t sinkSampleRate,
+ MultiChannelResampler::Quality resamplerQuality) {
+ AAudioFlowGraph flowgraph;
+ aaudio_result_t result = flowgraph.configure(AUDIO_FORMAT_PCM_FLOAT /* sourceFormat */,
+ 1 /* sourceChannelCount */,
+ sourceSampleRate,
+ AUDIO_FORMAT_PCM_FLOAT /* sinkFormat */,
+ 1 /* sinkChannelCount */,
+ sinkSampleRate,
+ false /* useMonoBlend */,
+ false /* useVolumeRamps */,
+ 0.0f /* audioBalance */,
+ resamplerQuality);
+
+ IntegerRatio ratio(sourceSampleRate, sinkSampleRate);
+ ratio.reduce();
+
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ const int inputSize = ratio.getNumerator();
+ const int outputSize = ratio.getDenominator();
+ float input[inputSize];
+ float output[outputSize];
+
+ for (int i = 0; i < inputSize; i++) {
+ input[i] = i * 1.0f / inputSize;
+ }
+
+ int inputUsed = 0;
+ int outputRead = 0;
+ int curInputSize = 1;
+
+ // Process the data with larger and larger input buffer sizes.
+ while (inputUsed < inputSize) {
+ outputRead += flowgraph.process((void *) (input + inputUsed),
+ curInputSize,
+ (void *) (output + outputRead),
+ outputSize - outputRead);
+ inputUsed += curInputSize;
+ curInputSize = std::min(curInputSize + 5, inputSize - inputUsed);
+ }
+
+ ASSERT_EQ(outputSize, outputRead);
+
+ for (int i = 1; i < outputSize; i++) {
+ // The first values of the flowgraph will be close to zero.
+ // Besides those, the values should be strictly increasing.
+ if (output[i - 1] > 0.01f) {
+ EXPECT_GT(output[i], output[i - 1]);
+ }
+ }
+}
+
+TEST(test_flowgraph, flowgraph_varied_sizes_all) {
+ const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000, 64000, 88200, 96000};
+ const MultiChannelResampler::Quality qualities[] =
+ {
+ MultiChannelResampler::Quality::Fastest,
+ MultiChannelResampler::Quality::Low,
+ MultiChannelResampler::Quality::Medium,
+ MultiChannelResampler::Quality::High,
+ MultiChannelResampler::Quality::Best
+ };
+ for (int srcRate : rates) {
+ for (int destRate : rates) {
+ for (auto quality : qualities) {
+ if (srcRate != destRate) {
+ checkSampleRateConversionVariedSizes(srcRate, destRate, quality);
+ }
+ }
+ }
+ }
+}
+
+void checkSampleRateConversionPullLater(int32_t sourceSampleRate,
+ int32_t sinkSampleRate,
+ MultiChannelResampler::Quality resamplerQuality) {
+ AAudioFlowGraph flowgraph;
+ aaudio_result_t result = flowgraph.configure(AUDIO_FORMAT_PCM_FLOAT /* sourceFormat */,
+ 1 /* sourceChannelCount */,
+ sourceSampleRate,
+ AUDIO_FORMAT_PCM_FLOAT /* sinkFormat */,
+ 1 /* sinkChannelCount */,
+ sinkSampleRate,
+ false /* useMonoBlend */,
+ false /* useVolumeRamps */,
+ 0.0f /* audioBalance */,
+ resamplerQuality);
+
+ IntegerRatio ratio(sourceSampleRate, sinkSampleRate);
+ ratio.reduce();
+
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ const int inputSize = ratio.getNumerator();
+ const int outputSize = ratio.getDenominator();
+ float input[inputSize];
+ float output[outputSize];
+
+ for (int i = 0; i < inputSize; i++) {
+ input[i] = i * 1.0f / inputSize;
+ }
+
+ // Read half the data with process.
+ int outputRead = flowgraph.process((void *) input,
+ inputSize,
+ (void *) output,
+ outputSize / 2);
+
+ ASSERT_EQ(outputSize / 2, outputRead);
+
+ // Now read the other half of the data with pull.
+ outputRead += flowgraph.pull(
+ (void *) (output + outputRead),
+ outputSize - outputRead);
+
+ ASSERT_EQ(outputSize, outputRead);
+ for (int i = 1; i < outputSize; i++) {
+ // The first values of the flowgraph will be close to zero.
+ // Besides those, the values should be strictly increasing.
+ if (output[i - 1] > 0.01f) {
+ EXPECT_GT(output[i], output[i - 1]);
+ }
+ }
+}
+
+// TODO: b/289508408 - Remove non-parameterized tests if they get noisy.
+TEST(test_flowgraph, flowgraph_pull_later_all) {
+ const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000, 64000, 88200, 96000};
+ const MultiChannelResampler::Quality qualities[] =
+ {
+ MultiChannelResampler::Quality::Fastest,
+ MultiChannelResampler::Quality::Low,
+ MultiChannelResampler::Quality::Medium,
+ MultiChannelResampler::Quality::High,
+ MultiChannelResampler::Quality::Best
+ };
+ for (int srcRate : rates) {
+ for (int destRate : rates) {
+ for (auto quality : qualities) {
+ if (srcRate != destRate) {
+ checkSampleRateConversionPullLater(srcRate, destRate, quality);
+ }
+ }
+ }
+ }
+}
+
+class TestFlowgraphSampleRateConversion : public ::testing::Test,
+ public ::testing::WithParamInterface<TestFlowgraphResamplerParams> {
+};
+
+const char* resamplerQualityToString(MultiChannelResampler::Quality quality) {
+ switch (quality) {
+ case MultiChannelResampler::Quality::Fastest: return "FASTEST";
+ case MultiChannelResampler::Quality::Low: return "LOW";
+ case MultiChannelResampler::Quality::Medium: return "MEDIUM";
+ case MultiChannelResampler::Quality::High: return "HIGH";
+ case MultiChannelResampler::Quality::Best: return "BEST";
+ }
+ return "UNKNOWN";
+}
+
+static std::string getTestName(
+ const ::testing::TestParamInfo<TestFlowgraphResamplerParams>& info) {
+ return std::string()
+ + std::to_string(std::get<PARAM_SOURCE_SAMPLE_RATE>(info.param))
+ + "__" + std::to_string(std::get<PARAM_SINK_SAMPLE_RATE>(info.param))
+ + "__" + resamplerQualityToString(std::get<PARAM_RESAMPLER_QUALITY>(info.param));
+}
+
+TEST_P(TestFlowgraphSampleRateConversion, test_flowgraph_pull_later) {
+ checkSampleRateConversionPullLater(std::get<PARAM_SOURCE_SAMPLE_RATE>(GetParam()),
+ std::get<PARAM_SINK_SAMPLE_RATE>(GetParam()),
+ std::get<PARAM_RESAMPLER_QUALITY>(GetParam()));
+}
+
+TEST_P(TestFlowgraphSampleRateConversion, test_flowgraph_varied_sizes) {
+ checkSampleRateConversionVariedSizes(std::get<PARAM_SOURCE_SAMPLE_RATE>(GetParam()),
+ std::get<PARAM_SINK_SAMPLE_RATE>(GetParam()),
+ std::get<PARAM_RESAMPLER_QUALITY>(GetParam()));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ test_flowgraph,
+ TestFlowgraphSampleRateConversion,
+ ::testing::Values(
+ TestFlowgraphResamplerParams({8000, 11025, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({8000, 48000, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({8000, 44100, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({11025, 24000, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({11025, 48000,
+ MultiChannelResampler::Quality::Fastest}),
+ TestFlowgraphResamplerParams({11025, 48000, MultiChannelResampler::Quality::Low}),
+ TestFlowgraphResamplerParams({11025, 48000,
+ MultiChannelResampler::Quality::Medium}),
+ TestFlowgraphResamplerParams({11025, 48000, MultiChannelResampler::Quality::High}),
+ TestFlowgraphResamplerParams({11025, 48000, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({11025, 44100, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({11025, 88200, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({16000, 48000, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({44100, 48000, MultiChannelResampler::Quality::Low}),
+ TestFlowgraphResamplerParams({44100, 48000, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({48000, 11025, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({48000, 44100, MultiChannelResampler::Quality::Best}),
+ TestFlowgraphResamplerParams({44100, 11025, MultiChannelResampler::Quality::Best})),
+ &getTestName
+);
diff --git a/media/libaaudio/tests/test_resampler.cpp b/media/libaaudio/tests/test_resampler.cpp
index 1e4f59c..13e4a20 100644
--- a/media/libaaudio/tests/test_resampler.cpp
+++ b/media/libaaudio/tests/test_resampler.cpp
@@ -101,14 +101,20 @@
}
}
+ // Flush out remaining frames from the flowgraph
+ while (!mcResampler->isWriteNeeded()) {
+ mcResampler->readNextFrame(output);
+ output++;
+ numRead++;
+ }
+
ASSERT_LE(numRead, kNumOutputSamples);
// Some frames are lost priming the FIR filter.
- const int kMaxAlgorithmicFrameLoss = 16;
+ const int kMaxAlgorithmicFrameLoss = 5;
EXPECT_GT(numRead, kNumOutputSamples - kMaxAlgorithmicFrameLoss);
int sinkZeroCrossingCount = countZeroCrossingsWithHysteresis(outputBuffer.get(), numRead);
- // Some cycles may get chopped off at the end.
- const int kMaxZeroCrossingDelta = 3;
+ const int kMaxZeroCrossingDelta = std::max(sinkRate / sourceRate / 2, 1);
EXPECT_LE(abs(sourceZeroCrossingCount - sinkZeroCrossingCount), kMaxZeroCrossingDelta);
// Detect glitches by looking for spikes in the second derivative.
@@ -136,8 +142,7 @@
TEST(test_resampler, resampler_scan_all) {
- // TODO Add 64000, 88200, 96000 when they work. Failing now.
- const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000};
+ const int rates[] = {8000, 11025, 22050, 32000, 44100, 48000, 64000, 88200, 96000};
const MultiChannelResampler::Quality qualities[] =
{
MultiChannelResampler::Quality::Fastest,
@@ -193,10 +198,9 @@
checkResampler(11025, 44100, MultiChannelResampler::Quality::Best);
}
-// TODO This fails because the output is very low.
-//TEST(test_resampler, resampler_11025_88200_best) {
-// checkResampler(11025, 88200, MultiChannelResampler::Quality::Best);
-//}
+TEST(test_resampler, resampler_11025_88200_best) {
+ checkResampler(11025, 88200, MultiChannelResampler::Quality::Best);
+}
TEST(test_resampler, resampler_16000_48000_best) {
checkResampler(16000, 48000, MultiChannelResampler::Quality::Best);
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 7cec2e8..871318f 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -132,12 +132,10 @@
binder = gAudioFlingerBinder;
} else {
sp<IServiceManager> sm = defaultServiceManager();
- do {
- binder = sm->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
- if (binder != nullptr) break;
- ALOGW("AudioFlinger not published, waiting...");
- usleep(500000); // 0.5 s
- } while (true);
+ binder = sm->waitForService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+ if (binder == nullptr) {
+ return nullptr;
+ }
}
binder->linkToDeath(gAudioFlingerClient);
const auto afs = interface_cast<media::IAudioFlingerService>(binder);
@@ -870,14 +868,10 @@
Mutex::Autolock _l(gLockAPS);
if (gAudioPolicyService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder;
- do {
- binder = sm->getService(String16("media.audio_policy"));
- if (binder != 0)
- break;
- ALOGW("AudioPolicyService not published, waiting...");
- usleep(500000); // 0.5 s
- } while (true);
+ sp<IBinder> binder = sm->waitForService(String16("media.audio_policy"));
+ if (binder == nullptr) {
+ return nullptr;
+ }
if (gAudioPolicyServiceClient == NULL) {
gAudioPolicyServiceClient = new AudioPolicyServiceClient();
}
@@ -2093,8 +2087,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>
- & aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<AudioFormatDescription> formatsAidl;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 7caaaaf..4bd12b8 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -646,7 +646,7 @@
return result.value_or(0);
}
-uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() {
+uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() const {
auto result = [&]() -> ConversionResult<uint32_t> {
int32_t aidlRet;
RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -657,7 +657,7 @@
return result.value_or(0);
}
-size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() {
+size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() const {
auto result = [&]() -> ConversionResult<size_t> {
int64_t aidlRet;
RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -672,7 +672,7 @@
return statusTFromBinderStatus(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
}
-status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
+status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) const {
media::AudioPortFw portAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_v7_AudioPortFw(*port));
media::AudioPortFw aidlRet;
@@ -705,7 +705,7 @@
}
status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
- struct audio_patch* patches) {
+ struct audio_patch* patches) const {
std::vector<media::AudioPatchFw> aidlRet;
int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -753,7 +753,8 @@
}
status_t
-AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
+AudioFlingerClientAdapter::getMicrophones(
+ std::vector<media::MicrophoneInfoFw>* microphones) const {
std::vector<media::MicrophoneInfoFw> aidlRet;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mDelegate->getMicrophones(&aidlRet)));
if (microphones != nullptr) {
@@ -788,7 +789,7 @@
return statusTFromBinderStatus(mDelegate->getMmapPolicyInfos(policyType, policyInfos));
}
-int32_t AudioFlingerClientAdapter::getAAudioMixerBurstCount() {
+int32_t AudioFlingerClientAdapter::getAAudioMixerBurstCount() const {
auto result = [&]() -> ConversionResult<int32_t> {
int32_t aidlRet;
RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->getAAudioMixerBurstCount(&aidlRet)));
@@ -798,7 +799,7 @@
return result.value_or(0);
}
-int32_t AudioFlingerClientAdapter::getAAudioHardwareBurstMinUsec() {
+int32_t AudioFlingerClientAdapter::getAAudioHardwareBurstMinUsec() const {
auto result = [&]() -> ConversionResult<int32_t> {
int32_t aidlRet;
RETURN_IF_ERROR(statusTFromBinderStatus(
@@ -829,7 +830,7 @@
}
status_t AudioFlingerClientAdapter::getSupportedLatencyModes(
- audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) {
+ audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) const {
if (modes == nullptr) {
return BAD_VALUE;
}
@@ -851,7 +852,7 @@
return statusTFromBinderStatus(mDelegate->setBluetoothVariableLatencyEnabled(enabled));
}
-status_t AudioFlingerClientAdapter::isBluetoothVariableLatencyEnabled(bool* enabled) {
+status_t AudioFlingerClientAdapter::isBluetoothVariableLatencyEnabled(bool* enabled) const {
if (enabled == nullptr) {
return BAD_VALUE;
}
@@ -862,7 +863,7 @@
return NO_ERROR;
}
-status_t AudioFlingerClientAdapter::supportsBluetoothVariableLatency(bool* support) {
+status_t AudioFlingerClientAdapter::supportsBluetoothVariableLatency(bool* support) const {
if (support == nullptr) {
return BAD_VALUE;
}
@@ -875,7 +876,7 @@
status_t AudioFlingerClientAdapter::getSoundDoseInterface(
const sp<media::ISoundDoseCallback> &callback,
- sp<media::ISoundDose>* soundDose) {
+ sp<media::ISoundDose>* soundDose) const {
return statusTFromBinderStatus(mDelegate->getSoundDoseInterface(callback, soundDose));
}
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
new file mode 100644
index 0000000..67258d9
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_defaults {
+ name: "libaudioclient_aidl_fuzzer_defaults",
+ static_libs: [
+ "android.hardware.audio.common@7.0-enums",
+ "effect-aidl-cpp",
+ "liblog",
+ "libcgrouprc",
+ "libcgrouprc_format",
+ "libjsoncpp",
+ "libmediametricsservice",
+ "libmedia_helper",
+ "libprocessgroup",
+ "shared-file-region-aidl-cpp",
+ "libfakeservicemanager"
+ ],
+ shared_libs: [
+ "libaudioclient",
+ "libaudioflinger",
+ "libmediautils",
+ "libnblog",
+ "libaudioprocessing",
+ "libnbaio",
+ "libpowermanager",
+ "libvibrator",
+ "packagemanager_aidl-cpp",
+ "android.hardware.audio.common-util",
+ "audioclient-types-aidl-cpp",
+ "audioflinger-aidl-cpp",
+ "audiopolicy-aidl-cpp",
+ "audiopolicy-types-aidl-cpp",
+ "av-types-aidl-cpp",
+ "capture_state_listener-aidl-cpp",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
+ "libaudiomanager",
+ "libaudiopolicy",
+ "libaudioutils",
+ "libdl",
+ "libxml2",
+ "mediametricsservice-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ "libvndksupport",
+ "libmediametrics",
+ "libfakeservicemanager",
+ "libactivitymanager_aidl",
+ "libheadtracking",
+ "libaudiopolicyservice",
+ "libsensorprivacy",
+ "libaudiopolicymanagerdefault",
+ "libaudiohal",
+ "libhidlbase",
+ "libpermission",
+ "libaudiohal@7.0",
+ ],
+ header_libs: [
+ "libaudiopolicymanager_interface_headers",
+ "libbinder_headers",
+ "libaudiofoundation_headers",
+ "libmedia_headers",
+ "libaudiohal_headers",
+ "libaudioflinger_headers",
+ "mediautils_headers",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ hotlists: ["4593311"],
+ description: "The fuzzer targets the APIs of libaudioflinger",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
+}
+
+cc_fuzz {
+ name: "audioflinger_aidl_fuzzer",
+ srcs: ["audioflinger_aidl_fuzzer.cpp"],
+ defaults: [
+ "libaudioclient_aidl_fuzzer_defaults",
+ "service_fuzzer_defaults"
+ ],
+}
diff --git a/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
new file mode 100644
index 0000000..fac5f53
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <AudioFlinger.h>
+#include <ISchedulingPolicyService.h>
+#include <fakeservicemanager/FakeServiceManager.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_process.h>
+#include <android/media/IAudioPolicyService.h>
+#include <binder/IActivityManager.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <binder/PermissionController.h>
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/IAudioFlinger.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
+#include <service/AudioPolicyService.h>
+
+using namespace android;
+using namespace android::binder;
+using android::fuzzService;
+
+static sp<media::IAudioFlingerService> gAudioFlingerService;
+
+class FuzzerSchedulingPolicyService : public BnInterface<ISchedulingPolicyService> {
+ int32_t requestPriority(int32_t /*pid_t*/, int32_t /*tid*/, int32_t /*prio*/, bool /*isForApp*/,
+ bool /*asynchronous*/) {
+ return 0;
+ }
+
+ int32_t requestCpusetBoost(bool /*enable*/, const sp<IBinder>& /*client*/) { return 0; }
+};
+
+class FuzzerPermissionController : public BnInterface<IPermissionController> {
+ public:
+ bool checkPermission(const String16& /*permission*/, int32_t /*pid*/, int32_t /*uid*/) {
+ return true;
+ }
+ int32_t noteOp(const String16& /*op*/, int32_t /*uid*/, const String16& /*packageName*/) {
+ return 0;
+ }
+ void getPackagesForUid(const uid_t /*uid*/, Vector<String16>& /*packages*/) {}
+ bool isRuntimePermission(const String16& /*permission*/) { return true; }
+ int32_t getPackageUid(const String16& /*package*/, int /*flags*/) { return 0; }
+};
+
+class FuzzerSensorPrivacyManager : public BnInterface<hardware::ISensorPrivacyManager> {
+ public:
+ Status supportsSensorToggle(int32_t /*toggleType*/, int32_t /*sensor*/,
+ bool* /*_aidl_return*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status addSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+ return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+ }
+ Status addToggleSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status removeSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+ return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+ }
+ Status removeToggleSensorPrivacyListener(
+ const sp<hardware::ISensorPrivacyListener>& /*listener*/) override {
+ return Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+ }
+ Status isSensorPrivacyEnabled(bool* /*_aidl_return*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status isCombinedToggleSensorPrivacyEnabled(int32_t /*sensor*/,
+ bool* /*_aidl_return*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status isToggleSensorPrivacyEnabled(int32_t /*toggleType*/, int32_t /*sensor*/,
+ bool* /*_aidl_return*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status setSensorPrivacy(bool /*enable*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status setToggleSensorPrivacy(int32_t /*userId*/, int32_t /*source*/, int32_t /*sensor*/,
+ bool /*enable*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+ Status setToggleSensorPrivacyForProfileGroup(int32_t /*userId*/, int32_t /*source*/,
+ int32_t /*sensor*/, bool /*enable*/) override {
+ return Status::fromStatusT(UNKNOWN_TRANSACTION);
+ }
+};
+
+class FuzzerActivityManager : public BnInterface<IActivityManager> {
+ public:
+ int32_t openContentUri(const String16& /*stringUri*/) override { return 0; }
+
+ status_t registerUidObserver(const sp<IUidObserver>& /*observer*/, const int32_t /*event*/,
+ const int32_t /*cutpoint*/,
+ const String16& /*callingPackage*/) override {
+ return OK;
+ }
+
+ status_t unregisterUidObserver(const sp<IUidObserver>& /*observer*/) override { return OK; }
+
+ bool isUidActive(const uid_t /*uid*/, const String16& /*callingPackage*/) override {
+ return true;
+ }
+
+ int32_t getUidProcessState(const uid_t /*uid*/, const String16& /*callingPackage*/) override {
+ return ActivityManager::PROCESS_STATE_UNKNOWN;
+ }
+
+ status_t checkPermission(const String16& /*permission*/, const pid_t /*pid*/,
+ const uid_t /*uid*/, int32_t* /*outResult*/) override {
+ return NO_ERROR;
+ }
+
+ status_t registerUidObserverForUids(const sp<IUidObserver>& /*observer*/ ,
+ const int32_t /*event*/ ,
+ const int32_t /*cutpoint*/ ,
+ const String16& /*callingPackage*/ ,
+ const int32_t uids[] ,
+ size_t /*nUids*/ ,
+ /*out*/ sp<IBinder>& /*observerToken*/ ) {
+ (void)uids;
+ return OK;
+ }
+
+ status_t addUidToObserver(const sp<IBinder>& /*observerToken*/ ,
+ const String16& /*callingPackage*/ ,
+ int32_t /*uid*/ ) override {
+ return NO_ERROR;
+ }
+
+ status_t removeUidFromObserver(const sp<IBinder>& /*observerToken*/ ,
+ const String16& /*callingPackage*/ ,
+ int32_t /*uid*/ ) override {
+ return NO_ERROR;
+ }
+
+ status_t logFgsApiBegin(int32_t /*apiType*/ , int32_t /*appUid*/ ,
+ int32_t /*appPid*/ ) override {
+ return NO_ERROR;
+ }
+ status_t logFgsApiEnd(int32_t /*apiType*/ , int32_t /*appUid*/ ,
+ int32_t /*appPid*/ ) override {
+ return NO_ERROR;
+ }
+ status_t logFgsApiStateChanged(int32_t /*apiType*/ , int32_t /*state*/ ,
+ int32_t /*appUid*/ ,
+ int32_t /*appPid*/ ) override {
+ return NO_ERROR;
+ }
+};
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+ /* Create a FakeServiceManager instance and add required services */
+ sp<FakeServiceManager> fakeServiceManager = new FakeServiceManager();
+ setDefaultServiceManager(fakeServiceManager);
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ sp<FuzzerActivityManager> am = new FuzzerActivityManager();
+ fakeServiceManager->addService(String16("activity"), IInterface::asBinder(am));
+
+ sp<FuzzerSensorPrivacyManager> sensorPrivacyManager = new FuzzerSensorPrivacyManager();
+ fakeServiceManager->addService(String16("sensor_privacy"),
+ IInterface::asBinder(sensorPrivacyManager));
+ sp<FuzzerPermissionController> permissionController = new FuzzerPermissionController();
+ fakeServiceManager->addService(String16("permission"),
+ IInterface::asBinder(permissionController));
+
+ sp<FuzzerSchedulingPolicyService> schedulingService = new FuzzerSchedulingPolicyService();
+ fakeServiceManager->addService(String16("scheduling_policy"),
+ IInterface::asBinder(schedulingService));
+
+ const auto audioFlingerObj = sp<AudioFlinger>::make();
+ const auto afAdapter = sp<AudioFlingerServerAdapter>::make(audioFlingerObj);
+
+ fakeServiceManager->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
+ IInterface::asBinder(afAdapter), false /* allowIsolated */,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+
+ const auto audioPolicyService = sp<AudioPolicyService>::make();
+ fakeServiceManager->addService(String16("media.audio_policy"), audioPolicyService,
+ false /* allowIsolated */,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+
+ sp<IBinder> binder =
+ fakeServiceManager->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+ gAudioFlingerService = interface_cast<media::IAudioFlingerService>(binder);
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (!gAudioFlingerService) {
+ return 0;
+ }
+
+ fuzzService(media::IAudioFlingerService::asBinder(gAudioFlingerService),
+ FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 2e2ef65..3c96862 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -303,8 +303,8 @@
// helpers for android.media.AudioManager.getProperty(), see description there for meaning
// FIXME move these APIs to AudioPolicy to permit a more accurate implementation
// that looks on primary device for a stream with fast flag, primary flag, or first one.
- virtual uint32_t getPrimaryOutputSamplingRate() = 0;
- virtual size_t getPrimaryOutputFrameCount() = 0;
+ virtual uint32_t getPrimaryOutputSamplingRate() const = 0;
+ virtual size_t getPrimaryOutputFrameCount() const = 0;
// Intended for AudioService to inform AudioFlinger of device's low RAM attribute,
// and should be called at most once. For a definition of what "low RAM" means, see
@@ -313,7 +313,7 @@
virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) = 0;
/* Get attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+ virtual status_t getAudioPort(struct audio_port_v7* port) const = 0;
/* Create an audio patch between several source and sink ports */
virtual status_t createAudioPatch(const struct audio_patch *patch,
@@ -324,7 +324,7 @@
/* List existing audio patches */
virtual status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches) = 0;
+ struct audio_patch* patches) const = 0;
/* Set audio port configuration */
virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
@@ -341,7 +341,7 @@
virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
/* List available microphones and their characteristics */
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) = 0;
+ virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const = 0;
virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
@@ -357,9 +357,9 @@
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
- virtual int32_t getAAudioMixerBurstCount() = 0;
+ virtual int32_t getAAudioMixerBurstCount() const = 0;
- virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+ virtual int32_t getAAudioHardwareBurstMinUsec() const = 0;
virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
media::DeviceConnectedState state) = 0;
@@ -370,18 +370,18 @@
audio_io_handle_t output, audio_latency_mode_t mode) = 0;
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
- std::vector<audio_latency_mode_t>* modes) = 0;
+ std::vector<audio_latency_mode_t>* modes) const = 0;
virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
- sp<media::ISoundDose>* soundDose) = 0;
+ sp<media::ISoundDose>* soundDose) const = 0;
virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
virtual status_t setBluetoothVariableLatencyEnabled(bool enabled) = 0;
- virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) = 0;
+ virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) const = 0;
- virtual status_t supportsBluetoothVariableLatency(bool* support) = 0;
+ virtual status_t supportsBluetoothVariableLatency(bool* support) const = 0;
virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) = 0;
};
@@ -459,22 +459,22 @@
audio_session_t sessionId,
bool suspended) override;
audio_module_handle_t loadHwModule(const char* name) override;
- uint32_t getPrimaryOutputSamplingRate() override;
- size_t getPrimaryOutputFrameCount() override;
+ uint32_t getPrimaryOutputSamplingRate() const override;
+ size_t getPrimaryOutputFrameCount() const override;
status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
- status_t getAudioPort(struct audio_port_v7* port) override;
+ status_t getAudioPort(struct audio_port_v7* port) const override;
status_t createAudioPatch(const struct audio_patch* patch,
audio_patch_handle_t* handle) override;
status_t releaseAudioPatch(audio_patch_handle_t handle) override;
status_t listAudioPatches(unsigned int* num_patches,
- struct audio_patch* patches) override;
+ struct audio_patch* patches) const override;
status_t setAudioPortConfig(const struct audio_port_config* config) override;
audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) override;
status_t systemReady() override;
status_t audioPolicyReady() override;
size_t frameCountHAL(audio_io_handle_t ioHandle) const override;
- status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) override;
+ status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const override;
status_t setAudioHalPids(const std::vector<pid_t>& pids) override;
status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
status_t updateSecondaryOutputs(
@@ -482,20 +482,20 @@
status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) override;
- int32_t getAAudioMixerBurstCount() override;
- int32_t getAAudioHardwareBurstMinUsec() override;
+ int32_t getAAudioMixerBurstCount() const override;
+ int32_t getAAudioHardwareBurstMinUsec() const override;
status_t setDeviceConnectedState(const struct audio_port_v7 *port,
media::DeviceConnectedState state) override;
status_t setSimulateDeviceConnections(bool enabled) override;
status_t setRequestedLatencyMode(audio_io_handle_t output,
audio_latency_mode_t mode) override;
status_t getSupportedLatencyModes(
- audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
+ audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) const override;
status_t setBluetoothVariableLatencyEnabled(bool enabled) override;
- status_t isBluetoothVariableLatencyEnabled(bool* enabled) override;
- status_t supportsBluetoothVariableLatency(bool* support) override;
+ status_t isBluetoothVariableLatencyEnabled(bool* enabled) const override;
+ status_t supportsBluetoothVariableLatency(bool* support) const override;
status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
- sp<media::ISoundDose>* soundDose) override;
+ sp<media::ISoundDose>* soundDose) const override;
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) override;
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
index 19d1abc..e6916cc 100644
--- a/media/libaudioclient/tests/audiorouting_tests.cpp
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -53,7 +53,7 @@
ASSERT_NE(nullptr, ap);
ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
<< "Unable to open Resource";
- EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ ASSERT_EQ(OK, ap->create()) << "track creation failed";
sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cb));
EXPECT_EQ(OK, ap->start()) << "audio track start failed";
@@ -87,7 +87,7 @@
sp<AudioCapture> capture = sp<AudioCapture>::make(
AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
ASSERT_NE(nullptr, capture);
- EXPECT_EQ(OK, capture->create()) << "record creation failed";
+ ASSERT_EQ(OK, capture->create()) << "record creation failed";
sp<OnAudioDeviceUpdateNotifier> cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, capture->getAudioRecordHandle()->addAudioDeviceCallback(cbCapture));
@@ -98,7 +98,7 @@
ASSERT_NE(nullptr, playback);
ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
<< "Unable to open Resource";
- EXPECT_EQ(OK, playback->create()) << "track creation failed";
+ ASSERT_EQ(OK, playback->create()) << "track creation failed";
sp<OnAudioDeviceUpdateNotifier> cbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, playback->getAudioTrackHandle()->addAudioDeviceCallback(cbPlayback));
@@ -180,7 +180,7 @@
ASSERT_NE(nullptr, playback);
ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
<< "Unable to open Resource";
- EXPECT_EQ(OK, playback->create()) << "track creation failed";
+ ASSERT_EQ(OK, playback->create()) << "track creation failed";
sp<OnAudioDeviceUpdateNotifier> cbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, playback->getAudioTrackHandle()->addAudioDeviceCallback(cbPlayback));
@@ -188,7 +188,7 @@
sp<AudioCapture> captureA = sp<AudioCapture>::make(
AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
ASSERT_NE(nullptr, captureA);
- EXPECT_EQ(OK, captureA->create()) << "record creation failed";
+ ASSERT_EQ(OK, captureA->create()) << "record creation failed";
sp<OnAudioDeviceUpdateNotifier> cbCaptureA = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, captureA->getAudioRecordHandle()->addAudioDeviceCallback(cbCaptureA));
@@ -199,7 +199,7 @@
AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
AUDIO_INPUT_FLAG_NONE, AUDIO_SESSION_ALLOCATE, AudioRecord::TRANSFER_CALLBACK, &attr);
ASSERT_NE(nullptr, captureB);
- EXPECT_EQ(OK, captureB->create()) << "record creation failed";
+ ASSERT_EQ(OK, captureB->create()) << "record creation failed";
sp<OnAudioDeviceUpdateNotifier> cbCaptureB = sp<OnAudioDeviceUpdateNotifier>::make();
EXPECT_EQ(OK, captureB->getAudioRecordHandle()->addAudioDeviceCallback(cbCaptureB));
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.cpp b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
index 5d0d08d..a1726ad 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.cpp
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
@@ -223,8 +223,7 @@
deltaSamples = kMaxCaptureBufSize;
}
- int32_t capturePoint;
- //capturePoint = (int32_t)mCaptureIdx - deltaSamples;
+ int32_t capturePoint, captureSamples = mCaptureSamples;
__builtin_sub_overflow((int32_t) mCaptureIdx, deltaSamples, &capturePoint);
// a negative capturePoint means we wrap the buffer.
if (capturePoint < 0) {
@@ -232,13 +231,14 @@
if (size > mCaptureSamples) {
size = mCaptureSamples;
}
+ // first part of two stages copy, capture to the end of buffer and reset the size/point
result.insert(result.end(), &mCaptureBuf[kMaxCaptureBufSize + capturePoint],
&mCaptureBuf[kMaxCaptureBufSize + capturePoint + size]);
- mCaptureSamples -= size;
+ captureSamples -= size;
capturePoint = 0;
}
result.insert(result.end(), &mCaptureBuf[capturePoint],
- &mCaptureBuf[capturePoint + mCaptureSamples]);
+ &mCaptureBuf[capturePoint + captureSamples]);
mLastCaptureIdx = mCaptureIdx;
return result;
}
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 2ba1fc3..6834b7d 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -476,35 +476,37 @@
}
bool HeifDecoderImpl::setOutputColor(HeifColorFormat heifColor) {
- if (heifColor == (HeifColorFormat)mOutputColor) {
- return true;
- }
-
+ android_pixel_format_t outputColor;
switch(heifColor) {
case kHeifColorFormat_RGB565:
{
- mOutputColor = HAL_PIXEL_FORMAT_RGB_565;
+ outputColor = HAL_PIXEL_FORMAT_RGB_565;
break;
}
case kHeifColorFormat_RGBA_8888:
{
- mOutputColor = HAL_PIXEL_FORMAT_RGBA_8888;
+ outputColor = HAL_PIXEL_FORMAT_RGBA_8888;
break;
}
case kHeifColorFormat_BGRA_8888:
{
- mOutputColor = HAL_PIXEL_FORMAT_BGRA_8888;
+ outputColor = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}
case kHeifColorFormat_RGBA_1010102:
{
- mOutputColor = HAL_PIXEL_FORMAT_RGBA_1010102;
+ outputColor = HAL_PIXEL_FORMAT_RGBA_1010102;
break;
}
default:
ALOGE("Unsupported output color format %d", heifColor);
return false;
}
+ if (outputColor == mOutputColor) {
+ return true;
+ }
+
+ mOutputColor = outputColor;
if (mFrameDecoded) {
return reinit(nullptr);
diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp
index c43ef66..f498453 100644
--- a/media/libmedia/IMediaDeathNotifier.cpp
+++ b/media/libmedia/IMediaDeathNotifier.cpp
@@ -38,16 +38,10 @@
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder;
- do {
- binder = sm->getService(String16("media.player"));
- if (binder != 0) {
- break;
- }
- ALOGW("Media player service not published, waiting...");
- usleep(500000); // 0.5 s
- } while (true);
-
+ sp<IBinder> binder = sm->waitForService(String16("media.player"));
+ if (binder == nullptr) {
+ return nullptr;
+ }
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 2ae76b3..40fd022 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -41,14 +41,10 @@
if (sService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
- do {
- binder = sm->getService(String16("media.player"));
- if (binder != 0) {
- break;
- }
- ALOGW("MediaPlayerService not published, waiting...");
- usleep(500000); // 0.5 s
- } while (true);
+ binder = sm->waitForService(String16("media.player"));
+ if (binder == nullptr) {
+ return nullptr;
+ }
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index f80a467..26aa375 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -184,6 +184,7 @@
#define AMEDIAMETRICS_PROP_PLAYERIID "playerIId" // int32 (-1 invalid/unset IID)
#define AMEDIAMETRICS_PROP_ROUTEDDEVICEID "routedDeviceId" // int32
#define AMEDIAMETRICS_PROP_SAMPLERATE "sampleRate" // int32
+#define AMEDIAMETRICS_PROP_SAMPLERATECLIENT "sampleRateClient" // int32
#define AMEDIAMETRICS_PROP_SAMPLERATEHARDWARE "sampleRateHardware" // int32
#define AMEDIAMETRICS_PROP_SELECTEDDEVICEID "selectedDeviceId" // int32
#define AMEDIAMETRICS_PROP_SELECTEDMICDIRECTION "selectedMicDirection" // int32
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index 89e9806..434ae00 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -49,7 +49,7 @@
defaults: ["libnbaio_mono_defaults"],
}
-cc_library_shared {
+cc_library {
name: "libnbaio",
defaults: ["libnbaio_mono_defaults"],
srcs: [
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 967c316..4441121 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -32,6 +32,7 @@
#include <media/stagefright/MetaData.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
+#include <camera/StringUtils.h>
#include <gui/Surface.h>
#include <utils/String8.h>
#include <cutils/properties.h>
@@ -146,7 +147,7 @@
status_t CameraSource::isCameraAvailable(
const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
- int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) {
+ int32_t cameraId, const std::string& clientName, uid_t clientUid, pid_t clientPid) {
if (camera == 0) {
mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid,
@@ -535,7 +536,7 @@
status_t err = OK;
if ((err = isCameraAvailable(camera, proxy, cameraId,
- clientName, clientUid, clientPid)) != OK) {
+ toStdString(clientName), clientUid, clientPid)) != OK) {
ALOGE("Camera connection could not be established.");
return err;
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a58343f..a0d56f8 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -31,7 +31,6 @@
#include "include/SoftwareRenderer.h"
#include <android/api-level.h>
-#include <android/binder_manager.h>
#include <android/content/pm/IPackageManagerNative.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
@@ -74,7 +73,6 @@
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaCodecList.h>
-#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/OMXClient.h>
diff --git a/media/libstagefright/include/media/stagefright/CameraSource.h b/media/libstagefright/include/media/stagefright/CameraSource.h
index e8770ed..fcd17b9 100644
--- a/media/libstagefright/include/media/stagefright/CameraSource.h
+++ b/media/libstagefright/include/media/stagefright/CameraSource.h
@@ -259,7 +259,7 @@
status_t isCameraAvailable(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
- const String16& clientName,
+ const std::string& clientName,
uid_t clientUid,
pid_t clientPid);
diff --git a/media/libstagefright/rtsp/fuzzer/Android.bp b/media/libstagefright/rtsp/fuzzer/Android.bp
new file mode 100644
index 0000000..8e10b0c
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/Android.bp
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2023 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+cc_defaults {
+ name: "libstagefright_rtsp_fuzzer_defaults",
+ shared_libs: [
+ "liblog",
+ "libmedia",
+ "libutils",
+ "libstagefright_foundation",
+ ],
+ static_libs: [
+ "libdatasource",
+ "libstagefright_rtsp",
+ ],
+ header_libs: [
+ "libstagefright_rtsp_headers",
+ ],
+ fuzz_config:{
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
+
+cc_fuzz {
+ name: "sdploader_fuzzer",
+ srcs: [
+ "sdploader_fuzzer.cpp",
+ ],
+ defaults: [
+ "libstagefright_rtsp_fuzzer_defaults",
+ ]
+}
+
+cc_fuzz {
+ name: "rtp_writer_fuzzer",
+ srcs: [
+ "rtp_writer_fuzzer.cpp",
+ ],
+ defaults: [
+ "libstagefright_rtsp_fuzzer_defaults",
+ ],
+ shared_libs:[
+ "libandroid_net",
+ "libbase",
+ "libstagefright",
+ "libcutils",
+ ],
+}
diff --git a/media/libstagefright/rtsp/fuzzer/README.md b/media/libstagefright/rtsp/fuzzer/README.md
new file mode 100644
index 0000000..657fb48
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/README.md
@@ -0,0 +1,64 @@
+# Fuzzers for libstagefright_rtsp
+
+## Table of contents
++ [sdploader_fuzzer](#SDPLoader)
++ [rtp_writer_fuzzer](#ARTPWriter)
+
+# <a name="SDPLoader"></a> Fuzzer for SDPLoader
+
+SDPLoader supports the following parameters:
+1. Flag (parameter name: "flags")
+2. URL (parameter name: "url")
+3. Header (parameter name: "headers")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`flags`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`url`| `String` |Value obtained from FuzzedDataProvider|
+|`headers`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) sdploader_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/sdploader_fuzzer/sdploader_fuzzer
+```
+
+# <a name="ARTPWriter"></a> Fuzzer for ARTPWriter
+
+ARTPWriter supports the following parameters:
+1. File descriptor (parameter name: "fd")
+2. Local Ip (parameter name: "localIp")
+3. Local Port (parameter name: "localPort")
+4. Remote Ip (parameter name: "remoteIp")
+5. Remote Port (parameter name: "remotePort")
+6. Sequence No (parameter name: "seqNo")
+7. OpponentID (parameter name: "opponentID")
+8. Bit Rate (parameter name: "bitrate")
+9. kKeyMIMETypeArray (parameter name: "mimeType")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`localIp`| `String` |Value obtained from FuzzedDataProvider|
+|`localPort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`remoteIp`| `String` |Value obtained from FuzzedDataProvider|
+|`remotePort`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`seqNo`| `0` to `10000000` |Value obtained from FuzzedDataProvider|
+|`opponentID`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`bitrate`| `UINT32_MIN` to `UINT32_MAX` |Value obtained from FuzzedDataProvider|
+|`mimeType`| 0. `MEDIA_MIMETYPE_VIDEO_AVC`<br> 1. `MEDIA_MIMETYPE_VIDEO_HEVC`<br> 2. `MEDIA_MIMETYPE_VIDEO_H263`<br> 3. `MEDIA_MIMETYPE_AUDIO_AMR_NB`<br> 4. `MEDIA_MIMETYPE_AUDIO_AMR_WB`|Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) rtp_writer_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/rtp_writer_fuzzer/rtp_writer_fuzzer
+```
diff --git a/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp b/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp
new file mode 100644
index 0000000..8d9f923
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/rtp_writer_fuzzer.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/rtsp/ARTPWriter.h>
+
+constexpr int32_t kMinSize = 0;
+constexpr int32_t kMaxSize = 65536;
+constexpr int32_t kMaxTime = 1000;
+constexpr int32_t kMaxBytes = 128;
+constexpr int32_t kAMRNBFrameSizes[] = {13, 14, 16, 18, 20, 21, 27, 32};
+constexpr int32_t kAMRWBFrameSizes[] = {18, 24, 33, 37, 41, 47, 51, 59, 61};
+constexpr int32_t kAMRIndexOffset = 8;
+
+using namespace android;
+
+const char* kKeyMimeTypeArray[] = {MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_HEVC,
+ MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AMR_NB,
+ MEDIA_MIMETYPE_AUDIO_AMR_WB};
+
+struct TestMediaSource : public MediaSource {
+ public:
+ TestMediaSource(FuzzedDataProvider& mFdp) : mTestMetaData(new MetaData) {
+ int32_t vectorSize = 0;
+ mAllowRead = mFdp.ConsumeBool();
+ mKeySps = mFdp.ConsumeIntegral<int32_t>();
+ mKeyVps = mFdp.ConsumeIntegral<int32_t>();
+ mKeyPps = mFdp.ConsumeIntegral<int32_t>();
+ mKeyTime = mFdp.ConsumeIntegralInRange<int64_t>(kMinSize, kMaxTime);
+
+ mMimeType = mFdp.PickValueInArray(kKeyMimeTypeArray);
+ mTestMetaData->setCString(kKeyMIMEType, mMimeType);
+ if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_NB) {
+ int32_t index =
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRNBFrameSizes) - 1);
+ vectorSize = kAMRNBFrameSizes[index];
+ mData.push_back(kAMRIndexOffset * index);
+ } else if (mMimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB) {
+ int32_t index =
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, std::size(kAMRWBFrameSizes) - 1);
+ vectorSize = kAMRWBFrameSizes[index];
+ mData.push_back(kAMRIndexOffset * index);
+ } else if (mMimeType == MEDIA_MIMETYPE_VIDEO_H263) {
+ // Required format for H263 media data
+ mData.push_back(0);
+ mData.push_back(0);
+ vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ } else {
+ vectorSize = mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize);
+ }
+ for (size_t idx = mData.size(); idx < vectorSize; ++idx) {
+ mData.push_back(mFdp.ConsumeIntegral<uint8_t>());
+ }
+ }
+ virtual status_t start(MetaData* /*params*/) { return OK; }
+ virtual status_t stop() { return OK; }
+ virtual sp<MetaData> getFormat() { return mTestMetaData; }
+ virtual status_t read(MediaBufferBase** buffer, const ReadOptions* /*options*/) {
+ if (!mAllowRead) {
+ return -1;
+ }
+ *buffer = new MediaBuffer(mData.data() /*data*/, mData.size() /*size*/);
+ if (mKeySps) {
+ (*buffer)->meta_data().setInt32(kKeySps, mKeySps);
+ }
+ if (mKeyVps) {
+ (*buffer)->meta_data().setInt32(kKeyVps, mKeyVps);
+ }
+ if (mKeyPps) {
+ (*buffer)->meta_data().setInt32(kKeyPps, mKeyPps);
+ }
+ (*buffer)->meta_data().setInt64(kKeyTime, mKeyTime);
+ return OK;
+ }
+
+ private:
+ int32_t mKeySps;
+ int32_t mKeyVps;
+ int32_t mKeyPps;
+ int64_t mKeyTime;
+ bool mAllowRead;
+ const char* mMimeType;
+ sp<MetaData> mTestMetaData;
+ std::vector<uint8_t> mData;
+};
+
+class ARTPWriterFuzzer {
+ public:
+ ARTPWriterFuzzer(const uint8_t* data, size_t size)
+ : mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)), mFdp(data, size) {}
+ ~ARTPWriterFuzzer() { close(mDataSourceFd); }
+ void process();
+
+ private:
+ void createARTPWriter();
+ const int32_t mDataSourceFd;
+ FuzzedDataProvider mFdp;
+ sp<ARTPWriter> mArtpWriter;
+};
+
+void ARTPWriterFuzzer::createARTPWriter() {
+ String8 localIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
+ String8 remoteIp = String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str());
+ mArtpWriter = sp<ARTPWriter>::make(
+ mDataSourceFd, localIp, mFdp.ConsumeIntegral<uint16_t>() /* localPort */, remoteIp,
+ mFdp.ConsumeIntegral<uint16_t>() /* remotePort */,
+ mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize) /* seqNo */);
+}
+
+void ARTPWriterFuzzer::process() {
+ if (mFdp.ConsumeBool()) {
+ mArtpWriter = sp<ARTPWriter>::make(mDataSourceFd);
+ if (mArtpWriter->getSequenceNum() > kMaxSize) {
+ createARTPWriter();
+ }
+ } else {
+ createARTPWriter();
+ }
+
+ mArtpWriter->addSource(sp<TestMediaSource>::make(mFdp) /* source */);
+
+ while (mFdp.remaining_bytes()) {
+ auto invokeRTPWriterFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ sp<MetaData> metaData = sp<MetaData>::make();
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt32(kKeySelfID, mFdp.ConsumeIntegral<int32_t>());
+ }
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt32(kKeyPayloadType, mFdp.ConsumeIntegral<int32_t>());
+ }
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt32(kKeyRtpExtMap, mFdp.ConsumeIntegral<int32_t>());
+ }
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt32(kKeyRtpCvoDegrees, mFdp.ConsumeIntegral<int32_t>());
+ }
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt32(kKeyRtpDscp, mFdp.ConsumeIntegral<int32_t>());
+ }
+ if (mFdp.ConsumeBool()) {
+ metaData->setInt64(kKeySocketNetwork, mFdp.ConsumeIntegral<int64_t>());
+ }
+ mArtpWriter->start(metaData.get() /*param*/);
+ },
+ [&]() {
+ mArtpWriter->setTMMBNInfo(mFdp.ConsumeIntegral<uint32_t>() /* opponentID */,
+ mFdp.ConsumeIntegral<uint32_t>() /* bitrate */);
+ },
+ [&]() { mArtpWriter->stop(); },
+ [&]() {
+ mArtpWriter->updateCVODegrees(mFdp.ConsumeIntegral<int32_t>() /* cvoDegrees */);
+ },
+ [&]() {
+ mArtpWriter->updatePayloadType(
+ mFdp.ConsumeIntegral<int32_t>() /* payloadType */);
+ },
+
+ });
+ invokeRTPWriterFuzzer();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ARTPWriterFuzzer artpWriterFuzzer(data, size);
+ artpWriterFuzzer.process();
+ return 0;
+}
diff --git a/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp b/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp
new file mode 100644
index 0000000..748e5b6
--- /dev/null
+++ b/media/libstagefright/rtsp/fuzzer/sdploader_fuzzer.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <datasource/HTTPBase.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/rtsp/SDPLoader.h>
+
+using namespace android;
+
+constexpr int32_t kMinCapacity = 0;
+constexpr int32_t kMaxCapacity = 1000;
+constexpr int32_t kMaxStringLength = 20;
+constexpr int32_t kMaxBytes = 128;
+enum { kWhatLoad = 'load' };
+
+struct FuzzAHandler : public AHandler {
+ public:
+ FuzzAHandler(std::function<void()> signalEosFunction) : mSignalEosFunction(signalEosFunction) {}
+
+ protected:
+ void onMessageReceived(const sp<AMessage>& msg) override {
+ switch (msg->what()) {
+ case kWhatLoad: {
+ mSignalEosFunction();
+ break;
+ }
+ }
+ return;
+ }
+
+ private:
+ std::function<void()> mSignalEosFunction;
+};
+
+struct FuzzMediaHTTPConnection : public MediaHTTPConnection {
+ public:
+ FuzzMediaHTTPConnection(FuzzedDataProvider* fdp) : mFdp(fdp) {
+ mSize = mFdp->ConsumeIntegralInRange(kMinCapacity, kMaxCapacity);
+ mData = mFdp->ConsumeBytes<uint8_t>(mSize);
+ mSize = mData.size();
+ }
+ virtual bool connect(const char* /* uri */,
+ const KeyedVector<String8, String8>* /* headers */) {
+ return mFdp->ConsumeBool();
+ }
+ virtual void disconnect() { return; }
+ virtual ssize_t readAt(off64_t offset, void* data, size_t size) {
+ if ((size + offset <= mData.size()) && (offset >= 0)) {
+ memcpy(data, mData.data() + offset, size);
+ return size;
+ }
+ return 0;
+ }
+ virtual off64_t getSize() { return mSize; }
+ virtual status_t getMIMEType(String8* /*mimeType*/) {return mFdp->ConsumeIntegral<status_t>();}
+ virtual status_t getUri(String8* /*uri*/) {return mFdp->ConsumeIntegral<status_t>();}
+
+ private:
+ FuzzedDataProvider* mFdp = nullptr;
+ std::vector<uint8_t> mData;
+ size_t mSize = 0;
+};
+
+struct FuzzMediaHTTPService : public MediaHTTPService {
+ public:
+ FuzzMediaHTTPService(FuzzedDataProvider* fdp) : mFdp(fdp) {}
+ virtual sp<MediaHTTPConnection> makeHTTPConnection() {
+ mediaHTTPConnection = sp<FuzzMediaHTTPConnection>::make(mFdp);
+ return mediaHTTPConnection;
+ }
+
+ private:
+ sp<FuzzMediaHTTPConnection> mediaHTTPConnection = nullptr;
+ FuzzedDataProvider* mFdp = nullptr;
+};
+
+class SDPLoaderFuzzer {
+ public:
+ SDPLoaderFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {}
+ void process();
+
+ private:
+ void signalEos();
+
+ bool mEosReached = false;
+ std::mutex mMsgPostCompleteMutex;
+ std::condition_variable mConditionalVariable;
+ FuzzedDataProvider mFdp;
+};
+
+void SDPLoaderFuzzer::signalEos() {
+ mEosReached = true;
+ mConditionalVariable.notify_one();
+ return;
+}
+
+void SDPLoaderFuzzer::process() {
+ sp<FuzzAHandler> handler = sp<FuzzAHandler>::make(std::bind(&SDPLoaderFuzzer::signalEos, this));
+ sp<ALooper> looper = sp<ALooper>::make();
+ looper->start();
+ looper->registerHandler(handler);
+ const sp<AMessage> notify = sp<AMessage>::make(kWhatLoad, handler);
+ sp<SDPLoader> sdpLoader =
+ sp<SDPLoader>::make(notify, mFdp.ConsumeIntegral<uint32_t>() /* flags */,
+ sp<FuzzMediaHTTPService>::make(&mFdp) /* httpService */);
+
+ KeyedVector<String8, String8> headers;
+ for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange<size_t>(kMinCapacity, kMaxCapacity);
+ ++idx) {
+ headers.add(String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* key */,
+ String8(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str()) /* value */);
+ }
+
+ sdpLoader->load(mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* url */, &headers);
+
+ std::unique_lock waitForMsgPostComplete(mMsgPostCompleteMutex);
+ mConditionalVariable.wait(waitForMsgPostComplete, [this] { return mEosReached; });
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ SDPLoaderFuzzer sdpLoaderFuzzer(data, size);
+ sdpLoaderFuzzer.process();
+ return 0;
+}
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 38cf29d..184e4f4 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -2007,7 +2007,7 @@
uint8_t mhac_header[mhac_header_size];
off64_t data_offset = *offset;
- if (chunk_size < sizeof(mhac_header)) {
+ if (mLastTrack == NULL || chunk_size < sizeof(mhac_header)) {
return ERROR_MALFORMED;
}
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 2ffd775..ef8c9aa 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -297,6 +297,10 @@
}
void MtpFfsHandle::close() {
+ auto timeout = std::chrono::seconds(2);
+ std::unique_lock lk(m);
+ cv.wait_for(lk, timeout ,[this]{return child_threads==0;});
+
io_destroy(mCtx);
closeEndpoints();
closeConfig();
@@ -669,6 +673,11 @@
char *temp = new char[me.length];
memcpy(temp, me.data, me.length);
me.data = temp;
+
+ std::unique_lock lk(m);
+ child_threads++;
+ lk.unlock();
+
std::thread t([this, me]() { return this->doSendEvent(me); });
t.detach();
return 0;
@@ -680,6 +689,11 @@
if (static_cast<unsigned>(ret) != length)
PLOG(ERROR) << "Mtp error sending event thread!";
delete[] reinterpret_cast<char*>(me.data);
+
+ std::unique_lock lk(m);
+ child_threads--;
+ lk.unlock();
+ cv.notify_one();
}
} // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index e552e03..51cdef0 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -60,6 +60,10 @@
bool mCanceled;
bool mBatchCancel;
+ std::mutex m;
+ std::condition_variable cv;
+ std::atomic<int> child_threads{0};
+
android::base::unique_fd mControl;
// "in" from the host's perspective => sink for mtp server
android::base::unique_fd mBulkIn;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index f069a83..5faaac2 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -92,24 +92,46 @@
}
uint16_t MtpPacket::getUInt16(int offset) const {
- return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
uint32_t MtpPacket::getUInt32(int offset) const {
- return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
- ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
+ ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
void MtpPacket::putUInt16(int offset, uint16_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
void MtpPacket::putUInt32(int offset, uint32_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
uint16_t MtpPacket::getContainerCode() const {
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 067c8f4..0f7d98b 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -570,6 +570,9 @@
}
}
+// The LL-NDK API is now deprecated. New devices will no longer have the token
+// manager service installed, so createHalToken will return false and this
+// will return AMEDIA_ERROR_UNKNOWN on those devices.
media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) {
if (mWindowHandle != nullptr) {
*handle = mWindowHandle;
diff --git a/media/ndk/fuzzer/Android.bp b/media/ndk/fuzzer/Android.bp
index a3d6a96..ba92b19 100644
--- a/media/ndk/fuzzer/Android.bp
+++ b/media/ndk/fuzzer/Android.bp
@@ -56,6 +56,14 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 155276,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libmediandk library",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
@@ -63,6 +71,11 @@
name: "ndk_crypto_fuzzer",
srcs: ["ndk_crypto_fuzzer.cpp"],
defaults: ["libmediandk_fuzzer_defaults"],
+ fuzz_config: {
+ libfuzzer_options: [
+ "max_len=10000",
+ ],
+ },
}
cc_fuzz {
@@ -116,3 +129,16 @@
header_libs: ["libnativewindow_headers",],
defaults: ["libmediandk_fuzzer_defaults",],
}
+
+cc_fuzz {
+ name: "ndk_async_codec_fuzzer",
+ srcs: [
+ "ndk_async_codec_fuzzer.cpp",
+ "NdkMediaCodecFuzzerBase.cpp",
+ ],
+ header_libs: [
+ "libnativewindow_headers",
+ "libutils_headers",
+ ],
+ defaults: ["libmediandk_fuzzer_defaults",],
+}
diff --git a/media/ndk/fuzzer/README.md b/media/ndk/fuzzer/README.md
index 0fd08b0..7f6bdd7 100644
--- a/media/ndk/fuzzer/README.md
+++ b/media/ndk/fuzzer/README.md
@@ -8,6 +8,7 @@
+ [ndk_drm_fuzzer](#NdkDrm)
+ [ndk_mediamuxer_fuzzer](#NdkMediaMuxer)
+ [ndk_sync_codec_fuzzer](#NdkSyncCodec)
++ [ndk_async_codec_fuzzer](#NdkAsyncCodec)
# <a name="NdkCrypto"></a> Fuzzer for NdkCrypto
@@ -156,3 +157,16 @@
$ adb sync data
$ adb shell /data/fuzz/arm64/ndk_sync_codec_fuzzer/ndk_sync_codec_fuzzer
```
+
+# <a name="NdkAsyncCodec"></a>Fuzzer for NdkAsyncCodec
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) ndk_async_codec_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ndk_async_codec_fuzzer/ndk_sync_codec_fuzzer
+```
diff --git a/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp b/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp
new file mode 100644
index 0000000..28a38fe
--- /dev/null
+++ b/media/ndk/fuzzer/ndk_async_codec_fuzzer.cpp
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <NdkMediaCodecFuzzerBase.h>
+#include <media/NdkMediaFormatPriv.h>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+using namespace android;
+using namespace std;
+
+constexpr int32_t kMaxCryptoInfoAPIs = 3;
+constexpr int32_t kMaxNdkCodecAPIs = 5;
+
+template <typename T>
+class CallBackQueue {
+ public:
+ void push(T elem) {
+ bool needsNotify = false;
+ {
+ unique_lock<mutex> lock(mMutex);
+ needsNotify = mQueue.empty();
+ mQueue.push(std::move(elem));
+ }
+ if (needsNotify) {
+ mQueueNotEmptyCondition.notify_one();
+ }
+ }
+
+ T pop() {
+ unique_lock<mutex> lock(mMutex);
+ if (mQueue.empty()) {
+ mQueueNotEmptyCondition.wait(lock, [this]() { return !mQueue.empty(); });
+ }
+ auto result = mQueue.front();
+ mQueue.pop();
+ return result;
+ }
+
+ private:
+ mutex mMutex;
+ std::queue<T> mQueue;
+ std::condition_variable mQueueNotEmptyCondition;
+};
+
+class CallBackHandle {
+ public:
+ CallBackHandle() : mSawError(false), mIsDone(false) {}
+
+ virtual ~CallBackHandle() {}
+
+ void ioThread();
+
+ // Implementation in child class (Decoder/Encoder)
+ virtual void invokeInputBufferAPI(AMediaCodec* codec, int32_t index) {
+ (void)codec;
+ (void)index;
+ }
+ virtual void onFormatChanged(AMediaCodec* codec, AMediaFormat* format) {
+ (void)codec;
+ (void)format;
+ }
+ virtual void receiveError(void) {}
+ virtual void invokeOutputBufferAPI(AMediaCodec* codec, int32_t index,
+ AMediaCodecBufferInfo* bufferInfo) {
+ (void)codec;
+ (void)index;
+ (void)bufferInfo;
+ }
+
+ // Keep a queue of all function callbacks.
+ typedef function<void()> IOTask;
+ CallBackQueue<IOTask> mIOQueue;
+ bool mSawError;
+ bool mIsDone;
+};
+
+void CallBackHandle::ioThread() {
+ while (!mIsDone && !mSawError) {
+ auto task = mIOQueue.pop();
+ task();
+ }
+}
+
+static void onAsyncInputAvailable(AMediaCodec* codec, void* userdata, int32_t index) {
+ CallBackHandle* self = (CallBackHandle*)userdata;
+ self->mIOQueue.push([self, codec, index]() { self->invokeInputBufferAPI(codec, index); });
+}
+
+static void onAsyncOutputAvailable(AMediaCodec* codec, void* userdata, int32_t index,
+ AMediaCodecBufferInfo* bufferInfo) {
+ CallBackHandle* self = (CallBackHandle*)userdata;
+ AMediaCodecBufferInfo bufferInfoCopy = *bufferInfo;
+ self->mIOQueue.push([self, codec, index, bufferInfoCopy]() {
+ AMediaCodecBufferInfo bc = bufferInfoCopy;
+ self->invokeOutputBufferAPI(codec, index, &bc);
+ });
+}
+
+static void onAsyncFormatChanged(AMediaCodec* codec, void* userdata, AMediaFormat* format) {
+ (void)codec;
+ (void)userdata;
+ (void)format;
+};
+
+static void onAsyncError(AMediaCodec* codec, void* userdata, media_status_t err, int32_t actionCode,
+ const char* detail) {
+ CallBackHandle* self = (CallBackHandle*)userdata;
+ self->mSawError = true;
+ self->receiveError();
+ (void)codec;
+ (void)err;
+ (void)actionCode;
+ (void)detail;
+};
+
+class NdkAsyncCodecFuzzer : public NdkMediaCodecFuzzerBase, public CallBackHandle {
+ public:
+ NdkAsyncCodecFuzzer(const uint8_t* data, size_t size)
+ : NdkMediaCodecFuzzerBase(), mFdp(data, size) {
+ setFdp(&mFdp);
+ mStopCodec = false;
+ mSawInputEOS = false;
+ mSignalledError = false;
+ mIsEncoder = false;
+ mNumOfFrames = 0;
+ mNumInputFrames = 0;
+ };
+ ~NdkAsyncCodecFuzzer() {
+ mIOThreadPool->stop();
+ delete (mIOThreadPool);
+ };
+
+ void process();
+
+ static void codecOnFrameRendered(AMediaCodec* codec, void* userdata, int64_t mediaTimeUs,
+ int64_t systemNano) {
+ (void)codec;
+ (void)userdata;
+ (void)mediaTimeUs;
+ (void)systemNano;
+ };
+ class ThreadPool {
+ public:
+ void start();
+ void queueJob(const std::function<void()>& job);
+ void stop();
+
+ private:
+ void ThreadLoop();
+ bool mShouldTerminate = false;
+ std::vector<std::thread> mThreads;
+ std::mutex mQueueMutex;
+ std::condition_variable mQueueMutexCondition;
+ std::queue<std::function<void()>> mJobs;
+ };
+
+ private:
+ FuzzedDataProvider mFdp;
+ AMediaCodec* mCodec = nullptr;
+ void invokeCodecCryptoInfoAPI();
+ void invokekAsyncCodecAPIs(bool isEncoder);
+ void invokeAsyncCodeConfigAPI();
+ void invokeInputBufferAPI(AMediaCodec* codec, int32_t bufferIndex);
+ void invokeOutputBufferAPI(AMediaCodec* codec, int32_t bufferIndex,
+ AMediaCodecBufferInfo* bufferInfo);
+ void invokeFormatAPI(AMediaCodec* codec);
+ void receiveError();
+ bool mStopCodec;
+ bool mSawInputEOS;
+ bool mSignalledError;
+ int32_t mNumOfFrames;
+ int32_t mNumInputFrames;
+ mutable Mutex mMutex;
+ bool mIsEncoder;
+ ThreadPool* mIOThreadPool = new ThreadPool();
+};
+
+void NdkAsyncCodecFuzzer::ThreadPool::start() {
+ const uint32_t numThreads = std::thread::hardware_concurrency();
+ mThreads.resize(numThreads);
+ for (uint32_t i = 0; i < numThreads; ++i) {
+ mThreads.at(i) = std::thread(&ThreadPool::ThreadLoop, this);
+ }
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::ThreadLoop() {
+ while (true) {
+ std::function<void()> job;
+ {
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ mQueueMutexCondition.wait(lock, [this] { return !mJobs.empty() || mShouldTerminate; });
+ if (mShouldTerminate) {
+ return;
+ }
+ job = mJobs.front();
+ mJobs.pop();
+ }
+ job();
+ }
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::queueJob(const std::function<void()>& job) {
+ {
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ mJobs.push(job);
+ }
+ mQueueMutexCondition.notify_one();
+}
+
+void NdkAsyncCodecFuzzer::ThreadPool::stop() {
+ {
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ mShouldTerminate = true;
+ }
+ mQueueMutexCondition.notify_all();
+ for (std::thread& active_thread : mThreads) {
+ active_thread.join();
+ }
+ mThreads.clear();
+}
+
+void NdkAsyncCodecFuzzer::receiveError(void) {
+ mSignalledError = true;
+}
+
+void NdkAsyncCodecFuzzer::invokeInputBufferAPI(AMediaCodec* codec, int32_t bufferIndex) {
+ size_t bufferSize = 0;
+ Mutex::Autolock autoLock(mMutex);
+ if (mSignalledError) {
+ CallBackHandle::mSawError = true;
+ return;
+ }
+ if (mStopCodec || bufferIndex < 0 || mSawInputEOS) {
+ return;
+ }
+
+ uint8_t* buffer = AMediaCodec_getInputBuffer(codec, bufferIndex, &bufferSize);
+ if (buffer) {
+ std::vector<uint8_t> bytesRead = mFdp.ConsumeBytes<uint8_t>(
+ std::min(mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes), bufferSize));
+ memcpy(buffer, bytesRead.data(), bytesRead.size());
+ bufferSize = bytesRead.size();
+ } else {
+ mSignalledError = true;
+ return;
+ }
+
+ uint32_t flag = 0;
+ if (!bufferSize || mNumInputFrames == mNumOfFrames) {
+ flag |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+ mSawInputEOS = true;
+ }
+ AMediaCodec_queueInputBuffer(codec, bufferIndex, 0 /* offset */, bufferSize, 0 /* time */,
+ flag);
+ mNumInputFrames++;
+}
+
+void NdkAsyncCodecFuzzer::invokeOutputBufferAPI(AMediaCodec* codec, int32_t bufferIndex,
+ AMediaCodecBufferInfo* bufferInfo) {
+ size_t bufferSize = 0;
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mSignalledError) {
+ CallBackHandle::mSawError = true;
+ return;
+ }
+
+ if (mStopCodec || bufferIndex < 0 || mIsDone) {
+ return;
+ }
+
+ if (!mIsEncoder) {
+ (void)AMediaCodec_getOutputBuffer(codec, bufferIndex, &bufferSize);
+ }
+ AMediaCodec_releaseOutputBuffer(codec, bufferIndex, mFdp.ConsumeBool());
+ mIsDone = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
+}
+
+void NdkAsyncCodecFuzzer::invokeFormatAPI(AMediaCodec* codec) {
+ AMediaFormat* codecFormat = nullptr;
+ if (mFdp.ConsumeBool()) {
+ codecFormat = AMediaCodec_getInputFormat(codec);
+ } else {
+ codecFormat = AMediaCodec_getOutputFormat(codec);
+ }
+ if (codecFormat) {
+ AMediaFormat_delete(codecFormat);
+ }
+}
+
+void NdkAsyncCodecFuzzer::invokekAsyncCodecAPIs(bool isEncoder) {
+ ANativeWindow* nativeWindow = nullptr;
+
+ if (mFdp.ConsumeBool()) {
+ AMediaCodec_createInputSurface(mCodec, &nativeWindow);
+ }
+
+ if (AMEDIA_OK == AMediaCodec_configure(mCodec, getCodecFormat(), nativeWindow,
+ nullptr /* crypto */,
+ (isEncoder ? AMEDIACODEC_CONFIGURE_FLAG_ENCODE : 0))) {
+ mNumOfFrames = mFdp.ConsumeIntegralInRange<size_t>(kMinIterations, kMaxIterations);
+ // Configure codecs to run in async mode.
+ AMediaCodecOnAsyncNotifyCallback callBack = {onAsyncInputAvailable, onAsyncOutputAvailable,
+ onAsyncFormatChanged, onAsyncError};
+ AMediaCodec_setAsyncNotifyCallback(mCodec, callBack, this);
+ mIOThreadPool->queueJob([this] { CallBackHandle::ioThread(); });
+
+ AMediaCodec_start(mCodec);
+ sleep(5);
+ int32_t count = 0;
+ while (++count <= mNumOfFrames) {
+ int32_t ndkcodecAPI =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxNdkCodecAPIs);
+ switch (ndkcodecAPI) {
+ case 0: { // get input and output Format
+ invokeFormatAPI(mCodec);
+ break;
+ }
+ case 1: {
+ AMediaCodec_signalEndOfInputStream(mCodec);
+ mSawInputEOS = true;
+ break;
+ }
+ case 2: { // set parameters
+ // Create a new parameter and set
+ AMediaFormat* params = AMediaFormat_new();
+ AMediaFormat_setInt32(
+ params, "video-bitrate",
+ mFdp.ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue));
+ AMediaCodec_setParameters(mCodec, params);
+ AMediaFormat_delete(params);
+ break;
+ }
+ case 3: { // flush codec
+ AMediaCodec_flush(mCodec);
+ if (mFdp.ConsumeBool()) {
+ AMediaCodec_start(mCodec);
+ }
+ break;
+ }
+ case 4: {
+ char* name = nullptr;
+ AMediaCodec_getName(mCodec, &name);
+ AMediaCodec_releaseName(mCodec, name);
+ break;
+ }
+ case 5:
+ default: {
+ std::vector<uint8_t> userData = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ AMediaCodecOnFrameRendered callback = codecOnFrameRendered;
+ AMediaCodec_setOnFrameRenderedCallback(mCodec, callback, userData.data());
+ break;
+ }
+ }
+ }
+ {
+ Mutex::Autolock autoLock(mMutex);
+ mStopCodec = 1;
+ AMediaCodec_stop(mCodec);
+ }
+ }
+
+ if (nativeWindow) {
+ ANativeWindow_release(nativeWindow);
+ }
+}
+
+void NdkAsyncCodecFuzzer::invokeAsyncCodeConfigAPI() {
+ mIOThreadPool->start();
+
+ while (mFdp.remaining_bytes() > 0) {
+ mIsEncoder = mFdp.ConsumeBool();
+ mCodec = createCodec(mIsEncoder, mFdp.ConsumeBool() /* isCodecForClient */);
+ if (mCodec) {
+ invokekAsyncCodecAPIs(mIsEncoder);
+ AMediaCodec_delete(mCodec);
+ }
+ }
+ mIOThreadPool->stop();
+}
+
+void NdkAsyncCodecFuzzer::invokeCodecCryptoInfoAPI() {
+ while (mFdp.remaining_bytes() > 0) {
+ AMediaCodecCryptoInfo* cryptoInfo = getAMediaCodecCryptoInfo();
+ int32_t ndkCryptoInfoAPI =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxCryptoInfoAPIs);
+ switch (ndkCryptoInfoAPI) {
+ case 0: {
+ size_t sizes[kMaxCryptoKey];
+ AMediaCodecCryptoInfo_getEncryptedBytes(cryptoInfo, sizes);
+ break;
+ }
+ case 1: {
+ size_t sizes[kMaxCryptoKey];
+ AMediaCodecCryptoInfo_getClearBytes(cryptoInfo, sizes);
+ break;
+ }
+ case 2: {
+ uint8_t bytes[kMaxCryptoKey];
+ AMediaCodecCryptoInfo_getIV(cryptoInfo, bytes);
+ break;
+ }
+ case 3:
+ default: {
+ uint8_t bytes[kMaxCryptoKey];
+ AMediaCodecCryptoInfo_getKey(cryptoInfo, bytes);
+ break;
+ }
+ }
+ AMediaCodecCryptoInfo_delete(cryptoInfo);
+ }
+}
+
+void NdkAsyncCodecFuzzer::process() {
+ if (mFdp.ConsumeBool()) {
+ invokeCodecCryptoInfoAPI();
+ } else {
+ invokeAsyncCodeConfigAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ NdkAsyncCodecFuzzer ndkAsyncCodecFuzzer(data, size);
+ ndkAsyncCodecFuzzer.process();
+ return 0;
+}
diff --git a/media/ndk/fuzzer/ndk_crypto_fuzzer.cpp b/media/ndk/fuzzer/ndk_crypto_fuzzer.cpp
index 2b22f0f..a759ae7 100644
--- a/media/ndk/fuzzer/ndk_crypto_fuzzer.cpp
+++ b/media/ndk/fuzzer/ndk_crypto_fuzzer.cpp
@@ -20,10 +20,12 @@
constexpr size_t kMaxString = 256;
constexpr size_t kMinBytes = 0;
constexpr size_t kMaxBytes = 1000;
+constexpr size_t kMaxRuns = 100;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
AMediaUUID uuid = {};
+ size_t apiCount = 0;
int32_t maxLen = fdp.ConsumeIntegralInRange<size_t>(kMinBytes, (size_t)sizeof(AMediaUUID));
for (size_t idx = 0; idx < maxLen; ++idx) {
uuid[idx] = fdp.ConsumeIntegral<uint8_t>();
@@ -31,7 +33,14 @@
std::vector<uint8_t> initData =
fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
AMediaCrypto* crypto = AMediaCrypto_new(uuid, initData.data(), initData.size());
- while (fdp.remaining_bytes()) {
+ /*
+ * The AMediaCrypto_isCryptoSchemeSupported API doesn't consume any input bytes,
+ * so when PickValueInArray() selects it repeatedly, only one byte is consumed by 'fdp'.
+ * As a result, on larger inputs, AMediaCrypto_isCryptoSchemeSupported can run a large
+ * number of times, potentially causing a timeout crash.
+ * Therefore, to prevent this issue, while loop is limited to kMaxRuns.
+ */
+ while (fdp.remaining_bytes() && ++apiCount <= kMaxRuns) {
auto invokeNdkCryptoFuzzer = fdp.PickValueInArray<const std::function<void()>>({
[&]() {
AMediaCrypto_requiresSecureDecoderComponent(
diff --git a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
index c19ea13..23e2eaf 100644
--- a/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
+++ b/media/ndk/fuzzer/ndk_mediaformat_fuzzer.cpp
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <media/NdkMediaFormat.h>
+#include <media/stagefright/foundation/AMessage.h>
#include <sys/mman.h>
#include <unistd.h>
#include <utils/Log.h>
@@ -176,11 +177,13 @@
constexpr size_t kMaxBytes = 1000;
constexpr size_t kMinChoice = 0;
constexpr size_t kMaxChoice = 9;
+const size_t kMaxIteration = android::AMessage::maxAllowedEntries();
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
AMediaFormat* mediaFormat = AMediaFormat_new();
- while (fdp.remaining_bytes()) {
+ std::vector<std::string> nameCollection;
+ while (fdp.remaining_bytes() && nameCollection.size() < kMaxIteration) {
const char* name = nullptr;
std::string nameString;
if (fdp.ConsumeBool()) {
@@ -190,6 +193,11 @@
: fdp.ConsumeRandomLengthString(
fdp.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
name = nameString.c_str();
+ std::vector<std::string>::iterator it =
+ find(nameCollection.begin(), nameCollection.end(), name);
+ if (it == nameCollection.end()) {
+ nameCollection.push_back(name);
+ }
}
switch (fdp.ConsumeIntegralInRange<int32_t>(kMinChoice, kMaxChoice)) {
case 0: {
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index b6dcaae..48a0a82 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -540,9 +540,11 @@
*
* @return AMEDIA_OK if the method call succeeds.
* AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
- * AMEDIA_ERROR_UNKNOWN if some other error is encountered.
+ * AMEDIA_ERROR_UNKNOWN if some other error is encountered or
+ * the device no longer has android.hidl.token service to
+ * satisfy the request because it is deprecated.
*/
-media_status_t AImageReader_getWindowNativeHandle(
+[[deprecated]] media_status_t AImageReader_getWindowNativeHandle(
AImageReader *reader, /* out */native_handle_t **handle);
#endif
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 7abb0b6..07dac5e 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -179,3 +179,8 @@
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
+
+cc_library_headers {
+ name: "mediautils_headers",
+ export_include_dirs: ["include", "."],
+}
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
index 0689083..3fdc6eb 100644
--- a/media/utils/tests/Android.bp
+++ b/media/utils/tests/Android.bp
@@ -200,7 +200,10 @@
name: "timerthread_tests",
defaults: ["libmediautils_tests_defaults"],
-
+ // TODO(b/270180838)
+ test_options: {
+ unit_test: false,
+ },
srcs: [
"TimerThread-test.cpp",
],
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 17e6d15..7663250 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -138,30 +138,8 @@
],
}
-cc_library_shared {
- name: "libaudioflinger",
-
- defaults: [
- "latest_android_media_audio_common_types_cpp_shared",
- "latest_android_hardware_audio_core_sounddose_ndk_shared",
- "audioflinger_flags_defaults",
- ],
-
- srcs: [
- "AudioFlinger.cpp",
- "DeviceEffectManager.cpp",
- "Effects.cpp",
- "MelReporter.cpp",
- "PatchCommandThread.cpp",
- "PatchPanel.cpp",
- "Threads.cpp",
- "Tracks.cpp",
- ],
-
- include_dirs: [
- "frameworks/av/services/audiopolicy",
- "frameworks/av/services/medialog",
- ],
+cc_defaults {
+ name: "libaudioflinger_dependencies",
shared_libs: [
"audioflinger-aidl-cpp",
@@ -177,7 +155,6 @@
"libaudiofoundation",
"libaudiohal",
"libaudioprocessing",
- "libaudiospdif",
"libaudioutils",
"libcutils",
"libutils",
@@ -186,7 +163,6 @@
"libbinder_ndk",
"libaudioclient",
"libaudiomanager",
- "libmedialogservice",
"libmediametrics",
"libmediautils",
"libnbaio",
@@ -202,6 +178,40 @@
],
static_libs: [
+ "libmedialogservice",
+ "libaudiospdif",
+ ],
+}
+
+
+cc_library {
+ name: "libaudioflinger",
+
+ defaults: [
+ "libaudioflinger_dependencies",
+ "latest_android_media_audio_common_types_cpp_shared",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
+ "audioflinger_flags_defaults",
+ ],
+
+ srcs: [
+ "AudioFlinger.cpp",
+ "Client.cpp",
+ "DeviceEffectManager.cpp",
+ "Effects.cpp",
+ "MelReporter.cpp",
+ "PatchCommandThread.cpp",
+ "PatchPanel.cpp",
+ "Threads.cpp",
+ "Tracks.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/services/audiopolicy",
+ "frameworks/av/services/medialog",
+ ],
+
+ static_libs: [
"libcpustats",
"libpermission",
],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 262f6f4..1e59bf8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -15,7 +15,6 @@
** limitations under the License.
*/
-
#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
@@ -23,71 +22,44 @@
#define AUDIO_ARRAYS_STATIC_CHECK 1
#include "Configuration.h"
-#include <dirent.h>
-#include <math.h>
-#include <signal.h>
-#include <string>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <thread>
-
-#include <android-base/stringprintf.h>
-#include <android/media/IAudioPolicyService.h>
-#include <android/os/IExternalVibratorService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-#include <binder/Parcel.h>
-#include <media/audiohal/AudioHalVersionInfo.h>
-#include <media/audiohal/DeviceHalInterface.h>
-#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <media/AudioParameter.h>
-#include <media/MediaMetricsItem.h>
-#include <media/TypeConverter.h>
-#include <mediautils/TimeCheck.h>
-#include <memunreachable/memunreachable.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
-
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <system/audio.h>
-#include <audiomanager/IAudioManager.h>
-
#include "AudioFlinger.h"
#include "EffectConfiguration.h"
+
+//#define BUFLOG_NDEBUG 0
+#include <afutils/BufLog.h>
+#include <afutils/DumpTryLock.h>
+#include <afutils/Permission.h>
#include <afutils/PropertyUtils.h>
-
-#include <media/AudioResamplerPublic.h>
-
-#include <system/audio_effects/effect_visualizer.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_hapticgenerator.h>
-#include <system/audio_effects/effect_spatializer.h>
-
-#include <audio_utils/primitives.h>
-
-#include <powermanager/PowerManager.h>
-
-#include <media/IMediaLogService.h>
+#include <afutils/TypedLogger.h>
+#include <android-base/stringprintf.h>
+#include <android/media/IAudioPolicyService.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <cutils/properties.h>
#include <media/AidlConversion.h>
+#include <media/AudioParameter.h>
#include <media/AudioValidator.h>
-#include <media/nbaio/Pipe.h>
-#include <media/nbaio/PipeReader.h>
+#include <media/IMediaLogService.h>
+#include <media/MediaMetricsItem.h>
+#include <media/TypeConverter.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/MemoryLeakTrackUtil.h>
#include <mediautils/MethodStatistics.h>
#include <mediautils/ServiceUtilities.h>
#include <mediautils/TimeCheck.h>
-#include <private/android_filesystem_config.h>
+#include <memunreachable/memunreachable.h>
+// required for effect matching
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+#include <utils/Log.h>
-//#define BUFLOG_NDEBUG 0
-#include <afutils/BufLog.h>
-#include <afutils/TypedLogger.h>
+// not needed with the includes above, added to prevent transitive include dependency.
+#include <chrono>
+#include <thread>
// ----------------------------------------------------------------------------
@@ -124,10 +96,6 @@
static constexpr char kAudioServiceName[] = "audio";
-nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
-
-uint32_t AudioFlinger::mScreenState;
-
// In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off
// we define a minimum time during which a global effect is considered enabled.
static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
@@ -148,21 +116,6 @@
}
}
-// Keep a strong reference to external vibrator service
-static sp<os::IExternalVibratorService> sExternalVibratorService;
-
-static sp<os::IExternalVibratorService> getExternalVibratorService() {
- if (sExternalVibratorService == 0) {
- sp<IBinder> binder = defaultServiceManager()->getService(
- String16("external_vibrator_service"));
- if (binder != 0) {
- sExternalVibratorService =
- interface_cast<os::IExternalVibratorService>(binder);
- }
- }
- return sExternalVibratorService;
-}
-
// Creates association between Binder code to name for IAudioFlinger.
#define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \
BINDER_METHOD_ENTRY(createTrack) \
@@ -269,41 +222,6 @@
}
};
-// TODO b/182392769: use attribution source util
-/* static */
-AttributionSourceState AudioFlinger::checkAttributionSourcePackage(
- const AttributionSourceState& attributionSource) {
- Vector<String16> packages;
- PermissionController{}.getPackagesForUid(attributionSource.uid, packages);
-
- AttributionSourceState checkedAttributionSource = attributionSource;
- if (!attributionSource.packageName.has_value()
- || attributionSource.packageName.value().size() == 0) {
- if (!packages.isEmpty()) {
- checkedAttributionSource.packageName =
- std::move(legacy2aidl_String16_string(packages[0]).value());
- }
- } else {
- String16 opPackageLegacy = VALUE_OR_FATAL(
- aidl2legacy_string_view_String16(attributionSource.packageName.value_or("")));
- if (std::find_if(packages.begin(), packages.end(),
- [&opPackageLegacy](const auto& package) {
- return opPackageLegacy == package; }) == packages.end()) {
- ALOGW("The package name(%s) provided does not correspond to the uid %d",
- attributionSource.packageName.value_or("").c_str(), attributionSource.uid);
- }
- }
- return checkedAttributionSource;
-}
-
-// ----------------------------------------------------------------------------
-
-std::string formatToString(audio_format_t format) {
- std::string result;
- FormatConverter::toString(format, result);
- return result;
-}
-
// ----------------------------------------------------------------------------
void AudioFlinger::instantiate() {
@@ -328,10 +246,7 @@
mTotalMemory(0),
mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
mGlobalEffectEnableTime(0),
- mPatchPanel(this),
mPatchCommandThread(sp<PatchCommandThread>::make()),
- mDeviceEffectManager(sp<DeviceEffectManager>::make(*this)),
- mMelReporter(sp<MelReporter>::make(*this)),
mSystemReady(false),
mBluetoothLatencyModesEnabled(true)
{
@@ -388,24 +303,11 @@
{
Mutex::Autolock _l(mLock);
- /* TODO: move all this work into an Init() function */
- char val_str[PROPERTY_VALUE_MAX] = { 0 };
- if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
- uint32_t int_val;
- if (1 == sscanf(val_str, "%u", &int_val)) {
- mStandbyTimeInNsecs = milliseconds(int_val);
- ALOGI("Using %u mSec as standby time.", int_val);
- } else {
- mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
- ALOGI("Using default %u mSec as standby time.",
- (uint32_t)(mStandbyTimeInNsecs / 1000000));
- }
- }
-
mMode = AUDIO_MODE_NORMAL;
gAudioFlinger = this; // we are already refcounted, store into atomic pointer.
-
+ mDeviceEffectManager = sp<DeviceEffectManager>::make(
+ sp<IAfDeviceEffectManagerCallback>::fromExisting(this)),
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
@@ -413,6 +315,9 @@
mAAudioBurstsPerBuffer = getAAudioMixerBurstCountFromSystemProperty();
mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
}
+
+ mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this));
+ mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this));
}
status_t AudioFlinger::setAudioHalPids(const std::vector<pid_t>& pids) {
@@ -433,9 +338,9 @@
for (const auto& [trackId, secondaryOutputs] : trackSecondaryOutputs) {
size_t i = 0;
for (; i < mPlaybackThreads.size(); ++i) {
- PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
- Mutex::Autolock _tl(thread->mLock);
- sp<PlaybackThread::Track> track = thread->getTrackById_l(trackId);
+ IAfPlaybackThread* thread = mPlaybackThreads.valueAt(i).get();
+ Mutex::Autolock _tl(thread->mutex());
+ sp<IAfTrack> track = thread->getTrackById_l(trackId);
if (track != nullptr) {
ALOGD("%s trackId: %u", __func__, trackId);
updateSecondaryOutputsForTrack_l(track.get(), thread, secondaryOutputs);
@@ -476,12 +381,12 @@
return NO_ERROR;
}
-int32_t AudioFlinger::getAAudioMixerBurstCount() {
+int32_t AudioFlinger::getAAudioMixerBurstCount() const {
Mutex::Autolock _l(mLock);
return mAAudioBurstsPerBuffer;
}
-int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() {
+int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() const {
Mutex::Autolock _l(mLock);
return mAAudioHwBurstMinMicros;
}
@@ -527,7 +432,7 @@
}
// getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
-std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() {
+std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const {
if (mAudioVibratorInfos.empty()) {
return {};
}
@@ -580,7 +485,7 @@
sp<MmapStreamInterface>& interface,
audio_port_handle_t *handle)
{
- // TODO: Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
+ // TODO(b/292281786): Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
// This allows moving oboeservice (AAudio) to a separate process in the future.
sp<AudioFlinger> af = AudioFlinger::gAudioFlinger.load(); // either nullptr or singleton AF.
status_t ret = NO_INIT;
@@ -638,7 +543,7 @@
__func__, callingUid, callingPid, clientPid);
adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
}
- adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
adjAttributionSource);
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
@@ -678,9 +583,9 @@
// at this stage, a MmapThread was created when openOutput() or openInput() was called by
// audio policy manager and we can retrieve it
- sp<MmapThread> thread = mMmapThreads.valueFor(io);
+ const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
if (thread != 0) {
- interface = new MmapThreadHandle(thread);
+ interface = IAfMmapThread::createMmapStreamInterfaceAdapter(thread);
thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceId, portId);
*handle = portId;
*sessionId = actualSessionId;
@@ -701,34 +606,6 @@
return ret;
}
-/* static */
-os::HapticScale AudioFlinger::onExternalVibrationStart(
- const sp<os::ExternalVibration>& externalVibration) {
- sp<os::IExternalVibratorService> evs = getExternalVibratorService();
- if (evs != nullptr) {
- int32_t ret;
- binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
- if (status.isOk()) {
- ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
- return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
- }
- }
- ALOGD("%s, start external vibration with intensity as MUTE due to %s",
- __func__,
- evs == nullptr ? "external vibration service not found"
- : "error when querying intensity");
- return os::HapticScale::MUTE;
-}
-
-/* static */
-void AudioFlinger::onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
- sp<os::IExternalVibratorService> evs = getExternalVibratorService();
- if (evs != 0) {
- ALOGD("%s, stopping external vibration", __func__);
- evs->onExternalVibrationStop(*externalVibration);
- }
-}
-
status_t AudioFlinger::addEffectToHal(
const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
AutoMutex lock(mHardwareLock);
@@ -829,10 +706,7 @@
String8 result;
hardware_call_state hardwareStatus = mHardwareStatus;
- snprintf(buffer, SIZE, "Hardware status: %d\n"
- "Standby Time mSec: %u\n",
- hardwareStatus,
- (uint32_t)(mStandbyTimeInNsecs / 1000000));
+ snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
result.append(buffer);
write(fd, result.string(), result.size());
@@ -857,12 +731,6 @@
write(fd, result.string(), result.size());
}
-bool AudioFlinger::dumpTryLock(Mutex& mutex)
-{
- status_t err = mutex.timedLock(kDumpLockTimeoutNs);
- return err == NO_ERROR;
-}
-
status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
NO_THREAD_SAFETY_ANALYSIS // conditional try lock
{
@@ -870,7 +738,7 @@
dumpPermissionDenial(fd, args);
} else {
// get state of hardware lock
- bool hardwareLocked = dumpTryLock(mHardwareLock);
+ const bool hardwareLocked = afutils::dumpTryLock(mHardwareLock);
if (!hardwareLocked) {
String8 result(kHardwareLockedString);
write(fd, result.string(), result.size());
@@ -878,7 +746,7 @@
mHardwareLock.unlock();
}
- const bool locked = dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
@@ -886,7 +754,7 @@
write(fd, result.string(), result.size());
}
- bool clientLocked = dumpTryLock(mClientLock);
+ const bool clientLocked = afutils::dumpTryLock(mClientLock);
if (!clientLocked) {
String8 result(kClientLockedString);
write(fd, result.string(), result.size());
@@ -934,7 +802,7 @@
dev->dump(fd, args);
}
- mPatchPanel.dump(fd);
+ mPatchPanel->dump(fd);
mDeviceEffectManager->dump(fd);
@@ -1036,7 +904,7 @@
// (for which promote() is always != 0), otherwise create a new entry and Client.
sp<Client> client = mClients.valueFor(pid).promote();
if (client == 0) {
- client = new Client(this, pid);
+ client = sp<Client>::make(sp<IAfClientCallback>::fromExisting(this), pid);
mClients.add(pid, client);
}
@@ -1107,7 +975,7 @@
CreateTrackInput input = VALUE_OR_RETURN_STATUS(CreateTrackInput::fromAidl(_input));
CreateTrackOutput output;
- sp<PlaybackThread::Track> track;
+ sp<IAfTrack> track;
sp<Client> client;
status_t lStatus;
audio_stream_type_t streamType;
@@ -1144,7 +1012,7 @@
clientPid = callingPid;
adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
}
- adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
adjAttributionSource);
audio_session_t sessionId = input.sessionId;
@@ -1191,7 +1059,7 @@
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output.outputId);
+ IAfPlaybackThread* thread = checkPlaybackThread_l(output.outputId);
if (thread == NULL) {
ALOGE("no playback thread found for output handle %d", output.outputId);
lStatus = BAD_VALUE;
@@ -1200,14 +1068,14 @@
client = registerPid(clientPid);
- PlaybackThread *effectThread = NULL;
+ IAfPlaybackThread* effectThread = nullptr;
// check if an effect chain with the same session ID is present on another
// output thread and move it here.
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
+ sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
if (mPlaybackThreads.keyAt(i) != output.outputId) {
uint32_t sessions = t->hasAudioSession(sessionId);
- if (sessions & ThreadBase::EFFECT_SESSION) {
+ if (sessions & IAfThreadBase::EFFECT_SESSION) {
effectThread = t.get();
break;
}
@@ -1242,7 +1110,7 @@
if (lStatus == NO_ERROR) {
// no risk of deadlock because AudioFlinger::mLock is held
- Mutex::Autolock _dl(thread->mLock);
+ Mutex::Autolock _dl(thread->mutex());
// Connect secondary outputs. Failure on a secondary output must not imped the primary
// Any secondary output setup failure will lead to a desync between the AP and AF until
// the track is destroyed.
@@ -1250,7 +1118,7 @@
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
if (effectThread != nullptr) {
- Mutex::Autolock _sl(effectThread->mLock);
+ Mutex::Autolock _sl(effectThread->mutex());
if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
effectThreadId = thread->id();
effectIds = thread->getEffectIds_l(sessionId);
@@ -1297,7 +1165,7 @@
AudioSystem::moveEffectsToIo(effectIds, effectThreadId);
}
- output.audioTrack = PlaybackThread::Track::createIAudioTrackAdapter(track);
+ output.audioTrack = IAfTrack::createIAudioTrackAdapter(track);
_output = VALUE_OR_FATAL(output.toAidl());
Exit:
@@ -1310,7 +1178,7 @@
uint32_t AudioFlinger::sampleRate(audio_io_handle_t ioHandle) const
{
Mutex::Autolock _l(mLock);
- ThreadBase *thread = checkThread_l(ioHandle);
+ IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("sampleRate() unknown thread %d", ioHandle);
return 0;
@@ -1321,7 +1189,7 @@
audio_format_t AudioFlinger::format(audio_io_handle_t output) const
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
ALOGW("format() unknown thread %d", output);
return AUDIO_FORMAT_INVALID;
@@ -1332,7 +1200,7 @@
size_t AudioFlinger::frameCount(audio_io_handle_t ioHandle) const
{
Mutex::Autolock _l(mLock);
- ThreadBase *thread = checkThread_l(ioHandle);
+ IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("frameCount() unknown thread %d", ioHandle);
return 0;
@@ -1345,7 +1213,7 @@
size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
{
Mutex::Autolock _l(mLock);
- ThreadBase *thread = checkThread_l(ioHandle);
+ IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("frameCountHAL() unknown thread %d", ioHandle);
return 0;
@@ -1356,7 +1224,7 @@
uint32_t AudioFlinger::latency(audio_io_handle_t output) const
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
ALOGW("latency(): no playback thread found for output handle %d", output);
return 0;
@@ -1585,7 +1453,7 @@
// assigned to HALs which do not have master mute support will apply master mute
// during the mix operation. Threads with HALs which do support master mute
// will simply ignore the setting.
- Vector<VolumeInterface *> volumeInterfaces = getAllVolumeInterfaces_l();
+ std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
for (size_t i = 0; i < volumeInterfaces.size(); i++) {
volumeInterfaces[i]->setMasterMute(muted);
}
@@ -1661,7 +1529,7 @@
"AUDIO_STREAM_PATCH must have full scale volume");
AutoMutex lock(mLock);
- VolumeInterface *volumeInterface = getVolumeInterface_l(output);
+ sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
if (volumeInterface == NULL) {
return BAD_VALUE;
}
@@ -1676,7 +1544,7 @@
return BAD_VALUE;
}
AutoMutex lock(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == nullptr) {
return BAD_VALUE;
}
@@ -1684,12 +1552,12 @@
}
status_t AudioFlinger::getSupportedLatencyModes(audio_io_handle_t output,
- std::vector<audio_latency_mode_t>* modes) {
+ std::vector<audio_latency_mode_t>* modes) const {
if (output == AUDIO_IO_HANDLE_NONE) {
return BAD_VALUE;
}
AutoMutex lock(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == nullptr) {
return BAD_VALUE;
}
@@ -1711,7 +1579,7 @@
return status;
}
-status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool *enabled) {
+status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool* enabled) const {
if (enabled == nullptr) {
return BAD_VALUE;
}
@@ -1719,7 +1587,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) {
+status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) const {
if (support == nullptr) {
return BAD_VALUE;
}
@@ -1735,7 +1603,7 @@
}
status_t AudioFlinger::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
- sp<media::ISoundDose>* soundDose) {
+ sp<media::ISoundDose>* soundDose) const {
if (soundDose == nullptr) {
return BAD_VALUE;
}
@@ -1764,7 +1632,7 @@
AutoMutex lock(mLock);
mStreamTypes[stream].mute = muted;
- Vector<VolumeInterface *> volumeInterfaces = getAllVolumeInterfaces_l();
+ std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
for (size_t i = 0; i < volumeInterfaces.size(); i++) {
volumeInterfaces[i]->setStreamMute(stream, muted);
}
@@ -1783,7 +1651,7 @@
}
AutoMutex lock(mLock);
- VolumeInterface *volumeInterface = getVolumeInterface_l(output);
+ sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
if (volumeInterface == NULL) {
return 0.0f;
}
@@ -1820,14 +1688,15 @@
// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mLock held
void AudioFlinger::forwardParametersToDownstreamPatches_l(
audio_io_handle_t upStream, const String8& keyValuePairs,
- const std::function<bool(const sp<PlaybackThread>&)>& useThread)
+ const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread)
{
- std::vector<PatchPanel::SoftwarePatch> swPatches;
- if (mPatchPanel.getDownstreamSoftwarePatches(upStream, &swPatches) != OK) return;
+ std::vector<SoftwarePatch> swPatches;
+ if (mPatchPanel->getDownstreamSoftwarePatches(upStream, &swPatches) != OK) return;
ALOGV_IF(!swPatches.empty(), "%s found %zu downstream patches for stream ID %d",
__func__, swPatches.size(), upStream);
for (const auto& swPatch : swPatches) {
- sp<PlaybackThread> downStream = checkPlaybackThread_l(swPatch.getPlaybackThreadHandle());
+ const sp<IAfPlaybackThread> downStream =
+ checkPlaybackThread_l(swPatch.getPlaybackThreadHandle());
if (downStream != NULL && (useThread == nullptr || useThread(downStream))) {
downStream->setParameters(keyValuePairs);
}
@@ -1839,7 +1708,7 @@
const std::set<audio_io_handle_t>& streams)
{
for (const audio_io_handle_t stream : streams) {
- PlaybackThread *playbackThread = checkPlaybackThread_l(stream);
+ IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(stream);
if (playbackThread == nullptr || !playbackThread->isMsdDevice()) {
continue;
}
@@ -1953,8 +1822,8 @@
String8 screenState;
if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
bool isOff = (screenState == AudioParameter::valueOff);
- if (isOff != (AudioFlinger::mScreenState & 1)) {
- AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
+ if (isOff != (mScreenState & 1)) {
+ mScreenState = ((mScreenState & ~1) + 2) | isOff;
}
}
return final_result;
@@ -1962,7 +1831,7 @@
// hold a strong ref on thread in case closeOutput() or closeInput() is called
// and the thread is exited once the lock is released
- sp<ThreadBase> thread;
+ sp<IAfThreadBase> thread;
{
Mutex::Autolock _l(mLock);
thread = checkPlaybackThread_l(ioHandle);
@@ -2011,11 +1880,11 @@
return out_s8;
}
- ThreadBase *thread = (ThreadBase *)checkPlaybackThread_l(ioHandle);
+ IAfThreadBase* thread = checkPlaybackThread_l(ioHandle);
if (thread == NULL) {
- thread = (ThreadBase *)checkRecordThread_l(ioHandle);
+ thread = checkRecordThread_l(ioHandle);
if (thread == NULL) {
- thread = (ThreadBase *)checkMmapThread_l(ioHandle);
+ thread = checkMmapThread_l(ioHandle);
if (thread == NULL) {
return String8("");
}
@@ -2111,7 +1980,7 @@
{
Mutex::Autolock _l(mLock);
- RecordThread *recordThread = checkRecordThread_l(ioHandle);
+ IAfRecordThread* const recordThread = checkRecordThread_l(ioHandle);
if (recordThread != NULL) {
return recordThread->getInputFramesLost();
}
@@ -2151,7 +2020,7 @@
{
Mutex::Autolock _l(mLock);
- PlaybackThread *playbackThread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(output);
if (playbackThread != NULL) {
return playbackThread->getRenderPosition(halFrames, dspFrames);
}
@@ -2225,6 +2094,9 @@
}
if (removed) {
removedEffects = purgeStaleEffects_l();
+ std::vector< sp<IAfEffectModule> > removedOrphanEffects = purgeOrphanEffectChains_l();
+ removedEffects.insert(removedEffects.end(), removedOrphanEffects.begin(),
+ removedOrphanEffects.end());
}
}
for (auto& effect : removedEffects) {
@@ -2274,10 +2146,10 @@
}
// getEffectThread_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::ThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
+sp<IAfThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
int effectId)
{
- sp<ThreadBase> thread;
+ sp<IAfThreadBase> thread;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, effectId) != 0) {
@@ -2306,27 +2178,6 @@
return thread;
}
-
-
-// ----------------------------------------------------------------------------
-
-Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
- : RefBase(),
- mAudioFlinger(audioFlinger),
- mPid(pid),
- mClientAllocator(AllocatorFactory::getClientAllocator()) {}
-
-// Client destructor must be called with AudioFlinger::mClientLock held
-Client::~Client()
-{
- mAudioFlinger->removeClient_l(mPid);
-}
-
-AllocatorFactory::ClientAllocator& Client::allocator()
-{
- return mClientAllocator;
-}
-
// ----------------------------------------------------------------------------
AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
@@ -2391,7 +2242,7 @@
CreateRecordInput input = VALUE_OR_RETURN_STATUS(CreateRecordInput::fromAidl(_input));
CreateRecordOutput output;
- sp<RecordThread::RecordTrack> recordTrack;
+ sp<IAfRecordTrack> recordTrack;
sp<Client> client;
status_t lStatus;
audio_session_t sessionId = input.sessionId;
@@ -2423,7 +2274,7 @@
__func__, callingUid, callingPid, currentPid);
adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
}
- adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
adjAttributionSource);
// we don't yet support anything other than linear PCM
if (!audio_is_valid_format(input.config.format) || !audio_is_linear_pcm(input.config.format)) {
@@ -2480,7 +2331,7 @@
{
Mutex::Autolock _l(mLock);
- RecordThread *thread = checkRecordThread_l(output.inputId);
+ IAfRecordThread* const thread = checkRecordThread_l(output.inputId);
if (thread == NULL) {
ALOGW("createRecord() checkRecordThread_l failed, input handle %d", output.inputId);
lStatus = FAILED_TRANSACTION;
@@ -2536,7 +2387,7 @@
// session and move it to this thread.
sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
if (chain != 0) {
- Mutex::Autolock _l2(thread->mLock);
+ Mutex::Autolock _l2(thread->mutex());
thread->addEffectChain_l(chain);
}
break;
@@ -2549,7 +2400,7 @@
output.buffers = recordTrack->getBuffers();
output.portId = portId;
- output.audioRecord = RecordThread::RecordTrack::createIAudioRecordAdapter(recordTrack);
+ output.audioRecord = IAfRecordTrack::createIAudioRecordAdapter(recordTrack);
_output = VALUE_OR_FATAL(output.toAidl());
Exit:
@@ -2735,17 +2586,17 @@
// ----------------------------------------------------------------------------
-uint32_t AudioFlinger::getPrimaryOutputSamplingRate()
+uint32_t AudioFlinger::getPrimaryOutputSamplingRate() const
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = fastPlaybackThread_l();
+ IAfPlaybackThread* const thread = fastPlaybackThread_l();
return thread != NULL ? thread->sampleRate() : 0;
}
-size_t AudioFlinger::getPrimaryOutputFrameCount()
+size_t AudioFlinger::getPrimaryOutputFrameCount() const
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = fastPlaybackThread_l();
+ IAfPlaybackThread* const thread = fastPlaybackThread_l();
return thread != NULL ? thread->frameCountHAL() : 0;
}
@@ -2870,15 +2721,15 @@
mHwAvSyncIds.add(sessionId, value);
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i);
+ const sp<IAfPlaybackThread> thread = mPlaybackThreads.valueAt(i);
uint32_t sessions = thread->hasAudioSession(sessionId);
- if (sessions & ThreadBase::TRACK_SESSION) {
+ if (sessions & IAfThreadBase::TRACK_SESSION) {
AudioParameter param = AudioParameter();
param.addInt(String8(AudioParameter::keyStreamHwAvSync), value);
String8 keyValuePairs = param.toString();
thread->setParameters(keyValuePairs);
forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
- [](const sp<PlaybackThread>& thread) { return thread->usesHwAvSync(); });
+ [](const sp<IAfPlaybackThread>& thread) { return thread->usesHwAvSync(); });
break;
}
}
@@ -2897,15 +2748,15 @@
}
mSystemReady = true;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- ThreadBase *thread = (ThreadBase *)mPlaybackThreads.valueAt(i).get();
+ IAfThreadBase* const thread = mPlaybackThreads.valueAt(i).get();
thread->systemReady();
}
for (size_t i = 0; i < mRecordThreads.size(); i++) {
- ThreadBase *thread = (ThreadBase *)mRecordThreads.valueAt(i).get();
+ IAfThreadBase* const thread = mRecordThreads.valueAt(i).get();
thread->systemReady();
}
for (size_t i = 0; i < mMmapThreads.size(); i++) {
- ThreadBase *thread = (ThreadBase *)mMmapThreads.valueAt(i).get();
+ IAfThreadBase* const thread = mMmapThreads.valueAt(i).get();
thread->systemReady();
}
@@ -2930,7 +2781,7 @@
return mAudioManager.load();
}
-status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones)
+status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const
{
AutoMutex lock(mHardwareLock);
status_t status = INVALID_OPERATION;
@@ -2957,7 +2808,8 @@
}
// setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId)
+void AudioFlinger::setAudioHwSyncForSession_l(
+ IAfPlaybackThread* const thread, audio_session_t sessionId)
{
ssize_t index = mHwAvSyncIds.indexOfKey(sessionId);
if (index >= 0) {
@@ -2968,7 +2820,7 @@
String8 keyValuePairs = param.toString();
thread->setParameters(keyValuePairs);
forwardParametersToDownstreamPatches_l(thread->id(), keyValuePairs,
- [](const sp<PlaybackThread>& thread) { return thread->usesHwAvSync(); });
+ [](const sp<IAfPlaybackThread>& thread) { return thread->usesHwAvSync(); });
}
}
@@ -2976,7 +2828,7 @@
// ----------------------------------------------------------------------------
-sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
+sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *halConfig,
audio_config_base_t *mixerConfig,
@@ -2999,28 +2851,6 @@
}
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
-
- // FOR TESTING ONLY:
- // This if statement allows overriding the audio policy settings
- // and forcing a specific format or channel mask to the HAL/Sink device for testing.
- if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) {
- // Check only for Normal Mixing mode
- if (kEnableExtendedPrecision) {
- // Specify format (uncomment one below to choose)
- //halConfig->format = AUDIO_FORMAT_PCM_FLOAT;
- //halConfig->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- //halConfig->format = AUDIO_FORMAT_PCM_32_BIT;
- //halConfig->format = AUDIO_FORMAT_PCM_8_24_BIT;
- // ALOGV("openOutput_l() upgrading format to %#08x", halConfig->format);
- }
- if (kEnableExtendedChannels) {
- // Specify channel mask (uncomment one below to choose)
- //halConfig->channel_mask = audio_channel_out_mask_from_count(4); // for USB 4ch
- //halConfig->channel_mask = audio_channel_mask_from_representation_and_bits(
- // AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1); // another 4ch example
- }
- }
-
AudioStreamOut *outputStream = NULL;
status_t status = outHwDev->openOutputStream(
&outputStream,
@@ -3034,43 +2864,45 @@
if (status == NO_ERROR) {
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
- sp<MmapPlaybackThread> thread =
- new MmapPlaybackThread(this, *output, outHwDev, outputStream, mSystemReady);
+ const sp<IAfMmapPlaybackThread> thread = IAfMmapPlaybackThread::create(
+ this, *output, outHwDev, outputStream, mSystemReady);
mMmapThreads.add(*output, thread);
ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
*output, thread.get());
return thread;
} else {
- sp<PlaybackThread> thread;
+ sp<IAfPlaybackThread> thread;
if (flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
- thread = sp<BitPerfectThread>::make(this, outputStream, *output, mSystemReady);
+ thread = IAfPlaybackThread::createBitPerfectThread(
+ this, outputStream, *output, mSystemReady);
ALOGV("%s() created bit-perfect output: ID %d thread %p",
__func__, *output, thread.get());
} else if (flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
- thread = new SpatializerThread(this, outputStream, *output,
+ thread = IAfPlaybackThread::createSpatializerThread(this, outputStream, *output,
mSystemReady, mixerConfig);
ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
*output, thread.get());
} else if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- thread = new OffloadThread(this, outputStream, *output,
+ thread = IAfPlaybackThread::createOffloadThread(this, outputStream, *output,
mSystemReady, halConfig->offload_info);
ALOGV("openOutput_l() created offload output: ID %d thread %p",
*output, thread.get());
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
- || !isValidPcmSinkFormat(halConfig->format)
- || !isValidPcmSinkChannelMask(halConfig->channel_mask)) {
- thread = new DirectOutputThread(this, outputStream, *output,
+ || !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
+ || !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
+ thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
mSystemReady, halConfig->offload_info);
ALOGV("openOutput_l() created direct output: ID %d thread %p",
*output, thread.get());
} else {
- thread = new MixerThread(this, outputStream, *output, mSystemReady);
+ thread = IAfPlaybackThread::createMixerThread(
+ this, outputStream, *output, mSystemReady);
ALOGV("openOutput_l() created mixer output: ID %d thread %p",
*output, thread.get());
}
mPlaybackThreads.add(*output, thread);
struct audio_patch patch;
- mPatchPanel.notifyStreamOpened(outHwDev, *output, &patch);
+ mPatchPanel->notifyStreamOpened(outHwDev, *output, &patch);
if (thread->isMsdDevice()) {
thread->setDownStreamPatch(&patch);
}
@@ -3116,12 +2948,12 @@
Mutex::Autolock _l(mLock);
- sp<ThreadBase> thread = openOutput_l(module, &output, &halConfig,
+ const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
&mixerConfig, deviceType, address, flags);
if (thread != 0) {
uint32_t latencyMs = 0;
if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ const auto playbackThread = thread->asIAfPlaybackThread();
latencyMs = playbackThread->latency();
// notify client processes of the new output creation
@@ -3139,8 +2971,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
}
} else {
- MmapThread *mmapThread = (MmapThread *)thread.get();
- mmapThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
+ thread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
}
response->output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
response->config = VALUE_OR_RETURN_STATUS(
@@ -3158,8 +2989,8 @@
audio_io_handle_t output2)
{
Mutex::Autolock _l(mLock);
- MixerThread *thread1 = checkMixerThread_l(output1);
- MixerThread *thread2 = checkMixerThread_l(output2);
+ IAfPlaybackThread* const thread1 = checkMixerThread_l(output1);
+ IAfPlaybackThread* const thread2 = checkMixerThread_l(output2);
if (thread1 == NULL || thread2 == NULL) {
ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
@@ -3168,7 +2999,8 @@
}
audio_io_handle_t id = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
- DuplicatingThread *thread = new DuplicatingThread(this, thread1, id, mSystemReady);
+ const sp<IAfDuplicatingThread> thread = IAfDuplicatingThread::create(
+ this, thread1, id, mSystemReady);
thread->addOutputTrack(thread2);
mPlaybackThreads.add(id, thread);
// notify client processes of the new output creation
@@ -3185,8 +3017,8 @@
{
// keep strong reference on the playback thread so that
// it is not destroyed while exit() is executed
- sp<PlaybackThread> playbackThread;
- sp<MmapPlaybackThread> mmapThread;
+ sp<IAfPlaybackThread> playbackThread;
+ sp<IAfMmapPlaybackThread> mmapThread;
{
Mutex::Autolock _l(mLock);
playbackThread = checkPlaybackThread_l(output);
@@ -3195,12 +3027,12 @@
dumpToThreadLog_l(playbackThread);
- if (playbackThread->type() == ThreadBase::MIXER) {
+ if (playbackThread->type() == IAfThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
- DuplicatingThread *dupThread =
- (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
- dupThread->removeOutputTrack((MixerThread *)playbackThread.get());
+ IAfDuplicatingThread* const dupThread =
+ mPlaybackThreads.valueAt(i)->asIAfDuplicatingThread().get();
+ dupThread->removeOutputTrack(playbackThread.get());
}
}
}
@@ -3209,11 +3041,12 @@
mPlaybackThreads.removeItem(output);
// save all effects to the default thread
if (mPlaybackThreads.size()) {
- PlaybackThread *dstThread = checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
+ IAfPlaybackThread* const dstThread =
+ checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
if (dstThread != NULL) {
// audioflinger lock is held so order of thread lock acquisition doesn't matter
- Mutex::Autolock _dl(dstThread->mLock);
- Mutex::Autolock _sl(playbackThread->mLock);
+ Mutex::Autolock _dl(dstThread->mutex());
+ Mutex::Autolock _sl(playbackThread->mutex());
Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
for (size_t i = 0; i < effectChains.size(); i ++) {
moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
@@ -3222,7 +3055,8 @@
}
}
} else {
- mmapThread = (MmapPlaybackThread *)checkMmapThread_l(output);
+ const sp<IAfMmapThread> mt = checkMmapThread_l(output);
+ mmapThread = mt ? mt->asIAfMmapPlaybackThread().get() : nullptr;
if (mmapThread == 0) {
return BAD_VALUE;
}
@@ -3231,10 +3065,10 @@
ALOGD("closing mmapThread %p", mmapThread.get());
}
ioConfigChanged(AUDIO_OUTPUT_CLOSED, sp<AudioIoDescriptor>::make(output));
- mPatchPanel.notifyStreamClosed(output);
+ mPatchPanel->notifyStreamClosed(output);
}
// The thread entity (active unit of execution) is no longer running here,
- // but the ThreadBase container still exists.
+ // but the IAfThreadBase container still exists.
if (playbackThread != 0) {
playbackThread->exit();
@@ -3252,7 +3086,7 @@
return NO_ERROR;
}
-void AudioFlinger::closeOutputFinish(const sp<PlaybackThread>& thread)
+void AudioFlinger::closeOutputFinish(const sp<IAfPlaybackThread>& thread)
{
AudioStreamOut *out = thread->clearOutput();
ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
@@ -3260,9 +3094,9 @@
delete out;
}
-void AudioFlinger::closeThreadInternal_l(const sp<PlaybackThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<IAfPlaybackThread>& thread)
{
- mPlaybackThreads.removeItem(thread->mId);
+ mPlaybackThreads.removeItem(thread->id());
thread->exit();
closeOutputFinish(thread);
}
@@ -3270,7 +3104,7 @@
status_t AudioFlinger::suspendOutput(audio_io_handle_t output)
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
return BAD_VALUE;
@@ -3285,7 +3119,7 @@
status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
{
Mutex::Autolock _l(mLock);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
return BAD_VALUE;
@@ -3314,7 +3148,7 @@
audio_config_t config = VALUE_OR_RETURN_STATUS(
aidl2legacy_AudioConfig_audio_config_t(request.config, true /*isInput*/));
- sp<ThreadBase> thread = openInput_l(
+ const sp<IAfThreadBase> thread = openInput_l(
VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_module_handle_t(request.module)),
&input,
&config,
@@ -3338,7 +3172,7 @@
return NO_INIT;
}
-sp<AudioFlinger::ThreadBase> AudioFlinger::openInput_l(audio_module_handle_t module,
+sp<IAfThreadBase> AudioFlinger::openInput_l(audio_module_handle_t module,
audio_io_handle_t *input,
audio_config_t *config,
audio_devices_t devices,
@@ -3404,17 +3238,18 @@
if (status == NO_ERROR && inStream != 0) {
AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream, flags);
if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
- sp<MmapCaptureThread> thread =
- new MmapCaptureThread(this, *input, inHwDev, inputStream, mSystemReady);
+ const sp<IAfMmapCaptureThread> thread =
+ IAfMmapCaptureThread::create(this, *input, inHwDev, inputStream, mSystemReady);
mMmapThreads.add(*input, thread);
ALOGV("openInput_l() created mmap capture thread: ID %d thread %p", *input,
thread.get());
return thread;
} else {
// Start record thread
- // RecordThread requires both input and output device indication to forward to audio
- // pre processing modules
- sp<RecordThread> thread = new RecordThread(this, inputStream, *input, mSystemReady);
+ // IAfRecordThread requires both input and output device indication
+ // to forward to audio pre processing modules
+ const sp<IAfRecordThread> thread =
+ IAfRecordThread::create(this, inputStream, *input, mSystemReady);
mRecordThreads.add(*input, thread);
ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
return thread;
@@ -3434,8 +3269,8 @@
{
// keep strong reference on the record thread so that
// it is not destroyed while exit() is executed
- sp<RecordThread> recordThread;
- sp<MmapCaptureThread> mmapThread;
+ sp<IAfRecordThread> recordThread;
+ sp<IAfMmapCaptureThread> mmapThread;
{
Mutex::Autolock _l(mLock);
recordThread = checkRecordThread_l(input);
@@ -3450,8 +3285,8 @@
// new capture on the same session
sp<IAfEffectChain> chain;
{
- Mutex::Autolock _sl(recordThread->mLock);
- Vector< sp<IAfEffectChain> > effectChains = recordThread->getEffectChains_l();
+ Mutex::Autolock _sl(recordThread->mutex());
+ const Vector<sp<IAfEffectChain>> effectChains = recordThread->getEffectChains_l();
// Note: maximum one chain per record thread
if (effectChains.size() != 0) {
chain = effectChains[0];
@@ -3463,12 +3298,12 @@
// creation of its replacement
size_t i;
for (i = 0; i < mRecordThreads.size(); i++) {
- sp<RecordThread> t = mRecordThreads.valueAt(i);
+ const sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
if (t == recordThread) {
continue;
}
if (t->hasAudioSession(chain->sessionId()) != 0) {
- Mutex::Autolock _l2(t->mLock);
+ Mutex::Autolock _l2(t->mutex());
ALOGV("closeInput() found thread %d for effect session %d",
t->id(), chain->sessionId());
t->addEffectChain_l(chain);
@@ -3482,7 +3317,8 @@
}
mRecordThreads.removeItem(input);
} else {
- mmapThread = (MmapCaptureThread *)checkMmapThread_l(input);
+ const sp<IAfMmapThread> mt = checkMmapThread_l(input);
+ mmapThread = mt ? mt->asIAfMmapCaptureThread().get() : nullptr;
if (mmapThread == 0) {
return BAD_VALUE;
}
@@ -3505,7 +3341,7 @@
return NO_ERROR;
}
-void AudioFlinger::closeInputFinish(const sp<RecordThread>& thread)
+void AudioFlinger::closeInputFinish(const sp<IAfRecordThread>& thread)
{
thread->exit();
AudioStreamIn *in = thread->clearInput();
@@ -3514,9 +3350,9 @@
delete in;
}
-void AudioFlinger::closeThreadInternal_l(const sp<RecordThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<IAfRecordThread>& thread)
{
- mRecordThreads.removeItem(thread->mId);
+ mRecordThreads.removeItem(thread->id());
closeInputFinish(thread);
}
@@ -3526,7 +3362,7 @@
std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
thread->invalidateTracks(portIdSet);
if (portIdSet.empty()) {
return NO_ERROR;
@@ -3646,14 +3482,15 @@
ALOGV("purging stale effects");
- Vector< sp<IAfEffectChain> > chains;
+ Vector<sp<IAfEffectChain>> chains;
std::vector< sp<IAfEffectModule> > removedEffects;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
- Mutex::Autolock _l(t->mLock);
- for (size_t j = 0; j < t->mEffectChains.size(); j++) {
- sp<IAfEffectChain> ec = t->mEffectChains[j];
+ sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
+ Mutex::Autolock _l(t->mutex());
+ const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
+ for (size_t j = 0; j < threadChains.size(); j++) {
+ sp<IAfEffectChain> ec = threadChains[j];
if (!audio_is_global_session(ec->sessionId())) {
chains.push(ec);
}
@@ -3661,19 +3498,21 @@
}
for (size_t i = 0; i < mRecordThreads.size(); i++) {
- sp<RecordThread> t = mRecordThreads.valueAt(i);
- Mutex::Autolock _l(t->mLock);
- for (size_t j = 0; j < t->mEffectChains.size(); j++) {
- sp<IAfEffectChain> ec = t->mEffectChains[j];
+ sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
+ Mutex::Autolock _l(t->mutex());
+ const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
+ for (size_t j = 0; j < threadChains.size(); j++) {
+ sp<IAfEffectChain> ec = threadChains[j];
chains.push(ec);
}
}
for (size_t i = 0; i < mMmapThreads.size(); i++) {
- sp<MmapThread> t = mMmapThreads.valueAt(i);
- Mutex::Autolock _l(t->mLock);
- for (size_t j = 0; j < t->mEffectChains.size(); j++) {
- sp<IAfEffectChain> ec = t->mEffectChains[j];
+ const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
+ Mutex::Autolock _l(t->mutex());
+ const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
+ for (size_t j = 0; j < threadChains.size(); j++) {
+ sp<IAfEffectChain> ec = threadChains[j];
chains.push(ec);
}
}
@@ -3682,7 +3521,7 @@
// clang-tidy suggests const ref
sp<IAfEffectChain> ec = chains[i]; // NOLINT(performance-unnecessary-copy-initialization)
int sessionid = ec->sessionId();
- sp<ThreadBase> t = sp<ThreadBase>::cast(ec->thread().promote()); // TODO(b/288339104)
+ const auto t = ec->thread().promote();
if (t == 0) {
continue;
}
@@ -3698,7 +3537,7 @@
}
}
if (!found) {
- Mutex::Autolock _l(t->mLock);
+ Mutex::Autolock _l(t->mutex());
// remove all effects from the chain
while (ec->numberOfEffects()) {
sp<IAfEffectModule> effect = ec->getEffectModule(0);
@@ -3714,8 +3553,44 @@
return removedEffects;
}
+std::vector< sp<IAfEffectModule> > AudioFlinger::purgeOrphanEffectChains_l()
+{
+ ALOGV("purging stale effects from orphan chains");
+ std::vector< sp<IAfEffectModule> > removedEffects;
+ for (size_t index = 0; index < mOrphanEffectChains.size(); index++) {
+ sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index);
+ audio_session_t session = mOrphanEffectChains.keyAt(index);
+ if (session == AUDIO_SESSION_OUTPUT_MIX || session == AUDIO_SESSION_DEVICE
+ || session == AUDIO_SESSION_OUTPUT_STAGE) {
+ continue;
+ }
+ size_t numSessionRefs = mAudioSessionRefs.size();
+ bool found = false;
+ for (size_t k = 0; k < numSessionRefs; k++) {
+ AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
+ if (ref->mSessionid == session) {
+ ALOGV(" session %d still exists for %d with %d refs", session, ref->mPid,
+ ref->mCnt);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ for (size_t i = 0; i < chain->numberOfEffects(); i++) {
+ sp<IAfEffectModule> effect = chain->getEffectModule(i);
+ removedEffects.push_back(effect);
+ }
+ }
+ }
+ for (auto& effect : removedEffects) {
+ effect->unPin();
+ updateOrphanEffectChains_l(effect);
+ }
+ return removedEffects;
+}
+
// dumpToThreadLog_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::dumpToThreadLog_l(const sp<ThreadBase> &thread)
+void AudioFlinger::dumpToThreadLog_l(const sp<IAfThreadBase> &thread)
{
constexpr int THREAD_DUMP_TIMEOUT_MS = 2;
audio_utils::FdToString fdToString("- ", THREAD_DUMP_TIMEOUT_MS);
@@ -3727,9 +3602,9 @@
}
// checkThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::ThreadBase *AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
+IAfThreadBase* AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
{
- ThreadBase *thread = checkMmapThread_l(ioHandle);
+ IAfThreadBase* thread = checkMmapThread_l(ioHandle);
if (thread == 0) {
switch (audio_unique_id_get_use(ioHandle)) {
case AUDIO_UNIQUE_ID_USE_OUTPUT:
@@ -3746,13 +3621,13 @@
}
// checkOutputThread_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::ThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
+sp<IAfThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
{
if (audio_unique_id_get_use(ioHandle) != AUDIO_UNIQUE_ID_USE_OUTPUT) {
return nullptr;
}
- sp<AudioFlinger::ThreadBase> thread = mPlaybackThreads.valueFor(ioHandle);
+ sp<IAfThreadBase> thread = mPlaybackThreads.valueFor(ioHandle);
if (thread == nullptr) {
thread = mMmapThreads.valueFor(ioHandle);
}
@@ -3760,41 +3635,41 @@
}
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
+IAfPlaybackThread* AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
{
return mPlaybackThreads.valueFor(output).get();
}
// checkMixerThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
+IAfPlaybackThread* AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
{
- PlaybackThread *thread = checkPlaybackThread_l(output);
- return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
+ IAfPlaybackThread * const thread = checkPlaybackThread_l(output);
+ return thread != nullptr && thread->type() != IAfThreadBase::DIRECT ? thread : nullptr;
}
// checkRecordThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
+IAfRecordThread* AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
{
return mRecordThreads.valueFor(input).get();
}
// checkMmapThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::MmapThread *AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
+IAfMmapThread* AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
{
return mMmapThreads.valueFor(io).get();
}
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::VolumeInterface *AudioFlinger::getVolumeInterface_l(audio_io_handle_t output) const
+sp<VolumeInterface> AudioFlinger::getVolumeInterface_l(audio_io_handle_t output) const
{
- VolumeInterface *volumeInterface = mPlaybackThreads.valueFor(output).get();
+ sp<VolumeInterface> volumeInterface = mPlaybackThreads.valueFor(output).get();
if (volumeInterface == nullptr) {
- MmapThread *mmapThread = mMmapThreads.valueFor(output).get();
+ IAfMmapThread* const mmapThread = mMmapThreads.valueFor(output).get();
if (mmapThread != nullptr) {
if (mmapThread->isOutput()) {
- MmapPlaybackThread *mmapPlaybackThread =
- static_cast<MmapPlaybackThread *>(mmapThread);
+ IAfMmapPlaybackThread* const mmapPlaybackThread =
+ mmapThread->asIAfMmapPlaybackThread().get();
volumeInterface = mmapPlaybackThread;
}
}
@@ -3802,17 +3677,17 @@
return volumeInterface;
}
-Vector <AudioFlinger::VolumeInterface *> AudioFlinger::getAllVolumeInterfaces_l() const
+std::vector<sp<VolumeInterface>> AudioFlinger::getAllVolumeInterfaces_l() const
{
- Vector <VolumeInterface *> volumeInterfaces;
+ std::vector<sp<VolumeInterface>> volumeInterfaces;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- volumeInterfaces.add(mPlaybackThreads.valueAt(i).get());
+ volumeInterfaces.push_back(mPlaybackThreads.valueAt(i).get());
}
for (size_t i = 0; i < mMmapThreads.size(); i++) {
if (mMmapThreads.valueAt(i)->isOutput()) {
- MmapPlaybackThread *mmapPlaybackThread =
- static_cast<MmapPlaybackThread *>(mMmapThreads.valueAt(i).get());
- volumeInterfaces.add(mmapPlaybackThread);
+ IAfMmapPlaybackThread* const mmapPlaybackThread =
+ mMmapThreads.valueAt(i)->asIAfMmapPlaybackThread().get();
+ volumeInterfaces.push_back(mmapPlaybackThread);
}
}
return volumeInterfaces;
@@ -3839,14 +3714,14 @@
// TODO Use a floor after wraparound. This may need a mutex.
}
-AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
+IAfPlaybackThread* AudioFlinger::primaryPlaybackThread_l() const
{
AutoMutex lock(mHardwareLock);
if (mPrimaryHardwareDev == nullptr) {
return nullptr;
}
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
if(thread->isDuplicating()) {
continue;
}
@@ -3860,7 +3735,7 @@
DeviceTypeSet AudioFlinger::primaryOutputDevice_l() const
{
- PlaybackThread *thread = primaryPlaybackThread_l();
+ IAfPlaybackThread* const thread = primaryPlaybackThread_l();
if (thread == NULL) {
return {};
@@ -3869,12 +3744,12 @@
return thread->outDeviceTypes();
}
-AudioFlinger::PlaybackThread *AudioFlinger::fastPlaybackThread_l() const
+IAfPlaybackThread* AudioFlinger::fastPlaybackThread_l() const
{
size_t minFrameCount = 0;
- PlaybackThread *minThread = NULL;
+ IAfPlaybackThread* minThread = nullptr;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
if (!thread->isDuplicating()) {
size_t frameCount = thread->frameCountHAL();
if (frameCount != 0 && (minFrameCount == 0 || frameCount < minFrameCount ||
@@ -3888,9 +3763,9 @@
return minThread;
}
-AudioFlinger::ThreadBase *AudioFlinger::hapticPlaybackThread_l() const {
+IAfThreadBase* AudioFlinger::hapticPlaybackThread_l() const {
for (size_t i = 0; i < mPlaybackThreads.size(); ++i) {
- PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get();
if (thread->hapticChannelMask() != AUDIO_CHANNEL_NONE) {
return thread;
}
@@ -3899,12 +3774,12 @@
}
void AudioFlinger::updateSecondaryOutputsForTrack_l(
- PlaybackThread::Track* track,
- PlaybackThread* thread,
+ IAfTrack* track,
+ IAfPlaybackThread* thread,
const std::vector<audio_io_handle_t> &secondaryOutputs) const {
TeePatches teePatches;
for (audio_io_handle_t secondaryOutput : secondaryOutputs) {
- PlaybackThread *secondaryThread = checkPlaybackThread_l(secondaryOutput);
+ IAfPlaybackThread* const secondaryThread = checkPlaybackThread_l(secondaryOutput);
if (secondaryThread == nullptr) {
ALOGE("no playback thread found for secondary output %d", thread->id());
continue;
@@ -3930,10 +3805,10 @@
// The frameCount should also not be smaller than the secondary thread min frame
// count
size_t minFrameCount = AudioSystem::calculateMinFrameCount(
- [&] { Mutex::Autolock _l(secondaryThread->mLock);
+ [&] { Mutex::Autolock _l(secondaryThread->mutex());
return secondaryThread->latency_l(); }(),
- secondaryThread->mNormalFrameCount,
- secondaryThread->mSampleRate,
+ secondaryThread->frameCount(), // normal frame count
+ secondaryThread->sampleRate(),
track->sampleRate(),
track->getSpeed());
frameCount = std::max(frameCount, minFrameCount);
@@ -3946,7 +3821,7 @@
// use an index mask here to create the PatchRecord.
inChannelMask = audio_channel_mask_out_to_in_index_mask(track->channelMask());
}
- sp patchRecord = new RecordThread::PatchRecord(nullptr /* thread */,
+ sp<IAfPatchRecord> patchRecord = IAfPatchRecord::create(nullptr /* thread */,
track->sampleRate(),
inChannelMask,
track->format(),
@@ -3966,7 +3841,7 @@
// for now, we exclude fast tracks by removing the Fast flag.
const audio_output_flags_t outputFlags =
(audio_output_flags_t)(track->getOutputFlags() & ~AUDIO_OUTPUT_FLAG_FAST);
- sp patchTrack = new PlaybackThread::PatchTrack(secondaryThread,
+ sp<IAfPatchTrack> patchTrack = IAfPatchTrack::create(secondaryThread,
track->streamType(),
track->sampleRate(),
track->channelMask(),
@@ -3996,7 +3871,7 @@
audio_session_t triggerSession,
audio_session_t listenerSession,
const audioflinger::SyncEventCallback& callBack,
- const wp<RefBase>& cookie)
+ const wp<IAfTrackBase>& cookie)
{
Mutex::Autolock _l(mLock);
@@ -4157,7 +4032,7 @@
adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
currentPid = callingPid;
}
- adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(adjAttributionSource);
+ adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
adjAttributionSource.pid, effectClient.get(), priority, sessionId, io,
@@ -4182,7 +4057,7 @@
lStatus = BAD_VALUE;
goto Exit;
}
- PlaybackThread *thread = checkPlaybackThread_l(io);
+ IAfPlaybackThread* const thread = checkPlaybackThread_l(io);
if (thread == nullptr) {
ALOGE("%s: invalid output %d specified for AUDIO_SESSION_OUTPUT_STAGE", __func__, io);
lStatus = BAD_VALUE;
@@ -4279,7 +4154,7 @@
sp<Client> client = registerPid(currentPid);
ALOGV("%s device type %#x address %s", __func__, device.mType, device.getAddress());
handle = mDeviceEffectManager->createEffect_l(
- &descOut, device, client, effectClient, mPatchPanel.patches_l(),
+ &descOut, device, client, effectClient, mPatchPanel->patches_l(),
&enabledOut, &lStatus, probe, request.notifyFramesProcessed);
if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
// remove local strong reference to Client with mClientLock held
@@ -4351,7 +4226,7 @@
}
const uint32_t sessionType =
mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
- if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
+ if ((sessionType & IAfThreadBase::EFFECT_SESSION) != 0) {
ALOGE("%s: effect %s io %d denied because session %d effect exists on io %d",
__func__, descOut.name, (int) io, (int) sessionId, (int) checkIo);
android_errorWriteLog(0x534e4554, "123237974");
@@ -4360,7 +4235,7 @@
}
}
}
- ThreadBase *thread = checkRecordThread_l(io);
+ IAfThreadBase* thread = checkRecordThread_l(io);
if (thread == NULL) {
thread = checkPlaybackThread_l(io);
if (thread == NULL) {
@@ -4376,7 +4251,7 @@
// session and used it instead of creating a new one.
sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
if (chain != 0) {
- Mutex::Autolock _l2(thread->mLock);
+ Mutex::Autolock _l2(thread->mutex());
thread->addEffectChain_l(chain);
}
}
@@ -4385,9 +4260,9 @@
// create effect on selected output thread
bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
- ThreadBase *oriThread = nullptr;
+ IAfThreadBase* oriThread = nullptr;
if (hapticPlaybackRequired && thread->hapticChannelMask() == AUDIO_CHANNEL_NONE) {
- ThreadBase *hapticThread = hapticPlaybackThread_l();
+ IAfThreadBase* const hapticThread = hapticPlaybackThread_l();
if (hapticThread == nullptr) {
ALOGE("%s haptic thread not found while it is required", __func__);
lStatus = INVALID_OPERATION;
@@ -4447,29 +4322,47 @@
return lStatus;
}
-status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput)
+status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t srcIo,
+ audio_io_handle_t dstIo)
+NO_THREAD_SAFETY_ANALYSIS
{
- ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
- sessionId, srcOutput, dstOutput);
+ ALOGV("%s() session %d, srcIo %d, dstIo %d", __func__, sessionId, srcIo, dstIo);
Mutex::Autolock _l(mLock);
- if (srcOutput == dstOutput) {
- ALOGW("moveEffects() same dst and src outputs %d", dstOutput);
+ if (srcIo == dstIo) {
+ ALOGW("%s() same dst and src outputs %d", __func__, dstIo);
return NO_ERROR;
}
- PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
- if (srcThread == NULL) {
- ALOGW("moveEffects() bad srcOutput %d", srcOutput);
+ IAfRecordThread* const srcRecordThread = checkRecordThread_l(srcIo);
+ IAfRecordThread* const dstRecordThread = checkRecordThread_l(dstIo);
+ if (srcRecordThread != nullptr || dstRecordThread != nullptr) {
+ if (srcRecordThread != nullptr) {
+ srcRecordThread->mutex().lock();
+ }
+ if (dstRecordThread != nullptr) {
+ dstRecordThread->mutex().lock();
+ }
+ status_t ret = moveEffectChain_l(sessionId, srcRecordThread, dstRecordThread);
+ if (srcRecordThread != nullptr) {
+ srcRecordThread->mutex().unlock();
+ }
+ if (dstRecordThread != nullptr) {
+ dstRecordThread->mutex().unlock();
+ }
+ return ret;
+ }
+ IAfPlaybackThread* const srcThread = checkPlaybackThread_l(srcIo);
+ if (srcThread == nullptr) {
+ ALOGW("%s() bad srcIo %d", __func__, srcIo);
return BAD_VALUE;
}
- PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
- if (dstThread == NULL) {
- ALOGW("moveEffects() bad dstOutput %d", dstOutput);
+ IAfPlaybackThread* const dstThread = checkPlaybackThread_l(dstIo);
+ if (dstThread == nullptr) {
+ ALOGW("%s() bad dstIo %d", __func__, dstIo);
return BAD_VALUE;
}
- Mutex::Autolock _dl(dstThread->mLock);
- Mutex::Autolock _sl(srcThread->mLock);
+ Mutex::Autolock _dl(dstThread->mutex());
+ Mutex::Autolock _sl(srcThread->mutex());
return moveEffectChain_l(sessionId, srcThread, dstThread);
}
@@ -4480,11 +4373,11 @@
{
Mutex::Autolock _l(mLock);
- sp<ThreadBase> thread = getEffectThread_l(sessionId, effectId);
+ sp<IAfThreadBase> thread = getEffectThread_l(sessionId, effectId);
if (thread == nullptr) {
return;
}
- Mutex::Autolock _sl(thread->mLock);
+ Mutex::Autolock _sl(thread->mutex());
sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId);
thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
}
@@ -4492,8 +4385,7 @@
// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
- AudioFlinger::PlaybackThread *srcThread,
- AudioFlinger::PlaybackThread *dstThread)
+ IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks
{
ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
@@ -4602,18 +4494,60 @@
return status;
}
+
+// moveEffectChain_l must be called with both srcThread (if not null) and dstThread (if not null)
+// mLocks held
+status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
+ IAfRecordThread* srcThread, IAfRecordThread* dstThread)
+NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks
+{
+ sp<IAfEffectChain> chain = nullptr;
+ if (srcThread != 0) {
+ const Vector<sp<IAfEffectChain>> effectChains = srcThread->getEffectChains_l();
+ for (size_t i = 0; i < effectChains.size(); i ++) {
+ if (effectChains[i]->sessionId() == sessionId) {
+ chain = effectChains[i];
+ break;
+ }
+ }
+ ALOGV_IF(effectChains.size() == 0, "%s: no effect chain on io=%d", __func__,
+ srcThread->id());
+ if (chain == nullptr) {
+ ALOGE("%s wrong session id %d", __func__, sessionId);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: removing effect chain for session=%d io=%d", __func__, sessionId,
+ srcThread->id());
+ srcThread->removeEffectChain_l(chain);
+ } else {
+ chain = getOrphanEffectChain_l(sessionId);
+ if (chain == nullptr) {
+ ALOGE("%s: no orphan effect chain found for session=%d", __func__, sessionId);
+ return BAD_VALUE;
+ }
+ }
+ if (dstThread != 0) {
+ ALOGV("%s: adding effect chain for session=%d on io=%d", __func__, sessionId,
+ dstThread->id());
+ dstThread->addEffectChain_l(chain);
+ return NO_ERROR;
+ }
+ ALOGV("%s: parking to orphan effect chain for session=%d", __func__, sessionId);
+ putOrphanEffectChain_l(chain);
+ return NO_ERROR;
+}
+
status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
- const sp<PlaybackThread>& dstThread,
- sp<PlaybackThread> *srcThread)
+ const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread)
{
status_t status = NO_ERROR;
Mutex::Autolock _l(mLock);
- sp<PlaybackThread> thread =
- static_cast<PlaybackThread *>(getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId).get());
+ const sp<IAfThreadBase> threadBase = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
+ const sp<IAfPlaybackThread> thread = threadBase ? threadBase->asIAfPlaybackThread() : nullptr;
if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
- Mutex::Autolock _dl(dstThread->mLock);
- Mutex::Autolock _sl(thread->mLock);
+ Mutex::Autolock _dl(dstThread->mutex());
+ Mutex::Autolock _sl(thread->mutex());
sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
sp<IAfEffectChain> dstChain;
if (srcChain == 0) {
@@ -4652,7 +4586,7 @@
return status;
}
-bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l()
+bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const
NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l.
{
if (mGlobalEffectEnableTime != 0 &&
@@ -4677,8 +4611,8 @@
mGlobalEffectEnableTime = systemTime();
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
- if (t->mType == ThreadBase::OFFLOAD) {
+ const sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
+ if (t->type() == IAfThreadBase::OFFLOAD) {
t->invalidateTracks(AUDIO_STREAM_MUSIC);
}
}
@@ -4718,6 +4652,11 @@
bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
{
Mutex::Autolock _l(mLock);
+ return updateOrphanEffectChains_l(effect);
+}
+
+bool AudioFlinger::updateOrphanEffectChains_l(const sp<IAfEffectModule>& effect)
+{
audio_session_t session = effect->sessionId();
ssize_t index = mOrphanEffectChains.indexOfKey(session);
ALOGV("updateOrphanEffectChains session %d index %zd", session, index);
@@ -4732,6 +4671,55 @@
return false;
}
+// ----------------------------------------------------------------------------
+// from PatchPanel
+
+/* List connected audio ports and their attributes */
+status_t AudioFlinger::listAudioPorts(unsigned int* num_ports,
+ struct audio_port* ports) const
+{
+ Mutex::Autolock _l(mLock);
+ return mPatchPanel->listAudioPorts(num_ports, ports);
+}
+
+/* Get supported attributes for a given audio port */
+status_t AudioFlinger::getAudioPort(struct audio_port_v7* port) const {
+ const status_t status = AudioValidator::validateAudioPort(*port);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ Mutex::Autolock _l(mLock);
+ return mPatchPanel->getAudioPort(port);
+}
+
+/* Connect a patch between several source and sink ports */
+status_t AudioFlinger::createAudioPatch(
+ const struct audio_patch* patch, audio_patch_handle_t* handle)
+{
+ const status_t status = AudioValidator::validateAudioPatch(*patch);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ Mutex::Autolock _l(mLock);
+ return mPatchPanel->createAudioPatch(patch, handle);
+}
+
+/* Disconnect a patch */
+status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
+{
+ Mutex::Autolock _l(mLock);
+ return mPatchPanel->releaseAudioPatch(handle);
+}
+
+/* List connected audio ports and they attributes */
+status_t AudioFlinger::listAudioPatches(
+ unsigned int* num_patches, struct audio_patch* patches) const
+{
+ Mutex::Autolock _l(mLock);
+ return mPatchPanel->listAudioPatches(num_patches, patches);
+}
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 700eed4..9aefb6b 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -15,332 +15,355 @@
** limitations under the License.
*/
-#ifndef ANDROID_AUDIO_FLINGER_H
-#define ANDROID_AUDIO_FLINGER_H
+#pragma once
-#include "Configuration.h"
+// Classes and interfaces directly used.
+#include "Client.h"
+#include "DeviceEffectManager.h"
+#include "IAfEffect.h"
+#include "IAfPatchPanel.h"
+#include "IAfThread.h"
+#include "IAfTrack.h"
+#include "MelReporter.h"
+#include "PatchCommandThread.h"
+
+// External classes
+#include <audio_utils/FdToString.h>
+#include <audio_utils/SimpleLog.h>
+#include <media/IAudioFlinger.h>
+#include <media/MediaMetricsItem.h>
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/Synchronization.h>
+
+// not needed with the includes above, added to prevent transitive include dependency.
+#include <utils/KeyedVector.h>
+#include <utils/String16.h>
#include <atomic>
-#include <mutex>
-#include <chrono>
-#include <deque>
+#include <functional>
#include <map>
-#include <numeric>
#include <optional>
#include <set>
-#include <string>
-#include <vector>
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include <android/media/BnAudioTrack.h>
-#include <android/media/IAudioFlingerClient.h>
-#include <android/media/IAudioTrackCallback.h>
-#include <android/os/BnExternalVibrationController.h>
-#include <android/content/AttributionSourceState.h>
-
-
-#include <android-base/macros.h>
-#include <cutils/atomic.h>
-#include <cutils/compiler.h>
-
-#include <cutils/properties.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioSystem.h>
-#include <media/AudioTrack.h>
-#include <media/MmapStreamInterface.h>
-#include <media/MmapStreamCallback.h>
-
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/SortedVector.h>
-#include <utils/TypeHelpers.h>
-#include <utils/Vector.h>
-
-#include <binder/AppOpsManager.h>
-#include <binder/BinderService.h>
-#include <binder/IAppOpsCallback.h>
-#include <binder/MemoryDealer.h>
-
-#include <system/audio.h>
-#include <system/audio_policy.h>
-
-#include <media/audiohal/EffectBufferHalInterface.h>
-#include <media/audiohal/StreamHalInterface.h>
-#include <media/AudioBufferProvider.h>
-#include <media/AudioContainers.h>
-#include <media/AudioDeviceTypeAddr.h>
-#include <media/AudioMixer.h>
-#include <media/DeviceDescriptorBase.h>
-#include <media/ExtendedAudioBufferProvider.h>
-#include <media/VolumeShaper.h>
-#include <mediautils/BatteryNotifier.h>
-#include <mediautils/ServiceUtilities.h>
-#include <mediautils/SharedMemoryAllocator.h>
-#include <mediautils/Synchronization.h>
-#include <mediautils/ThreadSnapshot.h>
-
-#include <afutils/AllocatorFactory.h>
-#include <afutils/AudioWatchdog.h>
-#include <afutils/NBAIO_Tee.h>
-
-#include <audio_utils/clock.h>
-#include <audio_utils/FdToString.h>
-#include <audio_utils/LinearMap.h>
-#include <audio_utils/MelAggregator.h>
-#include <audio_utils/MelProcessor.h>
-#include <audio_utils/SimpleLog.h>
-#include <audio_utils/TimestampVerifier.h>
-
-#include <sounddose/SoundDoseManager.h>
-#include <timing/MonotonicFrameCounter.h>
-#include <timing/SyncEvent.h>
-#include <timing/SynchronizedRecordState.h>
-
-#include <datapath/AudioHwDevice.h>
-#include <datapath/AudioStreamOut.h>
-#include <datapath/SpdifStreamOut.h>
-#include <datapath/ThreadMetrics.h>
-#include <datapath/TrackMetrics.h>
-#include <fastpath/FastCapture.h>
-#include <fastpath/FastMixer.h>
-#include <media/nbaio/NBAIO.h>
-
-#include <android/os/IPowerManager.h>
-
-#include <media/nblog/NBLog.h>
-#include <private/media/AudioEffectShared.h>
-#include <private/media/AudioTrackShared.h>
-
-#include <vibrator/ExternalVibration.h>
-#include <vibrator/ExternalVibrationUtils.h>
-
-#include "android/media/BnAudioRecord.h"
-#include "android/media/BnEffect.h"
-
-#include "Client.h"
-
-// include AudioFlinger component interfaces
-#include "IAfEffect.h"
namespace android {
-class AudioMixer;
-class AudioBuffer;
-class AudioResampler;
-class DeviceHalInterface;
-class DevicesFactoryHalCallback;
-class DevicesFactoryHalInterface;
-class EffectsFactoryHalInterface;
-class FastMixer;
-class IAudioManager;
-class PassthruBufferProvider;
-class RecordBufferConverter;
-class ServerProxy;
-
-// ----------------------------------------------------------------------------
-
-static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
-
-#define INCLUDING_FROM_AUDIOFLINGER_H
-
-using android::content::AttributionSourceState;
-
-class AudioFlinger : public AudioFlingerServerAdapter::Delegate
+class AudioFlinger
+ : public AudioFlingerServerAdapter::Delegate // IAudioFlinger client interface
+ , public IAfClientCallback
+ , public IAfDeviceEffectManagerCallback
+ , public IAfMelReporterCallback
+ , public IAfPatchPanelCallback
+ , public IAfThreadCallback
{
friend class sp<AudioFlinger>;
- friend class Client; // removeClient_l();
public:
static void instantiate() ANDROID_API;
- static AttributionSourceState checkAttributionSourcePackage(
- const AttributionSourceState& attributionSource);
+private:
- status_t dump(int fd, const Vector<String16>& args) override;
+ // ---- begin IAudioFlinger interface
- // IAudioFlinger interface, in binder opcode order
+ status_t dump(int fd, const Vector<String16>& args) final;
+
status_t createTrack(const media::CreateTrackRequest& input,
- media::CreateTrackResponse& output) override;
+ media::CreateTrackResponse& output) final;
status_t createRecord(const media::CreateRecordRequest& input,
- media::CreateRecordResponse& output) override;
+ media::CreateRecordResponse& output) final;
- virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const;
- virtual audio_format_t format(audio_io_handle_t output) const;
- virtual size_t frameCount(audio_io_handle_t ioHandle) const;
- virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const;
- virtual uint32_t latency(audio_io_handle_t output) const;
+ uint32_t sampleRate(audio_io_handle_t ioHandle) const final;
+ audio_format_t format(audio_io_handle_t output) const final;
+ size_t frameCount(audio_io_handle_t ioHandle) const final;
+ size_t frameCountHAL(audio_io_handle_t ioHandle) const final;
+ uint32_t latency(audio_io_handle_t output) const final;
- virtual status_t setMasterVolume(float value);
- virtual status_t setMasterMute(bool muted);
-
- virtual float masterVolume() const;
- virtual bool masterMute() const;
+ status_t setMasterVolume(float value) final;
+ status_t setMasterMute(bool muted) final;
+ float masterVolume() const final;
+ bool masterMute() const final;
// Balance value must be within -1.f (left only) to 1.f (right only) inclusive.
- status_t setMasterBalance(float balance) override;
- status_t getMasterBalance(float *balance) const override;
+ status_t setMasterBalance(float balance) final;
+ status_t getMasterBalance(float* balance) const final;
- virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
- audio_io_handle_t output);
- virtual status_t setStreamMute(audio_stream_type_t stream, bool muted);
+ status_t setStreamVolume(audio_stream_type_t stream, float value,
+ audio_io_handle_t output) final;
+ status_t setStreamMute(audio_stream_type_t stream, bool muted) final;
- virtual float streamVolume(audio_stream_type_t stream,
- audio_io_handle_t output) const;
- virtual bool streamMute(audio_stream_type_t stream) const;
+ float streamVolume(audio_stream_type_t stream,
+ audio_io_handle_t output) const final;
+ bool streamMute(audio_stream_type_t stream) const final;
- virtual status_t setMode(audio_mode_t mode);
+ status_t setMode(audio_mode_t mode) final;
- virtual status_t setMicMute(bool state);
- virtual bool getMicMute() const;
+ status_t setMicMute(bool state) final;
+ bool getMicMute() const final;
- virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced);
+ void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
- virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
- virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const;
+ status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) final;
+ String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const final;
- virtual void registerClient(const sp<media::IAudioFlingerClient>& client);
+ void registerClient(const sp<media::IAudioFlingerClient>& client) final;
+ size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const final;
- virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
- audio_channel_mask_t channelMask) const;
+ status_t openOutput(const media::OpenOutputRequest& request,
+ media::OpenOutputResponse* response) final;
- virtual status_t openOutput(const media::OpenOutputRequest& request,
- media::OpenOutputResponse* response);
+ audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+ audio_io_handle_t output2) final;
- virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
- audio_io_handle_t output2);
+ status_t closeOutput(audio_io_handle_t output) final;
- virtual status_t closeOutput(audio_io_handle_t output);
+ status_t suspendOutput(audio_io_handle_t output) final;
- virtual status_t suspendOutput(audio_io_handle_t output);
+ status_t restoreOutput(audio_io_handle_t output) final;
- virtual status_t restoreOutput(audio_io_handle_t output);
+ status_t openInput(const media::OpenInputRequest& request,
+ media::OpenInputResponse* response) final;
- virtual status_t openInput(const media::OpenInputRequest& request,
- media::OpenInputResponse* response);
+ status_t closeInput(audio_io_handle_t input) final;
- virtual status_t closeInput(audio_io_handle_t input);
+ status_t setVoiceVolume(float volume) final;
- virtual status_t setVoiceVolume(float volume);
+ status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
+ audio_io_handle_t output) const final;
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
- audio_io_handle_t output) const;
-
- virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
+ uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const final;
// This is the binder API. For the internal API see nextUniqueId().
- virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
+ audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) final;
- void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override;
+ void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) final;
- virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid);
+ void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) final;
- virtual status_t queryNumberEffects(uint32_t *numEffects) const;
+ status_t queryNumberEffects(uint32_t* numEffects) const final;
- virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const;
+ status_t queryEffect(uint32_t index, effect_descriptor_t* descriptor) const final;
- virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
- const effect_uuid_t *pTypeUuid,
- uint32_t preferredTypeFlag,
- effect_descriptor_t *descriptor) const;
+ status_t getEffectDescriptor(const effect_uuid_t* pUuid,
+ const effect_uuid_t* pTypeUuid,
+ uint32_t preferredTypeFlag,
+ effect_descriptor_t* descriptor) const final;
- virtual status_t createEffect(const media::CreateEffectRequest& request,
- media::CreateEffectResponse* response);
+ status_t createEffect(const media::CreateEffectRequest& request,
+ media::CreateEffectResponse* response) final;
- virtual status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput);
+ status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
+ audio_io_handle_t dstOutput) final;
- void setEffectSuspended(int effectId,
- audio_session_t sessionId,
- bool suspended) override;
+ void setEffectSuspended(int effectId,
+ audio_session_t sessionId,
+ bool suspended) final;
- virtual audio_module_handle_t loadHwModule(const char *name);
+ audio_module_handle_t loadHwModule(const char* name) final;
- virtual uint32_t getPrimaryOutputSamplingRate();
- virtual size_t getPrimaryOutputFrameCount();
+ uint32_t getPrimaryOutputSamplingRate() const final;
+ size_t getPrimaryOutputFrameCount() const final;
- virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
-
- /* List available audio ports and their attributes */
- virtual status_t listAudioPorts(unsigned int *num_ports,
- struct audio_port *ports);
+ status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) final;
/* Get attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port_v7 *port);
+ status_t getAudioPort(struct audio_port_v7* port) const final;
/* Create an audio patch between several source and sink ports */
- virtual status_t createAudioPatch(const struct audio_patch *patch,
- audio_patch_handle_t *handle);
+ status_t createAudioPatch(const struct audio_patch *patch,
+ audio_patch_handle_t* handle) final;
/* Release an audio patch */
- virtual status_t releaseAudioPatch(audio_patch_handle_t handle);
+ status_t releaseAudioPatch(audio_patch_handle_t handle) final;
/* List existing audio patches */
- virtual status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches);
+ status_t listAudioPatches(unsigned int* num_patches,
+ struct audio_patch* patches) const final;
/* Set audio port configuration */
- virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+ status_t setAudioPortConfig(const struct audio_port_config* config) final;
/* Get the HW synchronization source used for an audio session */
- virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId);
+ audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) final;
/* Indicate JAVA services are ready (scheduling, power management ...) */
- virtual status_t systemReady();
- virtual status_t audioPolicyReady() { mAudioPolicyReady.store(true); return NO_ERROR; }
- bool isAudioPolicyReady() const { return mAudioPolicyReady.load(); }
+ status_t systemReady() final;
+ status_t audioPolicyReady() final { mAudioPolicyReady.store(true); return NO_ERROR; }
+ status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const final;
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones);
+ status_t setAudioHalPids(const std::vector<pid_t>& pids) final;
- virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
+ status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) final;
- virtual status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos);
+ status_t updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs) final;
- virtual status_t updateSecondaryOutputs(
- const TrackSecondaryOutputsMap& trackSecondaryOutputs);
-
- virtual status_t getMmapPolicyInfos(
+ status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
- std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos);
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final;
- virtual int32_t getAAudioMixerBurstCount();
+ int32_t getAAudioMixerBurstCount() const final;
- virtual int32_t getAAudioHardwareBurstMinUsec();
+ int32_t getAAudioHardwareBurstMinUsec() const final;
- virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
- media::DeviceConnectedState state);
+ status_t setDeviceConnectedState(const struct audio_port_v7* port,
+ media::DeviceConnectedState state) final;
- virtual status_t setSimulateDeviceConnections(bool enabled);
+ status_t setSimulateDeviceConnections(bool enabled) final;
- virtual status_t setRequestedLatencyMode(
- audio_io_handle_t output, audio_latency_mode_t mode);
+ status_t setRequestedLatencyMode(
+ audio_io_handle_t output, audio_latency_mode_t mode) final;
- virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
- std::vector<audio_latency_mode_t>* modes);
+ status_t getSupportedLatencyModes(audio_io_handle_t output,
+ std::vector<audio_latency_mode_t>* modes) const final;
- virtual status_t setBluetoothVariableLatencyEnabled(bool enabled);
+ status_t setBluetoothVariableLatencyEnabled(bool enabled) final;
- virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled);
+ status_t isBluetoothVariableLatencyEnabled(bool* enabled) const final;
- virtual status_t supportsBluetoothVariableLatency(bool* support);
+ status_t supportsBluetoothVariableLatency(bool* support) const final;
- virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
- sp<media::ISoundDose>* soundDose);
+ status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
+ sp<media::ISoundDose>* soundDose) const final;
- status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) final;
- virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* config);
+ status_t getAudioPolicyConfig(media::AudioPolicyConfig* config) final;
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
- const std::function<status_t()>& delegate) override;
+ const std::function<status_t()>& delegate) final;
- // end of IAudioFlinger interface
+ // ---- end of IAudioFlinger interface
- sp<NBLog::Writer> newWriter_l(size_t size, const char *name);
- void unregisterWriter(const sp<NBLog::Writer>& writer);
+ // ---- begin IAfClientCallback interface
+
+ Mutex& clientMutex() const final { return mClientLock; }
+ void removeClient_l(pid_t pid) final;
+ void removeNotificationClient(pid_t pid) final;
+ status_t moveAuxEffectToIo(
+ int effectId,
+ const sp<IAfPlaybackThread>& dstThread,
+ sp<IAfPlaybackThread>* srcThread) final;
+
+ // ---- end of IAfClientCallback interface
+
+ // ---- begin IAfDeviceEffectManagerCallback interface
+
+ // also used by IAfThreadCallback
+ bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); }
+ // below also used by IAfMelReporterCallback, IAfPatchPanelCallback
+ const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; }
+ status_t addEffectToHal(
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final;
+ status_t removeEffectFromHal(
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final;
+
+ // ---- end of IAfDeviceEffectManagerCallback interface
+
+ // ---- begin IAfMelReporterCallback interface
+
+ // below also used by IAfThreadCallback
+ Mutex& mutex() const final { return mLock; }
+ sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final REQUIRES(mLock);
+
+ // ---- end of IAfMelReporterCallback interface
+
+ // ---- begin IAfPatchPanelCallback interface
+
+ void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final;
+ void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final;
+ // return thread associated with primary hardware device, or NULL
+ IAfPlaybackThread* primaryPlaybackThread_l() const final;
+ IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final;
+ IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final;
+ IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final;
+ void lock() const final ACQUIRE(mLock) { mLock.lock(); }
+ void unlock() const final RELEASE(mLock) { mLock.unlock(); }
+ sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t* input,
+ audio_config_t* config,
+ audio_devices_t device,
+ const char* address,
+ audio_source_t source,
+ audio_input_flags_t flags,
+ audio_devices_t outputDevice,
+ const String8& outputDeviceAddress) final;
+ sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
+ audio_io_handle_t* output,
+ audio_config_t* halConfig,
+ audio_config_base_t* mixerConfig,
+ audio_devices_t deviceType,
+ const String8& address,
+ audio_output_flags_t flags) final;
+ const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+ getAudioHwDevs_l() const final { return mAudioHwDevs; }
+ void updateDownStreamPatches_l(const struct audio_patch* patch,
+ const std::set<audio_io_handle_t>& streams) final;
+ void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final;
+
+ // ---- end of IAfPatchPanelCallback interface
+
+ // ----- begin IAfThreadCallback interface
+
+ bool isNonOffloadableGlobalEffectEnabled_l() const final;
+ bool btNrecIsOff() const final { return mBtNrecIsOff.load(); }
+ float masterVolume_l() const final;
+ bool masterMute_l() const final;
+ float getMasterBalance_l() const;
+ // no range check, AudioFlinger::mLock held
+ bool streamMute_l(audio_stream_type_t stream) const final { return mStreamTypes[stream].mute; }
+ audio_mode_t getMode() const final { return mMode; }
+ bool isLowRamDevice() const final { return mIsLowRamDevice; }
+ uint32_t getScreenState() const final { return mScreenState; }
+
+ std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final;
+ const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; }
+ const sp<MelReporter>& getMelReporter() const final { return mMelReporter; }
+ const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final {
+ return mEffectsFactoryHal;
+ }
+ sp<IAudioManager> getOrCreateAudioManager() final;
+
+ // Called when the last effect handle on an effect instance is removed. If this
+ // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
+ // and removed from mOrphanEffectChains if it does not contain any effect.
+ // Return true if the effect was found in mOrphanEffectChains, false otherwise.
+ bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final;
+
+ status_t moveEffectChain_l(audio_session_t sessionId,
+ IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final;
+
+ // This is a helper that is called during incoming binder calls.
+ // Requests media.log to start merging log buffers
+ void requestLogMerge() final;
+ sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final;
+ void unregisterWriter(const sp<NBLog::Writer>& writer) final;
+
+ sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
+ audio_session_t triggerSession,
+ audio_session_t listenerSession,
+ const audioflinger::SyncEventCallback& callBack,
+ const wp<IAfTrackBase>& cookie) final;
+
+ void ioConfigChanged(audio_io_config_event_t event,
+ const sp<AudioIoDescriptor>& ioDesc,
+ pid_t pid = 0) final;
+ void onNonOffloadableGlobalEffectEnable() final;
+ void onSupportedLatencyModesChanged(
+ audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final;
+
+ // ---- end of IAfThreadCallback interface
+
+ /* List available audio ports and their attributes */
+ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const;
+
sp<EffectsFactoryHalInterface> getEffectsFactory();
+public:
+ // TODO(b/292281786): Remove this when Oboeservice can get access to
+ // openMmapStream through an IAudioFlinger handle directly.
+ static inline std::atomic<AudioFlinger*> gAudioFlinger = nullptr;
+
status_t openMmapStream(MmapStreamInterface::stream_direction_t direction,
const audio_attributes_t *attr,
audio_config_base_t *config,
@@ -350,21 +373,6 @@
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
audio_port_handle_t *handle);
-
- static os::HapticScale onExternalVibrationStart(
- const sp<os::ExternalVibration>& externalVibration);
- static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
-
- status_t addEffectToHal(
- const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
- status_t removeEffectFromHal(
- const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
-
- void updateDownStreamPatches_l(const struct audio_patch *patch,
- const std::set<audio_io_handle_t>& streams);
-
- std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l();
-
private:
// FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
static const size_t kLogMemorySize = 400 * 1024;
@@ -374,132 +382,30 @@
Vector< sp<NBLog::Writer> > mUnregisteredWriters;
Mutex mUnregisteredWritersLock;
-public:
- // Life cycle of gAudioFlinger and AudioFlinger:
- //
- // AudioFlinger is created once and survives until audioserver crashes
- // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we
- // don't issue a ServiceManager::tryUnregisterService().
- //
- // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef().
- // After this is set, it is safe to obtain a wp<> or sp<> from it as the
- // underlying object does not go away.
- //
- // Note: For most inner classes, it is acceptable to hold a reference to the outer
- // AudioFlinger instance as creation requires AudioFlinger to exist in the first place.
- //
- // An atomic here ensures underlying writes have completed before setting
- // the pointer. Access by memory_order_seq_cst.
- //
-
- static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;
-
- sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
- audio_session_t triggerSession,
- audio_session_t listenerSession,
- const audioflinger::SyncEventCallback& callBack,
- const wp<RefBase>& cookie);
-
- bool btNrecIsOff() const { return mBtNrecIsOff.load(); }
-
- void lock() ACQUIRE(mLock) { mLock.lock(); }
- void unlock() RELEASE(mLock) { mLock.unlock(); }
-
-private:
-
- audio_mode_t getMode() const { return mMode; }
-
AudioFlinger() ANDROID_API;
- virtual ~AudioFlinger();
+ ~AudioFlinger() override;
// call in any IAudioFlinger method that accesses mPrimaryHardwareDev
status_t initCheck() const { return mPrimaryHardwareDev == NULL ?
NO_INIT : NO_ERROR; }
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() override;
AudioHwDevice* findSuitableHwDev_l(audio_module_handle_t module,
audio_devices_t deviceType);
- // Set kEnableExtendedChannels to true to enable greater than stereo output
- // for the MixerThread and device sink. Number of channels allowed is
- // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS.
- static const bool kEnableExtendedChannels = true;
-
- // Returns true if channel mask is permitted for the PCM sink in the MixerThread
- static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
- switch (audio_channel_mask_get_representation(channelMask)) {
- case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
- // Haptic channel mask is only applicable for channel position mask.
- const uint32_t channelCount = audio_channel_count_from_out_mask(
- static_cast<audio_channel_mask_t>(channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL));
- const uint32_t maxChannelCount = kEnableExtendedChannels
- ? AudioMixer::MAX_NUM_CHANNELS : FCC_2;
- if (channelCount < FCC_2 // mono is not supported at this time
- || channelCount > maxChannelCount) {
- return false;
- }
- // check that channelMask is the "canonical" one we expect for the channelCount.
- return audio_channel_position_mask_is_out_canonical(channelMask);
- }
- case AUDIO_CHANNEL_REPRESENTATION_INDEX:
- if (kEnableExtendedChannels) {
- const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
- if (channelCount >= FCC_2 // mono is not supported at this time
- && channelCount <= AudioMixer::MAX_NUM_CHANNELS) {
- return true;
- }
- }
- return false;
- default:
- return false;
- }
- }
-
- // Set kEnableExtendedPrecision to true to use extended precision in MixerThread
- static const bool kEnableExtendedPrecision = true;
-
- // Returns true if format is permitted for the PCM sink in the MixerThread
- static inline bool isValidPcmSinkFormat(audio_format_t format) {
- switch (format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- return true;
- case AUDIO_FORMAT_PCM_FLOAT:
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- case AUDIO_FORMAT_PCM_32_BIT:
- case AUDIO_FORMAT_PCM_8_24_BIT:
- return kEnableExtendedPrecision;
- default:
- return false;
- }
- }
-
- // standby delay for MIXER and DUPLICATING playback threads is read from property
- // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
- static nsecs_t mStandbyTimeInNsecs;
-
// incremented by 2 when screen state changes, bit 0 == 1 means "off"
- // AudioFlinger::setParameters() updates, other threads read w/o lock
- static uint32_t mScreenState;
+ // AudioFlinger::setParameters() updates with mLock.
+ std::atomic_uint32_t mScreenState{};
- // Internal dump utilities.
- static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
-public:
- // TODO(b/288339104) extract to afutils
- static bool dumpTryLock(Mutex& mutex);
-private:
void dumpPermissionDenial(int fd, const Vector<String16>& args);
void dumpClients(int fd, const Vector<String16>& args);
void dumpInternals(int fd, const Vector<String16>& args);
SimpleLog mThreadLog{16}; // 16 Thread history limit
-public:
- // TODO(b/288339104)
- class ThreadBase;
-private:
- void dumpToThreadLog_l(const sp<ThreadBase> &thread);
+ void dumpToThreadLog_l(const sp<IAfThreadBase>& thread);
// --- Notification Client ---
class NotificationClient : public IBinder::DeathRecipient {
@@ -555,66 +461,6 @@
const sp<MediaLogNotifier> mMediaLogNotifier;
- // This is a helper that is called during incoming binder calls.
- // Requests media.log to start merging log buffers
- void requestLogMerge();
-
- // TODO(b/288339104) replace these forward declaration classes with interfaces.
-public:
- class RecordThread;
- class PlaybackThread;
- class MixerThread;
- class DirectOutputThread;
- class OffloadThread;
- class DuplicatingThread;
- class AsyncCallbackThread;
- class BitPerfectThread;
-private:
- class Track;
- class RecordTrack;
- class DeviceEffectManager;
- // TODO(b/288339104) these should be separate files
-public:
- class PatchPanel;
- class DeviceEffectManagerCallback;
-private:
- struct AudioStreamIn;
- struct TeePatch;
- using TeePatches = std::vector<TeePatch>;
-
-
- struct stream_type_t {
- stream_type_t()
- : volume(1.0f),
- mute(false)
- {
- }
- float volume;
- bool mute;
- };
-
- // Abstraction for the Audio Source for the RecordThread (HAL or PassthruPatchRecord).
- struct Source
- {
- virtual ~Source() = default;
- // The following methods have the same signatures as in StreamHalInterface.
- virtual status_t read(void *buffer, size_t bytes, size_t *read) = 0;
- virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
- virtual status_t standby() = 0;
- };
-
- // --- PlaybackThread ---
-
-#include "Threads.h"
-
-#include "PatchPanel.h"
-
-#include "PatchCommandThread.h"
-
-#include "DeviceEffectManager.h"
-
-#include "MelReporter.h"
-
// Find io handle by session id.
// Preference is given to an io handle with a matching effect chain to session id.
// If none found, AUDIO_IO_HANDLE_NONE is returned.
@@ -627,7 +473,7 @@
const uint32_t sessionType = threads.valueAt(i)->hasAudioSession(sessionId);
if (sessionType != 0) {
io = threads.keyAt(i);
- if ((sessionType & AudioFlinger::ThreadBase::EFFECT_SESSION) != 0) {
+ if ((sessionType & IAfThreadBase::EFFECT_SESSION) != 0) {
break; // effect chain here.
}
}
@@ -635,67 +481,15 @@
return io;
}
- // Mmap stream control interface implementation. Each MmapThreadHandle controls one
- // MmapPlaybackThread or MmapCaptureThread instance.
- class MmapThreadHandle : public MmapStreamInterface {
- public:
- explicit MmapThreadHandle(const sp<MmapThread>& thread);
- virtual ~MmapThreadHandle();
+ IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
+ IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
- // MmapStreamInterface virtuals
- virtual status_t createMmapBuffer(int32_t minSizeFrames,
- struct audio_mmap_buffer_info *info);
- virtual status_t getMmapPosition(struct audio_mmap_position *position);
- virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNanos);
- virtual status_t start(const AudioClient& client,
- const audio_attributes_t *attr,
- audio_port_handle_t *handle);
- virtual status_t stop(audio_port_handle_t handle);
- virtual status_t standby();
- status_t reportData(const void* buffer, size_t frameCount) override;
+ sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
+ std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;
- private:
- const sp<MmapThread> mThread;
- };
- ThreadBase *checkThread_l(audio_io_handle_t ioHandle) const;
- sp<AudioFlinger::ThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const
- REQUIRES(mLock);
- PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
- MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
- RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
- MmapThread *checkMmapThread_l(audio_io_handle_t io) const;
- VolumeInterface *getVolumeInterface_l(audio_io_handle_t output) const;
- Vector <VolumeInterface *> getAllVolumeInterfaces_l() const;
-
- sp<ThreadBase> openInput_l(audio_module_handle_t module,
- audio_io_handle_t *input,
- audio_config_t *config,
- audio_devices_t device,
- const char* address,
- audio_source_t source,
- audio_input_flags_t flags,
- audio_devices_t outputDevice,
- const String8& outputDeviceAddress);
- sp<ThreadBase> openOutput_l(audio_module_handle_t module,
- audio_io_handle_t *output,
- audio_config_t *halConfig,
- audio_config_base_t *mixerConfig,
- audio_devices_t deviceType,
- const String8& address,
- audio_output_flags_t flags);
-
- void closeOutputFinish(const sp<PlaybackThread>& thread);
- void closeInputFinish(const sp<RecordThread>& thread);
-
- // no range check, AudioFlinger::mLock held
- bool streamMute_l(audio_stream_type_t stream) const
- { return mStreamTypes[stream].mute; }
- void ioConfigChanged(audio_io_config_event_t event,
- const sp<AudioIoDescriptor>& ioDesc,
- pid_t pid = 0);
- void onSupportedLatencyModesChanged(
- audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes);
+ void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
+ void closeInputFinish(const sp<IAfRecordThread>& thread);
// Allocate an audio_unique_id_t.
// Specific types are audio_io_handle_t, audio_session_t, effect ID (int),
@@ -708,37 +502,27 @@
// Thus it may fail by returning an ID of the wrong sign,
// or by returning a non-unique ID.
// This is the internal API. For the binder API see newAudioUniqueId().
- audio_unique_id_t nextUniqueId(audio_unique_id_use_t use);
+ // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback, IAfThreadCallback
+ audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;
status_t moveEffectChain_l(audio_session_t sessionId,
- PlaybackThread *srcThread,
- PlaybackThread *dstThread);
-
- status_t moveAuxEffectToIo(int EffectId,
- const sp<PlaybackThread>& dstThread,
- sp<PlaybackThread> *srcThread);
+ IAfRecordThread* srcThread, IAfRecordThread* dstThread);
// return thread associated with primary hardware device, or NULL
- PlaybackThread *primaryPlaybackThread_l() const;
DeviceTypeSet primaryOutputDevice_l() const;
// return the playback thread with smallest HAL buffer size, and prefer fast
- PlaybackThread *fastPlaybackThread_l() const;
+ IAfPlaybackThread* fastPlaybackThread_l() const;
- sp<ThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);
+ sp<IAfThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);
- ThreadBase *hapticPlaybackThread_l() const;
+ IAfThreadBase* hapticPlaybackThread_l() const;
void updateSecondaryOutputsForTrack_l(
- PlaybackThread::Track* track,
- PlaybackThread* thread,
+ IAfTrack* track,
+ IAfPlaybackThread* thread,
const std::vector<audio_io_handle_t>& secondaryOutputs) const;
-
- void removeClient_l(pid_t pid);
- void removeNotificationClient(pid_t pid);
- bool isNonOffloadableGlobalEffectEnabled_l();
- void onNonOffloadableGlobalEffectEnable();
bool isSessionAcquired_l(audio_session_t audioSession);
// Store an effect chain to mOrphanEffectChains keyed vector.
@@ -752,49 +536,16 @@
// Get an effect chain for the specified session in mOrphanEffectChains and remove
// it if found. Returns 0 if not found (this is the most common case).
sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session);
- // Called when the last effect handle on an effect instance is removed. If this
- // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
- // and removed from mOrphanEffectChains if it does not contain any effect.
- // Return true if the effect was found in mOrphanEffectChains, false otherwise.
-public:
-// TODO(b/288339104) suggest better grouping
- bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect);
-private:
+
std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();
+ std::vector< sp<IAfEffectModule> > purgeOrphanEffectChains_l();
+ bool updateOrphanEffectChains_l(const sp<IAfEffectModule>& effect);
+
void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
- void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices);
void forwardParametersToDownstreamPatches_l(
audio_io_handle_t upStream, const String8& keyValuePairs,
- const std::function<bool(const sp<PlaybackThread>&)>& useThread = nullptr);
-
- // AudioStreamIn is immutable, so their fields are const.
- // For emphasis, we could also make all pointers to them be "const *",
- // but that would clutter the code unnecessarily.
-
- struct AudioStreamIn : public Source {
- AudioHwDevice* const audioHwDev;
- sp<StreamInHalInterface> stream;
- audio_input_flags_t flags;
-
- sp<DeviceHalInterface> hwDev() const { return audioHwDev->hwDevice(); }
-
- AudioStreamIn(AudioHwDevice *dev, const sp<StreamInHalInterface>& in,
- audio_input_flags_t flags) :
- audioHwDev(dev), stream(in), flags(flags) {}
- status_t read(void *buffer, size_t bytes, size_t *read) override {
- return stream->read(buffer, bytes, read);
- }
- status_t getCapturePosition(int64_t *frames, int64_t *time) override {
- return stream->getCapturePosition(frames, time);
- }
- status_t standby() override { return stream->standby(); }
- };
-
- struct TeePatch {
- sp<RecordThread::PatchRecord> patchRecord;
- sp<PlaybackThread::PatchTrack> patchTrack;
- };
+ const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr);
// for mAudioSessionRefs only
struct AudioSessionRef {
@@ -810,10 +561,9 @@
// protects mClients and mNotificationClients.
// must be locked after mLock and ThreadBase::mLock if both must be locked
// avoids acquiring AudioFlinger::mLock from inside thread loop.
-public:
- // TODO(b/288339104) access by getter,
- mutable Mutex mClientLock;
-private:
+
+ mutable Mutex mClientLock;
+
// protected by mClientLock
DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client()
@@ -860,7 +610,7 @@
mutable hardware_call_state mHardwareStatus; // for dump only
- DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> > mPlaybackThreads;
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfPlaybackThread>> mPlaybackThreads;
stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
// member variables below are protected by mLock
@@ -869,7 +619,7 @@
float mMasterBalance = 0.f;
// end of variables protected by mLock
- DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> > mRecordThreads;
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfRecordThread>> mRecordThreads;
// protected by mClientLock
DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
@@ -883,9 +633,6 @@
// protected by mLock
Vector<AudioSessionRef*> mAudioSessionRefs;
- float masterVolume_l() const;
- float getMasterBalance_l() const;
- bool masterMute_l() const;
AudioHwDevice* loadHwModule_l(const char *name);
// sync events awaiting for a session to be created.
@@ -900,17 +647,14 @@
// list of MMAP stream control threads. Those threads allow for wake lock, routing
// and volume control for activity on the associated MMAP stream at the HAL.
// Audio data transfer is directly handled by the client creating the MMAP stream
- DefaultKeyedVector< audio_io_handle_t, sp<MmapThread> > mMmapThreads;
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads;
-private:
sp<Client> registerPid(pid_t pid); // always returns non-0
// for use from destructor
status_t closeOutput_nonvirtual(audio_io_handle_t output);
- void closeThreadInternal_l(const sp<PlaybackThread>& thread);
status_t closeInput_nonvirtual(audio_io_handle_t input);
- void closeThreadInternal_l(const sp<RecordThread>& thread);
- void setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId);
+ void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId);
status_t checkStreamType(audio_stream_type_t stream) const;
@@ -919,15 +663,10 @@
size_t rejectedKVPSize, const String8& rejectedKVPs,
uid_t callingUid);
- sp<IAudioManager> getOrCreateAudioManager();
-
-public:
// These methods read variables atomically without mLock,
// though the variables are updated with mLock.
- bool isLowRamDevice() const { return mIsLowRamDevice; }
size_t getClientSharedHeapSize() const;
-private:
std::atomic<bool> mIsLowRamDevice;
bool mIsDeviceTypeKnown;
int64_t mTotalMemory;
@@ -936,16 +675,13 @@
nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled
- // protected by mLock
- PatchPanel mPatchPanel;
-public:
- // TODO(b/288339104) access by getter.
+ /* const */ sp<IAfPatchPanel> mPatchPanel;
+
sp<EffectsFactoryHalInterface> mEffectsFactoryHal;
-private:
const sp<PatchCommandThread> mPatchCommandThread;
- sp<DeviceEffectManager> mDeviceEffectManager;
- sp<MelReporter> mMelReporter;
+ /* const */ sp<DeviceEffectManager> mDeviceEffectManager; // set onFirstRef
+ /* const */ sp<MelReporter> mMelReporter; // set onFirstRef
bool mSystemReady;
std::atomic_bool mAudioPolicyReady{};
@@ -960,9 +696,6 @@
static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER;
- // Keep in sync with java definition in media/java/android/media/AudioRecord.java
- static constexpr int32_t kMaxSharedAudioHistoryMs = 5000;
-
std::map<media::audio::common::AudioMMapPolicyType,
std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
int32_t mAAudioBurstsPerBuffer = 0;
@@ -975,16 +708,6 @@
std::atomic_bool mBluetoothLatencyModesEnabled;
};
-#undef INCLUDING_FROM_AUDIOFLINGER_H
-
-std::string formatToString(audio_format_t format);
-std::string inputFlagsToString(audio_input_flags_t flags);
-std::string outputFlagsToString(audio_output_flags_t flags);
-std::string devicesToString(audio_devices_t devices);
-const char *sourceToString(audio_source_t source);
-
// ----------------------------------------------------------------------------
} // namespace android
-
-#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/services/audioflinger/Client.cpp b/services/audioflinger/Client.cpp
new file mode 100644
index 0000000..93599ac
--- /dev/null
+++ b/services/audioflinger/Client.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Client.h"
+
+namespace android {
+
+Client::Client(const sp<IAfClientCallback>& afClientCallback, pid_t pid)
+ : mAfClientCallback(afClientCallback)
+ , mPid(pid)
+ , mClientAllocator(AllocatorFactory::getClientAllocator()) {}
+
+// Client destructor must be called with AudioFlinger::mClientLock held
+Client::~Client()
+{
+ mAfClientCallback->removeClient_l(mPid);
+}
+
+AllocatorFactory::ClientAllocator& Client::allocator()
+{
+ return mClientAllocator;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/audioflinger/Client.h b/services/audioflinger/Client.h
index cb507fe..b2e3cf7 100644
--- a/services/audioflinger/Client.h
+++ b/services/audioflinger/Client.h
@@ -16,26 +16,42 @@
#pragma once
-// TODO(b/288339104) Move to nested namespace
+#include <afutils/AllocatorFactory.h>
+#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
+#include <utils/Mutex.h>
+#include <utils/RefBase.h> // avoid transitive dependency
+
+// TODO(b/291318727) Move to nested namespace
namespace android {
-class AudioFlinger;
+class IAfPlaybackThread;
+
+class IAfClientCallback : public virtual RefBase {
+public:
+ virtual Mutex& clientMutex() const = 0;
+ virtual void removeClient_l(pid_t pid) = 0;
+ virtual void removeNotificationClient(pid_t pid) = 0;
+ virtual status_t moveAuxEffectToIo(
+ int effectId,
+ const sp<IAfPlaybackThread>& dstThread,
+ sp<IAfPlaybackThread>* srcThread) = 0; // used by indirectly by clients.
+};
class Client : public RefBase {
public:
- Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+ Client(const sp<IAfClientCallback>& audioFlinger, pid_t pid);
// TODO(b/289139675) make Client container.
// Client destructor must be called with AudioFlinger::mClientLock held
~Client() override;
AllocatorFactory::ClientAllocator& allocator();
pid_t pid() const { return mPid; }
- sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
+ const auto& afClientCallback() const { return mAfClientCallback; }
private:
DISALLOW_COPY_AND_ASSIGN(Client);
- const sp<AudioFlinger> mAudioFlinger;
+ const sp<IAfClientCallback> mAfClientCallback;
const pid_t mPid;
AllocatorFactory::ClientAllocator mClientAllocator;
};
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 366a7ab..681ec5f 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -15,16 +15,17 @@
** limitations under the License.
*/
-
-#define LOG_TAG "AudioFlinger::DeviceEffectManager"
+#define LOG_TAG "DeviceEffectManager"
//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <audio_utils/primitives.h>
+#include "DeviceEffectManager.h"
-#include "AudioFlinger.h"
#include "EffectConfiguration.h"
+
+#include <afutils/DumpTryLock.h>
+#include <audio_utils/primitives.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <utils/Log.h>
// ----------------------------------------------------------------------------
@@ -34,39 +35,78 @@
using detail::AudioHalVersionInfo;
using media::IEffectClient;
-void AudioFlinger::DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) {
+DeviceEffectManager::DeviceEffectManager(
+ const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
+ : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
+ mMyCallback(new DeviceEffectManagerCallback(*this)) {}
+
+void DeviceEffectManager::onFirstRef() {
+ mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
+}
+
+status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
+ const sp<EffectHalInterface>& effect) {
+ return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
+};
+
+status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
+ const sp<EffectHalInterface>& effect) {
+ return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
+};
+
+void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
+ const IAfPatchPanel::Patch& patch) {
ALOGV("%s handle %d mHalHandle %d device sink %08x",
__func__, handle, patch.mHalHandle,
patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
Mutex::Autolock _l(mLock);
- for (auto& effect : mDeviceEffects) {
- status_t status = effect.second->onCreatePatch(handle, &patch); // TODO(b/288339104) void*
- ALOGV("%s Effect onCreatePatch status %d", __func__, status);
- ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
+ for (auto& effectProxies : mDeviceEffects) {
+ for (auto& effect : effectProxies.second) {
+ const status_t status = effect->onCreatePatch(handle, patch);
+ ALOGV("%s Effect onCreatePatch status %d", __func__, status);
+ ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
+ }
}
}
-void AudioFlinger::DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
+void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
ALOGV("%s", __func__);
Mutex::Autolock _l(mLock);
- for (auto& effect : mDeviceEffects) {
- effect.second->onReleasePatch(handle);
+ for (auto& effectProxies : mDeviceEffects) {
+ for (auto& effect : effectProxies.second) {
+ effect->onReleasePatch(handle);
+ }
+ }
+}
+
+void DeviceEffectManager::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
+ ALOGV("%s oldhandle %d newHandle %d mHalHandle %d device sink %08x",
+ __func__, oldHandle, newHandle, patch.mHalHandle,
+ patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
+ Mutex::Autolock _l(mLock);
+ for (auto& effectProxies : mDeviceEffects) {
+ for (auto& effect : effectProxies.second) {
+ const status_t status = effect->onUpdatePatch(oldHandle, newHandle, patch);
+ ALOGV("%s Effect onUpdatePatch status %d", __func__, status);
+ ALOGW_IF(status != NO_ERROR, "%s onUpdatePatch error %d", __func__, status);
+ }
}
}
// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
-sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l(
+sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
effect_descriptor_t *descriptor,
const AudioDeviceTypeAddr& device,
const sp<Client>& client,
const sp<IEffectClient>& effectClient,
- const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
+ const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
int *enabled,
status_t *status,
bool probe,
bool notifyFramesProcessed) {
sp<IAfDeviceEffectProxy> effect;
+ std::vector<sp<IAfDeviceEffectProxy>> effectsForDevice = {};
sp<IAfEffectHandle> handle;
status_t lStatus;
@@ -80,11 +120,21 @@
Mutex::Autolock _l(mLock);
auto iter = mDeviceEffects.find(device);
if (iter != mDeviceEffects.end()) {
- effect = iter->second;
- } else {
+ effectsForDevice = iter->second;
+ for (const auto& iterEffect : effectsForDevice) {
+ if (memcmp(&iterEffect->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) ==
+ 0) {
+ effect = iterEffect;
+ break;
+ }
+ }
+ }
+ if (effect == nullptr) {
effect = IAfDeviceEffectProxy::create(device, mMyCallback,
- descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
+ descriptor,
+ mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
notifyFramesProcessed);
+ effectsForDevice.push_back(effect);
}
// create effect handle and connect it to effect module
handle = IAfEffectHandle::create(
@@ -93,12 +143,13 @@
if (lStatus == NO_ERROR) {
lStatus = effect->addHandle(handle.get());
if (lStatus == NO_ERROR) {
- lStatus = effect->init(&patches); // TODO(b/288339104) void*
+ lStatus = effect->init(patches);
if (lStatus == NAME_NOT_FOUND) {
lStatus = NO_ERROR;
}
if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
- mDeviceEffects.emplace(device, effect);
+ mDeviceEffects.erase(device);
+ mDeviceEffects.emplace(device, effectsForDevice);
}
}
}
@@ -110,7 +161,7 @@
return handle;
}
-status_t AudioFlinger::DeviceEffectManager::checkEffectCompatibility(
+status_t DeviceEffectManager::checkEffectCompatibility(
const effect_descriptor_t *desc) {
const sp<EffectsFactoryHalInterface> effectsFactory =
audioflinger::EffectConfiguration::getEffectsFactoryHal();
@@ -136,7 +187,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::DeviceEffectManager::createEffectHal(
+status_t DeviceEffectManager::createEffectHal(
const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect) {
status_t status = NO_INIT;
@@ -149,10 +200,10 @@
return status;
}
-void AudioFlinger::DeviceEffectManager::dump(int fd)
+void DeviceEffectManager::dump(int fd)
NO_THREAD_SAFETY_ANALYSIS // conditional try lock
{
- const bool locked = dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
if (!locked) {
String8 result("DeviceEffectManager may be deadlocked\n");
write(fd, result.string(), result.size());
@@ -164,8 +215,10 @@
String8 outStr;
outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
- write(fd, outStr.string(), outStr.size());
- iter.second->dump2(fd, 4);
+ for (const auto& effect : iter.second) {
+ write(fd, outStr.string(), outStr.size());
+ effect->dump2(fd, 4);
+ }
}
if (locked) {
@@ -173,15 +226,27 @@
}
}
-
-size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
+size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
{
Mutex::Autolock _l(mLock);
- mDeviceEffects.erase(effect->device());
+ const auto& iter = mDeviceEffects.find(effect->device());
+ if (iter != mDeviceEffects.end()) {
+ const auto& iterEffect = std::find_if(
+ iter->second.begin(), iter->second.end(), [&effect](const auto& effectProxy) {
+ return memcmp(&effectProxy->desc().uuid, &effect->desc().uuid,
+ sizeof(effect_uuid_t)) == 0;
+ });
+ if (iterEffect != iter->second.end()) {
+ iter->second.erase(iterEffect);
+ if (iter->second.empty()) {
+ mDeviceEffects.erase(effect->device());
+ }
+ }
+ }
return mDeviceEffects.size();
}
-bool AudioFlinger::DeviceEffectManagerCallback::disconnectEffectHandle(
+bool DeviceEffectManagerCallback::disconnectEffectHandle(
IAfEffectHandle *handle, bool unpinIfLast) {
sp<IAfEffectBase> effectBase = handle->effect().promote();
if (effectBase == nullptr) {
@@ -203,4 +268,12 @@
return true;
}
+bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
+ return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
+}
+
+int DeviceEffectManagerCallback::newEffectId() const {
+ return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+}
+
} // namespace android
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index c589714..cb7fad1 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -15,26 +15,41 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
+
+#include "IAfEffect.h"
+#include "PatchCommandThread.h"
+
+#include <utils/Mutex.h> // avoid transitive dependency
+
+namespace android {
+
+class IAfDeviceEffectManagerCallback : public virtual RefBase {
+public:
+ virtual bool isAudioPolicyReady() const = 0;
+ virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
+ virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+ virtual status_t addEffectToHal(
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) = 0;
+ virtual status_t removeEffectFromHal(
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) = 0;
+};
+
+class DeviceEffectManagerCallback;
// DeviceEffectManager is concealed within AudioFlinger, their lifetimes are the same.
class DeviceEffectManager : public PatchCommandThread::PatchCommandListener {
public:
- explicit DeviceEffectManager(AudioFlinger& audioFlinger)
- : mAudioFlinger(audioFlinger),
- mMyCallback(new DeviceEffectManagerCallback(*this)) {}
+ explicit DeviceEffectManager(
+ const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback);
- void onFirstRef() override {
- mAudioFlinger.mPatchCommandThread->addListener(this);
- }
+ void onFirstRef() override;
sp<IAfEffectHandle> createEffect_l(effect_descriptor_t *descriptor,
const AudioDeviceTypeAddr& device,
const sp<Client>& client,
const sp<media::IEffectClient>& effectClient,
- const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
+ const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
int *enabled,
status_t *status,
bool probe,
@@ -45,34 +60,32 @@
int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect);
status_t addEffectToHal(const struct audio_port_config *device,
- const sp<EffectHalInterface>& effect) {
- return mAudioFlinger.addEffectToHal(device, effect);
- };
+ const sp<EffectHalInterface>& effect);
status_t removeEffectFromHal(const struct audio_port_config *device,
- const sp<EffectHalInterface>& effect) {
- return mAudioFlinger.removeEffectFromHal(device, effect);
- };
+ const sp<EffectHalInterface>& effect);
- AudioFlinger& audioFlinger() const { return mAudioFlinger; }
+ const auto& afDeviceEffectManagerCallback() const { return mAfDeviceEffectManagerCallback; }
void dump(int fd);
// PatchCommandThread::PatchCommandListener implementation
void onCreateAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) override;
- void onReleaseAudioPatch(audio_patch_handle_t handle) override;
+ const IAfPatchPanel::Patch& patch) final;
+ void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+ void onUpdateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch) final;
private:
status_t checkEffectCompatibility(const effect_descriptor_t *desc);
Mutex mLock;
- AudioFlinger &mAudioFlinger;
+ const sp<IAfDeviceEffectManagerCallback> mAfDeviceEffectManagerCallback;
const sp<DeviceEffectManagerCallback> mMyCallback;
- std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects;
+ std::map<AudioDeviceTypeAddr, std::vector<sp<IAfDeviceEffectProxy>>> mDeviceEffects;
};
-public: // TODO(b/288339104) extract inner class.
class DeviceEffectManagerCallback : public EffectCallbackInterface {
public:
explicit DeviceEffectManagerCallback(DeviceEffectManager& manager)
@@ -129,11 +142,9 @@
wp<IAfEffectChain> chain() const override { return nullptr; }
- bool isAudioPolicyReady() const override {
- return mManager.audioFlinger().isAudioPolicyReady();
- }
+ bool isAudioPolicyReady() const final;
- int newEffectId() { return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); }
+ int newEffectId() const;
status_t addEffectToHal(const struct audio_port_config *device,
const sp<EffectHalInterface>& effect) {
@@ -146,4 +157,5 @@
private:
DeviceEffectManager& mManager;
};
-private:
+
+} // namespace android
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 1f26cb0..c3e1fba 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -19,10 +19,25 @@
#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
-#include <algorithm>
+#include "Effects.h"
-#include "Configuration.h"
-#include <utils/Log.h>
+#include "Client.h"
+#include "EffectConfiguration.h"
+
+#include <afutils/DumpTryLock.h>
+#include <audio_utils/channels.h>
+#include <audio_utils/primitives.h>
+#include <media/AudioCommonTypes.h>
+#include <media/AudioContainers.h>
+#include <media/AudioDeviceTypeAddr.h>
+#include <media/AudioEffect.h>
+#include <media/ShmemCompat.h>
+#include <media/TypeConverter.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <mediautils/MethodStatistics.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
#include <system/audio_effects/effect_aec.h>
#include <system/audio_effects/effect_downmix.h>
#include <system/audio_effects/effect_dynamicsprocessing.h>
@@ -30,22 +45,9 @@
#include <system/audio_effects/effect_ns.h>
#include <system/audio_effects/effect_spatializer.h>
#include <system/audio_effects/effect_visualizer.h>
-#include <audio_utils/channels.h>
-#include <audio_utils/primitives.h>
-#include <media/AudioCommonTypes.h>
-#include <media/AudioContainers.h>
-#include <media/AudioEffect.h>
-#include <media/AudioDeviceTypeAddr.h>
-#include <media/ShmemCompat.h>
-#include <media/audiohal/EffectHalInterface.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <mediautils/MethodStatistics.h>
-#include <mediautils/ServiceUtilities.h>
-#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
-#include "AudioFlinger.h"
-#include "EffectConfiguration.h"
-#include "Effects.h"
+#include <algorithm>
// ----------------------------------------------------------------------------
@@ -507,16 +509,17 @@
result.appendFormat("\tEffect ID %d:\n", mId);
- bool locked = AudioFlinger::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
result.append("\t\tCould not lock Fx mutex:\n");
}
-
- result.append("\t\tSession State Registered Enabled Suspended:\n");
- result.appendFormat("\t\t%05d %03d %s %s %s\n",
- mSessionId, mState, mPolicyRegistered ? "y" : "n",
- mPolicyEnabled ? "y" : "n", mSuspended ? "y" : "n");
+ bool isInternal = isInternal_l();
+ result.append("\t\tSession State Registered Internal Enabled Suspended:\n");
+ result.appendFormat("\t\t%05d %03d %s %s %s %s\n",
+ mSessionId, mState, mPolicyRegistered ? "y" : "n", isInternal ? "y" : "n",
+ ((isInternal && isEnabled()) || (!isInternal && mPolicyEnabled)) ? "y" : "n",
+ mSuspended ? "y" : "n");
result.append("\t\tDescriptor:\n");
char uuidStr[64];
@@ -1006,8 +1009,9 @@
// mConfig.outputCfg.buffer.frameCount cannot be zero.
mMaxDisableWaitCnt = (uint32_t)std::max(
(uint64_t)1, // mMaxDisableWaitCnt must be greater than zero.
- (uint64_t)MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate
- / ((uint64_t)1000 * mConfig.outputCfg.buffer.frameCount));
+ (uint64_t)mConfig.outputCfg.buffer.frameCount == 0 ? 1
+ : (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate
+ / ((uint64_t)1000 * mConfig.outputCfg.buffer.frameCount)));
exit:
// TODO: consider clearing mConfig on error.
@@ -1621,7 +1625,7 @@
EffectBase::dump(fd, args);
String8 result;
- bool locked = AudioFlinger::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
result.append("\t\tStatus Engine:\n");
result.appendFormat("\t\t%03d %p\n",
@@ -1637,7 +1641,7 @@
mConfig.inputCfg.samplingRate,
mConfig.inputCfg.channels,
mConfig.inputCfg.format,
- formatToString((audio_format_t)mConfig.inputCfg.format).c_str());
+ toString(static_cast<audio_format_t>(mConfig.inputCfg.format)).c_str());
result.append("\t\t- Output configuration:\n");
result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
@@ -1647,7 +1651,7 @@
mConfig.outputCfg.samplingRate,
mConfig.outputCfg.channels,
mConfig.outputCfg.format,
- formatToString((audio_format_t)mConfig.outputCfg.format).c_str());
+ toString(static_cast<audio_format_t>(mConfig.outputCfg.format)).c_str());
result.appendFormat("\t\t- HAL buffers:\n"
"\t\t\tIn(%s) InConversion(%s) Out(%s) OutConversion(%s)\n",
@@ -1886,7 +1890,7 @@
}
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l2(mClient->audioFlinger()->mClientLock);
+ Mutex::Autolock _l2(mClient->afClientCallback()->clientMutex());
mClient.clear();
}
}
@@ -2095,7 +2099,7 @@
void EffectHandle::dumpToBuffer(char* buffer, size_t size) const
NO_THREAD_SAFETY_ANALYSIS // conditional try lock
{
- bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
+ const bool locked = mCblk != nullptr && afutils::dumpTryLock(mCblk->lock);
snprintf(buffer, size, "\t\t\t%5d %5d %3s %3s %5u %5u\n",
(mClient == 0) ? getpid() : mClient->pid(),
@@ -2116,34 +2120,25 @@
/* static */
sp<IAfEffectChain> IAfEffectChain::create(
- const wp<Thread /*ThreadBase*/>& wThread, // TODO(b/288339104) update type
+ const sp<IAfThreadBase>& thread,
audio_session_t sessionId)
{
- // TODO(b/288339104) no weak pointer cast.
- return sp<EffectChain>::make(sp<AudioFlinger::ThreadBase>::cast(wThread.promote()), sessionId);
+ return sp<EffectChain>::make(thread, sessionId);
}
-EffectChain::EffectChain(const wp<AudioFlinger::ThreadBase>& thread,
+EffectChain::EffectChain(const sp<IAfThreadBase>& thread,
audio_session_t sessionId)
: mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
{
- sp<AudioFlinger::ThreadBase> p = thread.promote();
- if (p == nullptr) {
- return;
- }
- mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC);
- mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) /
- p->frameCount();
+ mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
+ mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
+ thread->frameCount();
}
-EffectChain::~EffectChain()
-{
-}
-
-// getEffectFromDesc_l() must be called with AudioFlinger::ThreadBase::mLock held
+// getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held
sp<IAfEffectModule> EffectChain::getEffectFromDesc_l(
effect_descriptor_t *descriptor) const
{
@@ -2157,7 +2152,7 @@
return 0;
}
-// getEffectFromId_l() must be called with AudioFlinger::ThreadBase::mLock held
+// getEffectFromId_l() must be called with IAfThreadBase::mutex() held
sp<IAfEffectModule> EffectChain::getEffectFromId_l(int id) const
{
size_t size = mEffects.size();
@@ -2171,7 +2166,7 @@
return 0;
}
-// getEffectFromType_l() must be called with AudioFlinger::ThreadBase::mLock held
+// getEffectFromType_l() must be called with IAfThreadBase::mutex() held
sp<IAfEffectModule> EffectChain::getEffectFromType_l(
const effect_uuid_t *type) const
{
@@ -2266,7 +2261,7 @@
}
}
-// createEffect_l() must be called with AudioFlinger::ThreadBase::mLock held
+// createEffect_l() must be called with IAfThreadBase::mutex() held
status_t EffectChain::createEffect_l(sp<IAfEffectModule>& effect,
effect_descriptor_t *desc,
int id,
@@ -2285,13 +2280,13 @@
return lStatus;
}
-// addEffect_l() must be called with AudioFlinger::ThreadBase::mLock held
+// addEffect_l() must be called with IAfThreadBase::mutex() held
status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
{
Mutex::Autolock _l(mLock);
return addEffect_ll(effect);
}
-// addEffect_l() must be called with AudioFlinger::ThreadBase::mLock and EffectChain::mLock held
+// addEffect_l() must be called with IAfThreadBase::mLock and EffectChain::mutex() held
status_t EffectChain::addEffect_ll(const sp<IAfEffectModule>& effect)
{
effect->setCallback(mEffectCallback);
@@ -2445,7 +2440,7 @@
return idx_insert;
}
-// removeEffect_l() must be called with AudioFlinger::ThreadBase::mLock held
+// removeEffect_l() must be called with IAfThreadBase::mutex() held
size_t EffectChain::removeEffect_l(const sp<IAfEffectModule>& effect,
bool release)
{
@@ -2493,7 +2488,7 @@
return mEffects.size();
}
-// setDevices_l() must be called with AudioFlinger::ThreadBase::mLock held
+// setDevices_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setDevices_l(const AudioDeviceTypeAddrVector &devices)
{
size_t size = mEffects.size();
@@ -2502,7 +2497,7 @@
}
}
-// setInputDevice_l() must be called with AudioFlinger::ThreadBase::mLock held
+// setInputDevice_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setInputDevice_l(const AudioDeviceTypeAddr &device)
{
size_t size = mEffects.size();
@@ -2511,7 +2506,7 @@
}
}
-// setMode_l() must be called with AudioFlinger::ThreadBase::mLock held
+// setMode_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setMode_l(audio_mode_t mode)
{
size_t size = mEffects.size();
@@ -2520,7 +2515,7 @@
}
}
-// setAudioSource_l() must be called with AudioFlinger::ThreadBase::mLock held
+// setAudioSource_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setAudioSource_l(audio_source_t source)
{
size_t size = mEffects.size();
@@ -2536,7 +2531,7 @@
return false;
}
-// setVolume_l() must be called with AudioFlinger::ThreadBase::mLock or EffectChain::mLock held
+// setVolume_l() must be called with IAfThreadBase::mLock or EffectChain::mLock held
bool EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
{
uint32_t newLeft = *left;
@@ -2603,7 +2598,7 @@
return hasControl;
}
-// resetVolume_l() must be called with AudioFlinger::ThreadBase::mLock or EffectChain::mLock held
+// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mLock held
void EffectChain::resetVolume_l()
{
if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
@@ -2614,7 +2609,7 @@
}
// containsHapticGeneratingEffect_l must be called with
-// AudioFlinger::ThreadBase::mLock or EffectChain::mLock held
+// IAfThreadBase::mutex() or EffectChain::mLock held
bool EffectChain::containsHapticGeneratingEffect_l()
{
for (size_t i = 0; i < mEffects.size(); ++i) {
@@ -2653,7 +2648,7 @@
result.appendFormat(" %zu effects for session %d\n", numEffects, mSessionId);
if (numEffects) {
- bool locked = AudioFlinger::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
result.append("\tCould not lock mutex:\n");
@@ -2683,7 +2678,7 @@
}
}
-// must be called with AudioFlinger::ThreadBase::mLock held
+// must be called with IAfThreadBase::mutex() held
void EffectChain::setEffectSuspended_l(
const effect_uuid_t *type, bool suspend)
{
@@ -2739,7 +2734,7 @@
}
}
-// must be called with AudioFlinger::ThreadBase::mLock held
+// must be called with IAfThreadBase::mutex() held
void EffectChain::setEffectSuspendedAll_l(bool suspend)
{
sp<SuspendedEffectDesc> desc;
@@ -2895,7 +2890,7 @@
return false;
}
-void EffectChain::setThread(const sp<AudioFlinger::ThreadBase>& thread)
+void EffectChain::setThread(const sp<IAfThreadBase>& thread)
{
Mutex::Autolock _l(mLock);
mEffectCallback->setThread(thread);
@@ -2962,7 +2957,7 @@
}
// isCompatibleWithThread_l() must be called with thread->mLock held
-bool EffectChain::isCompatibleWithThread_l(const sp<AudioFlinger::ThreadBase>& thread) const
+bool EffectChain::isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mEffects.size(); i++) {
@@ -2989,18 +2984,18 @@
bool EffectChain::EffectCallback::updateOrphanEffectChains(
const sp<IAfEffectBase>& effect) {
// in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
- return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
+ return mAfThreadCallback->updateOrphanEffectChains(effect->asEffectModule());
}
status_t EffectChain::EffectCallback::allocateHalBuffer(
size_t size, sp<EffectBufferHalInterface>* buffer) {
- return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
+ return mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(size, buffer);
}
status_t EffectChain::EffectCallback::addEffectToHal(
const sp<EffectHalInterface>& effect) {
status_t result = NO_INIT;
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return result;
}
@@ -3016,7 +3011,7 @@
status_t EffectChain::EffectCallback::removeEffectFromHal(
const sp<EffectHalInterface>& effect) {
status_t result = NO_INIT;
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return result;
}
@@ -3030,7 +3025,7 @@
}
audio_io_handle_t EffectChain::EffectCallback::io() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_IO_HANDLE_NONE;
}
@@ -3038,7 +3033,7 @@
}
bool EffectChain::EffectCallback::isOutput() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return true;
}
@@ -3046,19 +3041,19 @@
}
bool EffectChain::EffectCallback::isOffload() const {
- return mThreadType == AudioFlinger::ThreadBase::OFFLOAD;
+ return mThreadType == IAfThreadBase::OFFLOAD;
}
bool EffectChain::EffectCallback::isOffloadOrDirect() const {
- return mThreadType == AudioFlinger::ThreadBase::OFFLOAD
- || mThreadType == AudioFlinger::ThreadBase::DIRECT;
+ return mThreadType == IAfThreadBase::OFFLOAD
+ || mThreadType == IAfThreadBase::DIRECT;
}
bool EffectChain::EffectCallback::isOffloadOrMmap() const {
switch (mThreadType) {
- case AudioFlinger::ThreadBase::OFFLOAD:
- case AudioFlinger::ThreadBase::MMAP_PLAYBACK:
- case AudioFlinger::ThreadBase::MMAP_CAPTURE:
+ case IAfThreadBase::OFFLOAD:
+ case IAfThreadBase::MMAP_PLAYBACK:
+ case IAfThreadBase::MMAP_CAPTURE:
return true;
default:
return false;
@@ -3066,11 +3061,11 @@
}
bool EffectChain::EffectCallback::isSpatializer() const {
- return mThreadType == AudioFlinger::ThreadBase::SPATIALIZER;
+ return mThreadType == IAfThreadBase::SPATIALIZER;
}
uint32_t EffectChain::EffectCallback::sampleRate() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -3078,7 +3073,7 @@
}
audio_channel_mask_t EffectChain::EffectCallback::inChannelMask(int id) const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_CHANNEL_NONE;
}
@@ -3087,7 +3082,7 @@
return AUDIO_CHANNEL_NONE;
}
- if (mThreadType == AudioFlinger::ThreadBase::SPATIALIZER) {
+ if (mThreadType == IAfThreadBase::SPATIALIZER) {
if (c->sessionId() == AUDIO_SESSION_OUTPUT_STAGE) {
if (c->isFirstEffect(id)) {
return t->mixerChannelMask();
@@ -3096,7 +3091,7 @@
}
} else if (!audio_is_global_session(c->sessionId())) {
if ((t->hasAudioSession_l(c->sessionId())
- & AudioFlinger::ThreadBase::SPATIALIZED_SESSION) != 0) {
+ & IAfThreadBase::SPATIALIZED_SESSION) != 0) {
return t->mixerChannelMask();
} else {
return t->channelMask();
@@ -3114,7 +3109,7 @@
}
audio_channel_mask_t EffectChain::EffectCallback::outChannelMask() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_CHANNEL_NONE;
}
@@ -3123,10 +3118,10 @@
return AUDIO_CHANNEL_NONE;
}
- if (mThreadType == AudioFlinger::ThreadBase::SPATIALIZER) {
+ if (mThreadType == IAfThreadBase::SPATIALIZER) {
if (!audio_is_global_session(c->sessionId())) {
if ((t->hasAudioSession_l(c->sessionId())
- & AudioFlinger::ThreadBase::SPATIALIZED_SESSION) != 0) {
+ & IAfThreadBase::SPATIALIZED_SESSION) != 0) {
return t->mixerChannelMask();
} else {
return t->channelMask();
@@ -3144,7 +3139,7 @@
}
audio_channel_mask_t EffectChain::EffectCallback::hapticChannelMask() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_CHANNEL_NONE;
}
@@ -3152,7 +3147,7 @@
}
size_t EffectChain::EffectCallback::frameCount() const {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -3162,7 +3157,7 @@
uint32_t EffectChain::EffectCallback::latency() const
NO_THREAD_SAFETY_ANALYSIS // latency_l() access
{
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -3173,7 +3168,7 @@
void EffectChain::EffectCallback::setVolumeForOutput(float left, float right) const
NO_THREAD_SAFETY_ANALYSIS // setVolumeForOutput_l() access
{
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -3182,7 +3177,7 @@
void EffectChain::EffectCallback::checkSuspendOnEffectEnabled(
const sp<IAfEffectBase>& effect, bool enabled, bool threadLocked) {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -3197,7 +3192,7 @@
}
void EffectChain::EffectCallback::onEffectEnable(const sp<IAfEffectBase>& effect) {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -3208,7 +3203,7 @@
void EffectChain::EffectCallback::onEffectDisable(const sp<IAfEffectBase>& effect) {
checkSuspendOnEffectEnabled(effect, false, false /*threadLocked*/);
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -3217,7 +3212,7 @@
bool EffectChain::EffectCallback::disconnectEffectHandle(IAfEffectHandle *handle,
bool unpinIfLast) {
- sp<AudioFlinger::ThreadBase> t = thread().promote();
+ const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
return false;
}
@@ -3257,11 +3252,11 @@
/* static */
sp<IAfDeviceEffectProxy> IAfDeviceEffectProxy::create(
const AudioDeviceTypeAddr& device,
- const sp</* DeviceEffectManagerCallback */ RefBase>& callback, // TODO(b/288339104) type
+ const sp<DeviceEffectManagerCallback>& callback,
effect_descriptor_t *desc, int id, bool notifyFramesProcessed)
{
return sp<DeviceEffectProxy>::make(device,
- sp<AudioFlinger::DeviceEffectManagerCallback>::cast(callback),
+ callback,
desc, id, notifyFramesProcessed);
}
@@ -3287,7 +3282,7 @@
}
status_t DeviceEffectProxy::init(
- const std::map <audio_patch_handle_t, AudioFlinger::PatchPanel::Patch>& patches) {
+ const std::map <audio_patch_handle_t, IAfPatchPanel::Patch>& patches) {
//For all audio patches
//If src or sink device match
//If the effect is HW accelerated
@@ -3309,8 +3304,25 @@
return status;
}
+status_t DeviceEffectProxy::onUpdatePatch(audio_patch_handle_t oldPatchHandle,
+ audio_patch_handle_t newPatchHandle,
+ const IAfPatchPanel::Patch& /* patch */) {
+ status_t status = NAME_NOT_FOUND;
+ ALOGV("%s", __func__);
+ Mutex::Autolock _l(mProxyLock);
+ if (mEffectHandles.find(oldPatchHandle) != mEffectHandles.end()) {
+ ALOGV("%s replacing effect from handle %d to handle %d", __func__, oldPatchHandle,
+ newPatchHandle);
+ sp<IAfEffectHandle> effect = mEffectHandles.at(oldPatchHandle);
+ mEffectHandles.erase(oldPatchHandle);
+ mEffectHandles.emplace(newPatchHandle, effect);
+ status = NO_ERROR;
+ }
+ return status;
+}
+
status_t DeviceEffectProxy::onCreatePatch(
- audio_patch_handle_t patchHandle, const AudioFlinger::PatchPanel::Patch& patch) {
+ audio_patch_handle_t patchHandle, const IAfPatchPanel::Patch& patch) {
status_t status = NAME_NOT_FOUND;
sp<IAfEffectHandle> handle;
// only consider source[0] as this is the only "true" source of a patch
@@ -3322,6 +3334,9 @@
}
if (status == NO_ERROR || status == ALREADY_EXISTS) {
Mutex::Autolock _l(mProxyLock);
+ size_t erasedHandle = mEffectHandles.erase(patchHandle);
+ ALOGV("%s %s effecthandle %p for patch %d",
+ __func__, (erasedHandle == 0 ? "adding" : "replacing"), handle.get(), patchHandle);
mEffectHandles.emplace(patchHandle, handle);
}
ALOGW_IF(status == BAD_VALUE,
@@ -3330,7 +3345,7 @@
return status;
}
-status_t DeviceEffectProxy::checkPort(const AudioFlinger::PatchPanel::Patch& patch,
+status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
const struct audio_port_config *port, sp<IAfEffectHandle> *handle) {
ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d",
@@ -3354,18 +3369,21 @@
if (mDescriptor.flags & EFFECT_FLAG_HW_ACC_TUNNEL) {
Mutex::Autolock _l(mProxyLock);
- mDevicePort = *port;
- mHalEffect = new EffectModule(mMyCallback,
+ if (mHalEffect != nullptr && mDevicePort.id == port->id) {
+ ALOGV("%s reusing HAL effect", __func__);
+ } else {
+ mDevicePort = *port;
+ mHalEffect = new EffectModule(mMyCallback,
const_cast<effect_descriptor_t *>(&mDescriptor),
mMyCallback->newEffectId(), AUDIO_SESSION_DEVICE,
false /* pinned */, port->id);
- if (audio_is_input_device(mDevice.mType)) {
- mHalEffect->setInputDevice(mDevice);
- } else {
- mHalEffect->setDevices({mDevice});
+ if (audio_is_input_device(mDevice.mType)) {
+ mHalEffect->setInputDevice(mDevice);
+ } else {
+ mHalEffect->setDevices({mDevice});
+ }
+ mHalEffect->configure();
}
- mHalEffect->configure();
-
*handle = new EffectHandle(mHalEffect, nullptr, nullptr, 0 /*priority*/,
mNotifyFramesProcessed);
status = (*handle)->initCheck();
@@ -3376,7 +3394,7 @@
mDevicePort.id = AUDIO_PORT_HANDLE_NONE;
}
} else if (patch.isSoftware() || patch.thread().promote() != nullptr) {
- sp <AudioFlinger::ThreadBase> thread;
+ sp<IAfThreadBase> thread;
if (audio_port_config_has_input_direction(port)) {
if (patch.isSoftware()) {
thread = patch.mRecord.thread();
@@ -3453,6 +3471,23 @@
return mManagerCallback->removeEffectFromHal(&mDevicePort, effect);
}
+status_t DeviceEffectProxy::command(
+ int32_t cmdCode, const std::vector<uint8_t>& cmdData, int32_t maxReplySize,
+ std::vector<uint8_t>* reply) {
+ Mutex::Autolock _l(mProxyLock);
+ status_t status = EffectBase::command(cmdCode, cmdData, maxReplySize, reply);
+ if (status == NO_ERROR) {
+ for (auto& handle : mEffectHandles) {
+ sp<IAfEffectBase> effect = handle.second->effect().promote();
+ if (effect != nullptr) {
+ status = effect->command(cmdCode, cmdData, maxReplySize, reply);
+ }
+ }
+ }
+ ALOGV("%s status %d", __func__, status);
+ return status;
+}
+
bool DeviceEffectProxy::isOutput() const {
if (mDevicePort.id != AUDIO_PORT_HANDLE_NONE) {
return mDevicePort.role == AUDIO_PORT_ROLE_SINK;
@@ -3489,7 +3524,7 @@
const Vector<String16> args;
EffectBase::dump(fd, args);
- const bool locked = AudioFlinger::dumpTryLock(mProxyLock);
+ const bool locked = afutils::dumpTryLock(mProxyLock);
if (!locked) {
String8 result("DeviceEffectProxy may be deadlocked\n");
write(fd, result.string(), result.size());
@@ -3519,7 +3554,7 @@
}
if (locked) {
- mLock.unlock();
+ mProxyLock.unlock();
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 07790be..79b4e63 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -15,6 +15,17 @@
** limitations under the License.
*/
+#pragma once
+
+#include "DeviceEffectManager.h"
+#include "IAfEffect.h"
+
+#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
+#include <mediautils/Synchronization.h>
+#include <private/media/AudioEffectShared.h>
+
+#include <map> // avoid transitive dependency
+
namespace android {
//--- Audio Effect Management
@@ -382,8 +393,7 @@
// it also provide it's own input buffer used by the track as accumulation buffer.
class EffectChain : public IAfEffectChain {
public:
- EffectChain(const wp<AudioFlinger::ThreadBase>& wThread, audio_session_t sessionId);
- ~EffectChain() override;
+ EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId);
void process_l() final;
@@ -479,12 +489,7 @@
bool isBitPerfectCompatible() const final;
// isCompatibleWithThread_l() must be called with thread->mLock held
- // TODO(b/288339104) type
- bool isCompatibleWithThread_l(const sp<Thread>& thread) const final {
- return isCompatibleWithThread_l(sp<AudioFlinger::ThreadBase>::cast(thread));
- }
-
- bool isCompatibleWithThread_l(const sp<AudioFlinger::ThreadBase>& thread) const;
+ bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final;
bool containsHapticGeneratingEffect_l() final;
@@ -492,8 +497,7 @@
sp<EffectCallbackInterface> effectCallback() const final { return mEffectCallback; }
- // TODO(b/288339104) type
- wp<Thread> thread() const final { return mEffectCallback->thread(); }
+ wp<IAfThreadBase> thread() const final { return mEffectCallback->thread(); }
bool isFirstEffect(int id) const final {
return !mEffects.isEmpty() && id == mEffects[0]->id();
@@ -507,12 +511,7 @@
return mEffects[index];
}
- // TODO(b/288339104) type
- void setThread(const sp<Thread>& thread) final {
- setThread(sp<AudioFlinger::ThreadBase>::cast(thread));
- }
-
- void setThread(const sp<AudioFlinger::ThreadBase>& thread);
+ void setThread(const sp<IAfThreadBase>& thread) final;
private:
@@ -527,16 +526,11 @@
// Note: ctors taking a weak pointer to their owner must not promote it
// during construction (but may keep a reference for later promotion).
EffectCallback(const wp<EffectChain>& owner,
- const wp<AudioFlinger::ThreadBase>& thread)
+ const sp<IAfThreadBase>& thread) // we take a sp<> but store a wp<>.
: mChain(owner)
- , mThread(thread)
- , mAudioFlinger(*AudioFlinger::gAudioFlinger) {
- sp<AudioFlinger::ThreadBase> base = thread.promote();
- if (base != nullptr) {
- mThreadType = base->type();
- } else {
- mThreadType = AudioFlinger::ThreadBase::MIXER; // assure a consistent value.
- }
+ , mThread(thread) {
+ mThreadType = thread->type();
+ mAfThreadCallback = thread->afThreadCallback();
}
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -577,21 +571,22 @@
wp<IAfEffectChain> chain() const final { return mChain; }
bool isAudioPolicyReady() const final {
- return mAudioFlinger.isAudioPolicyReady();
+ return mAfThreadCallback->isAudioPolicyReady();
}
- wp<AudioFlinger::ThreadBase> thread() const { return mThread.load(); }
+ wp<IAfThreadBase> thread() const { return mThread.load(); }
- void setThread(const sp<AudioFlinger::ThreadBase>& thread) {
+ void setThread(const sp<IAfThreadBase>& thread) {
mThread = thread;
mThreadType = thread->type();
+ mAfThreadCallback = thread->afThreadCallback();
}
private:
const wp<IAfEffectChain> mChain;
- mediautils::atomic_wp<AudioFlinger::ThreadBase> mThread;
- AudioFlinger &mAudioFlinger; // implementation detail: outer instance always exists.
- AudioFlinger::ThreadBase::type_t mThreadType;
+ mediautils::atomic_wp<IAfThreadBase> mThread;
+ sp<IAfThreadCallback> mAfThreadCallback;
+ IAfThreadBase::type_t mThreadType;
};
DISALLOW_COPY_AND_ASSIGN(EffectChain);
@@ -657,7 +652,7 @@
class DeviceEffectProxy : public IAfDeviceEffectProxy, public EffectBase {
public:
DeviceEffectProxy(const AudioDeviceTypeAddr& device,
- const sp<AudioFlinger::DeviceEffectManagerCallback>& callback,
+ const sp<DeviceEffectManagerCallback>& callback,
effect_descriptor_t *desc, int id, bool notifyFramesProcessed)
: EffectBase(callback, desc, id, AUDIO_SESSION_DEVICE, false),
mDevice(device), mManagerCallback(callback),
@@ -667,22 +662,14 @@
status_t setEnabled(bool enabled, bool fromHandle) final;
sp<IAfDeviceEffectProxy> asDeviceEffectProxy() final { return this; }
- // TODO(b/288339104) type
- status_t init(const /* std::map<audio_patch_handle_t,
- PatchPanel::Patch>& */ void * patches) final {
- return init(*reinterpret_cast<const std::map<
- audio_patch_handle_t, AudioFlinger::PatchPanel::Patch> *>(patches));
- }
- // TODO(b/288339104) type
- status_t onCreatePatch(audio_patch_handle_t patchHandle,
- /* const PatchPanel::Patch& */ const void * patch) final {
- return onCreatePatch(patchHandle,
- *reinterpret_cast<const AudioFlinger::PatchPanel::Patch *>(patch));
- }
+ status_t init(const std::map<audio_patch_handle_t,
+ IAfPatchPanel::Patch>& patches) final;
- status_t init(const std::map<audio_patch_handle_t, AudioFlinger::PatchPanel::Patch>& patches);
- status_t onCreatePatch(
- audio_patch_handle_t patchHandle, const AudioFlinger::PatchPanel::Patch& patch);
+ status_t onCreatePatch(audio_patch_handle_t patchHandle,
+ const IAfPatchPanel::Patch& patch) final;
+
+ status_t onUpdatePatch(audio_patch_handle_t oldPatchHandle, audio_patch_handle_t newPatchHandle,
+ const IAfPatchPanel::Patch& patch) final;
void onReleasePatch(audio_patch_handle_t patchHandle) final;
@@ -697,6 +684,11 @@
audio_channel_mask_t channelMask() const final;
uint32_t channelCount() const final;
+ status_t command(int32_t cmdCode,
+ const std::vector<uint8_t>& cmdData,
+ int32_t maxReplySize,
+ std::vector<uint8_t>* reply) final;
+
void dump2(int fd, int spaces) const final;
private:
@@ -706,7 +698,7 @@
// Note: ctors taking a weak pointer to their owner must not promote it
// during construction (but may keep a reference for later promotion).
ProxyCallback(const wp<DeviceEffectProxy>& owner,
- const sp<AudioFlinger::DeviceEffectManagerCallback>& callback)
+ const sp<DeviceEffectManagerCallback>& callback)
: mProxy(owner), mManagerCallback(callback) {}
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -757,14 +749,14 @@
private:
const wp<DeviceEffectProxy> mProxy;
- const sp<AudioFlinger::DeviceEffectManagerCallback> mManagerCallback;
+ const sp<DeviceEffectManagerCallback> mManagerCallback;
};
- status_t checkPort(const AudioFlinger::PatchPanel::Patch& patch,
+ status_t checkPort(const IAfPatchPanel::Patch& patch,
const struct audio_port_config *port, sp<IAfEffectHandle> *handle);
const AudioDeviceTypeAddr mDevice;
- const sp<AudioFlinger::DeviceEffectManagerCallback> mManagerCallback;
+ const sp<DeviceEffectManagerCallback> mManagerCallback;
const sp<ProxyCallback> mMyCallback;
mutable Mutex mProxyLock;
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 75112ca..c4f0de3 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -16,13 +16,28 @@
#pragma once
+#include "IAfPatchPanel.h" // full class Patch definition needed
+
+#include <android/media/AudioVibratorInfo.h>
+#include <android/media/BnEffect.h>
+#include <android/media/BnEffectClient.h>
+#include <media/AudioCommonTypes.h> // product_strategy_t
+#include <media/AudioDeviceTypeAddr.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
namespace android {
+class Client;
+class DeviceEffectManagerCallback;
+
class IAfDeviceEffectProxy;
class IAfEffectBase;
class IAfEffectChain;
class IAfEffectHandle;
class IAfEffectModule;
+class IAfThreadBase;
// Interface implemented by the EffectModule parent or owner (e.g an EffectChain) to abstract
// interactions between the EffectModule and the reset of the audio framework.
@@ -109,6 +124,11 @@
virtual sp<IAfEffectModule> asEffectModule() = 0;
virtual sp<IAfDeviceEffectProxy> asDeviceEffectProxy() = 0;
+ virtual status_t command(int32_t cmdCode,
+ const std::vector<uint8_t>& cmdData,
+ int32_t maxReplySize,
+ std::vector<uint8_t>* reply) = 0;
+
virtual void dump(int fd, const Vector<String16>& args) const = 0;
private:
@@ -117,11 +137,6 @@
virtual void setSuspended(bool suspended) = 0;
virtual bool suspended() const = 0;
- virtual status_t command(int32_t cmdCode,
- const std::vector<uint8_t>& cmdData,
- int32_t maxReplySize,
- std::vector<uint8_t>* reply) = 0;
-
virtual ssize_t disconnectHandle(IAfEffectHandle *handle, bool unpinIfLast) = 0;
virtual ssize_t removeHandle_l(IAfEffectHandle *handle) = 0;
virtual IAfEffectHandle* controlHandle_l() = 0;
@@ -190,7 +205,7 @@
// Most of these methods are accessed from AudioFlinger::Thread
public:
static sp<IAfEffectChain> create(
- const wp<Thread /*ThreadBase*/>& wThread, // TODO(b/288339104) type
+ const sp<IAfThreadBase>& thread,
audio_session_t sessionId);
// special key used for an entry in mSuspendedEffects keyed vector
@@ -279,8 +294,7 @@
virtual bool isBitPerfectCompatible() const = 0;
// isCompatibleWithThread_l() must be called with thread->mLock held
- // TODO(b/288339104) type
- virtual bool isCompatibleWithThread_l(const sp<Thread>& thread) const = 0;
+ virtual bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const = 0;
virtual bool containsHapticGeneratingEffect_l() = 0;
@@ -288,8 +302,8 @@
virtual sp<EffectCallbackInterface> effectCallback() const = 0;
- virtual wp<Thread> thread() const = 0; // TODO(b/288339104) type
- virtual void setThread(const sp<Thread>& thread) = 0; // TODO(b/288339104) type
+ virtual wp<IAfThreadBase> thread() const = 0;
+ virtual void setThread(const sp<IAfThreadBase>& thread) = 0;
virtual bool isFirstEffect(int id) const = 0;
@@ -335,22 +349,24 @@
class IAfDeviceEffectProxy : public virtual IAfEffectBase {
public:
- // TODO(b/288339104) type
static sp<IAfDeviceEffectProxy> create(const AudioDeviceTypeAddr& device,
- const sp</* DeviceEffectManagerCallback */ RefBase>& callback,
+ const sp<DeviceEffectManagerCallback>& callback,
effect_descriptor_t *desc, int id, bool notifyFramesProcessed);
virtual status_t init(
- const /* std::map<audio_patch_handle_t,
- PatchPanel::Patch>& */ void * patches) = 0; // TODO(b/288339104) type
+ const std::map<audio_patch_handle_t,
+ IAfPatchPanel::Patch>& patches) = 0;
virtual const AudioDeviceTypeAddr& device() const = 0;
virtual status_t onCreatePatch(
audio_patch_handle_t patchHandle,
- /* const PatchPanel::Patch& */ const void * patch) = 0;
+ const IAfPatchPanel::Patch& patch) = 0;
+ virtual status_t onUpdatePatch(audio_patch_handle_t oldPatchHandle,
+ audio_patch_handle_t newPatchHandle,
+ const IAfPatchPanel::Patch& patch) = 0;
virtual void onReleasePatch(audio_patch_handle_t patchHandle) = 0;
- virtual void dump2(int fd, int spaces) const = 0; // TODO(b/288339104) naming?
+ virtual void dump2(int fd, int spaces) const = 0; // TODO(b/291319101) naming?
private:
// used by DeviceEffectProxy
@@ -364,4 +380,4 @@
virtual status_t removeEffectFromHal(const sp<EffectHalInterface>& effect) = 0;
};
-} // namespace android
+} // namespace android
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
new file mode 100644
index 0000000..20e092d
--- /dev/null
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// The following includes are required because we have class definitions below
+// for EndPoint and Patch, which precludes using a forward declaration only.
+#include "IAfThread.h" // IAfThreadBase IAfMmapThread IAfPlaybackThread IAfRecordThread
+#include "IAfTrack.h" // IAfPatchRecord IAfPatchTrack
+
+#include <datapath/AudioHwDevice.h>
+#include <media/DeviceDescriptorBase.h>
+#include <utils/Log.h> // ALOG used in this file
+#include <utils/RefBase.h> // avoid transitive dependency
+#include <utils/Thread.h>
+
+namespace android {
+
+class IAfPatchPanel;
+class PatchCommandThread;
+
+class SoftwarePatch {
+public:
+ SoftwarePatch(
+ const sp<const IAfPatchPanel>& patchPanel,
+ audio_patch_handle_t patchHandle,
+ audio_io_handle_t playbackThreadHandle,
+ audio_io_handle_t recordThreadHandle)
+ : mPatchPanel(patchPanel),
+ mPatchHandle(patchHandle),
+ mPlaybackThreadHandle(playbackThreadHandle),
+ mRecordThreadHandle(recordThreadHandle) {}
+ SoftwarePatch(const SoftwarePatch&) = default;
+
+ // Must be called under AudioFlinger::mLock
+ status_t getLatencyMs_l(double* latencyMs) const;
+ audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
+ audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
+ audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
+
+private:
+ const sp<const IAfPatchPanel> mPatchPanel;
+ const audio_patch_handle_t mPatchHandle;
+ const audio_io_handle_t mPlaybackThreadHandle;
+ const audio_io_handle_t mRecordThreadHandle;
+};
+
+class IAfPatchPanelCallback : public virtual RefBase {
+public:
+ virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) = 0;
+ virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) = 0;
+ virtual IAfPlaybackThread* primaryPlaybackThread_l() const = 0;
+ virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const = 0;
+ virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const = 0;
+ virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const = 0;
+ virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t* input,
+ audio_config_t* config,
+ audio_devices_t device,
+ const char* address,
+ audio_source_t source,
+ audio_input_flags_t flags,
+ audio_devices_t outputDevice,
+ const String8& outputDeviceAddress) = 0;
+ virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
+ audio_io_handle_t* output,
+ audio_config_t* halConfig,
+ audio_config_base_t* mixerConfig,
+ audio_devices_t deviceType,
+ const String8& address,
+ audio_output_flags_t flags) = 0;
+ virtual void lock() const = 0;
+ virtual void unlock() const = 0;
+ virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+ getAudioHwDevs_l() const = 0;
+ virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
+ virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+ virtual void updateDownStreamPatches_l(
+ const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) = 0;
+ virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) = 0;
+};
+
+class IAfPatchPanel : public virtual RefBase {
+public:
+ static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback);
+
+ // Extraction of inner Endpoint and Patch classes would require interfaces
+ // (in the Endpoint case a templated interface) but that seems
+ // excessive for now. We keep them as inner classes until extraction
+ // is needed.
+ template <typename ThreadType, typename TrackType>
+ class Endpoint final {
+ public:
+ Endpoint() = default;
+ Endpoint(const Endpoint&) = delete;
+ Endpoint& operator=(const Endpoint& other) noexcept {
+ mThread = other.mThread;
+ mCloseThread = other.mCloseThread;
+ mHandle = other.mHandle;
+ mTrack = other.mTrack;
+ return *this;
+ }
+ Endpoint(Endpoint&& other) noexcept { swap(other); }
+ Endpoint& operator=(Endpoint&& other) noexcept {
+ swap(other);
+ return *this;
+ }
+ ~Endpoint() {
+ ALOGE_IF(
+ mHandle != AUDIO_PATCH_HANDLE_NONE,
+ "A non empty Patch Endpoint leaked, handle %d", mHandle);
+ }
+
+ status_t checkTrack(TrackType* trackOrNull) const {
+ if (trackOrNull == nullptr) return NO_MEMORY;
+ return trackOrNull->initCheck();
+ }
+ audio_patch_handle_t handle() const { return mHandle; }
+ sp<ThreadType> thread() const { return mThread; }
+ sp<TrackType> track() const { return mTrack; }
+ sp<const ThreadType> const_thread() const { return mThread; }
+ sp<const TrackType> const_track() const { return mTrack; }
+
+ void closeConnections(const sp<IAfPatchPanel>& panel) {
+ if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
+ panel->releaseAudioPatch(mHandle);
+ mHandle = AUDIO_PATCH_HANDLE_NONE;
+ }
+ if (mThread != nullptr) {
+ if (mTrack != nullptr) {
+ mThread->deletePatchTrack(mTrack);
+ }
+ if (mCloseThread) {
+ panel->closeThreadInternal_l(mThread);
+ }
+ }
+ }
+ audio_patch_handle_t* handlePtr() { return &mHandle; }
+ void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
+ mThread = thread;
+ mCloseThread = closeThread;
+ }
+ template <typename T>
+ void setTrackAndPeer(const sp<TrackType>& track, const sp<T>& peer, bool holdReference) {
+ mTrack = track;
+ mThread->addPatchTrack(mTrack);
+ mTrack->setPeerProxy(peer, holdReference);
+ mClearPeerProxy = holdReference;
+ }
+ void clearTrackPeer() {
+ if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy();
+ }
+ void stopTrack() {
+ if (mTrack) mTrack->stop();
+ }
+
+ void swap(Endpoint& other) noexcept {
+ using std::swap;
+ swap(mThread, other.mThread);
+ swap(mCloseThread, other.mCloseThread);
+ swap(mClearPeerProxy, other.mClearPeerProxy);
+ swap(mHandle, other.mHandle);
+ swap(mTrack, other.mTrack);
+ }
+
+ friend void swap(Endpoint& a, Endpoint& b) noexcept { a.swap(b); }
+
+ private:
+ sp<ThreadType> mThread;
+ bool mCloseThread = true;
+ bool mClearPeerProxy = true;
+ audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
+ sp<TrackType> mTrack;
+ };
+
+ class Patch final {
+ public:
+ Patch(const struct audio_patch& patch, bool endpointPatch)
+ : mAudioPatch(patch), mIsEndpointPatch(endpointPatch) {}
+ Patch() = default;
+ ~Patch();
+ Patch(const Patch& other) noexcept {
+ mAudioPatch = other.mAudioPatch;
+ mHalHandle = other.mHalHandle;
+ mPlayback = other.mPlayback;
+ mRecord = other.mRecord;
+ mThread = other.mThread;
+ mIsEndpointPatch = other.mIsEndpointPatch;
+ }
+ Patch(Patch&& other) noexcept { swap(other); }
+ Patch& operator=(Patch&& other) noexcept {
+ swap(other);
+ return *this;
+ }
+
+ void swap(Patch& other) noexcept {
+ using std::swap;
+ swap(mAudioPatch, other.mAudioPatch);
+ swap(mHalHandle, other.mHalHandle);
+ swap(mPlayback, other.mPlayback);
+ swap(mRecord, other.mRecord);
+ swap(mThread, other.mThread);
+ swap(mIsEndpointPatch, other.mIsEndpointPatch);
+ }
+
+ friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); }
+
+ status_t createConnections(const sp<IAfPatchPanel>& panel);
+ void clearConnections(const sp<IAfPatchPanel>& panel);
+ bool isSoftware() const {
+ return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
+ mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE;
+ }
+
+ void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; }
+ wp<IAfThreadBase> thread() const { return mThread; }
+
+ // returns the latency of the patch (from record to playback).
+ status_t getLatencyMs(double* latencyMs) const;
+
+ String8 dump(audio_patch_handle_t myHandle) const;
+
+ // Note that audio_patch::id is only unique within a HAL module
+ struct audio_patch mAudioPatch;
+ // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
+ audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
+ // below members are used by a software audio patch connecting a source device from a
+ // given audio HW module to a sink device on an other audio HW module.
+ // the objects are created by createConnections() and released by clearConnections()
+ // playback thread is created if no existing playback thread can be used
+ // connects playback thread output to sink device
+ Endpoint<IAfPlaybackThread, IAfPatchTrack> mPlayback;
+ // connects source device to record thread input
+ Endpoint<IAfRecordThread, IAfPatchRecord> mRecord;
+
+ wp<IAfThreadBase> mThread;
+ bool mIsEndpointPatch;
+ };
+
+ /* List connected audio ports and their attributes */
+ virtual status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) = 0;
+
+ /* Get supported attributes for a given audio port */
+ virtual status_t getAudioPort(struct audio_port_v7* port) = 0;
+
+ /* Create a patch between several source and sink ports */
+ virtual status_t createAudioPatch(
+ const struct audio_patch* patch,
+ audio_patch_handle_t* handle,
+ bool endpointPatch = false) = 0;
+
+ /* Release a patch */
+ virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
+
+ /* List connected audio devices and they attributes */
+ virtual status_t listAudioPatches(unsigned int* num_patches, struct audio_patch* patches) = 0;
+
+ // Retrieves all currently estrablished software patches for a stream
+ // opened on an intermediate module.
+ virtual status_t getDownstreamSoftwarePatches(
+ audio_io_handle_t stream, std::vector<SoftwarePatch>* patches) const = 0;
+
+ // Notifies patch panel about all opened and closed streams.
+ virtual void notifyStreamOpened(
+ AudioHwDevice* audioHwDevice, audio_io_handle_t stream, struct audio_patch* patch) = 0;
+
+ virtual void notifyStreamClosed(audio_io_handle_t stream) = 0;
+
+ virtual void dump(int fd) const = 0;
+
+ // Must be called under AudioFlinger::mLock
+
+ virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const = 0;
+
+ virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const = 0;
+
+ virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const = 0;
+};
+
+} // namespace android
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
new file mode 100644
index 0000000..be51d51
--- /dev/null
+++ b/services/audioflinger/IAfThread.h
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/media/IAudioTrackCallback.h>
+#include <android/media/IEffectClient.h>
+#include <audiomanager/IAudioManager.h>
+#include <audio_utils/MelProcessor.h>
+#include <binder/MemoryDealer.h>
+#include <datapath/AudioStreamIn.h>
+#include <datapath/AudioStreamOut.h>
+#include <datapath/VolumeInterface.h>
+#include <fastpath/FastMixerDumpState.h>
+#include <media/DeviceDescriptorBase.h>
+#include <media/MmapStreamInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <media/nblog/NBLog.h>
+#include <timing/SyncEvent.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
+#include <optional>
+
+namespace android {
+
+class IAfDirectOutputThread;
+class IAfDuplicatingThread;
+class IAfMmapCaptureThread;
+class IAfMmapPlaybackThread;
+class IAfPlaybackThread;
+class IAfRecordThread;
+
+class IAfEffectChain;
+class IAfEffectHandle;
+class IAfEffectModule;
+class IAfPatchPanel;
+class IAfPatchRecord;
+class IAfPatchTrack;
+class IAfRecordTrack;
+class IAfTrack;
+class IAfTrackBase;
+class Client;
+class MelReporter;
+
+// Used internally for Threads.cpp and AudioFlinger.cpp
+struct stream_type_t {
+ float volume = 1.f;
+ bool mute = false;
+};
+
+// Note this is exposed through IAfThreadBase::afThreadCallback()
+// and hence may be used by the Effect / Track framework.
+class IAfThreadCallback : public virtual RefBase {
+public:
+ virtual Mutex& mutex() const = 0;
+ virtual bool isNonOffloadableGlobalEffectEnabled_l() const = 0; // Tracks
+ virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
+ virtual bool btNrecIsOff() const = 0;
+ virtual float masterVolume_l() const = 0;
+ virtual bool masterMute_l() const = 0;
+ virtual float getMasterBalance_l() const = 0;
+ virtual bool streamMute_l(audio_stream_type_t stream) const = 0;
+ virtual audio_mode_t getMode() const = 0;
+ virtual bool isLowRamDevice() const = 0;
+ virtual bool isAudioPolicyReady() const = 0; // Effects
+ virtual uint32_t getScreenState() const = 0;
+ virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const = 0;
+ virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0;
+ virtual const sp<MelReporter>& getMelReporter() const = 0;
+ virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0;
+ virtual sp<IAudioManager> getOrCreateAudioManager() = 0; // Tracks
+
+ virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) = 0;
+ virtual status_t moveEffectChain_l(audio_session_t sessionId,
+ IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) = 0;
+
+ virtual void requestLogMerge() = 0;
+ virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) = 0;
+ virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0;
+
+ virtual sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
+ audio_session_t triggerSession,
+ audio_session_t listenerSession,
+ const audioflinger::SyncEventCallback& callBack,
+ const wp<IAfTrackBase>& cookie) = 0;
+
+ virtual void ioConfigChanged(audio_io_config_event_t event,
+ const sp<AudioIoDescriptor>& ioDesc,
+ pid_t pid = 0) = 0;
+ virtual void onNonOffloadableGlobalEffectEnable() = 0;
+ virtual void onSupportedLatencyModesChanged(
+ audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) = 0;
+};
+
+class IAfThreadBase : public virtual RefBase {
+public:
+ enum type_t {
+ MIXER, // Thread class is MixerThread
+ DIRECT, // Thread class is DirectOutputThread
+ DUPLICATING, // Thread class is DuplicatingThread
+ RECORD, // Thread class is RecordThread
+ OFFLOAD, // Thread class is OffloadThread
+ MMAP_PLAYBACK, // Thread class for MMAP playback stream
+ MMAP_CAPTURE, // Thread class for MMAP capture stream
+ SPATIALIZER, //
+ BIT_PERFECT, // Thread class for BitPerfectThread
+ // When adding a value, also update IAfThreadBase::threadTypeToString()
+ };
+
+ static const char* threadTypeToString(type_t type);
+ static std::string formatToString(audio_format_t format); // compliant for MediaMetrics
+ static bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask);
+ static bool isValidPcmSinkFormat(audio_format_t format);
+
+ virtual status_t readyToRun() = 0;
+ virtual void clearPowerManager() = 0;
+ virtual status_t initCheck() const = 0;
+ virtual type_t type() const = 0;
+ virtual bool isDuplicating() const = 0;
+ virtual audio_io_handle_t id() const = 0;
+ virtual uint32_t sampleRate() const = 0;
+ virtual audio_channel_mask_t channelMask() const = 0;
+ virtual audio_channel_mask_t mixerChannelMask() const = 0;
+ virtual audio_format_t format() const = 0;
+ virtual uint32_t channelCount() const = 0;
+
+ // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
+ // and returns the [normal mix] buffer's frame count.
+ virtual size_t frameCount() const = 0;
+ virtual audio_channel_mask_t hapticChannelMask() const = 0;
+ virtual uint32_t hapticChannelCount() const = 0;
+ virtual uint32_t latency_l() const = 0;
+ virtual void setVolumeForOutput_l(float left, float right) const = 0;
+
+ // Return's the HAL's frame count i.e. fast mixer buffer size.
+ virtual size_t frameCountHAL() const = 0;
+ virtual size_t frameSize() const = 0;
+ // Should be "virtual status_t requestExitAndWait()" and override same
+ // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
+ virtual void exit() = 0;
+ virtual bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) = 0;
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+ virtual void ioConfigChanged(
+ audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+
+ // sendConfigEvent_l() must be called with ThreadBase::mLock held
+ // Can temporarily release the lock if waiting for a reply from
+ // processConfigEvents_l().
+ // status_t sendConfigEvent_l(sp<ConfigEvent>& event);
+ virtual void sendIoConfigEvent(
+ audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+ virtual void sendIoConfigEvent_l(
+ audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+ virtual void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) = 0;
+ virtual void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) = 0;
+ virtual status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) = 0;
+ virtual status_t sendCreateAudioPatchConfigEvent(
+ const struct audio_patch* patch, audio_patch_handle_t* handle) = 0;
+ virtual status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) = 0;
+ virtual status_t sendUpdateOutDeviceConfigEvent(
+ const DeviceDescriptorBaseVector& outDevices) = 0;
+ virtual void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) = 0;
+ virtual void sendCheckOutputStageEffectsEvent() = 0;
+ virtual void sendCheckOutputStageEffectsEvent_l() = 0;
+ virtual void sendHalLatencyModesChangedEvent_l() = 0;
+
+ virtual void processConfigEvents_l() = 0;
+ virtual void setCheckOutputStageEffects() = 0;
+ virtual void cacheParameters_l() = 0;
+ virtual status_t createAudioPatch_l(
+ const struct audio_patch* patch, audio_patch_handle_t* handle) = 0;
+ virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
+ virtual void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) = 0;
+ virtual void toAudioPortConfig(struct audio_port_config* config) = 0;
+ virtual void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) = 0;
+
+ // see note at declaration of mStandby, mOutDevice and mInDevice
+ virtual bool inStandby() const = 0;
+ virtual const DeviceTypeSet outDeviceTypes() const = 0;
+ virtual audio_devices_t inDeviceType() const = 0;
+ virtual DeviceTypeSet getDeviceTypes() const = 0;
+ virtual const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const = 0;
+ virtual const AudioDeviceTypeAddr& inDeviceTypeAddr() const = 0;
+ virtual bool isOutput() const = 0;
+ virtual bool isOffloadOrMmap() const = 0;
+ virtual sp<StreamHalInterface> stream() const = 0;
+ virtual sp<IAfEffectHandle> createEffect_l(
+ const sp<Client>& client,
+ const sp<media::IEffectClient>& effectClient,
+ int32_t priority,
+ audio_session_t sessionId,
+ effect_descriptor_t* desc,
+ int* enabled,
+ status_t* status /*non-NULL*/,
+ bool pinned,
+ bool probe,
+ bool notifyFramesProcessed) = 0;
+
+ // return values for hasAudioSession (bit field)
+ enum effect_state {
+ EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
+ // effect
+ TRACK_SESSION = 0x2, // the audio session corresponds to at least one
+ // track
+ FAST_SESSION = 0x4, // the audio session corresponds to at least one
+ // fast track
+ SPATIALIZED_SESSION = 0x8, // the audio session corresponds to at least one
+ // spatialized track
+ BIT_PERFECT_SESSION = 0x10 // the audio session corresponds to at least one
+ // bit-perfect track
+ };
+
+ // get effect chain corresponding to session Id.
+ virtual sp<IAfEffectChain> getEffectChain(audio_session_t sessionId) const = 0;
+ // same as getEffectChain() but must be called with ThreadBase mutex locked
+ virtual sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const = 0;
+ virtual std::vector<int> getEffectIds_l(audio_session_t sessionId) const = 0;
+ // add an effect chain to the chain list (mEffectChains)
+ virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
+ // remove an effect chain from the chain list (mEffectChains)
+ virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
+ // lock all effect chains Mutexes. Must be called before releasing the
+ // ThreadBase mutex before processing the mixer and effects. This guarantees the
+ // integrity of the chains during the process.
+ // Also sets the parameter 'effectChains' to current value of mEffectChains.
+ virtual void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) = 0;
+ // unlock effect chains after process
+ virtual void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains) = 0;
+ // get a copy of mEffectChains vector
+ virtual Vector<sp<IAfEffectChain>> getEffectChains_l() const = 0;
+ // set audio mode to all effect chains
+ virtual void setMode(audio_mode_t mode) = 0;
+ // get effect module with corresponding ID on specified audio session
+ virtual sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const = 0;
+ virtual sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const = 0;
+ // add and effect module. Also creates the effect chain is none exists for
+ // the effects audio session. Only called in a context of moving an effect
+ // from one thread to another
+ virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0;
+ // remove and effect module. Also removes the effect chain is this was the last
+ // effect
+ virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0;
+ // disconnect an effect handle from module and destroy module if last handle
+ virtual void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) = 0;
+ // detach all tracks connected to an auxiliary effect
+ virtual void detachAuxEffect_l(int effectId) = 0;
+ // returns a combination of:
+ // - EFFECT_SESSION if effects on this audio session exist in one chain
+ // - TRACK_SESSION if tracks on this audio session exist
+ // - FAST_SESSION if fast tracks on this audio session exist
+ // - SPATIALIZED_SESSION if spatialized tracks on this audio session exist
+ virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const = 0;
+ virtual uint32_t hasAudioSession(audio_session_t sessionId) const = 0;
+
+ // the value returned by default implementation is not important as the
+ // strategy is only meaningful for PlaybackThread which implements this method
+ virtual product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const = 0;
+
+ // check if some effects must be suspended/restored when an effect is enabled
+ // or disabled
+ virtual void checkSuspendOnEffectEnabled(
+ bool enabled, audio_session_t sessionId, bool threadLocked) = 0;
+
+ virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
+ virtual bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const = 0;
+
+ // Return a reference to a per-thread heap which can be used to allocate IMemory
+ // objects that will be read-only to client processes, read/write to mediaserver,
+ // and shared by all client processes of the thread.
+ // The heap is per-thread rather than common across all threads, because
+ // clients can't be trusted not to modify the offset of the IMemory they receive.
+ // If a thread does not have such a heap, this method returns 0.
+ virtual sp<MemoryDealer> readOnlyHeap() const = 0;
+
+ virtual sp<IMemory> pipeMemory() const = 0;
+
+ virtual void systemReady() = 0;
+
+ // checkEffectCompatibility_l() must be called with ThreadBase::mLock held
+ virtual status_t checkEffectCompatibility_l(
+ const effect_descriptor_t* desc, audio_session_t sessionId) = 0;
+
+ virtual void broadcast_l() = 0;
+
+ virtual bool isTimestampCorrectionEnabled() const = 0;
+
+ virtual bool isMsdDevice() const = 0;
+
+ virtual void dump(int fd, const Vector<String16>& args) = 0;
+
+ // deliver stats to mediametrics.
+ virtual void sendStatistics(bool force) = 0;
+
+ virtual Mutex& mutex() const = 0;
+
+ virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0;
+ virtual void onEffectDisable() = 0;
+
+ // invalidateTracksForAudioSession_l must be called with holding mLock.
+ virtual void invalidateTracksForAudioSession_l(audio_session_t sessionId) const = 0;
+ // Invalidate all the tracks with the given audio session.
+ virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0;
+
+ virtual bool isStreamInitialized() const = 0;
+ virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0;
+ virtual void stopMelComputation_l() = 0;
+
+ virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0;
+
+ virtual void setEffectSuspended_l(
+ const effect_uuid_t* type, bool suspend, audio_session_t sessionId) = 0;
+
+ // Dynamic cast to derived interface
+ virtual sp<IAfDirectOutputThread> asIAfDirectOutputThread() { return nullptr; }
+ virtual sp<IAfDuplicatingThread> asIAfDuplicatingThread() { return nullptr; }
+ virtual sp<IAfPlaybackThread> asIAfPlaybackThread() { return nullptr; }
+ virtual sp<IAfRecordThread> asIAfRecordThread() { return nullptr; }
+ virtual IAfThreadCallback* afThreadCallback() const = 0;
+};
+
+class IAfPlaybackThread : public virtual IAfThreadBase, public virtual VolumeInterface {
+public:
+ static sp<IAfPlaybackThread> createBitPerfectThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady);
+
+ static sp<IAfPlaybackThread> createDirectOutputThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady, const audio_offload_info_t& offloadInfo);
+
+ static sp<IAfPlaybackThread> createMixerThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady, type_t type = MIXER,
+ audio_config_base_t* mixerConfig = nullptr);
+
+ static sp<IAfPlaybackThread> createOffloadThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady, const audio_offload_info_t& offloadInfo);
+
+ static sp<IAfPlaybackThread> createSpatializerThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady, audio_config_base_t* mixerConfig);
+
+ static constexpr int8_t kMaxTrackStopRetriesOffload = 2;
+
+ enum mixer_state {
+ MIXER_IDLE, // no active tracks
+ MIXER_TRACKS_ENABLED, // at least one active track, but no track has any data ready
+ MIXER_TRACKS_READY, // at least one active track, and at least one track has data
+ MIXER_DRAIN_TRACK, // drain currently playing track
+ MIXER_DRAIN_ALL, // fully drain the hardware
+ // standby mode does not have an enum value
+ // suspend by audio policy manager is orthogonal to mixer state
+ };
+
+ // return estimated latency in milliseconds, as reported by HAL
+ virtual uint32_t latency() const = 0; // should be in IAfThreadBase?
+
+ virtual uint32_t& fastTrackAvailMask_l() = 0;
+
+ virtual sp<IAfTrack> createTrack_l(
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ const audio_attributes_t& attr,
+ uint32_t* sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t* pFrameCount,
+ size_t* pNotificationFrameCount,
+ uint32_t notificationsPerBuffer,
+ float speed,
+ const sp<IMemory>& sharedBuffer,
+ audio_session_t sessionId,
+ audio_output_flags_t* flags,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ pid_t tid,
+ status_t* status /*non-NULL*/,
+ audio_port_handle_t portId,
+ const sp<media::IAudioTrackCallback>& callback,
+ bool isSpatialized,
+ bool isBitPerfect) = 0;
+
+ virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0;
+ virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0;
+ virtual bool isTrackActive(const sp<IAfTrack>& track) const = 0;
+ virtual void addOutputTrack_l(const sp<IAfTrack>& track) = 0;
+
+ virtual AudioStreamOut* getOutput_l() const = 0;
+ virtual AudioStreamOut* getOutput() const = 0;
+ virtual AudioStreamOut* clearOutput() = 0;
+
+ // a very large number of suspend() will eventually wraparound, but unlikely
+ virtual void suspend() = 0;
+ virtual void restore() = 0;
+ virtual bool isSuspended() const = 0;
+ virtual status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const = 0;
+ // Consider also removing and passing an explicit mMainBuffer initialization
+ // parameter to AF::IAfTrack::Track().
+ virtual float* sinkBuffer() const = 0;
+
+ virtual status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) = 0;
+ virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) = 0;
+
+ // called with AudioFlinger lock held
+ virtual bool invalidateTracks_l(audio_stream_type_t streamType) = 0;
+ virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) = 0;
+ virtual void invalidateTracks(audio_stream_type_t streamType) = 0;
+ // Invalidate tracks by a set of port ids. The port id will be removed from
+ // the given set if the corresponding track is found and invalidated.
+ virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;
+
+ virtual status_t getTimestamp_l(AudioTimestamp& timestamp) = 0;
+ virtual void addPatchTrack(const sp<IAfPatchTrack>& track) = 0;
+ virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) = 0;
+
+ // Return the asynchronous signal wait time.
+ virtual int64_t computeWaitTimeNs_l() const = 0;
+ // returns true if the track is allowed to be added to the thread.
+ virtual bool isTrackAllowed_l(
+ audio_channel_mask_t channelMask, audio_format_t format, audio_session_t sessionId,
+ uid_t uid) const = 0;
+
+ virtual bool supportsHapticPlayback() const = 0;
+
+ virtual void setDownStreamPatch(const struct audio_patch* patch) = 0;
+
+ virtual IAfTrack* getTrackById_l(audio_port_handle_t trackId) = 0;
+
+ virtual bool hasMixer() const = 0;
+
+ virtual status_t setRequestedLatencyMode(audio_latency_mode_t mode) = 0;
+
+ virtual status_t getSupportedLatencyModes(std::vector<audio_latency_mode_t>* modes) = 0;
+
+ virtual status_t setBluetoothVariableLatencyEnabled(bool enabled) = 0;
+
+ virtual void setStandby() = 0;
+ virtual void setStandby_l() = 0;
+ virtual bool waitForHalStart() = 0;
+
+ virtual bool hasFastMixer() const = 0;
+ virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const = 0;
+ virtual const std::atomic<int64_t>& framesWritten() const = 0;
+
+ virtual bool usesHwAvSync() const = 0;
+};
+
+class IAfDirectOutputThread : public virtual IAfPlaybackThread {
+public:
+ virtual status_t selectPresentation(int presentationId, int programId) = 0;
+};
+
+class IAfDuplicatingThread : public virtual IAfPlaybackThread {
+public:
+ static sp<IAfDuplicatingThread> create(
+ const sp<IAfThreadCallback>& afThreadCallback, IAfPlaybackThread* mainThread,
+ audio_io_handle_t id, bool systemReady);
+
+ virtual void addOutputTrack(IAfPlaybackThread* thread) = 0;
+ virtual uint32_t waitTimeMs() const = 0;
+ virtual void removeOutputTrack(IAfPlaybackThread* thread) = 0;
+};
+
+class IAfRecordThread : public virtual IAfThreadBase {
+public:
+ static sp<IAfRecordThread> create(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamIn* input,
+ audio_io_handle_t id, bool systemReady);
+
+ virtual sp<IAfRecordTrack> createRecordTrack_l(
+ const sp<Client>& client,
+ const audio_attributes_t& attr,
+ uint32_t* pSampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t* pFrameCount,
+ audio_session_t sessionId,
+ size_t* pNotificationFrameCount,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ audio_input_flags_t* flags,
+ pid_t tid,
+ status_t* status /*non-NULL*/,
+ audio_port_handle_t portId,
+ int32_t maxSharedAudioHistoryMs) = 0;
+ virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0;
+ virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0;
+
+ virtual status_t start(
+ IAfRecordTrack* recordTrack, AudioSystem::sync_event_t event,
+ audio_session_t triggerSession) = 0;
+
+ // ask the thread to stop the specified track, and
+ // return true if the caller should then do it's part of the stopping process
+ virtual bool stop(IAfRecordTrack* recordTrack) = 0;
+
+ virtual AudioStreamIn* getInput() const = 0;
+ virtual AudioStreamIn* clearInput() = 0;
+
+ virtual status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const = 0;
+ virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
+ virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+
+ virtual void addPatchTrack(const sp<IAfPatchRecord>& record) = 0;
+ virtual void deletePatchTrack(const sp<IAfPatchRecord>& record) = 0;
+ virtual bool fastTrackAvailable() const = 0;
+ virtual void setFastTrackAvailable(bool available) = 0;
+
+ virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
+ virtual bool hasFastCapture() const = 0;
+
+ virtual void checkBtNrec() = 0;
+ virtual uint32_t getInputFramesLost() const = 0;
+
+ virtual status_t shareAudioHistory(
+ const std::string& sharedAudioPackageName,
+ audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
+ int64_t sharedAudioStartMs = -1) = 0;
+ virtual void resetAudioHistory_l() = 0;
+};
+
+class IAfMmapThread : public virtual IAfThreadBase {
+public:
+ // createIAudioTrackAdapter() is a static constructor which creates an
+ // MmapStreamInterface AIDL interface adapter from the MmapThread object that
+ // may be passed back to the client.
+ //
+ // Only one AIDL MmapStreamInterface interface adapter should be created per MmapThread.
+ static sp<MmapStreamInterface> createMmapStreamInterfaceAdapter(
+ const sp<IAfMmapThread>& mmapThread);
+
+ virtual void configure(
+ const audio_attributes_t* attr,
+ audio_stream_type_t streamType,
+ audio_session_t sessionId,
+ const sp<MmapStreamCallback>& callback,
+ audio_port_handle_t deviceId,
+ audio_port_handle_t portId) = 0;
+ virtual void disconnect() = 0;
+
+ // MmapStreamInterface handling (see adapter)
+ virtual status_t createMmapBuffer(
+ int32_t minSizeFrames, struct audio_mmap_buffer_info* info) = 0;
+ virtual status_t getMmapPosition(struct audio_mmap_position* position) const = 0;
+ virtual status_t start(
+ const AudioClient& client, const audio_attributes_t* attr,
+ audio_port_handle_t* handle) = 0;
+ virtual status_t stop(audio_port_handle_t handle) = 0;
+ virtual status_t standby() = 0;
+ virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
+ virtual status_t reportData(const void* buffer, size_t frameCount) = 0;
+
+ // TODO(b/291317898) move to IAfThreadBase?
+ virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) = 0;
+
+ // Sets the UID records silence - TODO(b/291317898) move to IAfMmapCaptureThread
+ virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
+
+ virtual sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() { return nullptr; }
+ virtual sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() { return nullptr; }
+};
+
+class IAfMmapPlaybackThread : public virtual IAfMmapThread, public virtual VolumeInterface {
+public:
+ static sp<IAfMmapPlaybackThread> create(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+ AudioHwDevice* hwDev, AudioStreamOut* output, bool systemReady);
+
+ virtual AudioStreamOut* clearOutput() = 0;
+};
+
+class IAfMmapCaptureThread : public virtual IAfMmapThread {
+public:
+ static sp<IAfMmapCaptureThread> create(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+ AudioHwDevice* hwDev, AudioStreamIn* input, bool systemReady);
+
+ virtual AudioStreamIn* clearInput() = 0;
+};
+
+} // namespace android
diff --git a/services/audioflinger/IAfTrack.h b/services/audioflinger/IAfTrack.h
new file mode 100644
index 0000000..2302e13
--- /dev/null
+++ b/services/audioflinger/IAfTrack.h
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/media/BnAudioRecord.h>
+#include <android/media/BnAudioTrack.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/IMemory.h>
+#include <fastpath/FastMixerDumpState.h>
+#include <media/AudioSystem.h>
+#include <media/VolumeShaper.h>
+#include <private/media/AudioTrackShared.h>
+#include <timing/SyncEvent.h>
+#include <timing/SynchronizedRecordState.h>
+#include <utils/RefBase.h>
+#include <vibrator/ExternalVibration.h>
+
+#include <vector>
+
+namespace android {
+
+class Client;
+class ResamplerBufferProvider;
+struct Source;
+
+class IAfDuplicatingThread;
+class IAfPatchRecord;
+class IAfPatchTrack;
+class IAfPlaybackThread;
+class IAfRecordThread;
+class IAfThreadBase;
+
+struct TeePatch {
+ sp<IAfPatchRecord> patchRecord;
+ sp<IAfPatchTrack> patchTrack;
+};
+
+using TeePatches = std::vector<TeePatch>;
+
+// Common interface to all Playback and Record tracks.
+class IAfTrackBase : public virtual RefBase {
+public:
+ enum track_state : int32_t {
+ IDLE,
+ FLUSHED, // for PlaybackTracks only
+ STOPPED,
+ // next 2 states are currently used for fast tracks
+ // and offloaded tracks only
+ STOPPING_1, // waiting for first underrun
+ STOPPING_2, // waiting for presentation complete
+ RESUMING, // for PlaybackTracks only
+ ACTIVE,
+ PAUSING,
+ PAUSED,
+ STARTING_1, // for RecordTrack only
+ STARTING_2, // for RecordTrack only
+ };
+
+ // where to allocate the data buffer
+ enum alloc_type {
+ ALLOC_CBLK, // allocate immediately after control block
+ ALLOC_READONLY, // allocate from a separate read-only heap per thread
+ ALLOC_PIPE, // do not allocate; use the pipe buffer
+ ALLOC_LOCAL, // allocate a local buffer
+ ALLOC_NONE, // do not allocate:use the buffer passed to TrackBase constructor
+ };
+
+ enum track_type {
+ TYPE_DEFAULT,
+ TYPE_OUTPUT,
+ TYPE_PATCH,
+ };
+
+ virtual status_t initCheck() const = 0;
+ virtual status_t start(
+ AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) = 0;
+ virtual void stop() = 0;
+ virtual sp<IMemory> getCblk() const = 0;
+ virtual audio_track_cblk_t* cblk() const = 0;
+ virtual audio_session_t sessionId() const = 0;
+ virtual uid_t uid() const = 0;
+ virtual pid_t creatorPid() const = 0;
+ virtual uint32_t sampleRate() const = 0;
+ virtual size_t frameSize() const = 0;
+ virtual audio_port_handle_t portId() const = 0;
+ virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
+ virtual track_state state() const = 0;
+ virtual void setState(track_state state) = 0;
+ virtual sp<IMemory> getBuffers() const = 0;
+ virtual void* buffer() const = 0;
+ virtual size_t bufferSize() const = 0;
+ virtual bool isFastTrack() const = 0;
+ virtual bool isDirect() const = 0;
+ virtual bool isOutputTrack() const = 0;
+ virtual bool isPatchTrack() const = 0;
+ virtual bool isExternalTrack() const = 0;
+
+ virtual void invalidate() = 0;
+ virtual bool isInvalid() const = 0;
+
+ virtual void terminate() = 0;
+ virtual bool isTerminated() const = 0;
+
+ virtual audio_attributes_t attributes() const = 0;
+ virtual bool isSpatialized() const = 0;
+ virtual bool isBitPerfect() const = 0;
+
+ // not currently implemented in TrackBase, but overridden.
+ virtual void destroy() {}; // MmapTrack doesn't implement.
+ virtual void appendDumpHeader(String8& result) const = 0;
+ virtual void appendDump(String8& result, bool active) const = 0;
+
+ // Dup with AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+ virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+
+ // Added for RecordTrack and OutputTrack
+ virtual wp<IAfThreadBase> thread() const = 0;
+ virtual const sp<ServerProxy>& serverProxy() const = 0;
+
+ // TEE_SINK
+ virtual void dumpTee(int fd __unused, const std::string& reason __unused) const {};
+
+ /** returns the buffer contents size converted to time in milliseconds
+ * for PCM Playback or Record streaming tracks. The return value is zero for
+ * PCM static tracks and not defined for non-PCM tracks.
+ *
+ * This may be called without the thread lock.
+ */
+ virtual double bufferLatencyMs() const = 0;
+
+ /** returns whether the track supports server latency computation.
+ * This is set in the constructor and constant throughout the track lifetime.
+ */
+ virtual bool isServerLatencySupported() const = 0;
+
+ /** computes the server latency for PCM Playback or Record track
+ * to the device sink/source. This is the time for the next frame in the track buffer
+ * written or read from the server thread to the device source or sink.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the server thread to/from the track buffer
+ * from the device source/sink.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ virtual status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const = 0;
+
+ /** computes the total client latency for PCM Playback or Record tracks
+ * for the next client app access to the device sink/source; i.e. the
+ * server latency plus the buffer latency.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the client app to/from the track buffer
+ * from the device sink/source.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ virtual status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const = 0;
+
+ // TODO: Consider making this external.
+ struct FrameTime {
+ int64_t frames;
+ int64_t timeNs;
+ };
+
+ // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
+ virtual void getKernelFrameTime(FrameTime* ft) const = 0;
+
+ virtual audio_format_t format() const = 0;
+ virtual int id() const = 0;
+
+ virtual const char* getTrackStateAsString() const = 0;
+
+ // Called by the PlaybackThread to indicate that the track is becoming active
+ // and a new interval should start with a given device list.
+ virtual void logBeginInterval(const std::string& devices) = 0;
+
+ // Called by the PlaybackThread to indicate the track is no longer active.
+ virtual void logEndInterval() = 0;
+
+ // Called to tally underrun frames in playback.
+ virtual void tallyUnderrunFrames(size_t frames) = 0;
+
+ virtual audio_channel_mask_t channelMask() const = 0;
+
+ /** @return true if the track has changed (metadata or volume) since
+ * the last time this function was called,
+ * true if this function was never called since the track creation,
+ * false otherwise.
+ * Thread safe.
+ */
+ virtual bool readAndClearHasChanged() = 0;
+
+ /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
+ virtual void setMetadataHasChanged() = 0;
+
+ /**
+ * Called when a track moves to active state to record its contribution to battery usage.
+ * Track state transitions should eventually be handled within the track class.
+ */
+ virtual void beginBatteryAttribution() = 0;
+
+ /**
+ * Called when a track moves out of the active state to record its contribution
+ * to battery usage.
+ */
+ virtual void endBatteryAttribution() = 0;
+
+ /**
+ * For RecordTrack
+ * TODO(b/291317964) either use this or add asRecordTrack or asTrack etc.
+ */
+ virtual void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event __unused){};
+
+ // For Thread use, fast tracks and offloaded tracks only
+ // TODO(b/291317964) rearrange to IAfTrack.
+ virtual bool isStopped() const = 0;
+ virtual bool isStopping() const = 0;
+ virtual bool isStopping_1() const = 0;
+ virtual bool isStopping_2() const = 0;
+};
+
+// Common interface for Playback tracks.
+class IAfTrack : public virtual IAfTrackBase {
+public:
+ // FillingStatus is used for suppressing volume ramp at begin of playing
+ enum FillingStatus { FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE };
+
+ // createIAudioTrackAdapter() is a static constructor which creates an
+ // IAudioTrack AIDL interface adapter from the Track object that
+ // may be passed back to the client (if needed).
+ //
+ // Only one AIDL IAudioTrack interface adapter should be created per Track.
+ static sp<media::IAudioTrack> createIAudioTrackAdapter(const sp<IAfTrack>& track);
+
+ static sp<IAfTrack> create(
+ IAfPlaybackThread* thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount,
+ void* buffer,
+ size_t bufferSize,
+ const sp<IMemory>& sharedBuffer,
+ audio_session_t sessionId,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ audio_output_flags_t flags,
+ track_type type,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
+ /** default behaviour is to start when there are as many frames
+ * ready as possible (aka. Buffer is full). */
+ size_t frameCountToBeReady = SIZE_MAX,
+ float speed = 1.0f,
+ bool isSpatialized = false,
+ bool isBitPerfect = false);
+
+ virtual void pause() = 0;
+ virtual void flush() = 0;
+ virtual audio_stream_type_t streamType() const = 0;
+ virtual bool isOffloaded() const = 0;
+ virtual bool isOffloadedOrDirect() const = 0;
+ virtual bool isStatic() const = 0;
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual status_t selectPresentation(int presentationId, int programId) = 0;
+ virtual status_t attachAuxEffect(int EffectId) = 0;
+ virtual void setAuxBuffer(int EffectId, int32_t* buffer) = 0;
+ virtual int32_t* auxBuffer() const = 0;
+ virtual void setMainBuffer(float* buffer) = 0;
+ virtual float* mainBuffer() const = 0;
+ virtual int auxEffectId() const = 0;
+ virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
+ virtual void signal() = 0;
+ virtual status_t getDualMonoMode(audio_dual_mono_mode_t* mode) const = 0;
+ virtual status_t setDualMonoMode(audio_dual_mono_mode_t mode) = 0;
+ virtual status_t getAudioDescriptionMixLevel(float* leveldB) const = 0;
+ virtual status_t setAudioDescriptionMixLevel(float leveldB) = 0;
+ virtual status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) const = 0;
+ virtual status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) = 0;
+
+ // implement FastMixerState::VolumeProvider interface
+ virtual gain_minifloat_packed_t getVolumeLR() const = 0;
+
+ // implement volume handling.
+ virtual media::VolumeShaper::Status applyVolumeShaper(
+ const sp<media::VolumeShaper::Configuration>& configuration,
+ const sp<media::VolumeShaper::Operation>& operation) = 0;
+ virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) const = 0;
+ virtual sp<media::VolumeHandler> getVolumeHandler() const = 0;
+ /** Set the computed normalized final volume of the track.
+ * !masterMute * masterVolume * streamVolume * averageLRVolume */
+ virtual void setFinalVolume(float volumeLeft, float volumeRight) = 0;
+ virtual float getFinalVolume() const = 0;
+ virtual void getFinalVolume(float* left, float* right) const = 0;
+
+ using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
+ /** Copy the track metadata in the provided iterator. Thread safe. */
+ virtual void copyMetadataTo(MetadataInserter& backInserter) const = 0;
+
+ /** Return haptic playback of the track is enabled or not, used in mixer. */
+ virtual bool getHapticPlaybackEnabled() const = 0;
+ /** Set haptic playback of the track is enabled or not, should be
+ * set after query or get callback from vibrator service */
+ virtual void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) = 0;
+ /** Return at what intensity to play haptics, used in mixer. */
+ virtual os::HapticScale getHapticIntensity() const = 0;
+ /** Return the maximum amplitude allowed for haptics data, used in mixer. */
+ virtual float getHapticMaxAmplitude() const = 0;
+ /** Set intensity of haptic playback, should be set after querying vibrator service. */
+ virtual void setHapticIntensity(os::HapticScale hapticIntensity) = 0;
+ /** Set maximum amplitude allowed for haptic data, should be set after querying
+ * vibrator service.
+ */
+ virtual void setHapticMaxAmplitude(float maxAmplitude) = 0;
+ virtual sp<os::ExternalVibration> getExternalVibration() const = 0;
+
+ // This function should be called with holding thread lock.
+ virtual void updateTeePatches_l() = 0;
+
+ // Argument teePatchesToUpdate is by value, use std::move to optimize.
+ virtual void setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) = 0;
+
+ static bool checkServerLatencySupported(audio_format_t format, audio_output_flags_t flags) {
+ return audio_is_linear_pcm(format) && (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == 0;
+ }
+
+ virtual audio_output_flags_t getOutputFlags() const = 0;
+ virtual float getSpeed() const = 0;
+
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ virtual void processMuteEvent_l(
+ const sp<IAudioManager>& audioManager, mute_state_t muteState) = 0;
+
+ virtual void triggerEvents(AudioSystem::sync_event_t type) = 0;
+
+ virtual void disable() = 0;
+ virtual int& fastIndex() = 0;
+ virtual bool isPlaybackRestricted() const = 0;
+
+ // Used by thread only
+
+ virtual bool isPausing() const = 0;
+ virtual bool isPaused() const = 0;
+ virtual bool isResuming() const = 0;
+ virtual bool isReady() const = 0;
+ virtual void setPaused() = 0;
+ virtual void reset() = 0;
+ virtual bool isFlushPending() const = 0;
+ virtual void flushAck() = 0;
+ virtual bool isResumePending() const = 0;
+ virtual void resumeAck() = 0;
+ // For direct or offloaded tracks ensure that the pause state is acknowledged
+ // by the playback thread in case of an immediate flush.
+ virtual bool isPausePending() const = 0;
+ virtual void pauseAck() = 0;
+ virtual void updateTrackFrameInfo(
+ int64_t trackFramesReleased, int64_t sinkFramesWritten, uint32_t halSampleRate,
+ const ExtendedTimestamp& timeStamp) = 0;
+ virtual sp<IMemory> sharedBuffer() const = 0;
+
+ // Dup with ExtendedAudioBufferProvider
+ virtual size_t framesReady() const = 0;
+
+ // presentationComplete checked by frames. (Mixed Tracks).
+ // framesWritten is cumulative, never reset, and is shared all tracks
+ // audioHalFrames is derived from output latency
+ virtual bool presentationComplete(int64_t framesWritten, size_t audioHalFrames) = 0;
+
+ // presentationComplete checked by time. (Direct Tracks).
+ virtual bool presentationComplete(uint32_t latencyMs) = 0;
+
+ virtual void resetPresentationComplete() = 0;
+
+ virtual bool hasVolumeController() const = 0;
+ virtual void setHasVolumeController(bool hasVolumeController) = 0;
+ virtual const sp<AudioTrackServerProxy>& audioTrackServerProxy() const = 0;
+ virtual void setCachedVolume(float volume) = 0;
+ virtual void setResetDone(bool resetDone) = 0;
+
+ virtual ExtendedAudioBufferProvider* asExtendedAudioBufferProvider() = 0;
+ virtual VolumeProvider* asVolumeProvider() = 0;
+
+ // TODO(b/291317964) split into getter/setter
+ virtual FillingStatus& fillingStatus() = 0;
+ virtual int8_t& retryCount() = 0;
+ virtual FastTrackUnderruns& fastTrackUnderruns() = 0;
+};
+
+// playback track, used by DuplicatingThread
+class IAfOutputTrack : public virtual IAfTrack {
+public:
+ static sp<IAfOutputTrack> create(
+ IAfPlaybackThread* playbackThread,
+ IAfDuplicatingThread* sourceThread, uint32_t sampleRate,
+ audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount,
+ const AttributionSourceState& attributionSource);
+
+ virtual ssize_t write(void* data, uint32_t frames) = 0;
+ virtual bool bufferQueueEmpty() const = 0;
+ virtual bool isActive() const = 0;
+
+ /** Set the metadatas of the upstream tracks. Thread safe. */
+ virtual void setMetadatas(const SourceMetadatas& metadatas) = 0;
+ /** returns client timestamp to the upstream duplicating thread. */
+ virtual ExtendedTimestamp getClientProxyTimestamp() const = 0;
+};
+
+class IAfMmapTrack : public virtual IAfTrackBase {
+public:
+ static sp<IAfMmapTrack> create(IAfThreadBase* thread,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_session_t sessionId,
+ bool isOut,
+ const android::content::AttributionSourceState& attributionSource,
+ pid_t creatorPid,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+
+ // protected by MMapThread::mLock
+ virtual void setSilenced_l(bool silenced) = 0;
+ // protected by MMapThread::mLock
+ virtual bool isSilenced_l() const = 0;
+ // protected by MMapThread::mLock
+ virtual bool getAndSetSilencedNotified_l() = 0;
+
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ virtual void processMuteEvent_l( // see IAfTrack
+ const sp<IAudioManager>& audioManager, mute_state_t muteState) = 0;
+};
+
+class RecordBufferConverter;
+
+class IAfRecordTrack : public virtual IAfTrackBase {
+public:
+ // createIAudioRecordAdapter() is a static constructor which creates an
+ // IAudioRecord AIDL interface adapter from the RecordTrack object that
+ // may be passed back to the client (if needed).
+ //
+ // Only one AIDL IAudioRecord interface adapter should be created per RecordTrack.
+ static sp<media::IAudioRecord> createIAudioRecordAdapter(const sp<IAfRecordTrack>& recordTrack);
+
+ static sp<IAfRecordTrack> create(IAfRecordThread* thread,
+ const sp<Client>& client,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount,
+ void* buffer,
+ size_t bufferSize,
+ audio_session_t sessionId,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ audio_input_flags_t flags,
+ track_type type,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
+ int32_t startFrames = -1);
+
+ // clear the buffer overflow flag
+ virtual void clearOverflow() = 0;
+ // set the buffer overflow flag and return previous value
+ virtual bool setOverflow() = 0;
+
+ // TODO(b/291317964) handleSyncStartEvent in IAfTrackBase should move here.
+ virtual void clearSyncStartEvent() = 0;
+ virtual void updateTrackFrameInfo(
+ int64_t trackFramesReleased, int64_t sourceFramesRead, uint32_t halSampleRate,
+ const ExtendedTimestamp& timestamp) = 0;
+
+ virtual void setSilenced(bool silenced) = 0;
+ virtual bool isSilenced() const = 0;
+ virtual status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const = 0;
+
+ virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
+ virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+ virtual status_t shareAudioHistory(
+ const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) = 0;
+ virtual int32_t startFrames() const = 0;
+
+ static bool checkServerLatencySupported(audio_format_t format, audio_input_flags_t flags) {
+ return audio_is_linear_pcm(format) && (flags & AUDIO_INPUT_FLAG_HW_AV_SYNC) == 0;
+ }
+
+ using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
+ virtual void copyMetadataTo(MetadataInserter& backInserter) const = 0; // see IAfTrack
+
+ // private to Threads
+ virtual AudioBufferProvider::Buffer& sinkBuffer() = 0;
+ virtual audioflinger::SynchronizedRecordState& synchronizedRecordState() = 0;
+ virtual RecordBufferConverter* recordBufferConverter() const = 0;
+ virtual ResamplerBufferProvider* resamplerBufferProvider() const = 0;
+};
+
+// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
+// it provides buffer access methods that map those of a ClientProxy (see AudioTrackShared.h)
+class PatchProxyBufferProvider {
+public:
+ virtual ~PatchProxyBufferProvider() = default;
+ virtual bool producesBufferOnDemand() const = 0;
+ virtual status_t obtainBuffer(
+ Proxy::Buffer* buffer, const struct timespec* requested = nullptr) = 0;
+ virtual void releaseBuffer(Proxy::Buffer* buffer) = 0;
+};
+
+class IAfPatchTrackBase : public virtual RefBase {
+public:
+ using Timeout = std::optional<std::chrono::nanoseconds>;
+
+ virtual void setPeerTimeout(std::chrono::nanoseconds timeout) = 0;
+ virtual void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) = 0;
+ virtual void clearPeerProxy() = 0;
+ virtual PatchProxyBufferProvider* asPatchProxyBufferProvider() = 0;
+};
+
+class IAfPatchTrack : public virtual IAfTrack, public virtual IAfPatchTrackBase {
+public:
+ static sp<IAfPatchTrack> create(
+ IAfPlaybackThread* playbackThread,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ void *buffer,
+ size_t bufferSize,
+ audio_output_flags_t flags,
+ const Timeout& timeout = {},
+ size_t frameCountToBeReady = 1 /** Default behaviour is to start
+ * as soon as possible to have
+ * the lowest possible latency
+ * even if it might glitch. */);
+};
+
+class IAfPatchRecord : public virtual IAfRecordTrack, public virtual IAfPatchTrackBase {
+public:
+ static sp<IAfPatchRecord> create(
+ IAfRecordThread* recordThread,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ void* buffer,
+ size_t bufferSize,
+ audio_input_flags_t flags,
+ const Timeout& timeout = {},
+ audio_source_t source = AUDIO_SOURCE_DEFAULT);
+
+ static sp<IAfPatchRecord> createPassThru(
+ IAfRecordThread* recordThread,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ audio_input_flags_t flags,
+ audio_source_t source = AUDIO_SOURCE_DEFAULT);
+
+ virtual Source* getSource() = 0;
+ virtual size_t writeFrames(const void* src, size_t frameCount, size_t frameSize) = 0;
+};
+
+} // namespace android
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 39f772b..f3256a7 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -16,9 +16,9 @@
*/
// #define LOG_NDEBUG 0
-#define LOG_TAG "AudioFlinger::MelReporter"
+#define LOG_TAG "MelReporter"
-#include "AudioFlinger.h"
+#include "MelReporter.h"
#include <android/media/ISoundDoseCallback.h>
#include <audio_utils/power.h>
@@ -28,7 +28,7 @@
namespace android {
-bool AudioFlinger::MelReporter::activateHalSoundDoseComputation(const std::string& module,
+bool MelReporter::activateHalSoundDoseComputation(const std::string& module,
const sp<DeviceHalInterface>& device) {
if (mSoundDoseManager->forceUseFrameworkMel()) {
ALOGD("%s: Forcing use of internal MEL computation.", __func__);
@@ -63,7 +63,7 @@
return true;
}
-void AudioFlinger::MelReporter::activateInternalSoundDoseComputation() {
+void MelReporter::activateInternalSoundDoseComputation() {
{
std::lock_guard _l(mLock);
if (!mUseHalSoundDoseInterface) {
@@ -76,11 +76,11 @@
mSoundDoseManager->setHalSoundDoseInterface(nullptr);
}
-void AudioFlinger::MelReporter::onFirstRef() {
- mAudioFlinger.mPatchCommandThread->addListener(this);
+void MelReporter::onFirstRef() {
+ mAfMelReporterCallback->getPatchCommandThread()->addListener(this);
}
-bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
+bool MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return false;
@@ -104,14 +104,14 @@
}
}
-void AudioFlinger::MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle,
+void MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle,
const std::vector<playback_track_metadata_v7_t>& metadataVec) {
if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
}
- std::lock_guard _laf(mAudioFlinger.mLock);
+ std::lock_guard _laf(mAfMelReporterCallback->mutex());
std::lock_guard _l(mLock);
auto activeMelPatchId = activePatchStreamHandle_l(streamHandle);
if (!activeMelPatchId) {
@@ -140,8 +140,8 @@
}
}
-void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) {
+void MelReporter::onCreateAudioPatch(audio_patch_handle_t handle,
+ const IAfPatchPanel::Patch& patch) {
if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
@@ -171,7 +171,7 @@
}
if (!newPatch.deviceHandles.empty()) {
- std::lock_guard _afl(mAudioFlinger.mLock);
+ std::lock_guard _afl(mAfMelReporterCallback->mutex());
std::lock_guard _l(mLock);
ALOGV("%s add patch handle %d to active devices", __func__, handle);
startMelComputationForActivePatch_l(newPatch);
@@ -180,10 +180,10 @@
}
}
-void AudioFlinger::MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch)
+void MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch)
NO_THREAD_SAFETY_ANALYSIS // access of AudioFlinger::checkOutputThread_l
{
- auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+ auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
if (outputThread == nullptr) {
ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle);
return;
@@ -198,14 +198,14 @@
outputThread->startMelComputation_l(mSoundDoseManager->getOrCreateProcessorForDevice(
deviceHandle,
patch.streamHandle,
- outputThread->mSampleRate,
- outputThread->mChannelCount,
- outputThread->mFormat));
+ outputThread->sampleRate(),
+ outputThread->channelCount(),
+ outputThread->format()));
}
}
}
-void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
+void MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
@@ -226,25 +226,31 @@
mActiveMelPatches.erase(patchIt);
}
- std::lock_guard _afl(mAudioFlinger.mLock);
+ std::lock_guard _afl(mAfMelReporterCallback->mutex());
std::lock_guard _l(mLock);
stopMelComputationForPatch_l(melPatch);
}
-sp<media::ISoundDose> AudioFlinger::MelReporter::getSoundDoseInterface(
+void MelReporter::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
+ onReleaseAudioPatch(oldHandle);
+ onCreateAudioPatch(newHandle, patch);
+}
+
+sp<media::ISoundDose> MelReporter::getSoundDoseInterface(
const sp<media::ISoundDoseCallback>& callback) {
// no need to lock since getSoundDoseInterface is synchronized
return mSoundDoseManager->getSoundDoseInterface(callback);
}
-void AudioFlinger::MelReporter::stopInternalMelComputation() {
+void MelReporter::stopInternalMelComputation() {
ALOGV("%s", __func__);
std::lock_guard _l(mLock);
mActiveMelPatches.clear();
mUseHalSoundDoseInterface = true;
}
-void AudioFlinger::MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch)
+void MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch)
NO_THREAD_SAFETY_ANALYSIS // access of AudioFlinger::checkOutputThread_l
{
if (!patch.csdActive) {
@@ -252,7 +258,7 @@
return;
}
- auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+ auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
for (const auto& deviceId : patch.deviceHandles) {
@@ -272,7 +278,7 @@
}
-std::optional<audio_patch_handle_t> AudioFlinger::MelReporter::activePatchStreamHandle_l(
+std::optional<audio_patch_handle_t> MelReporter::activePatchStreamHandle_l(
audio_io_handle_t streamHandle) {
for(const auto& patchIt : mActiveMelPatches) {
if (patchIt.second.streamHandle == streamHandle) {
@@ -282,11 +288,11 @@
return std::nullopt;
}
-bool AudioFlinger::MelReporter::useHalSoundDoseInterface_l() {
+bool MelReporter::useHalSoundDoseInterface_l() {
return !mSoundDoseManager->forceUseFrameworkMel() & mUseHalSoundDoseInterface;
}
-std::string AudioFlinger::MelReporter::dump() {
+std::string MelReporter::dump() {
std::lock_guard _l(mLock);
std::string output("\nSound Dose:\n");
output.append(mSoundDoseManager->dump());
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 2bc33f2..005ca96 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -15,24 +15,35 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
+
+#include "IAfPatchPanel.h"
+#include "PatchCommandThread.h"
+
+#include <sounddose/SoundDoseManager.h>
#include <mutex>
-#include <sounddose/SoundDoseManager.h>
#include <unordered_map>
+namespace android {
+
constexpr static int kMaxTimestampDeltaInSec = 120;
+class IAfMelReporterCallback : public virtual RefBase {
+public:
+ virtual Mutex& mutex() const = 0;
+ virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
+ virtual sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const = 0;
+};
+
/**
* Class for listening to new patches and starting the MEL computation. MelReporter is
* concealed within AudioFlinger, their lifetimes are the same.
*/
class MelReporter : public PatchCommandThread::PatchCommandListener {
public:
- explicit MelReporter(AudioFlinger& audioFlinger)
- : mAudioFlinger(audioFlinger),
+ explicit MelReporter(const sp<IAfMelReporterCallback>& afMelReporterCallback)
+ : mAfMelReporterCallback(afMelReporterCallback),
mSoundDoseManager(sp<SoundDoseManager>::make()) {}
void onFirstRef() override;
@@ -67,8 +78,11 @@
// PatchCommandListener methods
void onCreateAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) override;
- void onReleaseAudioPatch(audio_patch_handle_t handle) override;
+ const IAfPatchPanel::Patch& patch) final;
+ void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+ void onUpdateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch) final;
/**
* The new metadata can determine whether we should compute MEL for the given thread.
@@ -100,7 +114,7 @@
bool useHalSoundDoseInterface_l() REQUIRES(mLock);
- AudioFlinger& mAudioFlinger; // does not own the object
+ const sp<IAfMelReporterCallback> mAfMelReporterCallback;
sp<SoundDoseManager> mSoundDoseManager;
@@ -109,9 +123,9 @@
* Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock.
*/
std::mutex mLock;
- std::unordered_map<audio_patch_handle_t, ActiveMelPatch>
- mActiveMelPatches GUARDED_BY(AudioFlinger::MelReporter::mLock);
- std::unordered_map<audio_port_handle_t, int>
- mActiveDevices GUARDED_BY(AudioFlinger::MelReporter::mLock);
- bool mUseHalSoundDoseInterface GUARDED_BY(AudioFlinger::MelReporter::mLock) = false;
+ std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches GUARDED_BY(mLock);
+ std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mLock);
+ bool mUseHalSoundDoseInterface GUARDED_BY(mLock) = false;
};
+
+} // namespace android
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index cb46c52..85ce142 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -15,14 +15,18 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
+
+#include "TrackBase.h"
+
+#include <android/content/AttributionSourceState.h>
+
+namespace android {
// playback track
-class MmapTrack : public TrackBase {
+class MmapTrack : public TrackBase, public IAfMmapTrack {
public:
- MmapTrack(ThreadBase *thread,
+ MmapTrack(IAfThreadBase* thread,
const audio_attributes_t& attr,
uint32_t sampleRate,
audio_format_t format,
@@ -32,26 +36,25 @@
const android::content::AttributionSourceState& attributionSource,
pid_t creatorPid,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
- virtual ~MmapTrack();
+ ~MmapTrack() override;
- // TrackBase virtual
- virtual status_t initCheck() const;
- virtual status_t start(AudioSystem::sync_event_t event,
- audio_session_t triggerSession);
- virtual void stop();
- virtual bool isFastTrack() const { return false; }
- bool isDirect() const override { return true; }
+ status_t initCheck() const final;
+ status_t start(
+ AudioSystem::sync_event_t event, audio_session_t triggerSession) final;
+ void stop() final;
+ bool isFastTrack() const final { return false; }
+ bool isDirect() const final { return true; }
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
// protected by MMapThread::mLock
- void setSilenced_l(bool silenced) { mSilenced = silenced;
+ void setSilenced_l(bool silenced) final { mSilenced = silenced;
mSilencedNotified = false;}
// protected by MMapThread::mLock
- bool isSilenced_l() const { return mSilenced; }
+ bool isSilenced_l() const final { return mSilenced; }
// protected by MMapThread::mLock
- bool getAndSetSilencedNotified_l() { bool silencedNotified = mSilencedNotified;
+ bool getAndSetSilencedNotified_l() final { bool silencedNotified = mSilencedNotified;
mSilencedNotified = true;
return silencedNotified; }
@@ -61,10 +64,8 @@
*/
void processMuteEvent_l(const sp<IAudioManager>& audioManager,
mute_state_t muteState)
- REQUIRES(AudioFlinger::MmapPlaybackThread::mLock);
+ /* REQUIRES(MmapPlaybackThread::mLock) */ final;
private:
- friend class MmapThread;
-
DISALLOW_COPY_AND_ASSIGN(MmapTrack);
// AudioBufferProvider interface
@@ -72,19 +73,20 @@
// releaseBuffer() not overridden
// ExtendedAudioBufferProvider interface
- virtual size_t framesReady() const;
- virtual int64_t framesReleased() const;
- virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+ size_t framesReady() const final;
+ int64_t framesReleased() const final;
+ void onTimestamp(const ExtendedTimestamp ×tamp) final;
- pid_t mPid;
+ const pid_t mPid;
bool mSilenced; // protected by MMapThread::mLock
bool mSilencedNotified; // protected by MMapThread::mLock
// TODO: replace PersistableBundle with own struct
// access these two variables only when holding player thread lock.
std::unique_ptr<os::PersistableBundle> mMuteEventExtras
- GUARDED_BY(AudioFlinger::MmapPlaybackThread::mLock);
+ /* GUARDED_BY(MmapPlaybackThread::mLock) */;
mute_state_t mMuteState
- GUARDED_BY(AudioFlinger::MmapPlaybackThread::mLock);
+ /* GUARDED_BY(MmapPlaybackThread::mLock) */;
}; // end of Track
+} // namespace android
\ No newline at end of file
diff --git a/services/audioflinger/PatchCommandThread.cpp b/services/audioflinger/PatchCommandThread.cpp
index f4aab1f..8d5eb9f 100644
--- a/services/audioflinger/PatchCommandThread.cpp
+++ b/services/audioflinger/PatchCommandThread.cpp
@@ -18,31 +18,33 @@
#define LOG_TAG "AudioFlinger::PatchCommandThread"
//#define LOG_NDEBUG 0
-#include "AudioFlinger.h"
+#include "PatchCommandThread.h"
+
+#include <utils/Log.h>
namespace android {
constexpr char kPatchCommandThreadName[] = "AudioFlinger_PatchCommandThread";
-AudioFlinger::PatchCommandThread::~PatchCommandThread() {
+PatchCommandThread::~PatchCommandThread() {
exit();
std::lock_guard _l(mLock);
mCommands.clear();
}
-void AudioFlinger::PatchCommandThread::onFirstRef() {
+void PatchCommandThread::onFirstRef() {
run(kPatchCommandThreadName, ANDROID_PRIORITY_AUDIO);
}
-void AudioFlinger::PatchCommandThread::addListener(const sp<PatchCommandListener>& listener) {
+void PatchCommandThread::addListener(const sp<PatchCommandListener>& listener) {
ALOGV("%s add listener %p", __func__, static_cast<void*>(listener.get()));
std::lock_guard _l(mListenerLock);
mListeners.emplace_back(listener);
}
-void AudioFlinger::PatchCommandThread::createAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) {
+void PatchCommandThread::createAudioPatch(audio_patch_handle_t handle,
+ const IAfPatchPanel::Patch& patch) {
ALOGV("%s handle %d mHalHandle %d num sinks %d device sink %08x",
__func__, handle, patch.mHalHandle,
patch.mAudioPatch.num_sinks,
@@ -51,12 +53,22 @@
createAudioPatchCommand(handle, patch);
}
-void AudioFlinger::PatchCommandThread::releaseAudioPatch(audio_patch_handle_t handle) {
+void PatchCommandThread::releaseAudioPatch(audio_patch_handle_t handle) {
ALOGV("%s", __func__);
releaseAudioPatchCommand(handle);
}
-bool AudioFlinger::PatchCommandThread::threadLoop()
+void PatchCommandThread::updateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
+ ALOGV("%s handle %d mHalHandle %d num sinks %d device sink %08x",
+ __func__, oldHandle, patch.mHalHandle,
+ patch.mAudioPatch.num_sinks,
+ patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
+
+ updateAudioPatchCommand(oldHandle, newHandle, patch);
+}
+
+bool PatchCommandThread::threadLoop()
NO_THREAD_SAFETY_ANALYSIS // bug in clang compiler.
{
std::unique_lock _l(mLock);
@@ -102,6 +114,21 @@
}
}
break;
+ case UPDATE_AUDIO_PATCH: {
+ const auto data = (UpdateAudioPatchData*) command->mData.get();
+ ALOGV("%s processing update audio patch old handle %d new handle %d",
+ __func__,
+ data->mOldHandle, data->mNewHandle);
+
+ for (const auto& listener : listenersCopy) {
+ auto spListener = listener.promote();
+ if (spListener) {
+ spListener->onUpdateAudioPatch(data->mOldHandle,
+ data->mNewHandle, data->mPatch);
+ }
+ }
+ }
+ break;
default:
ALOGW("%s unknown command %d", __func__, command->mCommand);
break;
@@ -119,14 +146,14 @@
return false;
}
-void AudioFlinger::PatchCommandThread::sendCommand(const sp<Command>& command) {
+void PatchCommandThread::sendCommand(const sp<Command>& command) {
std::lock_guard _l(mLock);
mCommands.emplace_back(command);
mWaitWorkCV.notify_one();
}
-void AudioFlinger::PatchCommandThread::createAudioPatchCommand(
- audio_patch_handle_t handle, const PatchPanel::Patch& patch) {
+void PatchCommandThread::createAudioPatchCommand(
+ audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch) {
auto command = sp<Command>::make(CREATE_AUDIO_PATCH,
new CreateAudioPatchData(handle, patch));
ALOGV("%s adding create patch handle %d mHalHandle %d.",
@@ -136,14 +163,24 @@
sendCommand(command);
}
-void AudioFlinger::PatchCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle) {
+void PatchCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle) {
sp<Command> command =
sp<Command>::make(RELEASE_AUDIO_PATCH, new ReleaseAudioPatchData(handle));
ALOGV("%s adding release patch", __func__);
sendCommand(command);
}
-void AudioFlinger::PatchCommandThread::exit() {
+void PatchCommandThread::updateAudioPatchCommand(
+ audio_patch_handle_t oldHandle, audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch) {
+ sp<Command> command = sp<Command>::make(UPDATE_AUDIO_PATCH,
+ new UpdateAudioPatchData(oldHandle, newHandle, patch));
+ ALOGV("%s adding update patch old handle %d new handle %d mHalHandle %d.",
+ __func__, oldHandle, newHandle, patch.mHalHandle);
+ sendCommand(command);
+}
+
+void PatchCommandThread::exit() {
ALOGV("%s", __func__);
{
std::lock_guard _l(mLock);
diff --git a/services/audioflinger/PatchCommandThread.h b/services/audioflinger/PatchCommandThread.h
index b52e0a9..66018d7 100644
--- a/services/audioflinger/PatchCommandThread.h
+++ b/services/audioflinger/PatchCommandThread.h
@@ -15,14 +15,22 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
+
+#include "IAfPatchPanel.h"
+
+#include <utils/RefBase.h> // avoid transitive dependency
+#include <utils/Thread.h> // avoid transitive dependency
+
+#include <deque>
+#include <mutex> // avoid transitive dependency
+
+namespace android {
class Command;
// Thread to execute create and release patch commands asynchronously. This is needed because
-// PatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service
+// IAfPatchPanel::createAudioPatch and releaseAudioPatch are executed from audio policy service
// with mutex locked and effect management requires to call back into audio policy service
class PatchCommandThread : public Thread {
public:
@@ -30,13 +38,17 @@
enum {
CREATE_AUDIO_PATCH,
RELEASE_AUDIO_PATCH,
+ UPDATE_AUDIO_PATCH,
};
class PatchCommandListener : public virtual RefBase {
public:
virtual void onCreateAudioPatch(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch) = 0;
+ const IAfPatchPanel::Patch& patch) = 0;
virtual void onReleaseAudioPatch(audio_patch_handle_t handle) = 0;
+ virtual void onUpdateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch) = 0;
};
PatchCommandThread() : Thread(false /* canCallJava */) {}
@@ -44,8 +56,11 @@
void addListener(const sp<PatchCommandListener>& listener);
- void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
+ void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch);
void releaseAudioPatch(audio_patch_handle_t handle);
+ void updateAudioPatch(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch);
// Thread virtuals
void onFirstRef() override;
@@ -54,9 +69,11 @@
void exit();
void createAudioPatchCommand(audio_patch_handle_t handle,
- const PatchPanel::Patch& patch);
+ const IAfPatchPanel::Patch& patch);
void releaseAudioPatchCommand(audio_patch_handle_t handle);
-
+ void updateAudioPatchCommand(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch);
private:
class CommandData;
@@ -75,11 +92,11 @@
class CreateAudioPatchData : public CommandData {
public:
- CreateAudioPatchData(audio_patch_handle_t handle, const PatchPanel::Patch& patch)
+ CreateAudioPatchData(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch)
: mHandle(handle), mPatch(patch) {}
const audio_patch_handle_t mHandle;
- const PatchPanel::Patch mPatch;
+ const IAfPatchPanel::Patch mPatch;
};
class ReleaseAudioPatchData : public CommandData {
@@ -90,6 +107,18 @@
audio_patch_handle_t mHandle;
};
+ class UpdateAudioPatchData : public CommandData {
+ public:
+ UpdateAudioPatchData(audio_patch_handle_t oldHandle,
+ audio_patch_handle_t newHandle,
+ const IAfPatchPanel::Patch& patch)
+ : mOldHandle(oldHandle), mNewHandle(newHandle), mPatch(patch) {}
+
+ const audio_patch_handle_t mOldHandle;
+ const audio_patch_handle_t mNewHandle;
+ const IAfPatchPanel::Patch mPatch;
+ };
+
void sendCommand(const sp<Command>& command);
std::string mThreadName;
@@ -100,3 +129,5 @@
std::mutex mListenerLock;
std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(mListenerLock);
};
+
+} // namespace android
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d0feba5..f11a530 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -19,16 +19,16 @@
#define LOG_TAG "AudioFlinger::PatchPanel"
//#define LOG_NDEBUG 0
-#include "Configuration.h"
-#include <utils/Log.h>
-#include <audio_utils/primitives.h>
+#include "PatchPanel.h"
+#include "PatchCommandThread.h"
-#include "AudioFlinger.h"
+#include <audio_utils/primitives.h>
#include <media/AudioParameter.h>
#include <media/AudioValidator.h>
#include <media/DeviceDescriptorBase.h>
#include <media/PatchBuilder.h>
#include <mediautils/ServiceUtilities.h>
+#include <utils/Log.h>
// ----------------------------------------------------------------------------
@@ -47,65 +47,43 @@
namespace android {
-/* List connected audio ports and their attributes */
-status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,
- struct audio_port *ports)
-{
- Mutex::Autolock _l(mLock);
- return mPatchPanel.listAudioPorts(num_ports, ports);
+/* static */
+sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) {
+ return sp<PatchPanel>::make(afPatchPanelCallback);
}
-/* Get supported attributes for a given audio port */
-status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
- status_t status = AudioValidator::validateAudioPort(*port);
- if (status != NO_ERROR) {
- return status;
- }
-
- Mutex::Autolock _l(mLock);
- return mPatchPanel.getAudioPort(port);
+status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const {
+ return mPatchPanel->getLatencyMs_l(mPatchHandle, latencyMs);
}
-/* Connect a patch between several source and sink ports */
-status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
- audio_patch_handle_t *handle)
+status_t PatchPanel::getLatencyMs_l(
+ audio_patch_handle_t patchHandle, double* latencyMs) const
{
- status_t status = AudioValidator::validateAudioPatch(*patch);
- if (status != NO_ERROR) {
- return status;
- }
-
- Mutex::Autolock _l(mLock);
- return mPatchPanel.createAudioPatch(patch, handle);
-}
-
-/* Disconnect a patch */
-status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
-{
- Mutex::Autolock _l(mLock);
- return mPatchPanel.releaseAudioPatch(handle);
-}
-
-/* List connected audio ports and they attributes */
-status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches)
-{
- Mutex::Autolock _l(mLock);
- return mPatchPanel.listAudioPatches(num_patches, patches);
-}
-
-status_t AudioFlinger::PatchPanel::SoftwarePatch::getLatencyMs_l(double *latencyMs) const
-{
- const auto& iter = mPatchPanel.mPatches.find(mPatchHandle);
- if (iter != mPatchPanel.mPatches.end()) {
+ const auto& iter = mPatches.find(patchHandle);
+ if (iter != mPatches.end()) {
return iter->second.getLatencyMs(latencyMs);
} else {
return BAD_VALUE;
}
}
+void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
+{
+ if (const auto recordThread = thread->asIAfRecordThread();
+ recordThread) {
+ mAfPatchPanelCallback->closeThreadInternal_l(recordThread);
+ } else if (const auto playbackThread = thread->asIAfPlaybackThread();
+ playbackThread) {
+ mAfPatchPanelCallback->closeThreadInternal_l(playbackThread);
+ } else {
+ LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, "
+ "invalid thread, id: %d type: %d",
+ __func__, thread->id(), thread->type());
+ }
+}
+
/* List connected audio ports and their attributes */
-status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
+status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */,
struct audio_port *ports __unused)
{
ALOGV(__func__);
@@ -113,7 +91,7 @@
}
/* Get supported attributes for a given audio port */
-status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port_v7 *port)
+status_t PatchPanel::getAudioPort(struct audio_port_v7* port)
{
if (port->type != AUDIO_PORT_TYPE_DEVICE) {
// Only query the HAL when the port is a device.
@@ -132,10 +110,10 @@
}
/* Connect a patch between several source and sink ports */
-status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
+status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
audio_patch_handle_t *handle,
bool endpointPatch)
- //unlocks AudioFlinger::mLock when calling ThreadBase::sendCreateAudioPatchConfigEvent
+ //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent
//to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
//before processing the create patch request.
NO_THREAD_SAFETY_ANALYSIS
@@ -156,7 +134,8 @@
if (patch->num_sources > 2) {
return INVALID_OPERATION;
}
-
+ bool reuseExistingHalPatch = false;
+ audio_patch_handle_t oldhandle = AUDIO_PATCH_HANDLE_NONE;
if (*handle != AUDIO_PATCH_HANDLE_NONE) {
auto iter = mPatches.find(*handle);
if (iter != mPatches.end()) {
@@ -174,6 +153,7 @@
if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
+ oldhandle = *handle;
if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
(patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
oldPatch.sources[0].ext.device.hw_module !=
@@ -196,8 +176,12 @@
hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
halHandle = removedPatch.mHalHandle;
+ // Prevent to remove/add device effect when mix / device did not change, and
+ // hal patch has not been released
+ // Note that no patch leak at hal layer as halHandle is reused.
+ reuseExistingHalPatch = (hwDevice == 0) && patchesHaveSameRoute(*patch, oldPatch);
}
- erasePatch(*handle);
+ erasePatch(*handle, reuseExistingHalPatch);
}
}
@@ -249,8 +233,8 @@
status = INVALID_OPERATION;
goto exit;
}
- sp<ThreadBase> thread =
- mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+ patch->sources[1].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() cannot get playback thread", __func__);
status = INVALID_OPERATION;
@@ -258,7 +242,7 @@
}
// existing playback thread is reused, so it is not closed when patch is cleared
newPatch.mPlayback.setThread(
- reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
+ thread->asIAfPlaybackThread().get(), false /*closeThread*/);
} else {
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
audio_config_base_t mixerConfig = AUDIO_CONFIG_BASE_INITIALIZER;
@@ -276,7 +260,7 @@
if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
flags = patch->sinks[0].flags.output;
}
- sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
patch->sinks[0].ext.device.hw_module,
&output,
&config,
@@ -284,12 +268,12 @@
outputDevice,
outputDeviceAddress,
flags);
- ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
+ ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
if (thread == 0) {
status = NO_MEMORY;
goto exit;
}
- newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
+ newPatch.mPlayback.setThread(thread->asIAfPlaybackThread().get());
}
audio_devices_t device = patch->sources[0].ext.device.type;
String8 address = String8(patch->sources[0].ext.device.address);
@@ -323,7 +307,7 @@
== AUDIO_STREAM_VOICE_CALL) {
source = AUDIO_SOURCE_VOICE_COMMUNICATION;
}
- sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
&input,
&config,
device,
@@ -332,13 +316,13 @@
flags,
outputDevice,
outputDeviceAddress);
- ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
+ ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
thread.get(), config.channel_mask);
if (thread == 0) {
status = NO_MEMORY;
goto exit;
}
- newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
+ newPatch.mRecord.setThread(thread->asIAfRecordThread().get());
status = newPatch.createConnections(this);
if (status != NO_ERROR) {
goto exit;
@@ -348,10 +332,11 @@
}
} else {
if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
patch->sinks[0].ext.mix.handle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(
+ patch->sinks[0].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() bad capture I/O handle %d",
__func__, patch->sinks[0].ext.mix.handle);
@@ -359,9 +344,9 @@
goto exit;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -385,7 +370,7 @@
} break;
case AUDIO_PORT_TYPE_MIX: {
audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
- ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
+ ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
if (index < 0) {
ALOGW("%s() bad src hw module %d", __func__, srcModule);
status = BAD_VALUE;
@@ -411,10 +396,11 @@
device->applyAudioPortConfig(&patch->sinks[i]);
devices.push_back(device);
}
- sp<ThreadBase> thread =
- mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+ patch->sources[0].ext.mix.handle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(
+ patch->sources[0].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() bad playback I/O handle %d",
__func__, patch->sources[0].ext.mix.handle);
@@ -422,13 +408,13 @@
goto exit;
}
}
- if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
- mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
+ if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
+ mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -453,9 +439,15 @@
exit:
ALOGV("%s() status %d", __func__, status);
if (status == NO_ERROR) {
- *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
+ *handle = static_cast<audio_patch_handle_t>(
+ mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
newPatch.mHalHandle = halHandle;
- mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch);
+ if (reuseExistingHalPatch) {
+ mAfPatchPanelCallback->getPatchCommandThread()->updateAudioPatch(
+ oldhandle, *handle, newPatch);
+ } else {
+ mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch);
+ }
if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
}
@@ -466,13 +458,13 @@
return status;
}
-AudioFlinger::PatchPanel::Patch::~Patch()
+PatchPanel::Patch::~Patch()
{
ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
mRecord.handle(), mPlayback.handle());
}
-status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
+status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel)
{
// create patch from source device to record thread input
status_t status = panel->createAudioPatch(
@@ -546,7 +538,7 @@
outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
}
- sp<RecordThread::PatchRecord> tempRecordTrack;
+ sp<IAfPatchRecord> tempRecordTrack;
const bool usePassthruPatchRecord =
(inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
const size_t playbackFrameCount = mPlayback.thread()->frameCount();
@@ -558,7 +550,7 @@
frameCount = std::max(playbackFrameCount, recordFrameCount);
ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
__func__, playbackFrameCount, recordFrameCount, frameCount);
- tempRecordTrack = new RecordThread::PassthruPatchRecord(
+ tempRecordTrack = IAfPatchRecord::createPassThru(
mRecord.thread().get(),
sampleRate,
inChannelMask,
@@ -577,7 +569,7 @@
ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
__func__, playbackFrameCount, recordFrameCount, frameCount);
- tempRecordTrack = new RecordThread::PatchRecord(
+ tempRecordTrack = IAfPatchRecord::create(
mRecord.thread().get(),
sampleRate,
inChannelMask,
@@ -602,7 +594,7 @@
// Disable this behavior for FM Tuner source if no fast capture/mixer available.
const bool isFmBridge = mAudioPatch.sources[0].ext.device.type == AUDIO_DEVICE_IN_FM_TUNER;
const size_t frameCountToBeReady = isFmBridge && !usePassthruPatchRecord ? frameCount / 4 : 1;
- sp<PlaybackThread::PatchTrack> tempPatchTrack = new PlaybackThread::PatchTrack(
+ sp<IAfPatchTrack> tempPatchTrack = IAfPatchTrack::create(
mPlayback.thread().get(),
streamType,
sampleRate,
@@ -636,7 +628,7 @@
return status;
}
-void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
+void PatchPanel::Patch::clearConnections(const sp<IAfPatchPanel>& panel)
{
ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
__func__, mRecord.handle(), mPlayback.handle());
@@ -647,7 +639,7 @@
mPlayback.closeConnections(panel);
}
-status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
+status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const
{
if (!isSoftware()) return INVALID_OPERATION;
@@ -679,7 +671,7 @@
// If so, do a frame diff and time difference computation to estimate
// the total patch latency. This requires that frame counts are reported by the
// HAL are matched properly in the case of record overruns and playback underruns.
- ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
+ IAfTrack::FrameTime recordFT{}, playFT{};
recordTrack->getKernelFrameTime(&recordFT);
playbackTrack->getKernelFrameTime(&playFT);
if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
@@ -706,7 +698,7 @@
return INVALID_OPERATION;
}
-String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
+String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
{
// TODO: Consider table dump form for patches, just like tracks.
String8 result = String8::format("Patch %d: %s (thread %p => thread %p)",
@@ -734,8 +726,8 @@
}
/* Disconnect a patch */
-status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
- //unlocks AudioFlinger::mLock when calling ThreadBase::sendReleaseAudioPatchConfigEvent
+status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
+ //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent
//to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
//before processing the release patch request.
NO_THREAD_SAFETY_ANALYSIS
@@ -767,18 +759,18 @@
if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
- sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
if (thread == 0) {
ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
} else {
status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
@@ -790,18 +782,18 @@
break;
}
audio_io_handle_t ioHandle = src.ext.mix.handle;
- sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
if (thread == 0) {
ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
} break;
default:
status = BAD_VALUE;
@@ -811,23 +803,25 @@
return status;
}
-void AudioFlinger::PatchPanel::erasePatch(audio_patch_handle_t handle) {
+void PatchPanel::erasePatch(audio_patch_handle_t handle, bool reuseExistingHalPatch) {
mPatches.erase(handle);
removeSoftwarePatchFromInsertedModules(handle);
- mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle);
+ if (!reuseExistingHalPatch) {
+ mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
+ }
}
/* List connected audio ports and they attributes */
-status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
+status_t PatchPanel::listAudioPatches(unsigned int* /* num_patches */,
struct audio_patch *patches __unused)
{
ALOGV(__func__);
return NO_ERROR;
}
-status_t AudioFlinger::PatchPanel::getDownstreamSoftwarePatches(
+status_t PatchPanel::getDownstreamSoftwarePatches(
audio_io_handle_t stream,
- std::vector<AudioFlinger::PatchPanel::SoftwarePatch> *patches) const
+ std::vector<SoftwarePatch>* patches) const
{
for (const auto& module : mInsertedModules) {
if (module.second.streams.count(stream)) {
@@ -835,7 +829,8 @@
const auto& patch_iter = mPatches.find(patchHandle);
if (patch_iter != mPatches.end()) {
const Patch &patch = patch_iter->second;
- patches->emplace_back(*this, patchHandle,
+ patches->emplace_back(sp<const IAfPatchPanel>::fromExisting(this),
+ patchHandle,
patch.mPlayback.const_thread()->id(),
patch.mRecord.const_thread()->id());
} else {
@@ -849,7 +844,7 @@
return BAD_VALUE;
}
-void AudioFlinger::PatchPanel::notifyStreamOpened(
+void PatchPanel::notifyStreamOpened(
AudioHwDevice *audioHwDevice, audio_io_handle_t stream, struct audio_patch *patch)
{
if (audioHwDevice->isInsert()) {
@@ -867,41 +862,41 @@
}
}
-void AudioFlinger::PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
+void PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
{
for (auto& module : mInsertedModules) {
module.second.streams.erase(stream);
}
}
-AudioHwDevice* AudioFlinger::PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
+AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
{
if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
- ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
+ ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
if (index < 0) {
ALOGW("%s() bad hw module %d", __func__, module);
return nullptr;
}
- return mAudioFlinger.mAudioHwDevs.valueAt(index);
+ return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
}
-sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
+sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
{
AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
}
-void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
+void PatchPanel::addSoftwarePatchToInsertedModules(
audio_module_handle_t module, audio_patch_handle_t handle,
const struct audio_patch *patch)
{
mInsertedModules[module].sw_patches.insert(handle);
if (!mInsertedModules[module].streams.empty()) {
- mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
+ mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
}
}
-void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
+void PatchPanel::removeSoftwarePatchFromInsertedModules(
audio_patch_handle_t handle)
{
for (auto& module : mInsertedModules) {
@@ -909,7 +904,7 @@
}
}
-void AudioFlinger::PatchPanel::dump(int fd) const
+void PatchPanel::dump(int fd) const
{
String8 patchPanelDump;
const char *indent = " ";
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 2c5e47c..a95c601 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -15,217 +15,58 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
-public: // TODO(b/288339104) extract out of AudioFlinger class
-// PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
-class PatchPanel {
+#include "IAfPatchPanel.h"
+
+#include <map> // avoid transitive dependency
+#include <set> // avoid transitive dependency
+
+namespace android {
+
+class PatchPanel : public IAfPatchPanel {
public:
- class SoftwarePatch {
- public:
- SoftwarePatch(const PatchPanel &patchPanel, audio_patch_handle_t patchHandle,
- audio_io_handle_t playbackThreadHandle, audio_io_handle_t recordThreadHandle)
- : mPatchPanel(patchPanel), mPatchHandle(patchHandle),
- mPlaybackThreadHandle(playbackThreadHandle),
- mRecordThreadHandle(recordThreadHandle) {}
- SoftwarePatch(const SoftwarePatch&) = default;
-
- // Must be called under AudioFlinger::mLock
- status_t getLatencyMs_l(double *latencyMs) const;
- audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
- audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
- audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
- private:
- const PatchPanel &mPatchPanel;
- const audio_patch_handle_t mPatchHandle;
- const audio_io_handle_t mPlaybackThreadHandle;
- const audio_io_handle_t mRecordThreadHandle;
- };
-
- explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
+ explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback)
+ : mAfPatchPanelCallback(afPatchPanelCallback) {}
/* List connected audio ports and their attributes */
status_t listAudioPorts(unsigned int *num_ports,
- struct audio_port *ports);
+ struct audio_port* ports) final;
/* Get supported attributes for a given audio port */
- status_t getAudioPort(struct audio_port_v7 *port);
+ status_t getAudioPort(struct audio_port_v7* port) final;
/* Create a patch between several source and sink ports */
status_t createAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
- bool endpointPatch = false);
+ bool endpointPatch = false) final;
/* Release a patch */
- status_t releaseAudioPatch(audio_patch_handle_t handle);
+ status_t releaseAudioPatch(audio_patch_handle_t handle) final;
/* List connected audio devices and they attributes */
status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches);
+ struct audio_patch* patches) final;
// Retrieves all currently estrablished software patches for a stream
// opened on an intermediate module.
status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
- std::vector<SoftwarePatch> *patches) const;
+ std::vector<SoftwarePatch>* patches) const final;
// Notifies patch panel about all opened and closed streams.
void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream,
- struct audio_patch *patch);
- void notifyStreamClosed(audio_io_handle_t stream);
+ struct audio_patch* patch) final;
+ void notifyStreamClosed(audio_io_handle_t stream) final;
- void dump(int fd) const;
-
- template<typename ThreadType, typename TrackType>
- class Endpoint final {
- public:
- Endpoint() = default;
- Endpoint(const Endpoint&) = delete;
- Endpoint& operator=(const Endpoint& other) noexcept {
- mThread = other.mThread;
- mCloseThread = other.mCloseThread;
- mHandle = other.mHandle;
- mTrack = other.mTrack;
- return *this;
- }
- Endpoint(Endpoint&& other) noexcept { swap(other); }
- Endpoint& operator=(Endpoint&& other) noexcept {
- swap(other);
- return *this;
- }
- ~Endpoint() {
- ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
- "A non empty Patch Endpoint leaked, handle %d", mHandle);
- }
-
- status_t checkTrack(TrackType *trackOrNull) const {
- if (trackOrNull == nullptr) return NO_MEMORY;
- return trackOrNull->initCheck();
- }
- audio_patch_handle_t handle() const { return mHandle; }
- sp<ThreadType> thread() const { return mThread; }
- sp<TrackType> track() const { return mTrack; }
- sp<const ThreadType> const_thread() const { return mThread; }
- sp<const TrackType> const_track() const { return mTrack; }
-
- void closeConnections(PatchPanel *panel) {
- if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
- panel->releaseAudioPatch(mHandle);
- mHandle = AUDIO_PATCH_HANDLE_NONE;
- }
- if (mThread != 0) {
- if (mTrack != 0) {
- mThread->deletePatchTrack(mTrack);
- }
- if (mCloseThread) {
- panel->mAudioFlinger.closeThreadInternal_l(mThread);
- }
- }
- }
- audio_patch_handle_t* handlePtr() { return &mHandle; }
- void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
- mThread = thread;
- mCloseThread = closeThread;
- }
- template <typename T>
- void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer, bool holdReference) {
- mTrack = track;
- mThread->addPatchTrack(mTrack);
- mTrack->setPeerProxy(peer, holdReference);
- mClearPeerProxy = holdReference;
- }
- void clearTrackPeer() { if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); }
- void stopTrack() { if (mTrack) mTrack->stop(); }
-
- void swap(Endpoint &other) noexcept {
- using std::swap;
- swap(mThread, other.mThread);
- swap(mCloseThread, other.mCloseThread);
- swap(mClearPeerProxy, other.mClearPeerProxy);
- swap(mHandle, other.mHandle);
- swap(mTrack, other.mTrack);
- }
-
- friend void swap(Endpoint &a, Endpoint &b) noexcept {
- a.swap(b);
- }
-
- private:
- sp<ThreadType> mThread;
- bool mCloseThread = true;
- bool mClearPeerProxy = true;
- audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
- sp<TrackType> mTrack;
- };
-
- class Patch final {
- public:
- Patch(const struct audio_patch &patch, bool endpointPatch) :
- mAudioPatch(patch), mIsEndpointPatch(endpointPatch) {}
- Patch() = default;
- ~Patch();
- Patch(const Patch& other) noexcept {
- mAudioPatch = other.mAudioPatch;
- mHalHandle = other.mHalHandle;
- mPlayback = other.mPlayback;
- mRecord = other.mRecord;
- mThread = other.mThread;
- mIsEndpointPatch = other.mIsEndpointPatch;
- }
- Patch(Patch&& other) noexcept { swap(other); }
- Patch& operator=(Patch&& other) noexcept {
- swap(other);
- return *this;
- }
-
- void swap(Patch &other) noexcept {
- using std::swap;
- swap(mAudioPatch, other.mAudioPatch);
- swap(mHalHandle, other.mHalHandle);
- swap(mPlayback, other.mPlayback);
- swap(mRecord, other.mRecord);
- swap(mThread, other.mThread);
- swap(mIsEndpointPatch, other.mIsEndpointPatch);
- }
-
- friend void swap(Patch &a, Patch &b) noexcept {
- a.swap(b);
- }
-
- status_t createConnections(PatchPanel *panel);
- void clearConnections(PatchPanel *panel);
- bool isSoftware() const {
- return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
- mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
-
- void setThread(const sp<ThreadBase>& thread) { mThread = thread; }
- wp<ThreadBase> thread() const { return mThread; }
-
- // returns the latency of the patch (from record to playback).
- status_t getLatencyMs(double *latencyMs) const;
-
- String8 dump(audio_patch_handle_t myHandle) const;
-
- // Note that audio_patch::id is only unique within a HAL module
- struct audio_patch mAudioPatch;
- // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
- audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
- // below members are used by a software audio patch connecting a source device from a
- // given audio HW module to a sink device on an other audio HW module.
- // the objects are created by createConnections() and released by clearConnections()
- // playback thread is created if no existing playback thread can be used
- // connects playback thread output to sink device
- Endpoint<PlaybackThread, PlaybackThread::PatchTrack> mPlayback;
- // connects source device to record thread input
- Endpoint<RecordThread, RecordThread::PatchRecord> mRecord;
-
- wp<ThreadBase> mThread;
- bool mIsEndpointPatch;
- };
+ void dump(int fd) const final;
// Call with AudioFlinger mLock held
- std::map<audio_patch_handle_t, Patch>& patches_l() { return mPatches; }
+ const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; }
+
+ // Must be called under AudioFlinger::mLock
+ status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final;
+
+ void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final;
private:
AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
@@ -234,9 +75,40 @@
audio_module_handle_t module, audio_patch_handle_t handle,
const struct audio_patch *patch);
void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
- void erasePatch(audio_patch_handle_t handle);
+ /**
+ * erase the patch referred by its handle.
+ * @param handle of the patch to be erased
+ * @param reuseExistingHalPatch if set, do not trig the callback of listeners, listener
+ * would receive instead a onUpdateAudioPatch when the patch will be recreated.
+ * It prevents for example DeviceEffectManager to spuriously remove / add a device on an already
+ * opened input / output mix.
+ */
+ void erasePatch(audio_patch_handle_t handle, bool reuseExistingHalPatch = false);
- AudioFlinger &mAudioFlinger;
+ /**
+ * Returns true if the old and new patches passed as arguments describe the same
+ * connections between the first sink and the first source
+ * @param oldPatch previous patch
+ * @param newPatch new patch
+ * @return true if the route is unchanged between the old and new patch, false otherwise
+ */
+ inline bool patchesHaveSameRoute(
+ const struct audio_patch &newPatch, const struct audio_patch &oldPatch) const {
+ return (newPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ newPatch.sources[0].id == oldPatch.sources[0].id &&
+ newPatch.sinks[0].type == AUDIO_PORT_TYPE_MIX &&
+ oldPatch.sinks[0].type == AUDIO_PORT_TYPE_MIX &&
+ newPatch.sinks[0].ext.mix.handle == oldPatch.sinks[0].ext.mix.handle) ||
+ (newPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ newPatch.sinks[0].id == oldPatch.sinks[0].id &&
+ newPatch.sources[0].type == AUDIO_PORT_TYPE_MIX &&
+ oldPatch.sources[0].type == AUDIO_PORT_TYPE_MIX &&
+ newPatch.sources[0].ext.mix.handle == oldPatch.sources[0].ext.mix.handle);
+ }
+
+ const sp<IAfPatchPanelCallback> mAfPatchPanelCallback;
std::map<audio_patch_handle_t, Patch> mPatches;
// This map allows going from a thread to "downstream" software patches
@@ -266,4 +138,4 @@
std::map<audio_module_handle_t, ModuleConnections> mInsertedModules;
};
-private:
+} // namespace android
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 99d36b8..978c4aa 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -15,12 +15,15 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
-#include <math.h>
-#include <sys/types.h>
+#include "TrackBase.h"
+
+#include <android/os/BnExternalVibrationController.h>
+#include <audio_utils/LinearMap.h>
+#include <binder/AppOpsManager.h>
+
+namespace android {
// Checks and monitors OP_PLAY_AUDIO
class OpPlayAudioMonitor : public RefBase {
@@ -30,13 +33,13 @@
bool hasOpPlayAudio() const;
static sp<OpPlayAudioMonitor> createIfNeeded(
- AudioFlinger::ThreadBase* thread,
+ IAfThreadBase* thread,
const AttributionSourceState& attributionSource,
const audio_attributes_t& attr, int id,
audio_stream_type_t streamType);
private:
- OpPlayAudioMonitor(AudioFlinger::ThreadBase* thread,
+ OpPlayAudioMonitor(IAfThreadBase* thread,
const AttributionSourceState& attributionSource,
audio_usage_t usage, int id, uid_t uid);
void onFirstRef() override;
@@ -57,7 +60,7 @@
// called by PlayAudioOpCallback when OP_PLAY_AUDIO is updated in AppOp callback
void checkPlayAudioForUsage();
- wp<AudioFlinger::ThreadBase> mThread;
+ wp<IAfThreadBase> mThread;
std::atomic_bool mHasOpPlayAudio;
const AttributionSourceState mAttributionSource;
const int32_t mUsage; // on purpose not audio_usage_t because always checked in appOps as int32_t
@@ -67,16 +70,9 @@
};
// playback track
-class Track : public TrackBase, public VolumeProvider {
+class Track : public TrackBase, public virtual IAfTrack, public VolumeProvider {
public:
- // createIAudioTrackAdapter() is a static constructor which creates an
- // IAudioTrack AIDL interface adapter from the Track object that
- // may be passed back to the client (if needed).
- //
- // Only one AIDL IAudioTrack interface wrapper should be created per Track.
- static sp<media::IAudioTrack> createIAudioTrackAdapter(const sp<Track>& track);
-
- Track( PlaybackThread *thread,
+ Track(IAfPlaybackThread* thread,
const sp<Client>& client,
audio_stream_type_t streamType,
const audio_attributes_t& attr,
@@ -99,72 +95,66 @@
float speed = 1.0f,
bool isSpatialized = false,
bool isBitPerfect = false);
- virtual ~Track();
- virtual status_t initCheck() const;
-
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
- virtual status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
- virtual void stop();
- void pause();
-
- void flush();
- void destroy();
-
- virtual uint32_t sampleRate() const;
-
- audio_stream_type_t streamType() const {
+ ~Track() override;
+ status_t initCheck() const final;
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
+ status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) override;
+ void stop() override;
+ void pause() final;
+ void flush() final;
+ void destroy() final;
+ uint32_t sampleRate() const final;
+ audio_stream_type_t streamType() const final {
return mStreamType;
}
- bool isOffloaded() const
+ bool isOffloaded() const final
{ return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
- bool isDirect() const override
+ bool isDirect() const final
{ return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
- bool isOffloadedOrDirect() const { return (mFlags
+ bool isOffloadedOrDirect() const final { return (mFlags
& (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
| AUDIO_OUTPUT_FLAG_DIRECT)) != 0; }
- bool isStatic() const { return mSharedBuffer.get() != nullptr; }
+ bool isStatic() const final { return mSharedBuffer.get() != nullptr; }
- status_t setParameters(const String8& keyValuePairs);
- status_t selectPresentation(int presentationId, int programId);
- status_t attachAuxEffect(int EffectId);
- void setAuxBuffer(int EffectId, int32_t *buffer);
- int32_t *auxBuffer() const { return mAuxBuffer; }
- void setMainBuffer(float *buffer) { mMainBuffer = buffer; }
- float *mainBuffer() const { return mMainBuffer; }
- int auxEffectId() const { return mAuxEffectId; }
- virtual status_t getTimestamp(AudioTimestamp& timestamp);
- void signal();
- status_t getDualMonoMode(audio_dual_mono_mode_t* mode);
- status_t setDualMonoMode(audio_dual_mono_mode_t mode);
- status_t getAudioDescriptionMixLevel(float* leveldB);
- status_t setAudioDescriptionMixLevel(float leveldB);
- status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate);
- status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate);
+ status_t setParameters(const String8& keyValuePairs) final;
+ status_t selectPresentation(int presentationId, int programId) final;
+ status_t attachAuxEffect(int EffectId) final;
+ void setAuxBuffer(int EffectId, int32_t* buffer) final;
+ int32_t* auxBuffer() const final { return mAuxBuffer; }
+ void setMainBuffer(float* buffer) final { mMainBuffer = buffer; }
+ float* mainBuffer() const final { return mMainBuffer; }
+ int auxEffectId() const final { return mAuxEffectId; }
+ status_t getTimestamp(AudioTimestamp& timestamp) final;
+ void signal() final;
+ status_t getDualMonoMode(audio_dual_mono_mode_t* mode) const final;
+ status_t setDualMonoMode(audio_dual_mono_mode_t mode) final;
+ status_t getAudioDescriptionMixLevel(float* leveldB) const final;
+ status_t setAudioDescriptionMixLevel(float leveldB) final;
+ status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) const final;
+ status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) final;
-// implement FastMixerState::VolumeProvider interface
- virtual gain_minifloat_packed_t getVolumeLR();
+ // implement FastMixerState::VolumeProvider interface
+ gain_minifloat_packed_t getVolumeLR() const final;
- status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
-
- virtual bool isFastTrack() const { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
-
- double bufferLatencyMs() const override {
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
+ bool isFastTrack() const final { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
+ double bufferLatencyMs() const final {
return isStatic() ? 0. : TrackBase::bufferLatencyMs();
}
-// implement volume handling.
+ // implement volume handling.
media::VolumeShaper::Status applyVolumeShaper(
const sp<media::VolumeShaper::Configuration>& configuration,
const sp<media::VolumeShaper::Operation>& operation);
- sp<media::VolumeShaper::State> getVolumeShaperState(int id);
- sp<media::VolumeHandler> getVolumeHandler() { return mVolumeHandler; }
+ sp<media::VolumeShaper::State> getVolumeShaperState(int id) const final;
+ sp<media::VolumeHandler> getVolumeHandler() const final{ return mVolumeHandler; }
/** Set the computed normalized final volume of the track.
* !masterMute * masterVolume * streamVolume * averageLRVolume */
- void setFinalVolume(float volumeLeft, float volumeRight);
- float getFinalVolume() const { return mFinalVolume; }
- void getFinalVolume(float* left, float* right) const {
+ void setFinalVolume(float volumeLeft, float volumeRight) final;
+ float getFinalVolume() const final { return mFinalVolume; }
+ void getFinalVolume(float* left, float* right) const final {
*left = mFinalVolumeLeft;
*right = mFinalVolumeRight;
}
@@ -172,21 +162,22 @@
using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
/** Copy the track metadata in the provided iterator. Thread safe. */
- virtual void copyMetadataTo(MetadataInserter& backInserter) const;
+ void copyMetadataTo(MetadataInserter& backInserter) const override;
+
/** Return haptic playback of the track is enabled or not, used in mixer. */
- bool getHapticPlaybackEnabled() const { return mHapticPlaybackEnabled; }
+ bool getHapticPlaybackEnabled() const final { return mHapticPlaybackEnabled; }
/** Set haptic playback of the track is enabled or not, should be
* set after query or get callback from vibrator service */
- void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) {
+ void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) final {
mHapticPlaybackEnabled = hapticPlaybackEnabled;
}
/** Return at what intensity to play haptics, used in mixer. */
- os::HapticScale getHapticIntensity() const { return mHapticIntensity; }
+ os::HapticScale getHapticIntensity() const final { return mHapticIntensity; }
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
- float getHapticMaxAmplitude() const { return mHapticMaxAmplitude; }
+ float getHapticMaxAmplitude() const final { return mHapticMaxAmplitude; }
/** Set intensity of haptic playback, should be set after querying vibrator service. */
- void setHapticIntensity(os::HapticScale hapticIntensity) {
+ void setHapticIntensity(os::HapticScale hapticIntensity) final {
if (os::isValidHapticScale(hapticIntensity)) {
mHapticIntensity = hapticIntensity;
setHapticPlaybackEnabled(mHapticIntensity != os::HapticScale::MUTE);
@@ -195,16 +186,16 @@
/** Set maximum amplitude allowed for haptic data, should be set after querying
* vibrator service.
*/
- void setHapticMaxAmplitude(float maxAmplitude) {
+ void setHapticMaxAmplitude(float maxAmplitude) final {
mHapticMaxAmplitude = maxAmplitude;
}
- sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
+ sp<os::ExternalVibration> getExternalVibration() const final { return mExternalVibration; }
// This function should be called with holding thread lock.
- void updateTeePatches_l();
- void setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate);
+ void updateTeePatches_l() final;
+ void setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) final;
- void tallyUnderrunFrames(size_t frames) override {
+ void tallyUnderrunFrames(size_t frames) final {
if (isOut()) { // we expect this from output tracks only
mAudioTrackServerProxy->tallyUnderrunFrames(frames);
// Fetch absolute numbers from AudioTrackShared as it counts
@@ -215,29 +206,18 @@
}
}
- static bool checkServerLatencySupported(
- audio_format_t format, audio_output_flags_t flags) {
- return audio_is_linear_pcm(format)
- && (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == 0;
- }
-
- audio_output_flags_t getOutputFlags() const { return mFlags; }
- float getSpeed() const { return mSpeed; }
- bool isSpatialized() const override { return mIsSpatialized; }
- bool isBitPerfect() const override { return mIsBitPerfect; }
+ audio_output_flags_t getOutputFlags() const final { return mFlags; }
+ float getSpeed() const final { return mSpeed; }
+ bool isSpatialized() const final { return mIsSpatialized; }
+ bool isBitPerfect() const final { return mIsBitPerfect; }
/**
* Updates the mute state and notifies the audio service. Call this only when holding player
* thread lock.
*/
- void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState);
+ void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState) final;
protected:
- // for numerous
- friend class PlaybackThread;
- friend class MixerThread;
- friend class DirectOutputThread;
- friend class OffloadThread;
DISALLOW_COPY_AND_ASSIGN(Track);
@@ -246,38 +226,39 @@
void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
// ExtendedAudioBufferProvider interface
- virtual size_t framesReady() const;
- virtual int64_t framesReleased() const;
- virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+ size_t framesReady() const override;
+ int64_t framesReleased() const override;
+ void onTimestamp(const ExtendedTimestamp ×tamp) override;
- bool isPausing() const { return mState == PAUSING; }
- bool isPaused() const { return mState == PAUSED; }
- bool isResuming() const { return mState == RESUMING; }
- bool isReady() const;
- void setPaused() { mState = PAUSED; }
- void reset();
- bool isFlushPending() const { return mFlushHwPending; }
- void flushAck();
- bool isResumePending();
- void resumeAck();
+ // Used by thread
+ bool isPausing() const final { return mState == PAUSING; }
+ bool isPaused() const final { return mState == PAUSED; }
+ bool isResuming() const final { return mState == RESUMING; }
+ bool isReady() const final;
+ void setPaused() final { mState = PAUSED; }
+ void reset() final;
+ bool isFlushPending() const final { return mFlushHwPending; }
+ void flushAck() final;
+ bool isResumePending() const final;
+ void resumeAck() final;
// For direct or offloaded tracks ensure that the pause state is acknowledged
// by the playback thread in case of an immediate flush.
- bool isPausePending() const { return mPauseHwPending; }
- void pauseAck();
+ bool isPausePending() const final { return mPauseHwPending; }
+ void pauseAck() final;
void updateTrackFrameInfo(int64_t trackFramesReleased, int64_t sinkFramesWritten,
- uint32_t halSampleRate, const ExtendedTimestamp &timeStamp);
+ uint32_t halSampleRate, const ExtendedTimestamp& timeStamp) final;
- sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
+ sp<IMemory> sharedBuffer() const final { return mSharedBuffer; }
// presentationComplete checked by frames. (Mixed Tracks).
// framesWritten is cumulative, never reset, and is shared all tracks
// audioHalFrames is derived from output latency
- bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
+ bool presentationComplete(int64_t framesWritten, size_t audioHalFrames) final;
// presentationComplete checked by time. (Direct Tracks).
- bool presentationComplete(uint32_t latencyMs);
+ bool presentationComplete(uint32_t latencyMs) final;
- void resetPresentationComplete() {
+ void resetPresentationComplete() final {
mPresentationCompleteFrames = 0;
mPresentationCompleteTimeNs = 0;
}
@@ -288,25 +269,43 @@
void signalClientFlag(int32_t flag);
-public:
- void triggerEvents(AudioSystem::sync_event_t type);
- virtual void invalidate();
- void disable();
-
- int fastIndex() const { return mFastIndex; }
-
- bool isPlaybackRestricted() const {
+ void triggerEvents(AudioSystem::sync_event_t type) final;
+ void invalidate() final;
+ void disable() final;
+ int& fastIndex() final { return mFastIndex; }
+ bool isPlaybackRestricted() const final {
// The monitor is only created for tracks that can be silenced.
return mOpPlayAudioMonitor ? !mOpPlayAudioMonitor->hasOpPlayAudio() : false; }
-protected:
+ const sp<AudioTrackServerProxy>& audioTrackServerProxy() const final {
+ return mAudioTrackServerProxy;
+ }
+ bool hasVolumeController() const final { return mHasVolumeController; }
+ void setHasVolumeController(bool hasVolumeController) final {
+ mHasVolumeController = hasVolumeController;
+ }
+ void setCachedVolume(float volume) final {
+ mCachedVolume = volume;
+ }
+ void setResetDone(bool resetDone) final {
+ mResetDone = resetDone;
+ }
+ ExtendedAudioBufferProvider* asExtendedAudioBufferProvider() final {
+ return this;
+ }
+ VolumeProvider* asVolumeProvider() final {
+ return this;
+ }
- // FILLED state is used for suppressing volume ramp at begin of playing
- enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE};
- mutable uint8_t mFillingUpStatus;
+ FillingStatus& fillingStatus() final { return mFillingStatus; }
+ int8_t& retryCount() final { return mRetryCount; }
+ FastTrackUnderruns& fastTrackUnderruns() final { return mObservedUnderruns; }
+
+protected:
+ mutable FillingStatus mFillingStatus;
int8_t mRetryCount;
- // see comment at AudioFlinger::PlaybackThread::Track::~Track for why this can't be const
+ // see comment at ~Track for why this can't be const
sp<IMemory> mSharedBuffer;
bool mResetDone;
@@ -385,7 +384,7 @@
bool mFlushHwPending; // track requests for thread flush
bool mPauseHwPending = false; // direct/offload track request for thread pause
audio_output_flags_t mFlags;
- TeePatches mTeePatches;
+ TeePatches mTeePatches;
std::optional<TeePatches> mTeePatchesToUpdate;
const float mSpeed;
const bool mIsSpatialized;
@@ -399,7 +398,7 @@
// playback track, used by DuplicatingThread
-class OutputTrack : public Track {
+class OutputTrack : public Track, public IAfOutputTrack {
public:
class Buffer : public AudioBufferProvider::Buffer {
@@ -407,29 +406,28 @@
void *mBuffer;
};
- OutputTrack(PlaybackThread *thread,
- DuplicatingThread *sourceThread,
+ OutputTrack(IAfPlaybackThread* thread,
+ IAfDuplicatingThread* sourceThread,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t frameCount,
const AttributionSourceState& attributionSource);
- virtual ~OutputTrack();
+ ~OutputTrack() override;
- virtual status_t start(AudioSystem::sync_event_t event =
+ status_t start(AudioSystem::sync_event_t event =
AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
- virtual void stop();
- ssize_t write(void* data, uint32_t frames);
- bool bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
- bool isActive() const { return mActive; }
- const wp<ThreadBase>& thread() const { return mThread; }
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) final;
+ void stop() final;
+ ssize_t write(void* data, uint32_t frames) final;
+ bool bufferQueueEmpty() const final { return mBufferQueue.size() == 0; }
+ bool isActive() const final { return mActive; }
- void copyMetadataTo(MetadataInserter& backInserter) const override;
+ void copyMetadataTo(MetadataInserter& backInserter) const final;
/** Set the metadatas of the upstream tracks. Thread safe. */
- void setMetadatas(const SourceMetadatas& metadatas);
+ void setMetadatas(const SourceMetadatas& metadatas) final;
/** returns client timestamp to the upstream duplicating thread. */
- ExtendedTimestamp getClientProxyTimestamp() const {
+ ExtendedTimestamp getClientProxyTimestamp() const final {
// server - kernel difference is not true latency when drained
// i.e. mServerProxy->isDrained().
ExtendedTimestamp timestamp;
@@ -440,7 +438,6 @@
// (with mTimeNs[] filled with -1's) is returned.
return timestamp;
}
-
private:
status_t obtainBuffer(AudioBufferProvider::Buffer* buffer,
uint32_t waitTimeMs);
@@ -455,7 +452,7 @@
Vector < Buffer* > mBufferQueue;
AudioBufferProvider::Buffer mOutBuffer;
bool mActive;
- DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
+ IAfDuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
sp<AudioTrackClientProxy> mClientProxy;
/** Attributes of the source tracks.
@@ -475,10 +472,9 @@
}; // end of OutputTrack
// playback track, used by PatchPanel
-class PatchTrack : public Track, public PatchTrackBase {
+class PatchTrack : public Track, public PatchTrackBase, public IAfPatchTrack {
public:
-
- PatchTrack(PlaybackThread *playbackThread,
+ PatchTrack(IAfPlaybackThread* playbackThread,
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
@@ -492,23 +488,24 @@
* as soon as possible to have
* the lowest possible latency
* even if it might glitch. */);
- virtual ~PatchTrack();
+ ~PatchTrack() override;
- size_t framesReady() const override;
+ size_t framesReady() const final;
- virtual status_t start(AudioSystem::sync_event_t event =
+ status_t start(AudioSystem::sync_event_t event =
AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) final;
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) final;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) final;
// PatchProxyBufferProvider interface
- virtual status_t obtainBuffer(Proxy::Buffer* buffer,
- const struct timespec *timeOut = NULL);
- virtual void releaseBuffer(Proxy::Buffer* buffer);
+ status_t obtainBuffer(Proxy::Buffer* buffer, const struct timespec* timeOut = nullptr) final;
+ void releaseBuffer(Proxy::Buffer* buffer) final;
private:
void restartIfDisabled();
}; // end of PatchTrack
+
+} // namespace android
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 61f36a1..021add4 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -15,23 +15,19 @@
** limitations under the License.
*/
-#include <android/content/AttributionSourceState.h>
+#pragma once
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#include "TrackBase.h"
+
+#include <android/content/AttributionSourceState.h>
+#include <datapath/AudioStreamIn.h> // struct Source
+
+namespace android {
// record track
-class RecordTrack : public TrackBase {
+class RecordTrack : public TrackBase, public virtual IAfRecordTrack {
public:
- // createIAudioRecordAdapter() is a static constructor which creates an
- // IAudioRecord AIDL interface wrapper from the RecordTrack object that
- // may be passed back to the client (if needed).
- //
- // Only one AIDL IAudioRecord interface wrapper should be created per RecordTrack.
- static sp<media::IAudioRecord> createIAudioRecordAdapter(const sp<RecordTrack>& recordTrack);
-
- RecordTrack(RecordThread *thread,
+ RecordTrack(IAfRecordThread* thread,
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t sampleRate,
@@ -47,67 +43,70 @@
track_type type,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
int32_t startFrames = -1);
- virtual ~RecordTrack();
- virtual status_t initCheck() const;
+ ~RecordTrack() override;
+ status_t initCheck() const final;
- virtual status_t start(AudioSystem::sync_event_t event, audio_session_t triggerSession);
- virtual void stop();
+ status_t start(AudioSystem::sync_event_t event, audio_session_t triggerSession) final;
+ void stop() final;
+ void destroy() final;
+ void invalidate() final;
- void destroy();
-
- virtual void invalidate();
// clear the buffer overflow flag
- void clearOverflow() { mOverflow = false; }
+ void clearOverflow() final { mOverflow = false; }
// set the buffer overflow flag and return previous value
- bool setOverflow() { bool tmp = mOverflow; mOverflow = true;
+ bool setOverflow() final { bool tmp = mOverflow; mOverflow = true;
return tmp; }
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
- void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event);
- void clearSyncStartEvent();
+ void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event) final;
+ void clearSyncStartEvent() final;
- void updateTrackFrameInfo(int64_t trackFramesReleased,
+ void updateTrackFrameInfo(int64_t trackFramesReleased,
int64_t sourceFramesRead,
uint32_t halSampleRate,
- const ExtendedTimestamp ×tamp);
+ const ExtendedTimestamp ×tamp) final;
- virtual bool isFastTrack() const { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
- bool isDirect() const override
+ bool isFastTrack() const final { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
+ bool isDirect() const final
{ return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }
- void setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
- bool isSilenced() const { return mSilenced; }
+ void setSilenced(bool silenced) final { if (!isPatchTrack()) mSilenced = silenced; }
+ bool isSilenced() const final { return mSilenced; }
- status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final;
- status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
- status_t setPreferredMicrophoneFieldDimension(float zoom);
- status_t shareAudioHistory(const std::string& sharedAudioPackageName,
- int64_t sharedAudioStartMs);
- int32_t startFrames() { return mStartFrames; }
+ status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final;
+ status_t setPreferredMicrophoneFieldDimension(float zoom) final;
+ status_t shareAudioHistory(const std::string& sharedAudioPackageName,
+ int64_t sharedAudioStartMs) final;
+ int32_t startFrames() const final { return mStartFrames; }
- static bool checkServerLatencySupported(
- audio_format_t format, audio_input_flags_t flags) {
- return audio_is_linear_pcm(format)
- && (flags & AUDIO_INPUT_FLAG_HW_AV_SYNC) == 0;
- }
+ using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
+ void copyMetadataTo(MetadataInserter& backInserter) const final;
- using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
- using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
- virtual void copyMetadataTo(MetadataInserter& backInserter) const;
+ AudioBufferProvider::Buffer& sinkBuffer() final { return mSink; }
+ audioflinger::SynchronizedRecordState& synchronizedRecordState() final {
+ return mSynchronizedRecordState;
+ }
+ RecordBufferConverter* recordBufferConverter() const final { return mRecordBufferConverter; }
+ ResamplerBufferProvider* resamplerBufferProvider() const final {
+ return mResamplerBufferProvider;
+ }
private:
- friend class AudioFlinger; // for mState
-
DISALLOW_COPY_AND_ASSIGN(RecordTrack);
+protected:
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
// releaseBuffer() not overridden
+private:
+
bool mOverflow; // overflow on most recent attempt to fill client buffer
AudioBufferProvider::Buffer mSink; // references client's buffer sink in shared memory
@@ -120,7 +119,7 @@
mSynchronizedRecordState{mSampleRate}; // sampleRate defined in base
// used by resampler to find source frames
- ResamplerBufferProvider *mResamplerBufferProvider;
+ ResamplerBufferProvider* mResamplerBufferProvider;
// used by the record thread to convert frames to proper destination format
RecordBufferConverter *mRecordBufferConverter;
@@ -133,10 +132,9 @@
};
// playback track, used by PatchPanel
-class PatchRecord : public RecordTrack, public PatchTrackBase {
+class PatchRecord : public RecordTrack, public PatchTrackBase, public IAfPatchRecord {
public:
-
- PatchRecord(RecordThread *recordThread,
+ PatchRecord(IAfRecordThread* recordThread,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_format_t format,
@@ -146,20 +144,20 @@
audio_input_flags_t flags,
const Timeout& timeout = {},
audio_source_t source = AUDIO_SOURCE_DEFAULT);
- virtual ~PatchRecord();
+ ~PatchRecord() override;
- virtual Source* getSource() { return nullptr; }
+ Source* getSource() override { return nullptr; }
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
// PatchProxyBufferProvider interface
- virtual status_t obtainBuffer(Proxy::Buffer *buffer,
- const struct timespec *timeOut = NULL);
- virtual void releaseBuffer(Proxy::Buffer *buffer);
+ status_t obtainBuffer(Proxy::Buffer* buffer,
+ const struct timespec* timeOut = nullptr) override;
+ void releaseBuffer(Proxy::Buffer* buffer) override;
- size_t writeFrames(const void* src, size_t frameCount, size_t frameSize) {
+ size_t writeFrames(const void* src, size_t frameCount, size_t frameSize) final {
return writeFrames(this, src, frameCount, frameSize);
}
@@ -172,7 +170,7 @@
class PassthruPatchRecord : public PatchRecord, public Source {
public:
- PassthruPatchRecord(RecordThread *recordThread,
+ PassthruPatchRecord(IAfRecordThread* recordThread,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_format_t format,
@@ -180,25 +178,25 @@
audio_input_flags_t flags,
audio_source_t source = AUDIO_SOURCE_DEFAULT);
- Source* getSource() override { return static_cast<Source*>(this); }
+ Source* getSource() final { return static_cast<Source*>(this); }
// Source interface
- status_t read(void *buffer, size_t bytes, size_t *read) override;
- status_t getCapturePosition(int64_t *frames, int64_t *time) override;
- status_t standby() override;
+ status_t read(void* buffer, size_t bytes, size_t* read) final;
+ status_t getCapturePosition(int64_t* frames, int64_t* time) final;
+ status_t standby() final;
// AudioBufferProvider interface
// This interface is used by RecordThread to pass the data obtained
// from HAL or other source to the client. PassthruPatchRecord receives
// the data in 'obtainBuffer' so these calls are stubbed out.
- status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
- void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) final;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) final;
// PatchProxyBufferProvider interface
// This interface is used from DirectOutputThread to acquire data from HAL.
- bool producesBufferOnDemand() const override { return true; }
- status_t obtainBuffer(Proxy::Buffer *buffer, const struct timespec *timeOut = nullptr) override;
- void releaseBuffer(Proxy::Buffer *buffer) override;
+ bool producesBufferOnDemand() const final { return true; }
+ status_t obtainBuffer(Proxy::Buffer* buffer, const struct timespec* timeOut = nullptr) final;
+ void releaseBuffer(Proxy::Buffer* buffer) final;
private:
// This is to use with PatchRecord::writeFrames
@@ -215,7 +213,7 @@
PassthruPatchRecord& mPassthru;
};
- sp<StreamInHalInterface> obtainStream(sp<ThreadBase>* thread);
+ sp<StreamInHalInterface> obtainStream(sp<IAfThreadBase>* thread);
PatchRecordAudioBufferProvider mPatchRecordAudioBufferProvider;
std::unique_ptr<void, decltype(free)*> mSinkBuffer; // frame size aligned continuous buffer
@@ -227,3 +225,5 @@
status_t mReadError = NO_ERROR; // GUARDED_BY(mReadLock)
int64_t mLastReadFrames = 0; // accessed on RecordThread only
};
+
+} // namespace android
diff --git a/services/audioflinger/ResamplerBufferProvider.h b/services/audioflinger/ResamplerBufferProvider.h
new file mode 100644
index 0000000..b697743
--- /dev/null
+++ b/services/audioflinger/ResamplerBufferProvider.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace android {
+
+class IAfRecordTrack;
+
+/* The ResamplerBufferProvider is used to retrieve recorded input data from the
+ * RecordThread. It maintains local state on the relative position of the read
+ * position of the RecordTrack compared with the RecordThread.
+ */
+class ResamplerBufferProvider : public AudioBufferProvider
+{
+public:
+ explicit ResamplerBufferProvider(IAfRecordTrack* recordTrack) :
+ mRecordTrack(recordTrack) {}
+
+ // called to set the ResamplerBufferProvider to head of the RecordThread data buffer,
+ // skipping any previous data read from the hal.
+ void reset();
+
+ /* Synchronizes RecordTrack position with the RecordThread.
+ * Calculates available frames and handle overruns if the RecordThread
+ * has advanced faster than the ResamplerBufferProvider has retrieved data.
+ * TODO: why not do this for every getNextBuffer?
+ *
+ * Parameters
+ * framesAvailable: pointer to optional output size_t to store record track
+ * frames available.
+ * hasOverrun: pointer to optional boolean, returns true if track has overrun.
+ */
+
+ void sync(size_t* framesAvailable = nullptr, bool* hasOverrun = nullptr);
+
+ // AudioBufferProvider interface
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) final;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) final;
+
+ int32_t getFront() const { return mRsmpInFront; }
+ void setFront(int32_t front) { mRsmpInFront = front; }
+
+private:
+ IAfRecordTrack* const mRecordTrack;
+ size_t mRsmpInUnrel = 0; // unreleased frames remaining from
+ // most recent getNextBuffer
+ // for debug only
+ int32_t mRsmpInFront = 0; // next available frame
+ // rolling counter that is never cleared
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index af15cfc..575bcf9 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -20,45 +20,49 @@
// #define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_AUDIO
-#include "Configuration.h"
-#include <math.h>
-#include <fcntl.h>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <linux/futex.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
+#include "Threads.h"
+
+#include "Client.h"
+#include "IAfEffect.h"
+#include "MelReporter.h"
+#include "ResamplerBufferProvider.h"
+
+#include <afutils/DumpTryLock.h>
+#include <afutils/Permission.h>
+#include <afutils/TypedLogger.h>
+#include <afutils/Vibrator.h>
+#include <audio_utils/MelProcessor.h>
+#include <audio_utils/Metadata.h>
+#ifdef DEBUG_CPU_USAGE
+#include <audio_utils/Statistics.h>
+#include <cpustats/ThreadCpuUsage.h>
+#endif
+#include <audio_utils/channels.h>
+#include <audio_utils/format.h>
+#include <audio_utils/minifloat.h>
+#include <audio_utils/mono_blend.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/safe_math.h>
+#include <audiomanager/AudioManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/PersistableBundle.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
-#include <binder/PersistableBundle.h>
+#include <fastpath/AutoPark.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioParameter.h>
#include <media/AudioResamplerPublic.h>
+#ifdef ADD_BATTERY_DATA
+#include <media/IMediaPlayerService.h>
+#include <media/IMediaDeathNotifier.h>
+#endif
+#include <media/MmapStreamCallback.h>
#include <media/RecordBufferConverter.h>
#include <media/TypeConverter.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include <private/media/AudioTrackShared.h>
-#include <private/android_filesystem_config.h>
-#include <audio_utils/Balance.h>
-#include <audio_utils/MelProcessor.h>
-#include <audio_utils/Metadata.h>
-#include <audio_utils/channels.h>
-#include <audio_utils/mono_blend.h>
-#include <audio_utils/primitives.h>
-#include <audio_utils/format.h>
-#include <audio_utils/minifloat.h>
-#include <audio_utils/safe_math.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_downmix.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_spatializer.h>
-#include <system/audio.h>
-
-// NBAIO implementations
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
#include <media/nbaio/AudioStreamInSource.h>
#include <media/nbaio/AudioStreamOutSink.h>
#include <media/nbaio/MonoPipe.h>
@@ -68,31 +72,27 @@
#include <media/nbaio/SourceAudioBufferProvider.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/Process.h>
-
-#include <audiomanager/AudioManager.h>
-#include <powermanager/PowerManager.h>
-
-#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <media/audiohal/StreamHalInterface.h>
-
-#include "AudioFlinger.h"
#include <mediautils/SchedulingPolicyService.h>
#include <mediautils/ServiceUtilities.h>
+#include <powermanager/PowerManager.h>
+#include <private/android_filesystem_config.h>
+#include <private/media/AudioTrackShared.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
-#ifdef ADD_BATTERY_DATA
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaDeathNotifier.h>
-#endif
-
-#ifdef DEBUG_CPU_USAGE
-#include <audio_utils/Statistics.h>
-#include <cpustats/ThreadCpuUsage.h>
-#endif
-
-#include <fastpath/AutoPark.h>
-
+#include <fcntl.h>
+#include <linux/futex.h>
+#include <math.h>
+#include <memory>
#include <pthread.h>
-#include <afutils/TypedLogger.h>
+#include <sstream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/syscall.h>
// ----------------------------------------------------------------------------
@@ -120,9 +120,13 @@
namespace android {
+using audioflinger::SyncEvent;
using media::IEffectClient;
using content::AttributionSourceState;
+// Keep in sync with java definition in media/java/android/media/AudioRecord.java
+static constexpr int32_t kMaxSharedAudioHistoryMs = 5000;
+
// retry counts for buffer fill timeout
// 50 * ~20msecs = 1 second
static const int8_t kMaxTrackRetries = 50;
@@ -239,8 +243,84 @@
// and that all "fast" AudioRecord clients read from. In either case, the size can be small.
static const size_t kRecordThreadReadOnlyHeapSize = 0xD000;
+static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
+
+static nsecs_t getStandbyTimeInNanos() {
+ static nsecs_t standbyTimeInNanos = []() {
+ const int ms = property_get_int32("ro.audio.flinger_standbytime_ms",
+ kDefaultStandbyTimeInNsecs / NANOS_PER_MILLISECOND);
+ ALOGI("%s: Using %d ms as standby time", __func__, ms);
+ return milliseconds(ms);
+ }();
+ return standbyTimeInNanos;
+}
+
+// Set kEnableExtendedChannels to true to enable greater than stereo output
+// for the MixerThread and device sink. Number of channels allowed is
+// FCC_2 <= channels <= FCC_LIMIT.
+constexpr bool kEnableExtendedChannels = true;
+
+// Returns true if channel mask is permitted for the PCM sink in the MixerThread
+/* static */
+bool IAfThreadBase::isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
+ switch (audio_channel_mask_get_representation(channelMask)) {
+ case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
+ // Haptic channel mask is only applicable for channel position mask.
+ const uint32_t channelCount = audio_channel_count_from_out_mask(
+ static_cast<audio_channel_mask_t>(channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL));
+ const uint32_t maxChannelCount = kEnableExtendedChannels
+ ? FCC_LIMIT : FCC_2;
+ if (channelCount < FCC_2 // mono is not supported at this time
+ || channelCount > maxChannelCount) {
+ return false;
+ }
+ // check that channelMask is the "canonical" one we expect for the channelCount.
+ return audio_channel_position_mask_is_out_canonical(channelMask);
+ }
+ case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+ if (kEnableExtendedChannels) {
+ const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
+ if (channelCount >= FCC_2 // mono is not supported at this time
+ && channelCount <= FCC_LIMIT) {
+ return true;
+ }
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+// Set kEnableExtendedPrecision to true to use extended precision in MixerThread
+constexpr bool kEnableExtendedPrecision = true;
+
+// Returns true if format is permitted for the PCM sink in the MixerThread
+/* static */
+bool IAfThreadBase::isValidPcmSinkFormat(audio_format_t format) {
+ switch (format) {
+ case AUDIO_FORMAT_PCM_16_BIT:
+ return true;
+ case AUDIO_FORMAT_PCM_FLOAT:
+ case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+ case AUDIO_FORMAT_PCM_32_BIT:
+ case AUDIO_FORMAT_PCM_8_24_BIT:
+ return kEnableExtendedPrecision;
+ default:
+ return false;
+ }
+}
+
// ----------------------------------------------------------------------------
+// formatToString() needs to be exact for MediaMetrics purposes.
+// Do not use media/TypeConverter.h toString().
+/* static */
+std::string IAfThreadBase::formatToString(audio_format_t format) {
+ std::string result;
+ FormatConverter::toString(format, result);
+ return result;
+}
+
// TODO: move all toString helpers to audio.h
// under #ifdef __cplusplus #endif
static std::string patchSinksToString(const struct audio_patch *patch)
@@ -515,7 +595,7 @@
// ----------------------------------------------------------------------------
// static
-const char *AudioFlinger::ThreadBase::threadTypeToString(AudioFlinger::ThreadBase::type_t type)
+const char* ThreadBase::threadTypeToString(ThreadBase::type_t type)
{
switch (type) {
case MIXER:
@@ -541,11 +621,11 @@
}
}
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ThreadBase::ThreadBase(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
type_t type, bool systemReady, bool isOut)
: Thread(false /*canCallJava*/),
mType(type),
- mAudioFlinger(audioFlinger),
+ mAfThreadCallback(afThreadCallback),
mThreadMetrics(std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_THREAD) + std::to_string(id),
isOut),
mIsOut(isOut),
@@ -564,7 +644,7 @@
memset(&mPatch, 0, sizeof(struct audio_patch));
}
-AudioFlinger::ThreadBase::~ThreadBase()
+ThreadBase::~ThreadBase()
{
// mConfigEvents should be empty, but just in case it isn't, free the memory it owns
mConfigEvents.clear();
@@ -579,7 +659,7 @@
sendStatistics(true /* force */);
}
-status_t AudioFlinger::ThreadBase::readyToRun()
+status_t ThreadBase::readyToRun()
{
status_t status = initCheck();
if (status == NO_ERROR) {
@@ -590,7 +670,7 @@
return status;
}
-void AudioFlinger::ThreadBase::exit()
+void ThreadBase::exit()
{
ALOGV("ThreadBase::exit");
// do any cleanup required for exit to succeed
@@ -614,7 +694,7 @@
requestExitAndWait();
}
-status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
+status_t ThreadBase::setParameters(const String8& keyValuePairs)
{
ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
Mutex::Autolock _l(mLock);
@@ -624,7 +704,7 @@
// sendConfigEvent_l() must be called with ThreadBase::mLock held
// Can temporarily release the lock if waiting for a reply from processConfigEvents_l().
-status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event)
+status_t ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event)
NO_THREAD_SAFETY_ANALYSIS // condition variable
{
status_t status = NO_ERROR;
@@ -652,7 +732,7 @@
return status;
}
-void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event_t event, pid_t pid,
+void ThreadBase::sendIoConfigEvent(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId)
{
Mutex::Autolock _l(mLock);
@@ -660,7 +740,7 @@
}
// sendIoConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid,
+void ThreadBase::sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId)
{
// The audio statistics history is exponentially weighted to forget events
@@ -677,14 +757,14 @@
sendConfigEvent_l(configEvent);
}
-void AudioFlinger::ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp)
+void ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp)
{
Mutex::Autolock _l(mLock);
sendPrioConfigEvent_l(pid, tid, prio, forApp);
}
// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendPrioConfigEvent_l(
+void ThreadBase::sendPrioConfigEvent_l(
pid_t pid, pid_t tid, int32_t prio, bool forApp)
{
sp<ConfigEvent> configEvent = (ConfigEvent *)new PrioConfigEvent(pid, tid, prio, forApp);
@@ -692,7 +772,7 @@
}
// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair)
+status_t ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair)
{
sp<ConfigEvent> configEvent;
AudioParameter param(keyValuePair);
@@ -710,7 +790,7 @@
return sendConfigEvent_l(configEvent);
}
-status_t AudioFlinger::ThreadBase::sendCreateAudioPatchConfigEvent(
+status_t ThreadBase::sendCreateAudioPatchConfigEvent(
const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
@@ -725,7 +805,7 @@
return status;
}
-status_t AudioFlinger::ThreadBase::sendReleaseAudioPatchConfigEvent(
+status_t ThreadBase::sendReleaseAudioPatchConfigEvent(
const audio_patch_handle_t handle)
{
Mutex::Autolock _l(mLock);
@@ -733,7 +813,7 @@
return sendConfigEvent_l(configEvent);
}
-status_t AudioFlinger::ThreadBase::sendUpdateOutDeviceConfigEvent(
+status_t ThreadBase::sendUpdateOutDeviceConfigEvent(
const DeviceDescriptorBaseVector& outDevices)
{
if (type() != RECORD) {
@@ -745,7 +825,7 @@
return sendConfigEvent_l(configEvent);
}
-void AudioFlinger::ThreadBase::sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs)
+void ThreadBase::sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs)
{
ALOG_ASSERT(type() == RECORD, "sendResizeBufferConfigEvent_l() called on non record thread");
sp<ConfigEvent> configEvent =
@@ -753,27 +833,27 @@
sendConfigEvent_l(configEvent);
}
-void AudioFlinger::ThreadBase::sendCheckOutputStageEffectsEvent()
+void ThreadBase::sendCheckOutputStageEffectsEvent()
{
Mutex::Autolock _l(mLock);
sendCheckOutputStageEffectsEvent_l();
}
-void AudioFlinger::ThreadBase::sendCheckOutputStageEffectsEvent_l()
+void ThreadBase::sendCheckOutputStageEffectsEvent_l()
{
sp<ConfigEvent> configEvent =
(ConfigEvent *)new CheckOutputStageEffectsEvent();
sendConfigEvent_l(configEvent);
}
-void AudioFlinger::ThreadBase::sendHalLatencyModesChangedEvent_l()
+void ThreadBase::sendHalLatencyModesChangedEvent_l()
{
sp<ConfigEvent> configEvent = sp<HalLatencyModesChangedEvent>::make();
sendConfigEvent_l(configEvent);
}
// post condition: mConfigEvents.isEmpty()
-void AudioFlinger::ThreadBase::processConfigEvents_l()
+void ThreadBase::processConfigEvents_l()
{
bool configChanged = false;
@@ -940,13 +1020,13 @@
}
}
-void AudioFlinger::ThreadBase::dump(int fd, const Vector<String16>& args)
+void ThreadBase::dump(int fd, const Vector<String16>& args)
NO_THREAD_SAFETY_ANALYSIS // conditional try lock
{
dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input",
this, mThreadName, getTid(), type(), threadTypeToString(type()));
- bool locked = AudioFlinger::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mLock);
if (!locked) {
dprintf(fd, " Thread may be deadlocked\n");
}
@@ -978,18 +1058,20 @@
}
}
-void AudioFlinger::ThreadBase::dumpBase_l(int fd, const Vector<String16>& args __unused)
+void ThreadBase::dumpBase_l(int fd, const Vector<String16>& /* args */)
{
dprintf(fd, " I/O handle: %d\n", mId);
dprintf(fd, " Standby: %s\n", mStandby ? "yes" : "no");
dprintf(fd, " Sample rate: %u Hz\n", mSampleRate);
dprintf(fd, " HAL frame count: %zu\n", mFrameCount);
- dprintf(fd, " HAL format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat).c_str());
+ dprintf(fd, " HAL format: 0x%x (%s)\n", mHALFormat,
+ IAfThreadBase::formatToString(mHALFormat).c_str());
dprintf(fd, " HAL buffer size: %zu bytes\n", mBufferSize);
dprintf(fd, " Channel count: %u\n", mChannelCount);
dprintf(fd, " Channel mask: 0x%08x (%s)\n", mChannelMask,
channelMaskToString(mChannelMask, mType != RECORD).string());
- dprintf(fd, " Processing format: 0x%x (%s)\n", mFormat, formatToString(mFormat).c_str());
+ dprintf(fd, " Processing format: 0x%x (%s)\n", mFormat,
+ IAfThreadBase::formatToString(mFormat).c_str());
dprintf(fd, " Processing frame size: %zu bytes\n", mFrameSize);
dprintf(fd, " Pending config events:");
size_t numConfig = mConfigEvents.size();
@@ -1051,7 +1133,7 @@
}
}
-void AudioFlinger::ThreadBase::dumpEffectChains_l(int fd, const Vector<String16>& args)
+void ThreadBase::dumpEffectChains_l(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
char buffer[SIZE];
@@ -1068,13 +1150,13 @@
}
}
-void AudioFlinger::ThreadBase::acquireWakeLock()
+void ThreadBase::acquireWakeLock()
{
Mutex::Autolock _l(mLock);
acquireWakeLock_l();
}
-String16 AudioFlinger::ThreadBase::getWakeLockTag()
+String16 ThreadBase::getWakeLockTag()
{
switch (mType) {
case MIXER:
@@ -1099,7 +1181,7 @@
}
}
-void AudioFlinger::ThreadBase::acquireWakeLock_l()
+void ThreadBase::acquireWakeLock_l()
{
getPowerManager_l();
if (mPowerManager != 0) {
@@ -1122,13 +1204,13 @@
gBoottime.getBoottimeOffset();
}
-void AudioFlinger::ThreadBase::releaseWakeLock()
+void ThreadBase::releaseWakeLock()
{
Mutex::Autolock _l(mLock);
releaseWakeLock_l();
}
-void AudioFlinger::ThreadBase::releaseWakeLock_l()
+void ThreadBase::releaseWakeLock_l()
{
gBoottime.release(mWakeLockToken);
if (mWakeLockToken != 0) {
@@ -1140,7 +1222,7 @@
}
}
-void AudioFlinger::ThreadBase::getPowerManager_l() {
+void ThreadBase::getPowerManager_l() {
if (mSystemReady && mPowerManager == 0) {
// use checkService() to avoid blocking if power service is not up yet
sp<IBinder> binder =
@@ -1154,7 +1236,7 @@
}
}
-void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<uid_t> &uids) {
+void ThreadBase::updateWakeLockUids_l(const SortedVector<uid_t>& uids) {
getPowerManager_l();
#if !LOG_NDEBUG
@@ -1181,25 +1263,25 @@
}
}
-void AudioFlinger::ThreadBase::clearPowerManager()
+void ThreadBase::clearPowerManager()
{
Mutex::Autolock _l(mLock);
releaseWakeLock_l();
mPowerManager.clear();
}
-void AudioFlinger::ThreadBase::updateOutDevices(
+void ThreadBase::updateOutDevices(
const DeviceDescriptorBaseVector& outDevices __unused)
{
ALOGE("%s should only be called in RecordThread", __func__);
}
-void AudioFlinger::ThreadBase::resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs __unused)
+void ThreadBase::resizeInputBuffer_l(int32_t /* maxSharedAudioHistoryMs */)
{
ALOGE("%s should only be called in RecordThread", __func__);
}
-void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused)
+void ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& /* who */)
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
@@ -1208,7 +1290,7 @@
ALOGW("power manager service died !!!");
}
-void AudioFlinger::ThreadBase::setEffectSuspended_l(
+void ThreadBase::setEffectSuspended_l(
const effect_uuid_t *type, bool suspend, audio_session_t sessionId)
{
sp<IAfEffectChain> chain = getEffectChain_l(sessionId);
@@ -1223,7 +1305,7 @@
updateSuspendedSessions_l(type, suspend, sessionId);
}
-void AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<IAfEffectChain>& chain)
+void ThreadBase::checkSuspendOnAddEffectChain_l(const sp<IAfEffectChain>& chain)
{
ssize_t index = mSuspendedSessions.indexOfKey(chain->sessionId());
if (index < 0) {
@@ -1247,7 +1329,7 @@
}
}
-void AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
+void ThreadBase::updateSuspendedSessions_l(const effect_uuid_t* type,
bool suspend,
audio_session_t sessionId)
{
@@ -1308,7 +1390,7 @@
}
}
-void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(bool enabled,
+void ThreadBase::checkSuspendOnEffectEnabled(bool enabled,
audio_session_t sessionId,
bool threadLocked)
NO_THREAD_SAFETY_ANALYSIS // manual locking
@@ -1334,7 +1416,7 @@
}
// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::RecordThread::checkEffectCompatibility_l(
+status_t RecordThread::checkEffectCompatibility_l(
const effect_descriptor_t *desc, audio_session_t sessionId)
{
// No global output effect sessions on record threads
@@ -1378,7 +1460,7 @@
}
// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l(
+status_t PlaybackThread::checkEffectCompatibility_l(
const effect_descriptor_t *desc, audio_session_t sessionId)
{
// no preprocessing on playback threads
@@ -1533,7 +1615,7 @@
}
// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held
-sp<IAfEffectHandle> AudioFlinger::ThreadBase::createEffect_l(
+sp<IAfEffectHandle> ThreadBase::createEffect_l(
const sp<Client>& client,
const sp<IEffectClient>& effectClient,
int32_t priority,
@@ -1585,7 +1667,7 @@
ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
if (effect == 0) {
- effectId = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+ effectId = mAfThreadCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
// create a new effect module if none present in the chain
lStatus = chain->createEffect_l(effect, desc, effectId, sessionId, pinned);
if (lStatus != NO_ERROR) {
@@ -1596,14 +1678,14 @@
// FIXME: use vector of device and address when effect interface is ready.
effect->setDevices(outDeviceTypeAddrs());
effect->setInputDevice(inDeviceTypeAddr());
- effect->setMode(mAudioFlinger->getMode());
+ effect->setMode(mAfThreadCallback->getMode());
effect->setAudioSource(mAudioSource);
}
if (effect->isHapticGenerator()) {
// TODO(b/184194057): Use the vibrator information from the vibrator that will be used
// for the HapticGenerator.
const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
- std::move(mAudioFlinger->getDefaultVibratorInfo_l());
+ std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
if (defaultVibratorInfo) {
// Only set the vibrator info when it is a valid one.
effect->setVibratorInfo(*defaultVibratorInfo);
@@ -1638,7 +1720,7 @@
return handle;
}
-void AudioFlinger::ThreadBase::disconnectEffectHandle(IAfEffectHandle *handle,
+void ThreadBase::disconnectEffectHandle(IAfEffectHandle* handle,
bool unpinIfLast)
{
bool remove = false;
@@ -1661,14 +1743,14 @@
sendCheckOutputStageEffectsEvent_l();
}
if (remove) {
- mAudioFlinger->updateOrphanEffectChains(effect);
+ mAfThreadCallback->updateOrphanEffectChains(effect);
if (handle->enabled()) {
effect->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
}
}
}
-void AudioFlinger::ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) {
+void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) {
if (isOffloadOrMmap()) {
Mutex::Autolock _l(mLock);
broadcast_l();
@@ -1679,33 +1761,33 @@
t->invalidateTracks(AUDIO_STREAM_MUSIC);
}
if (effect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
- mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+ mAfThreadCallback->onNonOffloadableGlobalEffectEnable();
}
}
}
-void AudioFlinger::ThreadBase::onEffectDisable() {
+void ThreadBase::onEffectDisable() {
if (isOffloadOrMmap()) {
Mutex::Autolock _l(mLock);
broadcast_l();
}
}
-sp<IAfEffectModule> AudioFlinger::ThreadBase::getEffect(audio_session_t sessionId,
- int effectId)
+sp<IAfEffectModule> ThreadBase::getEffect(audio_session_t sessionId,
+ int effectId) const
{
Mutex::Autolock _l(mLock);
return getEffect_l(sessionId, effectId);
}
-sp<IAfEffectModule> AudioFlinger::ThreadBase::getEffect_l(audio_session_t sessionId,
- int effectId)
+sp<IAfEffectModule> ThreadBase::getEffect_l(audio_session_t sessionId,
+ int effectId) const
{
sp<IAfEffectChain> chain = getEffectChain_l(sessionId);
return chain != 0 ? chain->getEffectFromId_l(effectId) : 0;
}
-std::vector<int> AudioFlinger::ThreadBase::getEffectIds_l(audio_session_t sessionId)
+std::vector<int> ThreadBase::getEffectIds_l(audio_session_t sessionId) const
{
sp<IAfEffectChain> chain = getEffectChain_l(sessionId);
return chain != nullptr ? chain->getEffectIds() : std::vector<int>{};
@@ -1713,7 +1795,7 @@
// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
// PlaybackThread::mLock held
-status_t AudioFlinger::ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
+status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
{
// check for existing effect chain with the requested audio session
audio_session_t sessionId = effect->sessionId();
@@ -1752,13 +1834,13 @@
effect->setDevices(outDeviceTypeAddrs());
effect->setInputDevice(inDeviceTypeAddr());
- effect->setMode(mAudioFlinger->getMode());
+ effect->setMode(mAfThreadCallback->getMode());
effect->setAudioSource(mAudioSource);
return NO_ERROR;
}
-void AudioFlinger::ThreadBase::removeEffect_l(const sp<IAfEffectModule>& effect, bool release) {
+void ThreadBase::removeEffect_l(const sp<IAfEffectModule>& effect, bool release) {
ALOGV("%s %p effect %p", __FUNCTION__, this, effect.get());
effect_descriptor_t desc = effect->desc();
@@ -1777,7 +1859,7 @@
}
}
-void AudioFlinger::ThreadBase::lockEffectChains_l(
+void ThreadBase::lockEffectChains_l(
Vector<sp<IAfEffectChain>>& effectChains)
NO_THREAD_SAFETY_ANALYSIS // calls EffectChain::lock()
{
@@ -1787,7 +1869,7 @@
}
}
-void AudioFlinger::ThreadBase::unlockEffectChains(
+void ThreadBase::unlockEffectChains(
const Vector<sp<IAfEffectChain>>& effectChains)
NO_THREAD_SAFETY_ANALYSIS // calls EffectChain::unlock()
{
@@ -1796,13 +1878,13 @@
}
}
-sp<IAfEffectChain> AudioFlinger::ThreadBase::getEffectChain(audio_session_t sessionId)
+sp<IAfEffectChain> ThreadBase::getEffectChain(audio_session_t sessionId) const
{
Mutex::Autolock _l(mLock);
return getEffectChain_l(sessionId);
}
-sp<IAfEffectChain> AudioFlinger::ThreadBase::getEffectChain_l(audio_session_t sessionId)
+sp<IAfEffectChain> ThreadBase::getEffectChain_l(audio_session_t sessionId)
const
{
size_t size = mEffectChains.size();
@@ -1814,7 +1896,7 @@
return 0;
}
-void AudioFlinger::ThreadBase::setMode(audio_mode_t mode)
+void ThreadBase::setMode(audio_mode_t mode)
{
Mutex::Autolock _l(mLock);
size_t size = mEffectChains.size();
@@ -1823,7 +1905,7 @@
}
}
-void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config)
+void ThreadBase::toAudioPortConfig(struct audio_port_config* config)
{
config->type = AUDIO_PORT_TYPE_MIX;
config->ext.mix.handle = mId;
@@ -1834,7 +1916,7 @@
AUDIO_PORT_CONFIG_FORMAT;
}
-void AudioFlinger::ThreadBase::systemReady()
+void ThreadBase::systemReady()
{
Mutex::Autolock _l(mLock);
if (mSystemReady) {
@@ -1849,7 +1931,7 @@
}
template <typename T>
-ssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::add(const sp<T> &track) {
+ssize_t ThreadBase::ActiveTracks<T>::add(const sp<T>& track) {
ssize_t index = mActiveTracks.indexOf(track);
if (index >= 0) {
ALOGW("ActiveTracks<T>::add track %p already there", track.get());
@@ -1864,7 +1946,7 @@
}
template <typename T>
-ssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::remove(const sp<T> &track) {
+ssize_t ThreadBase::ActiveTracks<T>::remove(const sp<T>& track) {
ssize_t index = mActiveTracks.remove(track);
if (index < 0) {
ALOGW("ActiveTracks<T>::remove nonexistent track %p", track.get());
@@ -1883,7 +1965,7 @@
}
template <typename T>
-void AudioFlinger::ThreadBase::ActiveTracks<T>::clear() {
+void ThreadBase::ActiveTracks<T>::clear() {
for (const sp<T> &track : mActiveTracks) {
track->endBatteryAttribution();
logTrack("clear", track);
@@ -1895,7 +1977,7 @@
}
template <typename T>
-void AudioFlinger::ThreadBase::ActiveTracks<T>::updatePowerState(
+void ThreadBase::ActiveTracks<T>::updatePowerState(
const sp<ThreadBase>& thread, bool force) {
// Updates ActiveTracks client uids to the thread wakelock.
if (mActiveTracksGeneration != mLastActiveTracksGeneration || force) {
@@ -1905,7 +1987,7 @@
}
template <typename T>
-bool AudioFlinger::ThreadBase::ActiveTracks<T>::readAndClearHasChanged() {
+bool ThreadBase::ActiveTracks<T>::readAndClearHasChanged() {
bool hasChanged = mHasChanged;
mHasChanged = false;
@@ -1918,7 +2000,7 @@
}
template <typename T>
-void AudioFlinger::ThreadBase::ActiveTracks<T>::logTrack(
+void ThreadBase::ActiveTracks<T>::logTrack(
const char *funcName, const sp<T> &track) const {
if (mLocalLog != nullptr) {
String8 result;
@@ -1927,7 +2009,7 @@
}
}
-void AudioFlinger::ThreadBase::broadcast_l()
+void ThreadBase::broadcast_l()
{
// Thread could be blocked waiting for async
// so signal it to handle state changes immediately
@@ -1939,7 +2021,7 @@
// Call only from threadLoop() or when it is idle.
// Do not call from high performance code as this may do binder rpc to the MediaMetrics service.
-void AudioFlinger::ThreadBase::sendStatistics(bool force)
+void ThreadBase::sendStatistics(bool force)
{
// Do not log if we have no stats.
// We choose the timestamp verifier because it is the most likely item to be present.
@@ -2002,16 +2084,16 @@
item->selfrecord();
}
-product_strategy_t AudioFlinger::ThreadBase::getStrategyForStream(audio_stream_type_t stream) const
+product_strategy_t ThreadBase::getStrategyForStream(audio_stream_type_t stream) const
{
- if (!mAudioFlinger->isAudioPolicyReady()) {
+ if (!mAfThreadCallback->isAudioPolicyReady()) {
return PRODUCT_STRATEGY_NONE;
}
return AudioSystem::getStrategyForStream(stream);
}
// startMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::ThreadBase::startMelComputation_l(
+void ThreadBase::startMelComputation_l(
const sp<audio_utils::MelProcessor>& /*processor*/)
{
// Do nothing
@@ -2019,7 +2101,7 @@
}
// stopMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::ThreadBase::stopMelComputation_l()
+void ThreadBase::stopMelComputation_l()
{
// Do nothing
ALOGW("%s: ThreadBase does not support CSD", __func__);
@@ -2029,20 +2111,20 @@
// Playback
// ----------------------------------------------------------------------------
-AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
+PlaybackThread::PlaybackThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output,
audio_io_handle_t id,
type_t type,
bool systemReady,
audio_config_base_t *mixerConfig)
- : ThreadBase(audioFlinger, id, type, systemReady, true /* isOut */),
+ : ThreadBase(afThreadCallback, id, type, systemReady, true /* isOut */),
mNormalFrameCount(0), mSinkBuffer(NULL),
- mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision || type == SPATIALIZER),
+ mMixerBufferEnabled(kEnableExtendedPrecision || type == SPATIALIZER),
mMixerBuffer(NULL),
mMixerBufferSize(0),
mMixerBufferFormat(AUDIO_FORMAT_INVALID),
mMixerBufferValid(false),
- mEffectBufferEnabled(AudioFlinger::kEnableExtendedPrecision || type == SPATIALIZER),
+ mEffectBufferEnabled(kEnableExtendedPrecision || type == SPATIALIZER),
mEffectBuffer(NULL),
mEffectBufferSize(0),
mEffectBufferFormat(AUDIO_FORMAT_INVALID),
@@ -2057,13 +2139,13 @@
mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
mMixerStatus(MIXER_IDLE),
mMixerStatusIgnoringFastTracks(MIXER_IDLE),
- mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs),
+ mStandbyDelayNs(getStandbyTimeInNanos()),
mBytesRemaining(0),
mCurrentWriteLength(0),
mUseAsyncWrite(false),
mWriteAckSequence(0),
mDrainSequence(0),
- mScreenState(AudioFlinger::mScreenState),
+ mScreenState(mAfThreadCallback->getScreenState()),
// index 0 is reserved for normal mixer's submix
mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
@@ -2072,7 +2154,7 @@
mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
{
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
- mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
+ mNBLogWriter = afThreadCallback->newWriter_l(kLogSize, mThreadName);
// Assumes constructor is called by AudioFlinger with it's mLock held, but
// it would be safer to explicitly pass initial masterVolume/masterMute as
@@ -2081,8 +2163,8 @@
// If the HAL we are using has support for master volume or master mute,
// then do not attenuate or mute during mixing (just leave the volume at 1.0
// and the mute set to false).
- mMasterVolume = audioFlinger->masterVolume_l();
- mMasterMute = audioFlinger->masterMute_l();
+ mMasterVolume = afThreadCallback->masterVolume_l();
+ mMasterMute = afThreadCallback->masterMute_l();
if (mOutput->audioHwDev) {
if (mOutput->audioHwDev->canSetMasterVolume()) {
mMasterVolume = 1.0;
@@ -2120,7 +2202,7 @@
for (int i = AUDIO_STREAM_MIN; i < AUDIO_STREAM_FOR_POLICY_CNT; ++i) {
const audio_stream_type_t stream{static_cast<audio_stream_type_t>(i)};
mStreamTypes[stream].volume = 0.0f;
- mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
+ mStreamTypes[stream].mute = mAfThreadCallback->streamMute_l(stream);
}
// Audio patch and call assistant volume are always max
mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
@@ -2129,9 +2211,9 @@
mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].mute = false;
}
-AudioFlinger::PlaybackThread::~PlaybackThread()
+PlaybackThread::~PlaybackThread()
{
- mAudioFlinger->unregisterWriter(mNBLogWriter);
+ mAfThreadCallback->unregisterWriter(mNBLogWriter);
free(mSinkBuffer);
free(mMixerBuffer);
free(mEffectBuffer);
@@ -2140,7 +2222,7 @@
// Thread virtuals
-void AudioFlinger::PlaybackThread::onFirstRef()
+void PlaybackThread::onFirstRef()
{
if (!isStreamInitialized()) {
ALOGE("The stream is not open yet"); // This should not happen.
@@ -2155,7 +2237,7 @@
if (mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING &&
mOutput->stream->setCallback(this) == OK) {
mUseAsyncWrite = true;
- mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
+ mCallbackThread = sp<AsyncCallbackThread>::make(this);
}
if (mOutput->stream->setEventCallback(this) != OK) {
@@ -2167,14 +2249,14 @@
}
// ThreadBase virtuals
-void AudioFlinger::PlaybackThread::preExit()
+void PlaybackThread::preExit()
{
ALOGV(" preExit()");
status_t result = mOutput->stream->exit();
ALOGE_IF(result != OK, "Error when calling exit(): %d", result);
}
-void AudioFlinger::PlaybackThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
+void PlaybackThread::dumpTracks_l(int fd, const Vector<String16>& /* args */)
{
String8 result;
@@ -2208,7 +2290,7 @@
result.append(prefix);
mTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks; ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (track != 0) {
bool active = mActiveTracks.indexOf(track) >= 0;
if (active) {
@@ -2228,7 +2310,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
- sp<Track> track = mActiveTracks[i];
+ sp<IAfTrack> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
result.append(prefix);
track->appendDump(result, true /* active */);
@@ -2239,7 +2321,7 @@
write(fd, result.string(), result.size());
}
-void AudioFlinger::PlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
+void PlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
dprintf(fd, " Master volume: %f\n", mMasterVolume);
dprintf(fd, " Master mute: %s\n", mMasterMute ? "on" : "off");
@@ -2275,7 +2357,7 @@
}
// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
+sp<IAfTrack> PlaybackThread::createTrack_l(
const sp<Client>& client,
audio_stream_type_t streamType,
const audio_attributes_t& attr,
@@ -2300,7 +2382,7 @@
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
- sp<Track> track;
+ sp<IAfTrack> track;
status_t lStatus;
audio_output_flags_t outputFlags = mOutput->flags;
audio_output_flags_t requestedFlags = *flags;
@@ -2593,7 +2675,7 @@
// manager
product_strategy_t strategy = getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t != 0 && t->isExternalTrack()) {
product_strategy_t actual = getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
@@ -2615,11 +2697,11 @@
trackFlags = static_cast<audio_output_flags_t>(trackFlags | AUDIO_OUTPUT_FLAG_DIRECT);
}
- track = new Track(this, client, streamType, attr, sampleRate, format,
+ track = IAfTrack::create(this, client, streamType, attr, sampleRate, format,
channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
sessionId, creatorPid, attributionSource, trackFlags,
- TrackBase::TYPE_DEFAULT, portId, SIZE_MAX /*frameCountToBeReady*/,
+ IAfTrackBase::TYPE_DEFAULT, portId, SIZE_MAX /*frameCountToBeReady*/,
speed, isSpatialized, isBitPerfect);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
@@ -2660,7 +2742,7 @@
}
template<typename T>
-ssize_t AudioFlinger::PlaybackThread::Tracks<T>::remove(const sp<T> &track)
+ssize_t PlaybackThread::Tracks<T>::remove(const sp<T>& track)
{
const int trackId = track->id();
const ssize_t index = mTracks.remove(track);
@@ -2675,17 +2757,17 @@
return index;
}
-uint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
+uint32_t PlaybackThread::correctLatency_l(uint32_t latency) const
{
return latency;
}
-uint32_t AudioFlinger::PlaybackThread::latency() const
+uint32_t PlaybackThread::latency() const
{
Mutex::Autolock _l(mLock);
return latency_l();
}
-uint32_t AudioFlinger::PlaybackThread::latency_l() const
+uint32_t PlaybackThread::latency_l() const
{
uint32_t latency;
if (initCheck() == NO_ERROR && mOutput->stream->getLatency(&latency) == OK) {
@@ -2694,7 +2776,7 @@
return 0;
}
-void AudioFlinger::PlaybackThread::setMasterVolume(float value)
+void PlaybackThread::setMasterVolume(float value)
{
Mutex::Autolock _l(mLock);
// Don't apply master volume in SW if our HAL can do it for us.
@@ -2706,12 +2788,12 @@
}
}
-void AudioFlinger::PlaybackThread::setMasterBalance(float balance)
+void PlaybackThread::setMasterBalance(float balance)
{
mMasterBalance.store(balance);
}
-void AudioFlinger::PlaybackThread::setMasterMute(bool muted)
+void PlaybackThread::setMasterMute(bool muted)
{
if (isDuplicating()) {
return;
@@ -2726,33 +2808,33 @@
}
}
-void AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
+void PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
Mutex::Autolock _l(mLock);
mStreamTypes[stream].volume = value;
broadcast_l();
}
-void AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
+void PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
{
Mutex::Autolock _l(mLock);
mStreamTypes[stream].mute = muted;
broadcast_l();
}
-float AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const
+float PlaybackThread::streamVolume(audio_stream_type_t stream) const
{
Mutex::Autolock _l(mLock);
return mStreamTypes[stream].volume;
}
-void AudioFlinger::PlaybackThread::setVolumeForOutput_l(float left, float right) const
+void PlaybackThread::setVolumeForOutput_l(float left, float right) const
{
mOutput->stream->setVolume(left, right);
}
// addTrack_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
+status_t PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
status_t status = ALREADY_EXISTS;
@@ -2762,12 +2844,12 @@
// buffers before playing. This is to ensure the client will
// effectively get the latency it requested.
if (track->isExternalTrack()) {
- TrackBase::track_state state = track->mState;
+ IAfTrackBase::track_state state = track->state();
mLock.unlock();
status = AudioSystem::startOutput(track->portId());
mLock.lock();
// abort track was stopped/paused while we released the lock
- if (state != track->mState) {
+ if (state != track->state()) {
if (status == NO_ERROR) {
mLock.unlock();
AudioSystem::stopOutput(track->portId());
@@ -2793,15 +2875,15 @@
// set retry count for buffer fill
if (track->isOffloaded()) {
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackStartupRetriesOffload;
+ track->retryCount() = kMaxTrackStartupRetriesOffload;
}
- track->mFillingUpStatus = mStandby ? Track::FS_FILLING : Track::FS_FILLED;
+ track->fillingStatus() = mStandby ? IAfTrack::FS_FILLING : IAfTrack::FS_FILLED;
} else {
- track->mRetryCount = kMaxTrackStartupRetries;
- track->mFillingUpStatus =
- track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING;
+ track->retryCount() = kMaxTrackStartupRetries;
+ track->fillingStatus() =
+ track->sharedBuffer() != 0 ? IAfTrack::FS_FILLED : IAfTrack::FS_FILLING;
}
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
@@ -2811,14 +2893,14 @@
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
mLock.unlock();
- const os::HapticScale intensity = AudioFlinger::onExternalVibrationStart(
+ const os::HapticScale intensity = afutils::onExternalVibrationStart(
track->getExternalVibration());
std::optional<media::AudioVibratorInfo> vibratorInfo;
{
// TODO(b/184194780): Use the vibrator information from the vibrator that will be
// used to play this track.
- Mutex::Autolock _l(mAudioFlinger->mLock);
- vibratorInfo = std::move(mAudioFlinger->getDefaultVibratorInfo_l());
+ Mutex::Autolock _l(mAfThreadCallback->mutex());
+ vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
}
mLock.lock();
track->setHapticIntensity(intensity);
@@ -2841,7 +2923,7 @@
}
}
- track->mResetDone = false;
+ track->setResetDone(false);
track->resetPresentationComplete();
mActiveTracks.add(track);
if (chain != 0) {
@@ -2858,25 +2940,25 @@
return status;
}
-bool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
+bool PlaybackThread::destroyTrack_l(const sp<IAfTrack>& track)
{
track->terminate();
// active tracks are removed by threadLoop()
bool trackActive = (mActiveTracks.indexOf(track) >= 0);
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
if (!trackActive) {
removeTrack_l(track);
} else if (track->isFastTrack() || track->isOffloaded() || track->isDirect()) {
if (track->isPausePending()) {
track->pauseAck();
}
- track->mState = TrackBase::STOPPING_1;
+ track->setState(IAfTrackBase::STOPPING_1);
}
return trackActive;
}
-void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
+void PlaybackThread::removeTrack_l(const sp<IAfTrack>& track)
{
track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
@@ -2890,12 +2972,12 @@
mAudioTrackCallbacks.erase(track);
}
if (track->isFastTrack()) {
- int index = track->mFastIndex;
+ int index = track->fastIndex();
ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
mFastTrackAvailMask |= 1 << index;
// redundant as track is about to be destroyed, for dumpsys only
- track->mFastIndex = -1;
+ track->fastIndex() = -1;
}
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
@@ -2903,7 +2985,7 @@
}
}
-String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
+String8 PlaybackThread::getParameters(const String8& keys)
{
Mutex::Autolock _l(mLock);
String8 out_s8;
@@ -2913,7 +2995,7 @@
return {};
}
-status_t AudioFlinger::DirectOutputThread::selectPresentation(int presentationId, int programId) {
+status_t DirectOutputThread::selectPresentation(int presentationId, int programId) {
Mutex::Autolock _l(mLock);
if (!isStreamInitialized()) {
return NO_INIT;
@@ -2921,7 +3003,7 @@
return mOutput->stream->selectPresentation(presentationId, programId);
}
-void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void PlaybackThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId) {
ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
sp<AudioIoDescriptor> desc;
@@ -2943,30 +3025,30 @@
desc = sp<AudioIoDescriptor>::make(mId);
break;
}
- mAudioFlinger->ioConfigChanged(event, desc, pid);
+ mAfThreadCallback->ioConfigChanged(event, desc, pid);
}
-void AudioFlinger::PlaybackThread::onWriteReady()
+void PlaybackThread::onWriteReady()
{
mCallbackThread->resetWriteBlocked();
}
-void AudioFlinger::PlaybackThread::onDrainReady()
+void PlaybackThread::onDrainReady()
{
mCallbackThread->resetDraining();
}
-void AudioFlinger::PlaybackThread::onError()
+void PlaybackThread::onError()
{
mCallbackThread->setAsyncError();
}
-void AudioFlinger::PlaybackThread::onCodecFormatChanged(
+void PlaybackThread::onCodecFormatChanged(
const std::basic_string<uint8_t>& metadataBs)
{
- wp<AudioFlinger::PlaybackThread> weakPointerThis = this;
+ const auto weakPointerThis = wp<PlaybackThread>::fromExisting(this);
std::thread([this, metadataBs, weakPointerThis]() {
- sp<AudioFlinger::PlaybackThread> playbackThread = weakPointerThis.promote();
+ const sp<PlaybackThread> playbackThread = weakPointerThis.promote();
if (playbackThread == nullptr) {
ALOGW("PlaybackThread was destroyed, skip codec format change event");
return;
@@ -2991,7 +3073,7 @@
}).detach();
}
-void AudioFlinger::PlaybackThread::resetWriteBlocked(uint32_t sequence)
+void PlaybackThread::resetWriteBlocked(uint32_t sequence)
{
Mutex::Autolock _l(mLock);
// reject out of sequence requests
@@ -3001,7 +3083,7 @@
}
}
-void AudioFlinger::PlaybackThread::resetDraining(uint32_t sequence)
+void PlaybackThread::resetDraining(uint32_t sequence)
{
Mutex::Autolock _l(mLock);
// reject out of sequence requests
@@ -3016,7 +3098,7 @@
}
}
-void AudioFlinger::PlaybackThread::readOutputParameters_l()
+void PlaybackThread::readOutputParameters_l()
{
// unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL
const audio_config_base_t audioConfig = mOutput->getAudioProperties();
@@ -3187,14 +3269,14 @@
// create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
Vector<sp<IAfEffectChain>> effectChains = mEffectChains;
for (size_t i = 0; i < effectChains.size(); i ++) {
- mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(),
+ mAfThreadCallback->moveEffectChain_l(effectChains[i]->sessionId(),
this/* srcThread */, this/* dstThread */);
}
audio_output_flags_t flags = mOutput->flags;
mediametrics::LogItem item(mThreadMetrics.getMetricsId()); // TODO: method in ThreadMetrics?
item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
- .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+ .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
.set(AMEDIAMETRICS_PROP_CHANNELCOUNT, (int32_t)mChannelCount)
@@ -3205,7 +3287,7 @@
.set(AMEDIAMETRICS_PROP_PREFIX_HAPTIC AMEDIAMETRICS_PROP_CHANNELCOUNT,
(int32_t)mHapticChannelCount)
.set(AMEDIAMETRICS_PROP_PREFIX_HAL AMEDIAMETRICS_PROP_ENCODING,
- formatToString(mHALFormat).c_str())
+ IAfThreadBase::formatToString(mHALFormat).c_str())
.set(AMEDIAMETRICS_PROP_PREFIX_HAL AMEDIAMETRICS_PROP_FRAMECOUNT,
(int32_t)mFrameCount) // sic - added HAL
;
@@ -3216,14 +3298,14 @@
item.record();
}
-AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::PlaybackThread::updateMetadata_l()
+ThreadBase::MetadataUpdate PlaybackThread::updateMetadata_l()
{
if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
return {}; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
auto backInserter = std::back_inserter(metadata.tracks);
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
track->copyMetadataTo(backInserter);
}
@@ -3233,13 +3315,14 @@
return change;
}
-void AudioFlinger::PlaybackThread::sendMetadataToBackend_l(
+void PlaybackThread::sendMetadataToBackend_l(
const StreamOutHalInterface::SourceMetadata& metadata)
{
mOutput->stream->updateSourceMetadata(metadata);
};
-status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
+status_t PlaybackThread::getRenderPosition(
+ uint32_t* halFrames, uint32_t* dspFrames) const
{
if (halFrames == NULL || dspFrames == NULL) {
return BAD_VALUE;
@@ -3266,7 +3349,7 @@
}
}
-product_strategy_t AudioFlinger::PlaybackThread::getStrategyForSession_l(audio_session_t sessionId)
+product_strategy_t PlaybackThread::getStrategyForSession_l(audio_session_t sessionId) const
{
// session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
// it is moved to correct output by audio policy manager when A2DP is connected or disconnected
@@ -3274,7 +3357,7 @@
return getStrategyForStream(AUDIO_STREAM_MUSIC);
}
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (sessionId == track->sessionId() && !track->isInvalid()) {
return getStrategyForStream(track->streamType());
}
@@ -3283,13 +3366,13 @@
}
-AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const
+AudioStreamOut* PlaybackThread::getOutput() const
{
Mutex::Autolock _l(mLock);
return mOutput;
}
-AudioStreamOut* AudioFlinger::PlaybackThread::clearOutput()
+AudioStreamOut* PlaybackThread::clearOutput()
{
Mutex::Autolock _l(mLock);
AudioStreamOut *output = mOutput;
@@ -3303,7 +3386,7 @@
}
// this method must always be called either with ThreadBase mLock held or inside the thread loop
-sp<StreamHalInterface> AudioFlinger::PlaybackThread::stream() const
+sp<StreamHalInterface> PlaybackThread::stream() const
{
if (mOutput == NULL) {
return NULL;
@@ -3311,12 +3394,12 @@
return mOutput->stream;
}
-uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() const
+uint32_t PlaybackThread::activeSleepTimeUs() const
{
return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000);
}
-status_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<audioflinger::SyncEvent>& event)
+status_t PlaybackThread::setSyncEvent(const sp<SyncEvent>& event)
{
if (!isValidSyncEvent(event)) {
return BAD_VALUE;
@@ -3325,7 +3408,7 @@
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (event->triggerSession() == track->sessionId()) {
(void) track->setSyncEvent(event);
return NO_ERROR;
@@ -3335,14 +3418,13 @@
return NAME_NOT_FOUND;
}
-bool AudioFlinger::PlaybackThread::isValidSyncEvent(
- const sp<audioflinger::SyncEvent>& event) const
+bool PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const
{
return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
}
-void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
- [[maybe_unused]] const Vector< sp<Track> >& tracksToRemove)
+void PlaybackThread::threadLoop_removeTracks(
+ [[maybe_unused]] const Vector<sp<IAfTrack>>& tracksToRemove)
{
// Miscellaneous track cleanup when removed from the active list,
// called without Thread lock but synchronized with threadLoop processing.
@@ -3356,7 +3438,7 @@
#endif
}
-void AudioFlinger::PlaybackThread::checkSilentMode_l()
+void PlaybackThread::checkSilentMode_l()
{
if (!mMasterMute) {
char value[PROPERTY_VALUE_MAX];
@@ -3382,7 +3464,7 @@
}
// shared by MIXER and DIRECT, overridden by DUPLICATING
-ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
+ssize_t PlaybackThread::threadLoop_write()
{
LOG_HIST_TS();
mInWrite = true;
@@ -3396,7 +3478,7 @@
ATRACE_BEGIN("write");
// update the setpoint when AudioFlinger::mScreenState changes
- uint32_t screenState = AudioFlinger::mScreenState;
+ const uint32_t screenState = mAfThreadCallback->getScreenState();
if (screenState != mScreenState) {
mScreenState = screenState;
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
@@ -3454,7 +3536,7 @@
}
// startMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::PlaybackThread::startMelComputation_l(
+void PlaybackThread::startMelComputation_l(
const sp<audio_utils::MelProcessor>& processor)
{
auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
@@ -3464,7 +3546,7 @@
}
// stopMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::PlaybackThread::stopMelComputation_l()
+void PlaybackThread::stopMelComputation_l()
{
auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
if (outputSink != nullptr) {
@@ -3472,7 +3554,7 @@
}
}
-void AudioFlinger::PlaybackThread::threadLoop_drain()
+void PlaybackThread::threadLoop_drain()
{
bool supportsDrain = false;
if (mOutput->stream->supportsDrain(&supportsDrain) == OK && supportsDrain) {
@@ -3488,12 +3570,12 @@
}
}
-void AudioFlinger::PlaybackThread::threadLoop_exit()
+void PlaybackThread::threadLoop_exit()
{
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
track->invalidate();
}
// Clear ActiveTracks to update BatteryNotifier in case active tracks remain.
@@ -3524,13 +3606,13 @@
- idle sleep time
*/
-void AudioFlinger::PlaybackThread::cacheParameters_l()
+void PlaybackThread::cacheParameters_l()
{
mSinkBufferSize = mNormalFrameCount * mFrameSize;
mActiveSleepTimeUs = activeSleepTimeUs();
mIdleSleepTimeUs = idleSleepTimeUs();
- mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs;
+ mStandbyDelayNs = getStandbyTimeInNanos();
// make sure standby delay is not too short when connected to an A2DP sink to avoid
// truncating audio when going to standby.
@@ -3541,14 +3623,14 @@
}
}
-bool AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType)
+bool PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType)
{
ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu",
this, streamType, mTracks.size());
bool trackMatch = false;
size_t size = mTracks.size();
for (size_t i = 0; i < size; i++) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t->streamType() == streamType && t->isExternalTrack()) {
t->invalidate();
trackMatch = true;
@@ -3557,22 +3639,22 @@
return trackMatch;
}
-void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
+void PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
Mutex::Autolock _l(mLock);
invalidateTracks_l(streamType);
}
-void AudioFlinger::PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
+void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
Mutex::Autolock _l(mLock);
invalidateTracks_l(portIds);
}
-bool AudioFlinger::PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) {
+bool PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) {
bool trackMatch = false;
const size_t size = mTracks.size();
for (size_t i = 0; i < size; i++) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) {
t->invalidate();
portIds.erase(t->portId());
@@ -3586,7 +3668,7 @@
}
// getTrackById_l must be called with holding thread lock
-AudioFlinger::PlaybackThread::Track* AudioFlinger::PlaybackThread::getTrackById_l(
+IAfTrack* PlaybackThread::getTrackById_l(
audio_port_handle_t trackPortId) {
for (size_t i = 0; i < mTracks.size(); i++) {
if (mTracks[i]->portId() == trackPortId) {
@@ -3596,7 +3678,7 @@
return nullptr;
}
-status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
+status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
{
audio_session_t session = chain->sessionId();
sp<EffectBufferHalInterface> halInBuffer, halOutBuffer;
@@ -3617,12 +3699,12 @@
}
size_t numSamples = mNormalFrameCount
* (audio_channel_count_from_out_mask(channelMask) + mHapticChannelCount);
- status_t result = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
+ status_t result = mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(
numSamples * sizeof(float),
&halInBuffer);
if (result != OK) return result;
- result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+ result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
isSessionSpatialized ? mEffectBuffer : mPostSpatializerBuffer,
isSessionSpatialized ? mEffectBufferSize : mPostSpatializerBufferSize,
&halOutBuffer);
@@ -3637,10 +3719,10 @@
// - OUTPUT_STAGE session uses the mEffectBuffer as input buffer and
// mPostSpatializerBuffer as output buffer
// - DEVICE session uses the mPostSpatializerBuffer as input and output buffer.
- status_t result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+ status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
mEffectBuffer, mEffectBufferSize, &halInBuffer);
if (result != OK) return result;
- result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+ result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
mPostSpatializerBuffer, mPostSpatializerBufferSize, &halOutBuffer);
if (result != OK) return result;
@@ -3649,7 +3731,7 @@
}
}
} else {
- status_t result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer(
+ status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer,
mEffectBufferEnabled ? mEffectBufferSize : mSinkBufferSize,
&halInBuffer);
@@ -3665,7 +3747,8 @@
size_t numSamples = mNormalFrameCount
* (audio_channel_count_from_out_mask(mMixerChannelMask)
+ mHapticChannelCount);
- const status_t allocateStatus = mAudioFlinger->mEffectsFactoryHal->allocateBuffer(
+ const status_t allocateStatus =
+ mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(
numSamples * sizeof(float),
&halInBuffer);
if (allocateStatus != OK) return allocateStatus;
@@ -3680,7 +3763,7 @@
if (!audio_is_global_session(session)) {
// Attach all tracks with same session ID to this chain.
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (session == track->sessionId()) {
ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p",
track.get(), buffer);
@@ -3690,7 +3773,7 @@
}
// indicate all active tracks in the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
ALOGV("addEffectChain_l() activating track %p on session %d",
track.get(), session);
@@ -3732,7 +3815,7 @@
return NO_ERROR;
}
-size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
+size_t PlaybackThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
{
audio_session_t session = chain->sessionId();
@@ -3742,7 +3825,7 @@
if (chain == mEffectChains[i]) {
mEffectChains.removeAt(i);
// detach all active tracks from the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
chain.get(), session);
@@ -3752,7 +3835,7 @@
// detach all tracks with same session ID from this chain
for (size_t j = 0; j < mTracks.size(); ++j) {
- sp<Track> track = mTracks[j];
+ sp<IAfTrack> track = mTracks[j];
if (session == track->sessionId()) {
track->setMainBuffer(reinterpret_cast<float*>(mSinkBuffer));
chain->decTrackCnt();
@@ -3764,15 +3847,15 @@
return mEffectChains.size();
}
-status_t AudioFlinger::PlaybackThread::attachAuxEffect(
- const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId)
+status_t PlaybackThread::attachAuxEffect(
+ const sp<IAfTrack>& track, int EffectId)
{
Mutex::Autolock _l(mLock);
return attachAuxEffect_l(track, EffectId);
}
-status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(
- const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId)
+status_t PlaybackThread::attachAuxEffect_l(
+ const sp<IAfTrack>& track, int EffectId)
{
status_t status = NO_ERROR;
@@ -3794,22 +3877,22 @@
return status;
}
-void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
+void PlaybackThread::detachAuxEffect_l(int effectId)
{
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (track->auxEffectId() == effectId) {
attachAuxEffect_l(track, 0);
}
}
}
-bool AudioFlinger::PlaybackThread::threadLoop()
+bool PlaybackThread::threadLoop()
NO_THREAD_SAFETY_ANALYSIS // manual locking of AudioFlinger
{
aflog::setThreadWriter(mNBLogWriter.get());
- Vector< sp<Track> > tracksToRemove;
+ Vector<sp<IAfTrack>> tracksToRemove;
mStandbyTimeNs = systemTime();
int64_t lastLoopCountWritten = -2; // never matches "previous" loop, when loopCount = 0.
@@ -3857,14 +3940,14 @@
{
// Log merge requests are performed during AudioFlinger binder transactions, but
// that does not cover audio playback. It's requested here for that reason.
- mAudioFlinger->requestLogMerge();
+ mAfThreadCallback->requestLogMerge();
cpuStats.sample(myName);
Vector<sp<IAfEffectChain>> effectChains;
audio_session_t activeHapticSessionId = AUDIO_SESSION_NONE;
bool isHapticSessionSpatialized = false;
- std::vector<sp<Track>> activeTracks;
+ std::vector<sp<IAfTrack>> activeTracks;
// If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
//
@@ -3872,12 +3955,13 @@
if (isMsdDevice() && outDeviceTypes().count(AUDIO_DEVICE_OUT_BUS) != 0) {
// Here, we try for the AF lock, but do not block on it as the latency
// is more informational.
- if (mAudioFlinger->mLock.tryLock() == NO_ERROR) {
- std::vector<PatchPanel::SoftwarePatch> swPatches;
+ if (mAfThreadCallback->mutex().tryLock() == NO_ERROR) {
+ std::vector<SoftwarePatch> swPatches;
double latencyMs = 0.; // not required; initialized for clang-tidy
status_t status = INVALID_OPERATION;
audio_patch_handle_t downstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- if (mAudioFlinger->mPatchPanel.getDownstreamSoftwarePatches(id(), &swPatches) == OK
+ if (mAfThreadCallback->getPatchPanel()->getDownstreamSoftwarePatches(
+ id(), &swPatches) == OK
&& swPatches.size() > 0) {
status = swPatches[0].getLatencyMs_l(&latencyMs);
downstreamPatchHandle = swPatches[0].getPatchHandle();
@@ -3898,7 +3982,7 @@
}
mDownstreamLatencyStatMs.add(latencyMs);
}
- mAudioFlinger->mLock.unlock();
+ mAfThreadCallback->mutex().unlock();
}
} else {
if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
@@ -4082,14 +4166,15 @@
// Tally underrun frames as we are inserting 0s here.
for (const auto& track : activeTracks) {
- if (track->mFillingUpStatus == Track::FS_ACTIVE
+ if (track->fillingStatus() == IAfTrack::FS_ACTIVE
&& !track->isStopped()
&& !track->isPaused()
&& !track->isTerminated()) {
ALOGV("%s: track(%d) %s underrun due to thread sleep of %zu frames",
__func__, track->id(), track->getTrackStateAsString(),
mNormalFrameCount);
- track->mAudioTrackServerProxy->tallyUnderrunFrames(mNormalFrameCount);
+ track->audioTrackServerProxy()->tallyUnderrunFrames(
+ mNormalFrameCount);
}
}
}
@@ -4258,7 +4343,7 @@
unlockEffectChains(effectChains);
if (!metadataUpdate.playbackMetadataUpdate.empty()) {
- mAudioFlinger->mMelReporter->updateMetadataForCsd(id(),
+ mAfThreadCallback->getMelReporter()->updateMetadataForCsd(id(),
metadataUpdate.playbackMetadataUpdate);
}
@@ -4459,7 +4544,7 @@
return false;
}
-void AudioFlinger::PlaybackThread::collectTimestamps_l()
+void PlaybackThread::collectTimestamps_l()
{
if (mStandby) {
mTimestampVerifier.discontinuity(discontinuityForStandbyOrFlush());
@@ -4564,10 +4649,10 @@
? systemTime() : mLastIoBeginNs;
}
- for (const sp<Track> &t : mActiveTracks) {
+ for (const sp<IAfTrack>& t : mActiveTracks) {
if (!t->isFastTrack()) {
t->updateTrackFrameInfo(
- t->mAudioTrackServerProxy->framesReleased(),
+ t->audioTrackServerProxy()->framesReleased(),
mFramesWritten,
mSampleRate,
mTimestamp);
@@ -4595,7 +4680,7 @@
}
// removeTracks_l() must be called with ThreadBase::mLock held
-void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove)
+void PlaybackThread::removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove)
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
for (const auto& track : tracksToRemove) {
@@ -4625,7 +4710,7 @@
mLock.unlock();
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
- AudioFlinger::onExternalVibrationStop(track->getExternalVibration());
+ afutils::onExternalVibrationStop(track->getExternalVibration());
mLock.lock();
// When the track is stop, set the haptic intensity as MUTE
@@ -4637,7 +4722,7 @@
}
}
-status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
+status_t PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
{
if (mNormalSink != 0) {
ExtendedTimestamp ets;
@@ -4666,7 +4751,7 @@
// All tracks attached to a mixer with flag VOIP_RX are tied to the same
// stream type STREAM_VOICE_CALL so this will only change the HAL volume once even
// if more than one track are active
-status_t AudioFlinger::PlaybackThread::handleVoipVolume_l(float *volume)
+status_t PlaybackThread::handleVoipVolume_l(float* volume)
{
status_t result = NO_ERROR;
if ((mOutput->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
@@ -4688,7 +4773,7 @@
return result;
}
-status_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch *patch,
+status_t MixerThread::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle)
{
status_t status;
@@ -4705,7 +4790,7 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_patch *patch,
+status_t PlaybackThread::createAudioPatch_l(const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
status_t status = NO_ERROR;
@@ -4789,7 +4874,7 @@
return status;
}
-status_t AudioFlinger::MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
+status_t MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
status_t status;
if (property_get_bool("af.patch_park", false /* default_value */)) {
@@ -4803,7 +4888,7 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
+status_t PlaybackThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
status_t status = NO_ERROR;
@@ -4822,19 +4907,19 @@
return status;
}
-void AudioFlinger::PlaybackThread::addPatchTrack(const sp<PatchTrack>& track)
+void PlaybackThread::addPatchTrack(const sp<IAfPatchTrack>& track)
{
Mutex::Autolock _l(mLock);
mTracks.add(track);
}
-void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track)
+void PlaybackThread::deletePatchTrack(const sp<IAfPatchTrack>& track)
{
Mutex::Autolock _l(mLock);
destroyTrack_l(track);
}
-void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config)
+void PlaybackThread::toAudioPortConfig(struct audio_port_config* config)
{
ThreadBase::toAudioPortConfig(config);
config->role = AUDIO_PORT_ROLE_SOURCE;
@@ -4848,9 +4933,16 @@
// ----------------------------------------------------------------------------
-AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+/* static */
+sp<IAfPlaybackThread> IAfPlaybackThread::createMixerThread(
+ const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
+ audio_io_handle_t id, bool systemReady, type_t type, audio_config_base_t* mixerConfig) {
+ return sp<MixerThread>::make(afThreadCallback, output, id, systemReady, type, mixerConfig);
+}
+
+MixerThread::MixerThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
audio_io_handle_t id, bool systemReady, type_t type, audio_config_base_t *mixerConfig)
- : PlaybackThread(audioFlinger, output, id, type, systemReady, mixerConfig),
+ : PlaybackThread(afThreadCallback, output, id, type, systemReady, mixerConfig),
// mAudioMixer below
// mFastMixer below
mBluetoothLatencyModesEnabled(false),
@@ -4860,7 +4952,7 @@
// mPipeSink below
// mNormalSink below
{
- setMasterBalance(audioFlinger->getMasterBalance_l());
+ setMasterBalance(afThreadCallback->getMasterBalance_l());
ALOGV("MixerThread() id=%d type=%d", id, type);
ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, "
"mFrameCount=%zu, mNormalFrameCount=%zu",
@@ -4987,7 +5079,7 @@
state->mColdFutexAddr = &mFastMixerFutex;
state->mColdGen++;
state->mDumpState = &mFastMixerDumpState;
- mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer");
+ mFastMixerNBLogWriter = afThreadCallback->newWriter_l(kFastMixerLogSize, "FastMixer");
state->mNBLogWriter = mFastMixerNBLogWriter.get();
sq->end();
sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
@@ -5033,7 +5125,7 @@
}
}
-AudioFlinger::MixerThread::~MixerThread()
+MixerThread::~MixerThread()
{
if (mFastMixer != 0) {
FastMixerStateQueue *sq = mFastMixer->sq();
@@ -5066,11 +5158,11 @@
}
#endif
}
- mAudioFlinger->unregisterWriter(mFastMixerNBLogWriter);
+ mAfThreadCallback->unregisterWriter(mFastMixerNBLogWriter);
delete mAudioMixer;
}
-void AudioFlinger::MixerThread::onFirstRef() {
+void MixerThread::onFirstRef() {
PlaybackThread::onFirstRef();
Mutex::Autolock _l(mLock);
@@ -5086,7 +5178,7 @@
}
}
-uint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const
+uint32_t MixerThread::correctLatency_l(uint32_t latency) const
{
if (mFastMixer != 0) {
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
@@ -5095,7 +5187,7 @@
return latency;
}
-ssize_t AudioFlinger::MixerThread::threadLoop_write()
+ssize_t MixerThread::threadLoop_write()
{
// FIXME we should only do one push per cycle; confirm this is true
// Start the fast mixer if it's not already running
@@ -5123,7 +5215,7 @@
}
state->mCommand = FastMixerState::MIX_WRITE;
#ifdef FAST_THREAD_STATISTICS
- mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
+ mFastMixerDumpState.increaseSamplingN(mAfThreadCallback->isLowRamDevice() ?
FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
#endif
sq->end();
@@ -5138,7 +5230,7 @@
return PlaybackThread::threadLoop_write();
}
-void AudioFlinger::MixerThread::threadLoop_standby()
+void MixerThread::threadLoop_standby()
{
// Idle the fast mixer if it's currently running
if (mFastMixer != 0) {
@@ -5176,24 +5268,24 @@
PlaybackThread::threadLoop_standby();
}
-bool AudioFlinger::PlaybackThread::waitingAsyncCallback_l()
+bool PlaybackThread::waitingAsyncCallback_l()
{
return false;
}
-bool AudioFlinger::PlaybackThread::shouldStandby_l()
+bool PlaybackThread::shouldStandby_l()
{
return !mStandby;
}
-bool AudioFlinger::PlaybackThread::waitingAsyncCallback()
+bool PlaybackThread::waitingAsyncCallback()
{
Mutex::Autolock _l(mLock);
return waitingAsyncCallback_l();
}
// shared by MIXER and DIRECT, overridden by DUPLICATING
-void AudioFlinger::PlaybackThread::threadLoop_standby()
+void PlaybackThread::threadLoop_standby()
{
ALOGV("Audio hardware entering standby, mixer %p, suspend count %d", this, mSuspended);
mOutput->standby();
@@ -5209,20 +5301,20 @@
setHalLatencyMode_l();
}
-void AudioFlinger::PlaybackThread::onAddNewTrack_l()
+void PlaybackThread::onAddNewTrack_l()
{
ALOGV("signal playback thread");
broadcast_l();
}
-void AudioFlinger::PlaybackThread::onAsyncError()
+void PlaybackThread::onAsyncError()
{
for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
invalidateTracks((audio_stream_type_t)i);
}
}
-void AudioFlinger::MixerThread::threadLoop_mix()
+void MixerThread::threadLoop_mix()
{
// mix buffers...
mAudioMixer->process();
@@ -5240,7 +5332,7 @@
}
-void AudioFlinger::MixerThread::threadLoop_sleepTime()
+void MixerThread::threadLoop_sleepTime()
{
// If no tracks are ready, sleep once for the duration of an output
// buffer size, then write 0s to the output
@@ -5294,8 +5386,8 @@
}
// prepareTracks_l() must be called with ThreadBase::mLock held
-AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove)
+PlaybackThread::mixer_state MixerThread::prepareTracks_l(
+ Vector<sp<IAfTrack>>* tracksToRemove)
{
// clean up deleted track ids in AudioMixer before allocating new tracks
(void)mTracks.processDeletedTrackIds([this](int trackId) {
@@ -5371,23 +5463,23 @@
// tallyUnderrunFrames() is called to update the track counters
// with the number of underrun frames for a particular mixer period.
// We defer tallying until we know the final mixer status.
- void tallyUnderrunFrames(const sp<Track>& track, size_t underrunFrames) {
+ void tallyUnderrunFrames(const sp<IAfTrack>& track, size_t underrunFrames) {
mUnderrunFrames.emplace_back(track, underrunFrames);
}
private:
const mixer_state * const mMixerStatus;
ThreadMetrics * const mThreadMetrics;
- std::vector<std::pair<sp<Track>, size_t>> mUnderrunFrames;
+ std::vector<std::pair<sp<IAfTrack>, size_t>> mUnderrunFrames;
} deferredOperations(&mixerStatus, &mThreadMetrics);
// implicit nested scope for variable capture
bool noFastHapticTrack = true;
for (size_t i=0 ; i<count ; i++) {
- const sp<Track> t = mActiveTracks[i];
+ const sp<IAfTrack> t = mActiveTracks[i];
// this const just means the local variable doesn't change
- Track* const track = t.get();
+ IAfTrack* const track = t.get();
// process fast tracks
if (track->isFastTrack()) {
@@ -5405,7 +5497,7 @@
// The converse, of removing an (active) track and then creating a new track
// at the identical fast mixer slot within the same normal mix cycle,
// is impossible because the slot isn't marked available until the end of each cycle.
- int j = track->mFastIndex;
+ int j = track->fastIndex();
ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks);
ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
FastTrack *fastTrack = &state->mFastTracks[j];
@@ -5415,13 +5507,13 @@
FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j];
FastTrackUnderruns underruns = ftDump->mUnderruns;
uint32_t recentFull = (underruns.mBitFields.mFull -
- track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mFull) & UNDERRUN_MASK;
uint32_t recentPartial = (underruns.mBitFields.mPartial -
- track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mPartial) & UNDERRUN_MASK;
uint32_t recentEmpty = (underruns.mBitFields.mEmpty -
- track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mEmpty) & UNDERRUN_MASK;
uint32_t recentUnderruns = recentPartial + recentEmpty;
- track->mObservedUnderruns = underruns;
+ track->fastTrackUnderruns() = underruns;
// don't count underruns that occur while stopping or pausing
// or stopped which can occur when flush() is called while active
size_t underrunFrames = 0;
@@ -5431,30 +5523,30 @@
underrunFrames = recentUnderruns * mFrameCount;
}
// Immediately account for FastTrack underruns.
- track->mAudioTrackServerProxy->tallyUnderrunFrames(underrunFrames);
+ track->audioTrackServerProxy()->tallyUnderrunFrames(underrunFrames);
// This is similar to the state machine for normal tracks,
// with a few modifications for fast tracks.
bool isActive = true;
- switch (track->mState) {
- case TrackBase::STOPPING_1:
+ switch (track->state()) {
+ case IAfTrackBase::STOPPING_1:
// track stays active in STOPPING_1 state until first underrun
if (recentUnderruns > 0 || track->isTerminated()) {
- track->mState = TrackBase::STOPPING_2;
+ track->setState(IAfTrackBase::STOPPING_2);
}
break;
- case TrackBase::PAUSING:
+ case IAfTrackBase::PAUSING:
// ramp down is not yet implemented
track->setPaused();
break;
- case TrackBase::RESUMING:
+ case IAfTrackBase::RESUMING:
// ramp up is not yet implemented
- track->mState = TrackBase::ACTIVE;
+ track->setState(IAfTrackBase::ACTIVE);
break;
- case TrackBase::ACTIVE:
+ case IAfTrackBase::ACTIVE:
if (recentFull > 0 || recentPartial > 0) {
// track has provided at least some frames recently: reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->retryCount() = kMaxTrackRetries;
}
if (recentUnderruns == 0) {
// no recent underruns: stay active
@@ -5468,7 +5560,7 @@
break;
}
// there has recently been an "empty" underrun: decrement the retry counter
- if (--(track->mRetryCount) > 0) {
+ if (--(track->retryCount()) > 0) {
break;
}
// indicate to client process that the track was disabled because of underrun;
@@ -5479,10 +5571,10 @@
break;
}
FALLTHROUGH_INTENDED;
- case TrackBase::STOPPING_2:
- case TrackBase::PAUSED:
- case TrackBase::STOPPED:
- case TrackBase::FLUSHED: // flush() while active
+ case IAfTrackBase::STOPPING_2:
+ case IAfTrackBase::PAUSED:
+ case IAfTrackBase::STOPPED:
+ case IAfTrackBase::FLUSHED: // flush() while active
// Check for presentation complete if track is inactive
// We have consumed all the buffers of this track.
// This would be incomplete if we auto-paused on underrun
@@ -5499,7 +5591,7 @@
}
}
if (track->isStopping_2()) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
}
if (track->isStopped()) {
// Can't reset directly, as fast mixer is still polling this track
@@ -5509,20 +5601,20 @@
}
isActive = false;
break;
- case TrackBase::IDLE:
+ case IAfTrackBase::IDLE:
default:
- LOG_ALWAYS_FATAL("unexpected track state %d", (int)track->mState);
+ LOG_ALWAYS_FATAL("unexpected track state %d", (int)track->state());
}
if (isActive) {
// was it previously inactive?
if (!(state->mTrackMask & (1 << j))) {
- ExtendedAudioBufferProvider *eabp = track;
- VolumeProvider *vp = track;
+ ExtendedAudioBufferProvider *eabp = track->asExtendedAudioBufferProvider();
+ VolumeProvider *vp = track->asVolumeProvider();
fastTrack->mBufferProvider = eabp;
fastTrack->mVolumeProvider = vp;
- fastTrack->mChannelMask = track->mChannelMask;
- fastTrack->mFormat = track->mFormat;
+ fastTrack->mChannelMask = track->channelMask();
+ fastTrack->mFormat = track->format();
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
fastTrack->mHapticIntensity = track->getHapticIntensity();
fastTrack->mHapticMaxAmplitude = track->getHapticMaxAmplitude();
@@ -5531,7 +5623,7 @@
didModify = true;
// no acknowledgement required for newly active tracks
}
- sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
float volume;
if (track->isPlaybackRestricted() || mStreamTypes[track->streamType()].mute) {
volume = 0.f;
@@ -5546,12 +5638,12 @@
const float vh = track->getVolumeHandler()->getVolume(
proxy->framesReleased()).first;
volume *= vh;
- track->mCachedVolume = volume;
+ track->setCachedVolume(volume);
gain_minifloat_packed_t vlr = proxy->getVolumeLR();
float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
- track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
/*muteState=*/{masterVolume == 0.f,
mStreamTypes[track->streamType()].volume == 0.f,
mStreamTypes[track->streamType()].mute,
@@ -5582,13 +5674,13 @@
// TODO Remove the ALOGW when this theory is confirmed.
ALOGW("fast track %d should have been active; "
"mState=%d, mTrackMask=%#x, recentUnderruns=%u, isShared=%d",
- j, (int)track->mState, state->mTrackMask, recentUnderruns,
+ j, (int)track->state(), state->mTrackMask, recentUnderruns,
track->sharedBuffer() != 0);
// Since the FastMixer state already has the track inactive, do nothing here.
}
tracksToRemove->add(track);
// Avoids a misleading display in dumpsys
- track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL;
+ track->fastTrackUnderruns().mBitFields.mMostRecent = UNDERRUN_FULL;
}
if (fastTrack->mHapticPlaybackEnabled != track->getHapticPlaybackEnabled()) {
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
@@ -5610,14 +5702,14 @@
if (!mAudioMixer->exists(trackId)) {
status_t status = mAudioMixer->create(
trackId,
- track->mChannelMask,
- track->mFormat,
- track->mSessionId);
+ track->channelMask(),
+ track->format(),
+ track->sessionId());
if (status != OK) {
ALOGW("%s(): AudioMixer cannot create track(%d)"
" mask %#x, format %#x, sessionId %d",
__func__, trackId,
- track->mChannelMask, track->mFormat, track->mSessionId);
+ track->channelMask(), track->format(), track->sessionId());
tracksToRemove->add(track);
track->invalidate(); // consider it dead.
continue;
@@ -5630,8 +5722,8 @@
// hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
// during last round
size_t desiredFrames;
- const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate();
- const AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate();
+ const uint32_t sampleRate = track->audioTrackServerProxy()->getSampleRate();
+ const AudioPlaybackRate playbackRate = track->audioTrackServerProxy()->getPlaybackRate();
desiredFrames = sourceFramesNeededWithTimestretch(
sampleRate, mNormalFrameCount, mSampleRate, playbackRate.mSpeed);
@@ -5681,11 +5773,11 @@
int param = AudioMixer::VOLUME;
- if (track->mFillingUpStatus == Track::FS_FILLED) {
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
// no ramp for the first volume setting
- track->mFillingUpStatus = Track::FS_ACTIVE;
- if (track->mState == TrackBase::RESUMING) {
- track->mState = TrackBase::ACTIVE;
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
+ if (track->state() == IAfTrackBase::RESUMING) {
+ track->setState(IAfTrackBase::ACTIVE);
// If a new track is paused immediately after start, do not ramp on resume.
if (cblk->mServer != 0) {
param = AudioMixer::RAMP_VOLUME;
@@ -5706,9 +5798,9 @@
// read original volumes with volume control
float v = masterVolume * mStreamTypes[track->streamType()].volume;
// Always fetch volumeshaper volume to ensure state is updated.
- const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ const sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
const float vh = track->getVolumeHandler()->getVolume(
- track->mAudioTrackServerProxy->framesReleased()).first;
+ track->audioTrackServerProxy()->framesReleased()).first;
if (mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
v = 0;
@@ -5734,7 +5826,7 @@
vrf = GAIN_FLOAT_UNITY;
}
- track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
/*muteState=*/{masterVolume == 0.f,
mStreamTypes[track->streamType()].volume == 0.f,
mStreamTypes[track->streamType()].mute,
@@ -5770,18 +5862,18 @@
// Update remaining floating point volume levels
vlf = (float)vl / (1 << 24);
vrf = (float)vr / (1 << 24);
- track->mHasVolumeController = true;
+ track->setHasVolumeController(true);
} else {
// force no volume ramp when volume controller was just disabled or removed
// from effect chain to avoid volume spike
- if (track->mHasVolumeController) {
+ if (track->hasVolumeController()) {
param = AudioMixer::VOLUME;
}
- track->mHasVolumeController = false;
+ track->setHasVolumeController(false);
}
// XXX: these things DON'T need to be done each time
- mAudioMixer->setBufferProvider(trackId, track);
+ mAudioMixer->setBufferProvider(trackId, track->asExtendedAudioBufferProvider());
mAudioMixer->enable(trackId);
mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME0, &vlf);
@@ -5889,13 +5981,14 @@
trackId,
AudioMixer::TRACK,
AudioMixer::HAPTIC_INTENSITY, (void *)(uintptr_t)track->getHapticIntensity());
+ const float hapticMaxAmplitude = track->getHapticMaxAmplitude();
mAudioMixer->setParameter(
trackId,
AudioMixer::TRACK,
- AudioMixer::HAPTIC_MAX_AMPLITUDE, (void *)(&(track->mHapticMaxAmplitude)));
+ AudioMixer::HAPTIC_MAX_AMPLITUDE, (void *)&hapticMaxAmplitude);
// reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->retryCount() = kMaxTrackRetries;
// If one track is ready, set the mixer ready if:
// - the mixer was not ready during previous round OR
@@ -5947,7 +6040,7 @@
} else {
// No buffers for this track. Give it a few chances to
// fill a buffer, then remove it from active list.
- if (--(track->mRetryCount) <= 0) {
+ if (--(track->retryCount()) <= 0) {
ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p",
trackId, this);
tracksToRemove->add(track);
@@ -6023,7 +6116,7 @@
size_t i = __builtin_ctz(resetMask);
ALOG_ASSERT(i < count);
resetMask &= ~(1 << i);
- sp<Track> track = mActiveTracks[i];
+ sp<IAfTrack> track = mActiveTracks[i];
ALOG_ASSERT(track->isFastTrack() && track->isStopped());
track->reset();
}
@@ -6089,7 +6182,7 @@
}
// trackCountForUid_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const
+uint32_t PlaybackThread::trackCountForUid_l(uid_t uid) const
{
uint32_t trackCount = 0;
for (size_t i = 0; i < mTracks.size() ; i++) {
@@ -6100,7 +6193,7 @@
return trackCount;
}
-bool AudioFlinger::PlaybackThread::IsTimestampAdvancing::check(AudioStreamOut * output)
+bool PlaybackThread::IsTimestampAdvancing::check(AudioStreamOut* output)
{
// Check the timestamp to see if it's advancing once every 150ms. If we check too frequently, we
// could falsely detect that the frame position has stalled due to underrun because we haven't
@@ -6124,7 +6217,7 @@
return mLatchedValue;
}
-void AudioFlinger::PlaybackThread::IsTimestampAdvancing::clear()
+void PlaybackThread::IsTimestampAdvancing::clear()
{
mLatchedValue = true;
mPreviousPosition = 0;
@@ -6132,7 +6225,7 @@
}
// isTrackAllowed_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::MixerThread::isTrackAllowed_l(
+bool MixerThread::isTrackAllowed_l(
audio_channel_mask_t channelMask, audio_format_t format,
audio_session_t sessionId, uid_t uid) const
{
@@ -6152,7 +6245,7 @@
}
// checkForNewParameter_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePair,
+bool MixerThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
bool reconfig = false;
@@ -6166,7 +6259,7 @@
reconfig = true;
}
if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
- if (!isValidPcmSinkFormat((audio_format_t) value)) {
+ if (!isValidPcmSinkFormat(static_cast<audio_format_t>(value))) {
status = BAD_VALUE;
} else {
// no need to save value, since it's constant
@@ -6174,7 +6267,7 @@
}
}
if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
- if (!isValidPcmSinkChannelMask((audio_channel_mask_t) value)) {
+ if (!isValidPcmSinkChannelMask(static_cast<audio_channel_mask_t>(value))) {
status = BAD_VALUE;
} else {
// no need to save value, since it's constant
@@ -6215,14 +6308,14 @@
const int trackId = track->id();
const status_t createStatus = mAudioMixer->create(
trackId,
- track->mChannelMask,
- track->mFormat,
- track->mSessionId);
+ track->channelMask(),
+ track->format(),
+ track->sessionId());
ALOGW_IF(createStatus != NO_ERROR,
"%s(): AudioMixer cannot create track(%d)"
" mask %#x, format %#x, sessionId %d",
__func__,
- trackId, track->mChannelMask, track->mFormat, track->mSessionId);
+ trackId, track->channelMask(), track->format(), track->sessionId());
}
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
}
@@ -6232,7 +6325,7 @@
}
-void AudioFlinger::MixerThread::dumpInternals_l(int fd, const Vector<String16>& args)
+void MixerThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
PlaybackThread::dumpInternals_l(fd, args);
dprintf(fd, " Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs);
@@ -6279,17 +6372,17 @@
dprintf(fd, "Supported latency modes: %s\n", toString(mSupportedLatencyModes).c_str());
}
-uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
+uint32_t MixerThread::idleSleepTimeUs() const
{
return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2;
}
-uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() const
+uint32_t MixerThread::suspendSleepTimeUs() const
{
return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000);
}
-void AudioFlinger::MixerThread::cacheParameters_l()
+void MixerThread::cacheParameters_l()
{
PlaybackThread::cacheParameters_l();
@@ -6300,11 +6393,11 @@
maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15;
}
-void AudioFlinger::MixerThread::onHalLatencyModesChanged_l() {
- mAudioFlinger->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
+void MixerThread::onHalLatencyModesChanged_l() {
+ mAfThreadCallback->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
}
-void AudioFlinger::MixerThread::setHalLatencyMode_l() {
+void MixerThread::setHalLatencyMode_l() {
// Only handle latency mode if:
// - mBluetoothLatencyModesEnabled is true
// - the HAL supports latency modes
@@ -6346,7 +6439,7 @@
}
}
-void AudioFlinger::MixerThread::updateHalSupportedLatencyModes_l() {
+void MixerThread::updateHalSupportedLatencyModes_l() {
if (mOutput == nullptr || mOutput->stream == nullptr) {
return;
@@ -6364,7 +6457,7 @@
}
}
-status_t AudioFlinger::MixerThread::getSupportedLatencyModes(
+status_t MixerThread::getSupportedLatencyModes(
std::vector<audio_latency_mode_t>* modes) {
if (modes == nullptr) {
return BAD_VALUE;
@@ -6374,7 +6467,7 @@
return NO_ERROR;
}
-void AudioFlinger::MixerThread::onRecommendedLatencyModeChanged(
+void MixerThread::onRecommendedLatencyModeChanged(
std::vector<audio_latency_mode_t> modes) {
Mutex::Autolock _l(mLock);
if (modes != mSupportedLatencyModes) {
@@ -6385,7 +6478,7 @@
}
}
-status_t AudioFlinger::MixerThread::setBluetoothVariableLatencyEnabled(bool enabled) {
+status_t MixerThread::setBluetoothVariableLatencyEnabled(bool enabled) {
if (mOutput == nullptr || mOutput->audioHwDev == nullptr
|| !mOutput->audioHwDev->supportsBluetoothVariableLatency()) {
return INVALID_OPERATION;
@@ -6396,27 +6489,36 @@
// ----------------------------------------------------------------------------
-AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
+/* static */
+sp<IAfPlaybackThread> IAfPlaybackThread::createDirectOutputThread(
+ const sp<IAfThreadCallback>& afThreadCallback,
+ AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
+ const audio_offload_info_t& offloadInfo) {
+ return sp<DirectOutputThread>::make(
+ afThreadCallback, output, id, systemReady, offloadInfo);
+}
+
+DirectOutputThread::DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output, audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
const audio_offload_info_t& offloadInfo)
- : PlaybackThread(audioFlinger, output, id, type, systemReady)
+ : PlaybackThread(afThreadCallback, output, id, type, systemReady)
, mOffloadInfo(offloadInfo)
{
- setMasterBalance(audioFlinger->getMasterBalance_l());
+ setMasterBalance(afThreadCallback->getMasterBalance_l());
}
-AudioFlinger::DirectOutputThread::~DirectOutputThread()
+DirectOutputThread::~DirectOutputThread()
{
}
-void AudioFlinger::DirectOutputThread::dumpInternals_l(int fd, const Vector<String16>& args)
+void DirectOutputThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
PlaybackThread::dumpInternals_l(fd, args);
dprintf(fd, " Master balance: %f Left: %f Right: %f\n",
mMasterBalance.load(), mMasterBalanceLeft, mMasterBalanceRight);
}
-void AudioFlinger::DirectOutputThread::setMasterBalance(float balance)
+void DirectOutputThread::setMasterBalance(float balance)
{
Mutex::Autolock _l(mLock);
if (mMasterBalance != balance) {
@@ -6426,12 +6528,12 @@
}
}
-void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack)
+void DirectOutputThread::processVolume_l(IAfTrack* track, bool lastTrack)
{
float left, right;
// Ensure volumeshaper state always advances even when muted.
- const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ const sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
const size_t framesReleased = proxy->framesReleased();
const int64_t frames = mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
@@ -6466,14 +6568,14 @@
}
left *= v;
right *= v;
- if (mAudioFlinger->getMode() != AUDIO_MODE_IN_COMMUNICATION
+ if (mAfThreadCallback->getMode() != AUDIO_MODE_IN_COMMUNICATION
|| audio_channel_count_from_out_mask(mChannelMask) > 1) {
left *= mMasterBalanceLeft; // DirectOutputThread balance applied as track volume
right *= mMasterBalanceRight;
}
}
- track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
/*muteState=*/{mMasterMute,
mStreamTypes[track->streamType()].volume == 0.f,
mStreamTypes[track->streamType()].mute,
@@ -6505,10 +6607,10 @@
}
}
-void AudioFlinger::DirectOutputThread::onAddNewTrack_l()
+void DirectOutputThread::onAddNewTrack_l()
{
- sp<Track> previousTrack = mPreviousTrack.promote();
- sp<Track> latestTrack = mActiveTracks.getLatest();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> latestTrack = mActiveTracks.getLatest();
if (previousTrack != 0 && latestTrack != 0) {
if (mType == DIRECT) {
@@ -6530,8 +6632,8 @@
PlaybackThread::onAddNewTrack_l();
}
-AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove
+PlaybackThread::mixer_state DirectOutputThread::prepareTracks_l(
+ Vector<sp<IAfTrack>>* tracksToRemove
)
{
size_t count = mActiveTracks.size();
@@ -6540,14 +6642,14 @@
bool doHwResume = false;
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
+ for (const sp<IAfTrack>& t : mActiveTracks) {
if (t->isInvalid()) {
ALOGW("An invalidated track shouldn't be in active list");
tracksToRemove->add(t);
continue;
}
- Track* const track = t.get();
+ IAfTrack* const track = t.get();
#ifdef VERY_VERY_VERBOSE_LOGGING
audio_track_cblk_t* cblk = track->cblk();
#endif
@@ -6555,7 +6657,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<IAfTrack> l = mActiveTracks.getLatest();
bool last = l.get() == track;
if (track->isPausePending()) {
@@ -6591,8 +6693,8 @@
// for all its buffers to be filled before processing it.
// Allow draining the buffer in case the client
// app does not call stop() and relies on underrun to stop:
- // hence the test on (track->mRetryCount > 1).
- // If track->mRetryCount <= 1 then track is about to be disabled, paused, removed,
+ // hence the test on (track->retryCount() > 1).
+ // If track->retryCount() <= 1 then track is about to be disabled, paused, removed,
// so we accept any nonzero amount of data delivered by the AudioTrack (which will
// reset the retry counter).
// Do not use a high threshold for compressed audio.
@@ -6604,7 +6706,7 @@
const int32_t retryThreshold = targetRetryCount > 2 ? targetRetryCount - 1 : 1;
uint32_t minFrames;
if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()
- && (track->mRetryCount > retryThreshold) && audio_has_proportional_frames(mFormat)) {
+ && (track->retryCount() > retryThreshold) && audio_has_proportional_frames(mFormat)) {
minFrames = mNormalFrameCount;
} else {
minFrames = 1;
@@ -6622,8 +6724,8 @@
{
ALOGVV("track(%d) s=%08x [OK]", trackId, cblk->mServer);
- if (track->mFillingUpStatus == Track::FS_FILLED) {
- track->mFillingUpStatus = Track::FS_ACTIVE;
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
if (last) {
// make sure processVolume_l() will apply new volume even if 0
mLeftVolFloat = mRightVolFloat = -1.0;
@@ -6636,7 +6738,7 @@
// compute volume for this track
processVolume_l(track, last);
if (last) {
- sp<Track> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
if (previousTrack != 0) {
if (track != previousTrack.get()) {
// Flush any data still being written from last track
@@ -6648,7 +6750,7 @@
mPreviousTrack = track;
// reset retry count
- track->mRetryCount = targetRetryCount;
+ track->retryCount() = targetRetryCount;
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
if (mHwPaused) {
@@ -6663,7 +6765,7 @@
mEffectChains[0]->clearInputBuffer();
}
if (track->isStopping_1()) {
- track->mState = TrackBase::STOPPING_2;
+ track->setState(IAfTrackBase::STOPPING_2);
if (last && mHwPaused) {
doHwResume = true;
mHwPaused = false;
@@ -6681,7 +6783,7 @@
mOutput->presentationComplete();
}
if (track->isStopping_2()) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
}
if (track->isStopped()) {
track->reset();
@@ -6694,9 +6796,9 @@
// Only consider last track started for mixer state control
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (!isTunerStream() // tuner streams remain active in underrun
- && --(track->mRetryCount) <= 0) {
+ && --(track->retryCount()) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
} else {
ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId);
tracksToRemove->add(track);
@@ -6753,7 +6855,7 @@
return mixerStatus;
}
-void AudioFlinger::DirectOutputThread::threadLoop_mix()
+void DirectOutputThread::threadLoop_mix()
{
size_t frameCount = mFrameCount;
int8_t *curBuf = (int8_t *)mSinkBuffer;
@@ -6780,7 +6882,7 @@
mActiveTrack.clear();
}
-void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
+void DirectOutputThread::threadLoop_sleepTime()
{
// do not write to HAL when paused
if (mHwPaused || (usesHwAvSync() && mStandby)) {
@@ -6796,7 +6898,7 @@
// linear or proportional PCM direct tracks in underrun.
}
-void AudioFlinger::DirectOutputThread::threadLoop_exit()
+void DirectOutputThread::threadLoop_exit()
{
{
Mutex::Autolock _l(mLock);
@@ -6814,7 +6916,7 @@
}
// must be called with thread mutex locked
-bool AudioFlinger::DirectOutputThread::shouldStandby_l()
+bool DirectOutputThread::shouldStandby_l()
{
bool trackPaused = false;
bool trackStopped = false;
@@ -6824,14 +6926,14 @@
if (mTracks.size() > 0) {
trackPaused = mTracks[mTracks.size() - 1]->isPaused();
trackStopped = mTracks[mTracks.size() - 1]->isStopped() ||
- mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE;
+ mTracks[mTracks.size() - 1]->state() == IAfTrackBase::IDLE;
}
return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
}
// checkForNewParameter_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
+bool DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
bool reconfig = false;
@@ -6873,7 +6975,7 @@
return reconfig;
}
-uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const
+uint32_t DirectOutputThread::activeSleepTimeUs() const
{
uint32_t time;
if (audio_has_proportional_frames(mFormat)) {
@@ -6884,7 +6986,7 @@
return time;
}
-uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() const
+uint32_t DirectOutputThread::idleSleepTimeUs() const
{
uint32_t time;
if (audio_has_proportional_frames(mFormat)) {
@@ -6895,7 +6997,7 @@
return time;
}
-uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() const
+uint32_t DirectOutputThread::suspendSleepTimeUs() const
{
uint32_t time;
if (audio_has_proportional_frames(mFormat)) {
@@ -6906,7 +7008,7 @@
return time;
}
-void AudioFlinger::DirectOutputThread::cacheParameters_l()
+void DirectOutputThread::cacheParameters_l()
{
PlaybackThread::cacheParameters_l();
@@ -6922,7 +7024,7 @@
}
}
-void AudioFlinger::DirectOutputThread::flushHw_l()
+void DirectOutputThread::flushHw_l()
{
PlaybackThread::flushHw_l();
mOutput->flush();
@@ -6933,7 +7035,7 @@
mMonotonicFrameCounter.onFlush();
}
-int64_t AudioFlinger::DirectOutputThread::computeWaitTimeNs_l() const {
+int64_t DirectOutputThread::computeWaitTimeNs_l() const {
// If a VolumeShaper is active, we must wake up periodically to update volume.
const int64_t NS_PER_MS = 1000000;
return mVolumeShaperActive ?
@@ -6942,8 +7044,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::AsyncCallbackThread::AsyncCallbackThread(
- const wp<AudioFlinger::PlaybackThread>& playbackThread)
+AsyncCallbackThread::AsyncCallbackThread(
+ const wp<PlaybackThread>& playbackThread)
: Thread(false /*canCallJava*/),
mPlaybackThread(playbackThread),
mWriteAckSequence(0),
@@ -6952,16 +7054,12 @@
{
}
-AudioFlinger::AsyncCallbackThread::~AsyncCallbackThread()
-{
-}
-
-void AudioFlinger::AsyncCallbackThread::onFirstRef()
+void AsyncCallbackThread::onFirstRef()
{
run("Offload Cbk", ANDROID_PRIORITY_URGENT_AUDIO);
}
-bool AudioFlinger::AsyncCallbackThread::threadLoop()
+bool AsyncCallbackThread::threadLoop()
{
while (!exitPending()) {
uint32_t writeAckSequence;
@@ -6990,7 +7088,7 @@
mAsyncError = false;
}
{
- sp<AudioFlinger::PlaybackThread> playbackThread = mPlaybackThread.promote();
+ const sp<PlaybackThread> playbackThread = mPlaybackThread.promote();
if (playbackThread != 0) {
if (writeAckSequence & 1) {
playbackThread->resetWriteBlocked(writeAckSequence >> 1);
@@ -7007,7 +7105,7 @@
return false;
}
-void AudioFlinger::AsyncCallbackThread::exit()
+void AsyncCallbackThread::exit()
{
ALOGV("AsyncCallbackThread::exit");
Mutex::Autolock _l(mLock);
@@ -7015,14 +7113,14 @@
mWaitWorkCV.broadcast();
}
-void AudioFlinger::AsyncCallbackThread::setWriteBlocked(uint32_t sequence)
+void AsyncCallbackThread::setWriteBlocked(uint32_t sequence)
{
Mutex::Autolock _l(mLock);
// bit 0 is cleared
mWriteAckSequence = sequence << 1;
}
-void AudioFlinger::AsyncCallbackThread::resetWriteBlocked()
+void AsyncCallbackThread::resetWriteBlocked()
{
Mutex::Autolock _l(mLock);
// ignore unexpected callbacks
@@ -7032,14 +7130,14 @@
}
}
-void AudioFlinger::AsyncCallbackThread::setDraining(uint32_t sequence)
+void AsyncCallbackThread::setDraining(uint32_t sequence)
{
Mutex::Autolock _l(mLock);
// bit 0 is cleared
mDrainSequence = sequence << 1;
}
-void AudioFlinger::AsyncCallbackThread::resetDraining()
+void AsyncCallbackThread::resetDraining()
{
Mutex::Autolock _l(mLock);
// ignore unexpected callbacks
@@ -7049,7 +7147,7 @@
}
}
-void AudioFlinger::AsyncCallbackThread::setAsyncError()
+void AsyncCallbackThread::setAsyncError()
{
Mutex::Autolock _l(mLock);
mAsyncError = true;
@@ -7058,10 +7156,19 @@
// ----------------------------------------------------------------------------
-AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
+
+/* static */
+sp<IAfPlaybackThread> IAfPlaybackThread::createOffloadThread(
+ const sp<IAfThreadCallback>& afThreadCallback,
+ AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
+ const audio_offload_info_t& offloadInfo) {
+ return sp<OffloadThread>::make(afThreadCallback, output, id, systemReady, offloadInfo);
+}
+
+OffloadThread::OffloadThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
const audio_offload_info_t& offloadInfo)
- : DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady, offloadInfo),
+ : DirectOutputThread(afThreadCallback, output, id, OFFLOAD, systemReady, offloadInfo),
mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true)
{
//FIXME: mStandby should be set to true by ThreadBase constructo
@@ -7069,7 +7176,7 @@
mKeepWakeLock = property_get_bool("ro.audio.offload_wakelock", true /* default_value */);
}
-void AudioFlinger::OffloadThread::threadLoop_exit()
+void OffloadThread::threadLoop_exit()
{
if (mFlushPending || mHwPaused) {
// If a flush is pending or track was paused, just discard buffered data
@@ -7085,8 +7192,8 @@
PlaybackThread::threadLoop_exit();
}
-AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove
+PlaybackThread::mixer_state OffloadThread::prepareTracks_l(
+ Vector<sp<IAfTrack>>* tracksToRemove
)
{
size_t count = mActiveTracks.size();
@@ -7098,8 +7205,8 @@
ALOGV("OffloadThread::prepareTracks_l active tracks %zu", count);
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
- Track* const track = t.get();
+ for (const sp<IAfTrack>& t : mActiveTracks) {
+ IAfTrack* const track = t.get();
#ifdef VERY_VERY_VERBOSE_LOGGING
audio_track_cblk_t* cblk = track->cblk();
#endif
@@ -7107,7 +7214,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<IAfTrack> l = mActiveTracks.getLatest();
bool last = l.get() == track;
if (track->isInvalid()) {
@@ -7116,7 +7223,7 @@
continue;
}
- if (track->mState == TrackBase::IDLE) {
+ if (track->state() == IAfTrackBase::IDLE) {
ALOGW("An idle track shouldn't be in active list");
continue;
}
@@ -7148,9 +7255,9 @@
tracksToRemove->add(track);
} else if (track->isFlushPending()) {
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
}
track->flushAck();
if (last) {
@@ -7182,8 +7289,8 @@
} else if (track->framesReady() && track->isReady() &&
!track->isPaused() && !track->isTerminated() && !track->isStopping_2()) {
ALOGVV("OffloadThread: track(%d) s=%08x [OK]", track->id(), cblk->mServer);
- if (track->mFillingUpStatus == Track::FS_FILLED) {
- track->mFillingUpStatus = Track::FS_ACTIVE;
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
if (last) {
// make sure processVolume_l() will apply new volume even if 0
mLeftVolFloat = mRightVolFloat = -1.0;
@@ -7191,7 +7298,7 @@
}
if (last) {
- sp<Track> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
if (previousTrack != 0) {
if (track != previousTrack.get()) {
// Flush any data still being written from last track
@@ -7217,9 +7324,9 @@
mPreviousTrack = track;
// reset retry count
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
}
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
@@ -7227,7 +7334,7 @@
} else {
ALOGVV("OffloadThread: track(%d) s=%08x [NOT READY]", track->id(), cblk->mServer);
if (track->isStopping_1()) {
- if (--(track->mRetryCount) <= 0) {
+ if (--(track->retryCount()) <= 0) {
// Hardware buffer can hold a large amount of audio so we must
// wait for all current track's data to drain before we say
// that the track is stopped.
@@ -7235,7 +7342,8 @@
// Only start draining when all data in mixbuffer
// has been written
ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2");
- track->mState = TrackBase::STOPPING_2; // so presentation completes after
+ track->setState(IAfTrackBase::STOPPING_2);
+ // so presentation completes after
// drain do not drain if no data was ever sent to HAL (mStandby == true)
if (last && !mStandby) {
// do not modify drain sequence if we are already draining. This happens
@@ -7255,13 +7363,13 @@
}
}
} else if (last) {
- ALOGV("stopping1 underrun retries left %d", track->mRetryCount);
+ ALOGV("stopping1 underrun retries left %d", track->retryCount());
mixerStatus = MIXER_TRACKS_ENABLED;
}
} else if (track->isStopping_2()) {
// Drain has completed or we are in standby, signal presentation complete
if (!(mDrainSequence & 1) || !last || mStandby) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
mOutput->presentationComplete();
track->presentationComplete(latency_l()); // always returns true
track->reset();
@@ -7281,9 +7389,9 @@
// fill a buffer, then remove it from active list.
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (!isTunerStream() // tuner streams remain active in underrun
- && --(track->mRetryCount) <= 0) {
+ && --(track->retryCount()) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
} else {
ALOGV("OffloadThread: BUFFER TIMEOUT: remove track(%d) from active list",
track->id());
@@ -7327,7 +7435,7 @@
}
// must be called with thread mutex locked
-bool AudioFlinger::OffloadThread::waitingAsyncCallback_l()
+bool OffloadThread::waitingAsyncCallback_l()
{
ALOGVV("waitingAsyncCallback_l mWriteAckSequence %d mDrainSequence %d",
mWriteAckSequence, mDrainSequence);
@@ -7337,13 +7445,13 @@
return false;
}
-bool AudioFlinger::OffloadThread::waitingAsyncCallback()
+bool OffloadThread::waitingAsyncCallback()
{
Mutex::Autolock _l(mLock);
return waitingAsyncCallback_l();
}
-void AudioFlinger::OffloadThread::flushHw_l()
+void OffloadThread::flushHw_l()
{
DirectOutputThread::flushHw_l();
// Flush anything still waiting in the mixbuffer
@@ -7364,7 +7472,7 @@
}
}
-void AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType)
+void OffloadThread::invalidateTracks(audio_stream_type_t streamType)
{
Mutex::Autolock _l(mLock);
if (PlaybackThread::invalidateTracks_l(streamType)) {
@@ -7372,7 +7480,7 @@
}
}
-void AudioFlinger::OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
+void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
Mutex::Autolock _l(mLock);
if (PlaybackThread::invalidateTracks_l(portIds)) {
mFlushPending = true;
@@ -7381,23 +7489,30 @@
// ----------------------------------------------------------------------------
-AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
- AudioFlinger::MixerThread* mainThread, audio_io_handle_t id, bool systemReady)
- : MixerThread(audioFlinger, mainThread->getOutput(), id,
+/* static */
+sp<IAfDuplicatingThread> IAfDuplicatingThread::create(
+ const sp<IAfThreadCallback>& afThreadCallback,
+ IAfPlaybackThread* mainThread, audio_io_handle_t id, bool systemReady) {
+ return sp<DuplicatingThread>::make(afThreadCallback, mainThread, id, systemReady);
+}
+
+DuplicatingThread::DuplicatingThread(const sp<IAfThreadCallback>& afThreadCallback,
+ IAfPlaybackThread* mainThread, audio_io_handle_t id, bool systemReady)
+ : MixerThread(afThreadCallback, mainThread->getOutput(), id,
systemReady, DUPLICATING),
mWaitTimeMs(UINT_MAX)
{
addOutputTrack(mainThread);
}
-AudioFlinger::DuplicatingThread::~DuplicatingThread()
+DuplicatingThread::~DuplicatingThread()
{
for (size_t i = 0; i < mOutputTracks.size(); i++) {
mOutputTracks[i]->destroy();
}
}
-void AudioFlinger::DuplicatingThread::threadLoop_mix()
+void DuplicatingThread::threadLoop_mix()
{
// mix buffers...
if (outputsReady()) {
@@ -7415,7 +7530,7 @@
mStandbyTimeNs = systemTime() + mStandbyDelayNs;
}
-void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
+void DuplicatingThread::threadLoop_sleepTime()
{
if (mSleepTimeUs == 0) {
if (mMixerStatus == MIXER_TRACKS_ENABLED) {
@@ -7435,7 +7550,7 @@
}
}
-ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
+ssize_t DuplicatingThread::threadLoop_write()
{
for (size_t i = 0; i < outputTracks.size(); i++) {
const ssize_t actualWritten = outputTracks[i]->write(mSinkBuffer, writeFrames);
@@ -7463,7 +7578,7 @@
return (ssize_t)mSinkBufferSize;
}
-void AudioFlinger::DuplicatingThread::threadLoop_standby()
+void DuplicatingThread::threadLoop_standby()
{
// DuplicatingThread implements standby by stopping all tracks
for (size_t i = 0; i < outputTracks.size(); i++) {
@@ -7471,7 +7586,7 @@
}
}
-void AudioFlinger::DuplicatingThread::dumpInternals_l(int fd, const Vector<String16>& args)
+void DuplicatingThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
MixerThread::dumpInternals_l(fd, args);
@@ -7481,7 +7596,7 @@
if (numTracks > 0) {
ss << ":";
for (const auto &track : mOutputTracks) {
- const sp<ThreadBase> thread = track->thread().promote();
+ const auto thread = track->thread().promote();
ss << " (" << track->id() << " : ";
if (thread.get() != nullptr) {
ss << thread.get() << ", " << thread->id();
@@ -7496,17 +7611,17 @@
write(fd, result.c_str(), result.size());
}
-void AudioFlinger::DuplicatingThread::saveOutputTracks()
+void DuplicatingThread::saveOutputTracks()
{
outputTracks = mOutputTracks;
}
-void AudioFlinger::DuplicatingThread::clearOutputTracks()
+void DuplicatingThread::clearOutputTracks()
{
outputTracks.clear();
}
-void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
+void DuplicatingThread::addOutputTrack(IAfPlaybackThread* thread)
{
Mutex::Autolock _l(mLock);
// The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass.
@@ -7525,7 +7640,7 @@
attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(
IPCThreadState::self()->getCallingPid()));
attributionSource.token = sp<BBinder>::make();
- sp<OutputTrack> outputTrack = new OutputTrack(thread,
+ sp<IAfOutputTrack> outputTrack = IAfOutputTrack::create(thread,
this,
mSampleRate,
mFormat,
@@ -7543,7 +7658,7 @@
updateWaitTime_l();
}
-void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
+void DuplicatingThread::removeOutputTrack(IAfPlaybackThread* thread)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mOutputTracks.size(); i++) {
@@ -7561,11 +7676,11 @@
}
// caller must hold mLock
-void AudioFlinger::DuplicatingThread::updateWaitTime_l()
+void DuplicatingThread::updateWaitTime_l()
{
mWaitTimeMs = UINT_MAX;
for (size_t i = 0; i < mOutputTracks.size(); i++) {
- sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
+ const auto strong = mOutputTracks[i]->thread().promote();
if (strong != 0) {
uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
if (waitTimeMs < mWaitTimeMs) {
@@ -7575,18 +7690,18 @@
}
}
-bool AudioFlinger::DuplicatingThread::outputsReady()
+bool DuplicatingThread::outputsReady()
{
for (size_t i = 0; i < outputTracks.size(); i++) {
- sp<ThreadBase> thread = outputTracks[i]->thread().promote();
+ const auto thread = outputTracks[i]->thread().promote();
if (thread == 0) {
ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p",
outputTracks[i].get());
return false;
}
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ IAfPlaybackThread* const playbackThread = thread->asIAfPlaybackThread().get();
// see note at standby() declaration
- if (playbackThread->standby() && !playbackThread->isSuspended()) {
+ if (playbackThread->inStandby() && !playbackThread->isSuspended()) {
ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(),
thread.get());
return false;
@@ -7595,7 +7710,7 @@
return true;
}
-void AudioFlinger::DuplicatingThread::sendMetadataToBackend_l(
+void DuplicatingThread::sendMetadataToBackend_l(
const StreamOutHalInterface::SourceMetadata& metadata)
{
for (auto& outputTrack : outputTracks) { // not mOutputTracks
@@ -7603,12 +7718,12 @@
}
}
-uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
+uint32_t DuplicatingThread::activeSleepTimeUs() const
{
return (mWaitTimeMs * 1000) / 2;
}
-void AudioFlinger::DuplicatingThread::cacheParameters_l()
+void DuplicatingThread::cacheParameters_l()
{
// updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
updateWaitTime_l();
@@ -7618,16 +7733,26 @@
// ----------------------------------------------------------------------------
-AudioFlinger::SpatializerThread::SpatializerThread(const sp<AudioFlinger>& audioFlinger,
+/* static */
+sp<IAfPlaybackThread> IAfPlaybackThread::createSpatializerThread(
+ const sp<IAfThreadCallback>& afThreadCallback,
+ AudioStreamOut* output,
+ audio_io_handle_t id,
+ bool systemReady,
+ audio_config_base_t* mixerConfig) {
+ return sp<SpatializerThread>::make(afThreadCallback, output, id, systemReady, mixerConfig);
+}
+
+SpatializerThread::SpatializerThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output,
audio_io_handle_t id,
bool systemReady,
audio_config_base_t *mixerConfig)
- : MixerThread(audioFlinger, output, id, systemReady, SPATIALIZER, mixerConfig)
+ : MixerThread(afThreadCallback, output, id, systemReady, SPATIALIZER, mixerConfig)
{
}
-void AudioFlinger::SpatializerThread::onFirstRef() {
+void SpatializerThread::onFirstRef() {
MixerThread::onFirstRef();
const pid_t tid = getTid();
@@ -7642,7 +7767,7 @@
}
}
-void AudioFlinger::SpatializerThread::setHalLatencyMode_l() {
+void SpatializerThread::setHalLatencyMode_l() {
// if mSupportedLatencyModes is empty, the HAL stream does not support
// latency mode control and we can exit.
if (mSupportedLatencyModes.empty()) {
@@ -7680,7 +7805,7 @@
}
}
-status_t AudioFlinger::SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) {
+status_t SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) {
if (mode != AUDIO_LATENCY_MODE_LOW && mode != AUDIO_LATENCY_MODE_FREE) {
return BAD_VALUE;
}
@@ -7689,7 +7814,7 @@
return NO_ERROR;
}
-void AudioFlinger::SpatializerThread::checkOutputStageEffects()
+void SpatializerThread::checkOutputStageEffects()
{
bool hasVirtualizer = false;
bool hasDownMixer = false;
@@ -7714,7 +7839,7 @@
finalDownMixer.clear();
} else if (!hasDownMixer) {
std::vector<effect_descriptor_t> descriptors;
- status_t status = mAudioFlinger->mEffectsFactoryHal->getDescriptors(
+ status_t status = mAfThreadCallback->getEffectsFactoryHal()->getDescriptors(
EFFECT_UIID_DOWNMIX, &descriptors);
if (status != NO_ERROR) {
return;
@@ -7745,12 +7870,19 @@
// Record
// ----------------------------------------------------------------------------
-AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
+sp<IAfRecordThread> IAfRecordThread::create(const sp<IAfThreadCallback>& afThreadCallback,
+ AudioStreamIn* input,
+ audio_io_handle_t id,
+ bool systemReady) {
+ return sp<RecordThread>::make(afThreadCallback, input, id, systemReady);
+}
+
+RecordThread::RecordThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamIn *input,
audio_io_handle_t id,
bool systemReady
) :
- ThreadBase(audioFlinger, id, RECORD, systemReady, false /* isOut */),
+ ThreadBase(afThreadCallback, id, RECORD, systemReady, false /* isOut */),
mInput(input),
mSource(mInput),
mActiveTracks(&this->mLocalLog),
@@ -7771,7 +7903,7 @@
, mBtNrecSuspended(false)
{
snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
- mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
+ mNBLogWriter = afThreadCallback->newWriter_l(kLogSize, mThreadName);
if (mInput->audioHwDev != nullptr) {
mIsMsdDevice = strcmp(
@@ -7879,7 +8011,8 @@
#ifdef TEE_SINK
// FIXME
#endif
- mFastCaptureNBLogWriter = audioFlinger->newWriter_l(kFastCaptureLogSize, "FastCapture");
+ mFastCaptureNBLogWriter =
+ afThreadCallback->newWriter_l(kFastCaptureLogSize, "FastCapture");
state->mNBLogWriter = mFastCaptureNBLogWriter.get();
sq->end();
sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
@@ -7904,7 +8037,7 @@
// FIXME mNormalSource
}
-AudioFlinger::RecordThread::~RecordThread()
+RecordThread::~RecordThread()
{
if (mFastCapture != 0) {
FastCaptureStateQueue *sq = mFastCapture->sq();
@@ -7921,36 +8054,36 @@
mFastCapture->join();
mFastCapture.clear();
}
- mAudioFlinger->unregisterWriter(mFastCaptureNBLogWriter);
- mAudioFlinger->unregisterWriter(mNBLogWriter);
+ mAfThreadCallback->unregisterWriter(mFastCaptureNBLogWriter);
+ mAfThreadCallback->unregisterWriter(mNBLogWriter);
free(mRsmpInBuffer);
}
-void AudioFlinger::RecordThread::onFirstRef()
+void RecordThread::onFirstRef()
{
run(mThreadName, PRIORITY_URGENT_AUDIO);
}
-void AudioFlinger::RecordThread::preExit()
+void RecordThread::preExit()
{
ALOGV(" preExit()");
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
mStartStopCond.broadcast();
}
-bool AudioFlinger::RecordThread::threadLoop()
+bool RecordThread::threadLoop()
{
nsecs_t lastWarning = 0;
inputStandBy();
reacquire_wakelock:
- sp<RecordTrack> activeTrack;
+ sp<IAfRecordTrack> activeTrack;
{
Mutex::Autolock _l(mLock);
acquireWakeLock_l();
@@ -7966,13 +8099,13 @@
Vector<sp<IAfEffectChain>> effectChains;
// activeTracks accumulates a copy of a subset of mActiveTracks
- Vector< sp<RecordTrack> > activeTracks;
+ Vector<sp<IAfRecordTrack>> activeTracks;
// reference to the (first and only) active fast track
- sp<RecordTrack> fastTrack;
+ sp<IAfRecordTrack> fastTrack;
// reference to a fast track which is about to be removed
- sp<RecordTrack> fastTrackToRemove;
+ sp<IAfRecordTrack> fastTrackToRemove;
bool silenceFastCapture = false;
@@ -8025,40 +8158,40 @@
continue;
}
- TrackBase::track_state activeTrackState = activeTrack->mState;
+ IAfTrackBase::track_state activeTrackState = activeTrack->state();
switch (activeTrackState) {
- case TrackBase::PAUSING:
+ case IAfTrackBase::PAUSING:
mActiveTracks.remove(activeTrack);
- activeTrack->mState = TrackBase::PAUSED;
+ activeTrack->setState(IAfTrackBase::PAUSED);
doBroadcast = true;
size--;
continue;
- case TrackBase::STARTING_1:
+ case IAfTrackBase::STARTING_1:
sleepUs = 10000;
i++;
allStopped = false;
continue;
- case TrackBase::STARTING_2:
+ case IAfTrackBase::STARTING_2:
doBroadcast = true;
if (mStandby) {
mThreadMetrics.logBeginInterval();
mThreadSnapshot.onBegin();
mStandby = false;
}
- activeTrack->mState = TrackBase::ACTIVE;
+ activeTrack->setState(IAfTrackBase::ACTIVE);
allStopped = false;
break;
- case TrackBase::ACTIVE:
+ case IAfTrackBase::ACTIVE:
allStopped = false;
break;
- case TrackBase::IDLE: // cannot be on ActiveTracks if idle
- case TrackBase::PAUSED: // cannot be on ActiveTracks if paused
- case TrackBase::STOPPED: // cannot be on ActiveTracks if destroyed/terminated
+ case IAfTrackBase::IDLE: // cannot be on ActiveTracks if idle
+ case IAfTrackBase::PAUSED: // cannot be on ActiveTracks if paused
+ case IAfTrackBase::STOPPED: // cannot be on ActiveTracks if destroyed/terminated
default:
LOG_ALWAYS_FATAL("%s: Unexpected active track state:%d, id:%d, tracks:%zu",
__func__, activeTrackState, activeTrack->id(), size);
@@ -8150,7 +8283,7 @@
}
state->mCommand = FastCaptureState::READ_WRITE;
#if 0 // FIXME
- mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
+ mFastCaptureDumpState.increaseSamplingN(mAfThreadCallback->isLowRamDevice() ?
FastThreadDumpState::kSamplingNforLowRamDevice :
FastThreadDumpState::kSamplingN);
#endif
@@ -8305,7 +8438,7 @@
// From the timestamp, input read latency is negative output write latency.
const audio_input_flags_t flags = mInput != NULL ? mInput->flags : AUDIO_INPUT_FLAG_NONE;
- const double latencyMs = RecordTrack::checkServerLatencySupported(mFormat, flags)
+ const double latencyMs = IAfRecordTrack::checkServerLatencySupported(mFormat, flags)
? - mTimestamp.getOutputServerLatencyMs(mSampleRate) : 0.;
if (latencyMs != 0.) { // note 0. means timestamp is empty.
mLatencyMs.add(latencyMs);
@@ -8362,16 +8495,16 @@
// loop over getNextBuffer to handle circular sink
for (;;) {
- activeTrack->mSink.frameCount = ~0;
- status_t status = activeTrack->getNextBuffer(&activeTrack->mSink);
- size_t framesOut = activeTrack->mSink.frameCount;
+ activeTrack->sinkBuffer().frameCount = ~0;
+ status_t status = activeTrack->getNextBuffer(&activeTrack->sinkBuffer());
+ size_t framesOut = activeTrack->sinkBuffer().frameCount;
LOG_ALWAYS_FATAL_IF((status == OK) != (framesOut > 0));
// check available frames and handle overrun conditions
// if the record track isn't draining fast enough.
bool hasOverrun;
size_t framesIn;
- activeTrack->mResamplerBufferProvider->sync(&framesIn, &hasOverrun);
+ activeTrack->resamplerBufferProvider()->sync(&framesIn, &hasOverrun);
if (hasOverrun) {
overrun = OVERRUN_TRUE;
}
@@ -8385,7 +8518,7 @@
// RecordBufferConverter. TODO: remove when no longer needed.
framesOut = min(framesOut,
destinationFramesPossible(
- framesIn, mSampleRate, activeTrack->mSampleRate));
+ framesIn, mSampleRate, activeTrack->sampleRate()));
if (activeTrack->isDirect()) {
// No RecordBufferConverter used for direct streams. Pass
@@ -8393,14 +8526,15 @@
AudioBufferProvider::Buffer buffer;
buffer.frameCount = framesOut;
const status_t getNextBufferStatus =
- activeTrack->mResamplerBufferProvider->getNextBuffer(&buffer);
+ activeTrack->resamplerBufferProvider()->getNextBuffer(&buffer);
if (getNextBufferStatus == OK && buffer.frameCount != 0) {
ALOGV_IF(buffer.frameCount != framesOut,
"%s() read less than expected (%zu vs %zu)",
__func__, buffer.frameCount, framesOut);
framesOut = buffer.frameCount;
- memcpy(activeTrack->mSink.raw, buffer.raw, buffer.frameCount * mFrameSize);
- activeTrack->mResamplerBufferProvider->releaseBuffer(&buffer);
+ memcpy(activeTrack->sinkBuffer().raw,
+ buffer.raw, buffer.frameCount * mFrameSize);
+ activeTrack->resamplerBufferProvider()->releaseBuffer(&buffer);
} else {
framesOut = 0;
ALOGE("%s() cannot fill request, status: %d, frameCount: %zu",
@@ -8409,9 +8543,9 @@
} else {
// process frames from the RecordThread buffer provider to the RecordTrack
// buffer
- framesOut = activeTrack->mRecordBufferConverter->convert(
- activeTrack->mSink.raw,
- activeTrack->mResamplerBufferProvider,
+ framesOut = activeTrack->recordBufferConverter()->convert(
+ activeTrack->sinkBuffer().raw,
+ activeTrack->resamplerBufferProvider(),
framesOut);
}
@@ -8421,17 +8555,18 @@
// MediaSyncEvent handling: Synchronize AudioRecord to AudioTrack completion.
const ssize_t framesToDrop =
- activeTrack->mSynchronizedRecordState.updateRecordFrames(framesOut);
+ activeTrack->synchronizedRecordState().updateRecordFrames(framesOut);
if (framesToDrop == 0) {
// no sync event, process normally, otherwise ignore.
if (framesOut > 0) {
- activeTrack->mSink.frameCount = framesOut;
+ activeTrack->sinkBuffer().frameCount = framesOut;
// Sanitize before releasing if the track has no access to the source data
// An idle UID receives silence from non virtual devices until active
if (activeTrack->isSilenced()) {
- memset(activeTrack->mSink.raw, 0, framesOut * activeTrack->frameSize());
+ memset(activeTrack->sinkBuffer().raw,
+ 0, framesOut * activeTrack->frameSize());
}
- activeTrack->releaseBuffer(&activeTrack->mSink);
+ activeTrack->releaseBuffer(&activeTrack->sinkBuffer());
}
}
if (framesOut == 0) {
@@ -8460,7 +8595,7 @@
// update frame information and push timestamp out
activeTrack->updateTrackFrameInfo(
- activeTrack->mServerProxy->framesReleased(),
+ activeTrack->serverProxy()->framesReleased(),
mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER],
mSampleRate, mTimestamp);
}
@@ -8493,7 +8628,7 @@
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
@@ -8506,7 +8641,7 @@
return false;
}
-void AudioFlinger::RecordThread::standbyIfNotAlreadyInStandby()
+void RecordThread::standbyIfNotAlreadyInStandby()
{
if (!mStandby) {
inputStandBy();
@@ -8516,7 +8651,7 @@
}
}
-void AudioFlinger::RecordThread::inputStandBy()
+void RecordThread::inputStandBy()
{
// Idle the fast capture if it's currently running
if (mFastCapture != 0) {
@@ -8557,7 +8692,7 @@
}
// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
+sp<IAfRecordTrack> RecordThread::createRecordTrack_l(
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t *pSampleRate,
@@ -8576,7 +8711,7 @@
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
- sp<RecordTrack> track;
+ sp<IAfRecordTrack> track;
status_t lStatus;
audio_input_flags_t inputFlags = mInput->flags;
audio_input_flags_t requestedFlags = *flags;
@@ -8600,7 +8735,7 @@
goto Exit;
}
if (maxSharedAudioHistoryMs < 0
- || maxSharedAudioHistoryMs > AudioFlinger::kMaxSharedAudioHistoryMs) {
+ || maxSharedAudioHistoryMs > kMaxSharedAudioHistoryMs) {
lStatus = BAD_VALUE;
goto Exit;
}
@@ -8722,10 +8857,10 @@
startFrames = mSharedAudioStartFrames;
}
- track = new RecordTrack(this, client, attr, sampleRate,
+ track = IAfRecordTrack::create(this, client, attr, sampleRate,
format, channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid,
- attributionSource, *flags, TrackBase::TYPE_DEFAULT, portId,
+ attributionSource, *flags, IAfTrackBase::TYPE_DEFAULT, portId,
startFrames);
lStatus = track->initCheck();
@@ -8755,7 +8890,7 @@
return track;
}
-status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack,
+status_t RecordThread::start(IAfRecordTrack* recordTrack,
AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
@@ -8766,8 +8901,8 @@
if (event == AudioSystem::SYNC_EVENT_NONE) {
recordTrack->clearSyncStartEvent();
} else if (event != AudioSystem::SYNC_EVENT_SAME) {
- recordTrack->mSynchronizedRecordState.startRecording(
- mAudioFlinger->createSyncEvent(
+ recordTrack->synchronizedRecordState().startRecording(
+ mAfThreadCallback->createSyncEvent(
event, triggerSession,
recordTrack->sessionId(), syncStartEventCallback, recordTrack));
}
@@ -8781,13 +8916,13 @@
return DEAD_OBJECT;
}
if (mActiveTracks.indexOf(recordTrack) >= 0) {
- if (recordTrack->mState == TrackBase::PAUSING) {
+ if (recordTrack->state() == IAfTrackBase::PAUSING) {
// We haven't stopped yet (moved to PAUSED and not in mActiveTracks)
// so no need to startInput().
ALOGV("active record track PAUSING -> ACTIVE");
- recordTrack->mState = TrackBase::ACTIVE;
+ recordTrack->setState(IAfTrackBase::ACTIVE);
} else {
- ALOGV("active record track state %d", (int)recordTrack->mState);
+ ALOGV("active record track state %d", (int)recordTrack->state());
}
return status;
}
@@ -8795,7 +8930,7 @@
// TODO consider other ways of handling this, such as changing the state to :STARTING and
// adding the track to mActiveTracks after returning from AudioSystem::startInput(),
// or using a separate command thread
- recordTrack->mState = TrackBase::STARTING_1;
+ recordTrack->setState(IAfTrackBase::STARTING_1);
mActiveTracks.add(recordTrack);
if (recordTrack->isExternalTrack()) {
mLock.unlock();
@@ -8803,16 +8938,16 @@
mLock.lock();
if (recordTrack->isInvalid()) {
recordTrack->clearSyncStartEvent();
- if (status == NO_ERROR && recordTrack->mState == TrackBase::STARTING_1) {
- recordTrack->mState = TrackBase::STARTING_2;
+ if (status == NO_ERROR && recordTrack->state() == IAfTrackBase::STARTING_1) {
+ recordTrack->setState(IAfTrackBase::STARTING_2);
// STARTING_2 forces destroy to call stopInput.
}
ALOGW("%s track %d: invalidated after startInput", __func__, recordTrack->portId());
return DEAD_OBJECT;
}
- if (recordTrack->mState != TrackBase::STARTING_1) {
+ if (recordTrack->state() != IAfTrackBase::STARTING_1) {
ALOGW("%s(%d): unsynchronized mState:%d change",
- __func__, recordTrack->id(), (int)recordTrack->mState);
+ __func__, recordTrack->id(), (int)recordTrack->state());
// Someone else has changed state, let them take over,
// leave mState in the new state.
recordTrack->clearSyncStartEvent();
@@ -8839,67 +8974,66 @@
// was initialized to some value closer to the thread's mRsmpInFront, then the track could
// see previously buffered data before it called start(), but with greater risk of overrun.
- recordTrack->mResamplerBufferProvider->reset();
+ recordTrack->resamplerBufferProvider()->reset();
if (!recordTrack->isDirect()) {
// clear any converter state as new data will be discontinuous
- recordTrack->mRecordBufferConverter->reset();
+ recordTrack->recordBufferConverter()->reset();
}
- recordTrack->mState = TrackBase::STARTING_2;
+ recordTrack->setState(IAfTrackBase::STARTING_2);
// signal thread to start
mWaitWorkCV.broadcast();
return status;
}
}
-void AudioFlinger::RecordThread::syncStartEventCallback(const wp<audioflinger::SyncEvent>& event)
+void RecordThread::syncStartEventCallback(const wp<SyncEvent>& event)
{
- sp<audioflinger::SyncEvent> strongEvent = event.promote();
+ const sp<SyncEvent> strongEvent = event.promote();
if (strongEvent != 0) {
- sp<RefBase> ptr = std::any_cast<const wp<RefBase>>(strongEvent->cookie()).promote();
- if (ptr != 0) {
- RecordTrack *recordTrack = (RecordTrack *)ptr.get();
- recordTrack->handleSyncStartEvent(strongEvent);
+ sp<IAfTrackBase> ptr =
+ std::any_cast<const wp<IAfTrackBase>>(strongEvent->cookie()).promote();
+ if (ptr != nullptr) {
+ // TODO(b/291317898) handleSyncStartEvent is in IAfTrackBase not IAfRecordTrack.
+ ptr->handleSyncStartEvent(strongEvent);
}
}
}
-bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
+bool RecordThread::stop(IAfRecordTrack* recordTrack) {
ALOGV("RecordThread::stop");
AutoMutex _l(mLock);
// if we're invalid, we can't be on the ActiveTracks.
- if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->mState == TrackBase::PAUSING) {
+ if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->state() == IAfTrackBase::PAUSING) {
return false;
}
// note that threadLoop may still be processing the track at this point [without lock]
- recordTrack->mState = TrackBase::PAUSING;
+ recordTrack->setState(IAfTrackBase::PAUSING);
// NOTE: Waiting here is important to keep stop synchronous.
// This is needed for proper patchRecord peer release.
- while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
+ while (recordTrack->state() == IAfTrackBase::PAUSING && !recordTrack->isInvalid()) {
mWaitWorkCV.broadcast(); // signal thread to stop
mStartStopCond.wait(mLock);
}
- if (recordTrack->mState == TrackBase::PAUSED) { // successful stop
+ if (recordTrack->state() == IAfTrackBase::PAUSED) { // successful stop
ALOGV("Record stopped OK");
return true;
}
// don't handle anything - we've been invalidated or restarted and in a different state
ALOGW_IF("%s(%d): unsynchronized stop, state: %d",
- __func__, recordTrack->id(), recordTrack->mState);
+ __func__, recordTrack->id(), recordTrack->state());
return false;
}
-bool AudioFlinger::RecordThread::isValidSyncEvent(
- const sp<audioflinger::SyncEvent>& /* event */) const
+bool RecordThread::isValidSyncEvent(const sp<SyncEvent>& /* event */) const
{
return false;
}
-status_t AudioFlinger::RecordThread::setSyncEvent(
- const sp<audioflinger::SyncEvent>& event __unused)
+status_t RecordThread::setSyncEvent(const sp<SyncEvent>& /* event */)
{
#if 0 // This branch is currently dead code, but is preserved in case it will be needed in future
if (!isValidSyncEvent(event)) {
@@ -8912,7 +9046,7 @@
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (eventSession == track->sessionId()) {
(void) track->setSyncEvent(event);
ret = NO_ERROR;
@@ -8924,8 +9058,8 @@
#endif
}
-status_t AudioFlinger::RecordThread::getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones)
+status_t RecordThread::getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const
{
ALOGV("RecordThread::getActiveMicrophones");
AutoMutex _l(mLock);
@@ -8936,7 +9070,7 @@
return status;
}
-status_t AudioFlinger::RecordThread::setPreferredMicrophoneDirection(
+status_t RecordThread::setPreferredMicrophoneDirection(
audio_microphone_direction_t direction)
{
ALOGV("setPreferredMicrophoneDirection(%d)", direction);
@@ -8947,7 +9081,7 @@
return mInput->stream->setPreferredMicrophoneDirection(direction);
}
-status_t AudioFlinger::RecordThread::setPreferredMicrophoneFieldDimension(float zoom)
+status_t RecordThread::setPreferredMicrophoneFieldDimension(float zoom)
{
ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
AutoMutex _l(mLock);
@@ -8957,14 +9091,14 @@
return mInput->stream->setPreferredMicrophoneFieldDimension(zoom);
}
-status_t AudioFlinger::RecordThread::shareAudioHistory(
+status_t RecordThread::shareAudioHistory(
const std::string& sharedAudioPackageName, audio_session_t sharedSessionId,
int64_t sharedAudioStartMs) {
AutoMutex _l(mLock);
return shareAudioHistory_l(sharedAudioPackageName, sharedSessionId, sharedAudioStartMs);
}
-status_t AudioFlinger::RecordThread::shareAudioHistory_l(
+status_t RecordThread::shareAudioHistory_l(
const std::string& sharedAudioPackageName, audio_session_t sharedSessionId,
int64_t sharedAudioStartMs) {
@@ -9004,20 +9138,20 @@
return NO_ERROR;
}
-void AudioFlinger::RecordThread::resetAudioHistory_l() {
+void RecordThread::resetAudioHistory_l() {
mSharedAudioSessionId = AUDIO_SESSION_NONE;
mSharedAudioStartFrames = -1;
mSharedAudioPackageName = "";
}
-AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::RecordThread::updateMetadata_l()
+ThreadBase::MetadataUpdate RecordThread::updateMetadata_l()
{
if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
return {}; // nothing to do
}
StreamInHalInterface::SinkMetadata metadata;
auto backInserter = std::back_inserter(metadata.tracks);
- for (const sp<RecordTrack> &track : mActiveTracks) {
+ for (const sp<IAfRecordTrack>& track : mActiveTracks) {
track->copyMetadataTo(backInserter);
}
mInput->stream->updateSinkMetadata(metadata);
@@ -9027,10 +9161,10 @@
}
// destroyTrack_l() must be called with ThreadBase::mLock held
-void AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track)
+void RecordThread::destroyTrack_l(const sp<IAfRecordTrack>& track)
{
track->terminate();
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
// active tracks are removed by threadLoop()
if (mActiveTracks.indexOf(track) < 0) {
@@ -9038,7 +9172,7 @@
}
}
-void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
+void RecordThread::removeTrack_l(const sp<IAfRecordTrack>& track)
{
String8 result;
track->appendDump(result, false /* active */);
@@ -9052,7 +9186,7 @@
}
}
-void AudioFlinger::RecordThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
+void RecordThread::dumpInternals_l(int fd, const Vector<String16>& /* args */)
{
AudioStreamIn *input = mInput;
audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE;
@@ -9080,7 +9214,7 @@
copy->dump(fd);
}
-void AudioFlinger::RecordThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
+void RecordThread::dumpTracks_l(int fd, const Vector<String16>& /* args */)
{
String8 result;
size_t numtracks = mTracks.size();
@@ -9093,7 +9227,7 @@
result.append(prefix);
mTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (track != 0) {
bool active = mActiveTracks.indexOf(track) >= 0;
if (active) {
@@ -9113,7 +9247,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
- sp<RecordTrack> track = mActiveTracks[i];
+ sp<IAfRecordTrack> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
result.append(prefix);
track->appendDump(result, true /* active */);
@@ -9124,21 +9258,21 @@
write(fd, result.string(), result.size());
}
-void AudioFlinger::RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
+void RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size() ; i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (track != 0 && track->portId() == portId) {
track->setSilenced(silenced);
}
}
}
-void AudioFlinger::RecordThread::ResamplerBufferProvider::reset()
+void ResamplerBufferProvider::reset()
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ const auto threadBase = mRecordTrack->thread().promote();
+ auto* const recordThread = static_cast<RecordThread *>(threadBase->asIAfRecordThread().get());
mRsmpInUnrel = 0;
const int32_t rear = recordThread->mRsmpInRear;
ssize_t deltaFrames = 0;
@@ -9158,11 +9292,11 @@
mRsmpInFront = audio_utils::safe_sub_overflow(rear, static_cast<int32_t>(deltaFrames));
}
-void AudioFlinger::RecordThread::ResamplerBufferProvider::sync(
+void ResamplerBufferProvider::sync(
size_t *framesAvailable, bool *hasOverrun)
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ const auto threadBase = mRecordTrack->thread().promote();
+ auto* const recordThread = static_cast<RecordThread *>(threadBase->asIAfRecordThread().get());
const int32_t rear = recordThread->mRsmpInRear;
const int32_t front = mRsmpInFront;
const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
@@ -9192,16 +9326,16 @@
}
// AudioBufferProvider interface
-status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
+status_t ResamplerBufferProvider::getNextBuffer(
AudioBufferProvider::Buffer* buffer)
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
+ const auto threadBase = mRecordTrack->thread().promote();
if (threadBase == 0) {
buffer->frameCount = 0;
buffer->raw = NULL;
return NOT_ENOUGH_DATA;
}
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ auto* const recordThread = static_cast<RecordThread *>(threadBase->asIAfRecordThread().get());
int32_t rear = recordThread->mRsmpInRear;
int32_t front = mRsmpInFront;
ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
@@ -9235,7 +9369,7 @@
}
// AudioBufferProvider interface
-void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer(
+void ResamplerBufferProvider::releaseBuffer(
AudioBufferProvider::Buffer* buffer)
{
int32_t stepCount = static_cast<int32_t>(buffer->frameCount);
@@ -9249,18 +9383,18 @@
buffer->frameCount = 0;
}
-void AudioFlinger::RecordThread::checkBtNrec()
+void RecordThread::checkBtNrec()
{
Mutex::Autolock _l(mLock);
checkBtNrec_l();
}
-void AudioFlinger::RecordThread::checkBtNrec_l()
+void RecordThread::checkBtNrec_l()
{
// disable AEC and NS if the device is a BT SCO headset supporting those
// pre processings
bool suspend = audio_is_bluetooth_sco_device(inDeviceType()) &&
- mAudioFlinger->btNrecIsOff();
+ mAfThreadCallback->btNrecIsOff();
if (mBtNrecSuspended.exchange(suspend) != suspend) {
for (size_t i = 0; i < mEffectChains.size(); i++) {
setEffectSuspended_l(FX_IID_AEC, suspend, mEffectChains[i]->sessionId());
@@ -9270,7 +9404,7 @@
}
-bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValuePair,
+bool RecordThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
bool reconfig = false;
@@ -9358,7 +9492,7 @@
return reconfig;
}
-String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
+String8 RecordThread::getParameters(const String8& keys)
{
Mutex::Autolock _l(mLock);
if (initCheck() == NO_ERROR) {
@@ -9370,7 +9504,7 @@
return {};
}
-void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void RecordThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId) {
sp<AudioIoDescriptor> desc;
switch (event) {
@@ -9388,10 +9522,10 @@
desc = sp<AudioIoDescriptor>::make(mId);
break;
}
- mAudioFlinger->ioConfigChanged(event, desc, pid);
+ mAfThreadCallback->ioConfigChanged(event, desc, pid);
}
-void AudioFlinger::RecordThread::readInputParameters_l()
+void RecordThread::readInputParameters_l()
{
status_t result = mInput->stream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat);
LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result);
@@ -9425,7 +9559,7 @@
audio_input_flags_t flags = mInput->flags;
mediametrics::LogItem item(mThreadMetrics.getMetricsId());
item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
- .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+ .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_FLAGS, toString(flags).c_str())
.set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
@@ -9434,7 +9568,7 @@
.record();
}
-uint32_t AudioFlinger::RecordThread::getInputFramesLost()
+uint32_t RecordThread::getInputFramesLost() const
{
Mutex::Autolock _l(mLock);
uint32_t result;
@@ -9444,12 +9578,12 @@
return 0;
}
-KeyedVector<audio_session_t, bool> AudioFlinger::RecordThread::sessionIds() const
+KeyedVector<audio_session_t, bool> RecordThread::sessionIds() const
{
KeyedVector<audio_session_t, bool> ids;
Mutex::Autolock _l(mLock);
for (size_t j = 0; j < mTracks.size(); ++j) {
- sp<RecordThread::RecordTrack> track = mTracks[j];
+ sp<IAfRecordTrack> track = mTracks[j];
audio_session_t sessionId = track->sessionId();
if (ids.indexOfKey(sessionId) < 0) {
ids.add(sessionId, true);
@@ -9458,7 +9592,7 @@
return ids;
}
-AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput()
+AudioStreamIn* RecordThread::clearInput()
{
Mutex::Autolock _l(mLock);
AudioStreamIn *input = mInput;
@@ -9467,7 +9601,7 @@
}
// this method must always be called either with ThreadBase mLock held or inside the thread loop
-sp<StreamHalInterface> AudioFlinger::RecordThread::stream() const
+sp<StreamHalInterface> RecordThread::stream() const
{
if (mInput == NULL) {
return NULL;
@@ -9475,7 +9609,7 @@
return mInput->stream;
}
-status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
+status_t RecordThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
{
ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
chain->setThread(this);
@@ -9493,7 +9627,7 @@
return NO_ERROR;
}
-size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
+size_t RecordThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
{
ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
@@ -9506,7 +9640,7 @@
return mEffectChains.size();
}
-status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch *patch,
+status_t RecordThread::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle)
{
status_t status = NO_ERROR;
@@ -9563,7 +9697,7 @@
return status;
}
-status_t AudioFlinger::RecordThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
+status_t RecordThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
status_t status = NO_ERROR;
@@ -9582,7 +9716,7 @@
return status;
}
-void AudioFlinger::RecordThread::updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
+void RecordThread::updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
{
Mutex::Autolock _l(mLock);
mOutDevices = outDevices;
@@ -9592,7 +9726,7 @@
}
}
-int32_t AudioFlinger::RecordThread::getOldestFront_l()
+int32_t RecordThread::getOldestFront_l()
{
if (mTracks.size() == 0) {
return mRsmpInRear;
@@ -9600,7 +9734,7 @@
int32_t oldestFront = mRsmpInRear;
int32_t maxFilled = 0;
for (size_t i = 0; i < mTracks.size(); i++) {
- int32_t front = mTracks[i]->mResamplerBufferProvider->getFront();
+ int32_t front = mTracks[i]->resamplerBufferProvider()->getFront();
int32_t filled;
(void)__builtin_sub_overflow(mRsmpInRear, front, &filled);
if (filled > maxFilled) {
@@ -9614,19 +9748,19 @@
return oldestFront;
}
-void AudioFlinger::RecordThread::updateFronts_l(int32_t offset)
+void RecordThread::updateFronts_l(int32_t offset)
{
if (offset == 0) {
return;
}
for (size_t i = 0; i < mTracks.size(); i++) {
- int32_t front = mTracks[i]->mResamplerBufferProvider->getFront();
+ int32_t front = mTracks[i]->resamplerBufferProvider()->getFront();
front = audio_utils::safe_sub_overflow(front, offset);
- mTracks[i]->mResamplerBufferProvider->setFront(front);
+ mTracks[i]->resamplerBufferProvider()->setFront(front);
}
}
-void AudioFlinger::RecordThread::resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs)
+void RecordThread::resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs)
{
// This is the formula for calculating the temporary buffer size.
// With 7 HAL buffers, we can guarantee ability to down-sample the input by ratio of 6:1 to
@@ -9650,7 +9784,7 @@
mRsmpInRear = 0;
ALOG_ASSERT(maxSharedAudioHistoryMs >= 0
- && maxSharedAudioHistoryMs <= AudioFlinger::kMaxSharedAudioHistoryMs,
+ && maxSharedAudioHistoryMs <= kMaxSharedAudioHistoryMs,
"resizeInputBuffer_l() called with invalid max shared history %d",
maxSharedAudioHistoryMs);
if (maxSharedAudioHistoryMs != 0) {
@@ -9719,7 +9853,7 @@
mRsmpInBuffer = rsmpInBuffer;
}
-void AudioFlinger::RecordThread::addPatchTrack(const sp<PatchRecord>& record)
+void RecordThread::addPatchTrack(const sp<IAfPatchRecord>& record)
{
Mutex::Autolock _l(mLock);
mTracks.add(record);
@@ -9728,7 +9862,7 @@
}
}
-void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
+void RecordThread::deletePatchTrack(const sp<IAfPatchRecord>& record)
{
Mutex::Autolock _l(mLock);
if (mSource == record->getSource()) {
@@ -9737,7 +9871,7 @@
destroyTrack_l(record);
}
-void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config)
+void RecordThread::toAudioPortConfig(struct audio_port_config* config)
{
ThreadBase::toAudioPortConfig(config);
config->role = AUDIO_PORT_ROLE_SINK;
@@ -9753,59 +9887,88 @@
// Mmap
// ----------------------------------------------------------------------------
-AudioFlinger::MmapThreadHandle::MmapThreadHandle(const sp<MmapThread>& thread)
+// Mmap stream control interface implementation. Each MmapThreadHandle controls one
+// MmapPlaybackThread or MmapCaptureThread instance.
+class MmapThreadHandle : public MmapStreamInterface {
+public:
+ explicit MmapThreadHandle(const sp<IAfMmapThread>& thread);
+ ~MmapThreadHandle() override;
+
+ // MmapStreamInterface virtuals
+ status_t createMmapBuffer(int32_t minSizeFrames,
+ struct audio_mmap_buffer_info* info) final;
+ status_t getMmapPosition(struct audio_mmap_position* position) final;
+ status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) final;
+ status_t start(const AudioClient& client,
+ const audio_attributes_t* attr, audio_port_handle_t* handle) final;
+ status_t stop(audio_port_handle_t handle) final;
+ status_t standby() final;
+ status_t reportData(const void* buffer, size_t frameCount) final;
+private:
+ const sp<IAfMmapThread> mThread;
+};
+
+/* static */
+sp<MmapStreamInterface> IAfMmapThread::createMmapStreamInterfaceAdapter(
+ const sp<IAfMmapThread>& mmapThread) {
+ return sp<MmapThreadHandle>::make(mmapThread);
+}
+
+MmapThreadHandle::MmapThreadHandle(const sp<IAfMmapThread>& thread)
: mThread(thread)
{
assert(thread != 0); // thread must start non-null and stay non-null
}
-AudioFlinger::MmapThreadHandle::~MmapThreadHandle()
+// MmapStreamInterface could be directly implemented by MmapThread excepting this
+// special handling on adapter dtor.
+MmapThreadHandle::~MmapThreadHandle()
{
mThread->disconnect();
}
-status_t AudioFlinger::MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames,
+status_t MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info)
{
return mThread->createMmapBuffer(minSizeFrames, info);
}
-status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_position *position)
+status_t MmapThreadHandle::getMmapPosition(struct audio_mmap_position* position)
{
return mThread->getMmapPosition(position);
}
-status_t AudioFlinger::MmapThreadHandle::getExternalPosition(uint64_t *position,
+status_t MmapThreadHandle::getExternalPosition(uint64_t* position,
int64_t *timeNanos) {
return mThread->getExternalPosition(position, timeNanos);
}
-status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
+status_t MmapThreadHandle::start(const AudioClient& client,
const audio_attributes_t *attr, audio_port_handle_t *handle)
-
{
return mThread->start(client, attr, handle);
}
-status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle)
+status_t MmapThreadHandle::stop(audio_port_handle_t handle)
{
return mThread->stop(handle);
}
-status_t AudioFlinger::MmapThreadHandle::standby()
+status_t MmapThreadHandle::standby()
{
return mThread->standby();
}
-status_t AudioFlinger::MmapThreadHandle::reportData(const void* buffer, size_t frameCount) {
+status_t MmapThreadHandle::reportData(const void* buffer, size_t frameCount)
+{
return mThread->reportData(buffer, frameCount);
}
-AudioFlinger::MmapThread::MmapThread(
- const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+MmapThread::MmapThread(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, const sp<StreamHalInterface>& stream, bool systemReady, bool isOut)
- : ThreadBase(audioFlinger, id, (isOut ? MMAP_PLAYBACK : MMAP_CAPTURE), systemReady, isOut),
+ : ThreadBase(afThreadCallback, id, (isOut ? MMAP_PLAYBACK : MMAP_CAPTURE), systemReady, isOut),
mSessionId(AUDIO_SESSION_NONE),
mPortId(AUDIO_PORT_HANDLE_NONE),
mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
@@ -9817,25 +9980,21 @@
readHalParameters_l();
}
-AudioFlinger::MmapThread::~MmapThread()
-{
-}
-
-void AudioFlinger::MmapThread::onFirstRef()
+void MmapThread::onFirstRef()
{
run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}
-void AudioFlinger::MmapThread::disconnect()
+void MmapThread::disconnect()
{
- ActiveTracks<MmapTrack> activeTracks;
+ ActiveTracks<IAfMmapTrack> activeTracks;
{
Mutex::Autolock _l(mLock);
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
activeTracks.add(t);
}
}
- for (const sp<MmapTrack> &t : activeTracks) {
+ for (const sp<IAfMmapTrack>& t : activeTracks) {
stop(t->portId());
}
// This will decrement references and may cause the destruction of this thread.
@@ -9847,7 +10006,7 @@
}
-void AudioFlinger::MmapThread::configure(const audio_attributes_t *attr,
+void MmapThread::configure(const audio_attributes_t* attr,
audio_stream_type_t streamType __unused,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
@@ -9861,7 +10020,7 @@
mPortId = portId;
}
-status_t AudioFlinger::MmapThread::createMmapBuffer(int32_t minSizeFrames,
+status_t MmapThread::createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info)
{
if (mHalStream == 0) {
@@ -9871,7 +10030,7 @@
return mHalStream->createMmapBuffer(minSizeFrames, info);
}
-status_t AudioFlinger::MmapThread::getMmapPosition(struct audio_mmap_position *position)
+status_t MmapThread::getMmapPosition(struct audio_mmap_position* position) const
{
if (mHalStream == 0) {
return NO_INIT;
@@ -9879,7 +10038,7 @@
return mHalStream->getMmapPosition(position);
}
-status_t AudioFlinger::MmapThread::exitStandby_l()
+status_t MmapThread::exitStandby_l()
{
// The HAL must receive track metadata before starting the stream
updateMetadata_l();
@@ -9896,7 +10055,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::MmapThread::start(const AudioClient& client,
+status_t MmapThread::start(const AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *handle)
{
@@ -9917,7 +10076,7 @@
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
audio_io_handle_t io = mId;
- AttributionSourceState adjAttributionSource = AudioFlinger::checkAttributionSourcePackage(
+ const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage(
client.attributionSource);
if (isOutput()) {
@@ -10000,7 +10159,8 @@
}
// Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
- sp<MmapTrack> track = new MmapTrack(this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
+ sp<IAfMmapTrack> track = IAfMmapTrack::create(
+ this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
mChannelMask, mSessionId, isOutput(),
client.attributionSource,
IPCThreadState::self()->getCallingPid(), portId);
@@ -10012,7 +10172,7 @@
// force volume update when a new track is added
mHalVolFloat = -1.0f;
} else if (!track->isSilenced_l()) {
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
if (t->isSilenced_l()
&& t->uid() != static_cast<uid_t>(client.attributionSource.uid)) {
t->invalidate();
@@ -10042,7 +10202,7 @@
return ret;
}
-status_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle)
+status_t MmapThread::stop(audio_port_handle_t handle)
{
ALOGV("%s handle %d", __FUNCTION__, handle);
@@ -10057,8 +10217,8 @@
Mutex::Autolock _l(mLock);
- sp<MmapTrack> track;
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ sp<IAfMmapTrack> track;
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
if (handle == t->portId()) {
track = t;
break;
@@ -10096,7 +10256,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::MmapThread::standby()
+status_t MmapThread::standby()
{
ALOGV("%s", __FUNCTION__);
@@ -10116,12 +10276,12 @@
return NO_ERROR;
}
-status_t AudioFlinger::MmapThread::reportData(const void* /*buffer*/, size_t /*frameCount*/) {
+status_t MmapThread::reportData(const void* /*buffer*/, size_t /*frameCount*/) {
// This is a stub implementation. The MmapPlaybackThread overrides this function.
return INVALID_OPERATION;
}
-void AudioFlinger::MmapThread::readHalParameters_l()
+void MmapThread::readHalParameters_l()
{
status_t result = mHalStream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat);
LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result);
@@ -10138,7 +10298,7 @@
// TODO: make a readHalParameters call?
mediametrics::LogItem item(mThreadMetrics.getMetricsId());
item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
- .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
+ .set(AMEDIAMETRICS_PROP_ENCODING, IAfThreadBase::formatToString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
.set(AMEDIAMETRICS_PROP_CHANNELCOUNT, (int32_t)mChannelCount)
@@ -10151,13 +10311,13 @@
(int32_t)mHapticChannelCount)
*/
.set(AMEDIAMETRICS_PROP_PREFIX_HAL AMEDIAMETRICS_PROP_ENCODING,
- formatToString(mHALFormat).c_str())
+ IAfThreadBase::formatToString(mHALFormat).c_str())
.set(AMEDIAMETRICS_PROP_PREFIX_HAL AMEDIAMETRICS_PROP_FRAMECOUNT,
(int32_t)mFrameCount) // sic - added HAL
.record();
}
-bool AudioFlinger::MmapThread::threadLoop()
+bool MmapThread::threadLoop()
{
checkSilentMode_l();
@@ -10228,7 +10388,7 @@
}
// checkForNewParameter_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::MmapThread::checkForNewParameter_l(const String8& keyValuePair,
+bool MmapThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
AudioParameter param = AudioParameter(keyValuePair);
@@ -10246,7 +10406,7 @@
return false;
}
-String8 AudioFlinger::MmapThread::getParameters(const String8& keys)
+String8 MmapThread::getParameters(const String8& keys)
{
Mutex::Autolock _l(mLock);
String8 out_s8;
@@ -10256,7 +10416,7 @@
return {};
}
-void AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
+void MmapThread::ioConfigChanged(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId __unused) {
sp<AudioIoDescriptor> desc;
bool isInput = false;
@@ -10278,10 +10438,10 @@
desc = sp<AudioIoDescriptor>::make(mId);
break;
}
- mAudioFlinger->ioConfigChanged(event, desc, pid);
+ mAfThreadCallback->ioConfigChanged(event, desc, pid);
}
-status_t AudioFlinger::MmapThread::createAudioPatch_l(const struct audio_patch *patch,
+status_t MmapThread::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle)
NO_THREAD_SAFETY_ANALYSIS // elease and re-acquire mLock
{
@@ -10372,7 +10532,7 @@
return status;
}
-status_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
+status_t MmapThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
status_t status = NO_ERROR;
@@ -10394,7 +10554,7 @@
return status;
}
-void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config)
+void MmapThread::toAudioPortConfig(struct audio_port_config* config)
{
ThreadBase::toAudioPortConfig(config);
if (isOutput()) {
@@ -10408,14 +10568,14 @@
}
}
-status_t AudioFlinger::MmapThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
+status_t MmapThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
{
audio_session_t session = chain->sessionId();
ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
// Attach all tracks with same session ID to this chain.
// indicate all active tracks in the chain
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
chain->incTrackCnt();
chain->incActiveTrackCnt();
@@ -10432,7 +10592,7 @@
return NO_ERROR;
}
-size_t AudioFlinger::MmapThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
+size_t MmapThread::removeEffectChain_l(const sp<IAfEffectChain>& chain)
{
audio_session_t session = chain->sessionId();
@@ -10443,7 +10603,7 @@
mEffectChains.removeAt(i);
// detach all active tracks from the chain
// detach all tracks with same session ID from this chain
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
chain->decActiveTrackCnt();
chain->decTrackCnt();
@@ -10455,29 +10615,29 @@
return mEffectChains.size();
}
-void AudioFlinger::MmapThread::threadLoop_standby()
+void MmapThread::threadLoop_standby()
{
mHalStream->standby();
}
-void AudioFlinger::MmapThread::threadLoop_exit()
+void MmapThread::threadLoop_exit()
{
// Do not call callback->onTearDown() because it is redundant for thread exit
// and because it can cause a recursive mutex lock on stop().
}
-status_t AudioFlinger::MmapThread::setSyncEvent(const sp<audioflinger::SyncEvent>& /* event */)
+status_t MmapThread::setSyncEvent(const sp<SyncEvent>& /* event */)
{
return BAD_VALUE;
}
-bool AudioFlinger::MmapThread::isValidSyncEvent(
- const sp<audioflinger::SyncEvent>& /* event */) const
+bool MmapThread::isValidSyncEvent(
+ const sp<SyncEvent>& /* event */) const
{
return false;
}
-status_t AudioFlinger::MmapThread::checkEffectCompatibility_l(
+status_t MmapThread::checkEffectCompatibility_l(
const effect_descriptor_t *desc, audio_session_t sessionId)
{
// No global effect sessions on mmap threads
@@ -10511,11 +10671,11 @@
return NO_ERROR;
}
-void AudioFlinger::MmapThread::checkInvalidTracks_l()
+void MmapThread::checkInvalidTracks_l()
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
sp<MmapStreamCallback> callback;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (track->isInvalid()) {
callback = mCallback.promote();
if (callback == nullptr && mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
@@ -10532,7 +10692,7 @@
}
}
-void AudioFlinger::MmapThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)
+void MmapThread::dumpInternals_l(int fd, const Vector<String16>& /* args */)
{
dprintf(fd, " Attributes: content type %d usage %d source %d\n",
mAttr.content_type, mAttr.usage, mAttr.source);
@@ -10542,7 +10702,7 @@
}
}
-void AudioFlinger::MmapThread::dumpTracks_l(int fd, const Vector<String16>& args __unused)
+void MmapThread::dumpTracks_l(int fd, const Vector<String16>& /* args */)
{
String8 result;
size_t numtracks = mActiveTracks.size();
@@ -10552,7 +10712,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
- sp<MmapTrack> track = mActiveTracks[i];
+ sp<IAfMmapTrack> track = mActiveTracks[i];
result.append(prefix);
track->appendDump(result, true /* active */);
}
@@ -10562,19 +10722,36 @@
write(fd, result.string(), result.size());
}
-AudioFlinger::MmapPlaybackThread::MmapPlaybackThread(
- const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+/* static */
+sp<IAfMmapPlaybackThread> IAfMmapPlaybackThread::create(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+ AudioHwDevice* hwDev, AudioStreamOut* output, bool systemReady) {
+ return sp<MmapPlaybackThread>::make(afThreadCallback, id, hwDev, output, systemReady);
+}
+
+MmapPlaybackThread::MmapPlaybackThread(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, AudioStreamOut *output, bool systemReady)
- : MmapThread(audioFlinger, id, hwDev, output->stream, systemReady, true /* isOut */),
+ : MmapThread(afThreadCallback, id, hwDev, output->stream, systemReady, true /* isOut */),
mStreamType(AUDIO_STREAM_MUSIC),
- mStreamVolume(1.0),
- mStreamMute(false),
mOutput(output)
{
snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id);
mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
- mMasterVolume = audioFlinger->masterVolume_l();
- mMasterMute = audioFlinger->masterMute_l();
+ mMasterVolume = afThreadCallback->masterVolume_l();
+ mMasterMute = afThreadCallback->masterMute_l();
+
+ for (int i = AUDIO_STREAM_MIN; i < AUDIO_STREAM_FOR_POLICY_CNT; ++i) {
+ const audio_stream_type_t stream{static_cast<audio_stream_type_t>(i)};
+ mStreamTypes[stream].volume = 0.0f;
+ mStreamTypes[stream].mute = mAfThreadCallback->streamMute_l(stream);
+ }
+ // Audio patch and call assistant volume are always max
+ mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f;
+ mStreamTypes[AUDIO_STREAM_PATCH].mute = false;
+ mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].volume = 1.0f;
+ mStreamTypes[AUDIO_STREAM_CALL_ASSISTANT].mute = false;
+
if (mAudioHwDev) {
if (mAudioHwDev->canSetMasterVolume()) {
mMasterVolume = 1.0;
@@ -10586,7 +10763,7 @@
}
}
-void AudioFlinger::MmapPlaybackThread::configure(const audio_attributes_t *attr,
+void MmapPlaybackThread::configure(const audio_attributes_t* attr,
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
@@ -10597,7 +10774,7 @@
mStreamType = streamType;
}
-AudioStreamOut* AudioFlinger::MmapPlaybackThread::clearOutput()
+AudioStreamOut* MmapPlaybackThread::clearOutput()
{
Mutex::Autolock _l(mLock);
AudioStreamOut *output = mOutput;
@@ -10605,7 +10782,7 @@
return output;
}
-void AudioFlinger::MmapPlaybackThread::setMasterVolume(float value)
+void MmapPlaybackThread::setMasterVolume(float value)
{
Mutex::Autolock _l(mLock);
// Don't apply master volume in SW if our HAL can do it for us.
@@ -10617,7 +10794,7 @@
}
}
-void AudioFlinger::MmapPlaybackThread::setMasterMute(bool muted)
+void MmapPlaybackThread::setMasterMute(bool muted)
{
Mutex::Autolock _l(mLock);
// Don't apply master mute in SW if our HAL can do it for us.
@@ -10628,49 +10805,46 @@
}
}
-void AudioFlinger::MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
+void MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
Mutex::Autolock _l(mLock);
+ mStreamTypes[stream].volume = value;
if (stream == mStreamType) {
- mStreamVolume = value;
broadcast_l();
}
}
-float AudioFlinger::MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
+float MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
{
Mutex::Autolock _l(mLock);
- if (stream == mStreamType) {
- return mStreamVolume;
- }
- return 0.0f;
+ return mStreamTypes[stream].volume;
}
-void AudioFlinger::MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
+void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
{
Mutex::Autolock _l(mLock);
+ mStreamTypes[stream].mute = muted;
if (stream == mStreamType) {
- mStreamMute= muted;
broadcast_l();
}
}
-void AudioFlinger::MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
+void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
Mutex::Autolock _l(mLock);
if (streamType == mStreamType) {
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
track->invalidate();
}
broadcast_l();
}
}
-void AudioFlinger::MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
+void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
{
Mutex::Autolock _l(mLock);
bool trackMatch = false;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (portIds.find(track->portId()) != portIds.end()) {
track->invalidate();
trackMatch = true;
@@ -10685,19 +10859,18 @@
}
}
-void AudioFlinger::MmapPlaybackThread::processVolume_l()
+void MmapPlaybackThread::processVolume_l()
NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l
{
float volume;
- if (mMasterMute || mStreamMute) {
+ if (mMasterMute || streamMuted_l()) {
volume = 0;
} else {
- volume = mMasterVolume * mStreamVolume;
+ volume = mMasterVolume * streamVolume_l();
}
if (volume != mHalVolFloat) {
-
// Convert volumes from float to 8.24
uint32_t vol = (uint32_t)(volume * (1 << 24));
@@ -10727,12 +10900,12 @@
}
}
}
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
track->setMetadataHasChanged();
- track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
+ track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(),
/*muteState=*/{mMasterMute,
- mStreamVolume == 0.f,
- mStreamMute,
+ streamVolume_l() == 0.f,
+ streamMuted_l(),
// TODO(b/241533526): adjust logic to include mute from AppOps
false /*muteFromPlaybackRestricted*/,
false /*muteFromClientVolume*/,
@@ -10741,13 +10914,13 @@
}
}
-AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapPlaybackThread::updateMetadata_l()
+ThreadBase::MetadataUpdate MmapPlaybackThread::updateMetadata_l()
{
if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
return {}; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
playback_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
@@ -10766,7 +10939,7 @@
return change;
};
-void AudioFlinger::MmapPlaybackThread::checkSilentMode_l()
+void MmapPlaybackThread::checkSilentMode_l()
{
if (!mMasterMute) {
char value[PROPERTY_VALUE_MAX];
@@ -10783,7 +10956,7 @@
}
}
-void AudioFlinger::MmapPlaybackThread::toAudioPortConfig(struct audio_port_config *config)
+void MmapPlaybackThread::toAudioPortConfig(struct audio_port_config* config)
{
MmapThread::toAudioPortConfig(config);
if (mOutput && mOutput->flags != AUDIO_OUTPUT_FLAG_NONE) {
@@ -10792,8 +10965,8 @@
}
}
-status_t AudioFlinger::MmapPlaybackThread::getExternalPosition(uint64_t *position,
- int64_t *timeNanos)
+status_t MmapPlaybackThread::getExternalPosition(uint64_t* position,
+ int64_t* timeNanos) const
{
if (mOutput == nullptr) {
return NO_INIT;
@@ -10806,7 +10979,7 @@
return status;
}
-status_t AudioFlinger::MmapPlaybackThread::reportData(const void* buffer, size_t frameCount) {
+status_t MmapPlaybackThread::reportData(const void* buffer, size_t frameCount) {
// Send to MelProcessor for sound dose measurement.
auto processor = mMelProcessor.load();
if (processor) {
@@ -10817,7 +10990,7 @@
}
// startMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::MmapPlaybackThread::startMelComputation_l(
+void MmapPlaybackThread::startMelComputation_l(
const sp<audio_utils::MelProcessor>& processor)
{
ALOGV("%s: starting mel processor for thread %d", __func__, id());
@@ -10831,7 +11004,7 @@
}
// stopMelComputation_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::MmapPlaybackThread::stopMelComputation_l()
+void MmapPlaybackThread::stopMelComputation_l()
{
ALOGV("%s: pausing mel processor for thread %d", __func__, id());
auto melProcessor = mMelProcessor.load();
@@ -10840,26 +11013,33 @@
}
}
-void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
+void MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
MmapThread::dumpInternals_l(fd, args);
dprintf(fd, " Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
- mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
+ mStreamType, streamVolume_l(), mHalVolFloat, streamMuted_l());
dprintf(fd, " Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute);
}
-AudioFlinger::MmapCaptureThread::MmapCaptureThread(
- const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+/* static */
+sp<IAfMmapCaptureThread> IAfMmapCaptureThread::create(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
+ AudioHwDevice* hwDev, AudioStreamIn* input, bool systemReady) {
+ return sp<MmapCaptureThread>::make(afThreadCallback, id, hwDev, input, systemReady);
+}
+
+MmapCaptureThread::MmapCaptureThread(
+ const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, AudioStreamIn *input, bool systemReady)
- : MmapThread(audioFlinger, id, hwDev, input->stream, systemReady, false /* isOut */),
+ : MmapThread(afThreadCallback, id, hwDev, input->stream, systemReady, false /* isOut */),
mInput(input)
{
snprintf(mThreadName, kThreadNameLength, "AudioMmapIn_%X", id);
mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
}
-status_t AudioFlinger::MmapCaptureThread::exitStandby_l()
+status_t MmapCaptureThread::exitStandby_l()
{
{
// mInput might have been cleared by clearInput()
@@ -10870,7 +11050,7 @@
return MmapThread::exitStandby_l();
}
-AudioFlinger::AudioStreamIn* AudioFlinger::MmapCaptureThread::clearInput()
+AudioStreamIn* MmapCaptureThread::clearInput()
{
Mutex::Autolock _l(mLock);
AudioStreamIn *input = mInput;
@@ -10878,8 +11058,7 @@
return input;
}
-
-void AudioFlinger::MmapCaptureThread::processVolume_l()
+void MmapCaptureThread::processVolume_l()
{
bool changed = false;
bool silenced = false;
@@ -10906,13 +11085,13 @@
}
}
-AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapCaptureThread::updateMetadata_l()
+ThreadBase::MetadataUpdate MmapCaptureThread::updateMetadata_l()
{
if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) {
return {}; // nothing to do
}
StreamInHalInterface::SinkMetadata metadata;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
record_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
@@ -10929,7 +11108,7 @@
return change;
}
-void AudioFlinger::MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
+void MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mActiveTracks.size() ; i++) {
@@ -10941,7 +11120,7 @@
setClientSilencedIfExists_l(portId, silenced);
}
-void AudioFlinger::MmapCaptureThread::toAudioPortConfig(struct audio_port_config *config)
+void MmapCaptureThread::toAudioPortConfig(struct audio_port_config* config)
{
MmapThread::toAudioPortConfig(config);
if (mInput && mInput->flags != AUDIO_INPUT_FLAG_NONE) {
@@ -10950,8 +11129,8 @@
}
}
-status_t AudioFlinger::MmapCaptureThread::getExternalPosition(
- uint64_t *position, int64_t *timeNanos)
+status_t MmapCaptureThread::getExternalPosition(
+ uint64_t* position, int64_t* timeNanos) const
{
if (mInput == nullptr) {
return NO_INIT;
@@ -10961,12 +11140,19 @@
// ----------------------------------------------------------------------------
-AudioFlinger::BitPerfectThread::BitPerfectThread(const sp<AudioFlinger> &audioflinger,
- AudioStreamOut *output, audio_io_handle_t id, bool systemReady)
- : MixerThread(audioflinger, output, id, systemReady, BIT_PERFECT) {}
+/* static */
+sp<IAfPlaybackThread> IAfPlaybackThread::createBitPerfectThread(
+ const sp<IAfThreadCallback>& afThreadCallback,
+ AudioStreamOut* output, audio_io_handle_t id, bool systemReady) {
+ return sp<BitPerfectThread>::make(afThreadCallback, output, id, systemReady);
+}
-AudioFlinger::PlaybackThread::mixer_state AudioFlinger::BitPerfectThread::prepareTracks_l(
- Vector<sp<Track>> *tracksToRemove) {
+BitPerfectThread::BitPerfectThread(const sp<IAfThreadCallback> &afThreadCallback,
+ AudioStreamOut *output, audio_io_handle_t id, bool systemReady)
+ : MixerThread(afThreadCallback, output, id, systemReady, BIT_PERFECT) {}
+
+PlaybackThread::mixer_state BitPerfectThread::prepareTracks_l(
+ Vector<sp<IAfTrack>>* tracksToRemove) {
mixer_state result = MixerThread::prepareTracks_l(tracksToRemove);
// If there is only one active track and it is bit-perfect, enable tee buffer.
float volumeLeft = 1.0f;
@@ -10998,7 +11184,7 @@
return result;
}
-void AudioFlinger::BitPerfectThread::threadLoop_mix() {
+void BitPerfectThread::threadLoop_mix() {
MixerThread::threadLoop_mix();
mHasDataCopiedToSinkBuffer = mIsBitPerfect;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8b420c0..474da8e 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -15,38 +15,43 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
-public: // TODO(b/288339104) extract out of AudioFlinger class
-class ThreadBase : public Thread {
+// ADD_BATTERY_DATA AUDIO_WATCHDOG FAST_THREAD_STATISTICS STATE_QUEUE_DUMP TEE_SINK
+#include "Configuration.h"
+#include "IAfThread.h"
+#include "IAfTrack.h"
+
+#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
+#include <android/os/IPowerManager.h>
+#include <afutils/AudioWatchdog.h>
+#include <afutils/NBAIO_Tee.h>
+#include <audio_utils/Balance.h>
+#include <audio_utils/SimpleLog.h>
+#include <datapath/ThreadMetrics.h>
+#include <fastpath/FastCapture.h>
+#include <fastpath/FastMixer.h>
+#include <mediautils/Synchronization.h>
+#include <mediautils/ThreadSnapshot.h>
+#include <timing/MonotonicFrameCounter.h>
+#include <utils/Log.h>
+
+namespace android {
+
+class AsyncCallbackThread;
+
+class ThreadBase : public virtual IAfThreadBase, public Thread {
public:
-
-#include "TrackBase.h"
-
- enum type_t {
- MIXER, // Thread class is MixerThread
- DIRECT, // Thread class is DirectOutputThread
- DUPLICATING, // Thread class is DuplicatingThread
- RECORD, // Thread class is RecordThread
- OFFLOAD, // Thread class is OffloadThread
- MMAP_PLAYBACK, // Thread class for MMAP playback stream
- MMAP_CAPTURE, // Thread class for MMAP capture stream
- SPATIALIZER, //
- BIT_PERFECT, // Thread class for BitPerfectThread
- // If you add any values here, also update ThreadBase::threadTypeToString()
- };
-
static const char *threadTypeToString(type_t type);
- ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ IAfThreadCallback* afThreadCallback() const final { return mAfThreadCallback.get(); }
+
+ ThreadBase(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
type_t type, bool systemReady, bool isOut);
- virtual ~ThreadBase();
+ ~ThreadBase() override;
- virtual status_t readyToRun();
-
- void clearPowerManager();
+ status_t readyToRun() final;
+ void clearPowerManager() final;
// base for record and playback
enum {
@@ -90,8 +95,6 @@
class ConfigEvent: public RefBase {
public:
- virtual ~ConfigEvent() {}
-
void dump(char *buffer, size_t size) {
snprintf(buffer, size, "Event type: %d\n", mType);
if (mData != nullptr) {
@@ -135,7 +138,6 @@
ConfigEvent(CFG_EVENT_IO) {
mData = new IoConfigEventData(event, pid, portId);
}
- virtual ~IoConfigEvent() {}
};
class PrioConfigEventData : public ConfigEventData {
@@ -160,7 +162,6 @@
ConfigEvent(CFG_EVENT_PRIO, true) {
mData = new PrioConfigEventData(pid, tid, prio, forApp);
}
- virtual ~PrioConfigEvent() {}
};
class SetParameterConfigEventData : public ConfigEventData {
@@ -182,7 +183,6 @@
mData = new SetParameterConfigEventData(keyValuePairs);
mWaitStatus = true;
}
- virtual ~SetParameterConfigEvent() {}
};
class CreateAudioPatchConfigEventData : public ConfigEventData {
@@ -207,7 +207,6 @@
mData = new CreateAudioPatchConfigEventData(patch, handle);
mWaitStatus = true;
}
- virtual ~CreateAudioPatchConfigEvent() {}
};
class ReleaseAudioPatchConfigEventData : public ConfigEventData {
@@ -229,7 +228,6 @@
mData = new ReleaseAudioPatchConfigEventData(handle);
mWaitStatus = true;
}
- virtual ~ReleaseAudioPatchConfigEvent() {}
};
class UpdateOutDevicesConfigEventData : public ConfigEventData {
@@ -250,8 +248,6 @@
ConfigEvent(CFG_EVENT_UPDATE_OUT_DEVICE) {
mData = new UpdateOutDevicesConfigEventData(outDevices);
}
-
- virtual ~UpdateOutDevicesConfigEvent();
};
class ResizeBufferConfigEventData : public ConfigEventData {
@@ -272,8 +268,6 @@
ConfigEvent(CFG_EVENT_RESIZE_BUFFER) {
mData = new ResizeBufferConfigEventData(maxSharedAudioHistoryMs);
}
-
- virtual ~ResizeBufferConfigEvent() {}
};
class CheckOutputStageEffectsEvent : public ConfigEvent {
@@ -281,8 +275,6 @@
CheckOutputStageEffectsEvent() :
ConfigEvent(CFG_EVENT_CHECK_OUTPUT_STAGE_EFFECTS) {
}
-
- virtual ~CheckOutputStageEffectsEvent() {}
};
class HalLatencyModesChangedEvent : public ConfigEvent {
@@ -290,8 +282,6 @@
HalLatencyModesChangedEvent() :
ConfigEvent(CFG_EVENT_HAL_LATENCY_MODES_CHANGED) {
}
-
- virtual ~HalLatencyModesChangedEvent() {}
};
@@ -309,108 +299,87 @@
wp<ThreadBase> mThread;
};
- virtual status_t initCheck() const = 0;
+ type_t type() const final { return mType; }
+ bool isDuplicating() const final { return (mType == DUPLICATING); }
+ audio_io_handle_t id() const final { return mId;}
- // static externally-visible
- type_t type() const { return mType; }
- bool isDuplicating() const { return (mType == DUPLICATING); }
-
- audio_io_handle_t id() const { return mId;}
-
- // dynamic externally-visible
- uint32_t sampleRate() const { return mSampleRate; }
- audio_channel_mask_t channelMask() const { return mChannelMask; }
- virtual audio_channel_mask_t mixerChannelMask() const { return mChannelMask; }
-
- audio_format_t format() const { return mHALFormat; }
- uint32_t channelCount() const { return mChannelCount; }
-
- // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
- // and returns the [normal mix] buffer's frame count.
- virtual size_t frameCount() const = 0;
- virtual audio_channel_mask_t hapticChannelMask() const { return AUDIO_CHANNEL_NONE; }
- virtual uint32_t latency_l() const { return 0; }
- virtual void setVolumeForOutput_l(float left __unused, float right __unused) const {}
+ uint32_t sampleRate() const final { return mSampleRate; }
+ audio_channel_mask_t channelMask() const final { return mChannelMask; }
+ audio_channel_mask_t mixerChannelMask() const override { return mChannelMask; }
+ audio_format_t format() const final { return mHALFormat; }
+ uint32_t channelCount() const final { return mChannelCount; }
+ audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
+ uint32_t hapticChannelCount() const override { return 0; }
+ uint32_t latency_l() const override { return 0; }
+ void setVolumeForOutput_l(float /* left */, float /* right */) const override {}
// Return's the HAL's frame count i.e. fast mixer buffer size.
- size_t frameCountHAL() const { return mFrameCount; }
-
- size_t frameSize() const { return mFrameSize; }
+ size_t frameCountHAL() const final { return mFrameCount; }
+ size_t frameSize() const final { return mFrameSize; }
// Should be "virtual status_t requestExitAndWait()" and override same
// method in Thread, but Thread::requestExitAndWait() is not yet virtual.
- void exit();
- virtual bool checkForNewParameter_l(const String8& keyValuePair,
- status_t& status) = 0;
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys) = 0;
- virtual void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
+ void exit() final;
+ status_t setParameters(const String8& keyValuePairs) final;
+
// sendConfigEvent_l() must be called with ThreadBase::mLock held
// Can temporarily release the lock if waiting for a reply from
// processConfigEvents_l().
- status_t sendConfigEvent_l(sp<ConfigEvent>& event);
- void sendIoConfigEvent(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
- void sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
- void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp);
- void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp);
- status_t sendSetParameterConfigEvent_l(const String8& keyValuePair);
- status_t sendCreateAudioPatchConfigEvent(const struct audio_patch *patch,
- audio_patch_handle_t *handle);
- status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle);
- status_t sendUpdateOutDeviceConfigEvent(
- const DeviceDescriptorBaseVector& outDevices);
- void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs);
- void sendCheckOutputStageEffectsEvent();
- void sendCheckOutputStageEffectsEvent_l();
- void sendHalLatencyModesChangedEvent_l();
+ status_t sendConfigEvent_l(sp<ConfigEvent>& event);
+ void sendIoConfigEvent(audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
+ void sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
+ void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) final;
+ void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp) final;
+ status_t sendSetParameterConfigEvent_l(const String8& keyValuePair) final;
+ status_t sendCreateAudioPatchConfigEvent(const struct audio_patch* patch,
+ audio_patch_handle_t* handle) final;
+ status_t sendReleaseAudioPatchConfigEvent(audio_patch_handle_t handle) final;
+ status_t sendUpdateOutDeviceConfigEvent(
+ const DeviceDescriptorBaseVector& outDevices) final;
+ void sendResizeBufferConfigEvent_l(int32_t maxSharedAudioHistoryMs) final;
+ void sendCheckOutputStageEffectsEvent() final;
+ void sendCheckOutputStageEffectsEvent_l() final;
+ void sendHalLatencyModesChangedEvent_l() final;
- void processConfigEvents_l();
- virtual void setCheckOutputStageEffects() {}
- virtual void cacheParameters_l() = 0;
- virtual status_t createAudioPatch_l(const struct audio_patch *patch,
- audio_patch_handle_t *handle) = 0;
- virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
- virtual void updateOutDevices(const DeviceDescriptorBaseVector& outDevices);
- virtual void toAudioPortConfig(struct audio_port_config *config) = 0;
+ void processConfigEvents_l() final;
+ void setCheckOutputStageEffects() override {}
+ void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override;
+ void toAudioPortConfig(struct audio_port_config* config) override;
+ void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override;
- virtual void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs);
+ // see note at declaration of mStandby, mOutDevice and mInDevice
+ bool inStandby() const override { return mStandby; }
+ const DeviceTypeSet outDeviceTypes() const final {
+ return getAudioDeviceTypes(mOutDeviceTypeAddrs);
+ }
+ audio_devices_t inDeviceType() const final { return mInDeviceTypeAddr.mType; }
+ DeviceTypeSet getDeviceTypes() const final {
+ return isOutput() ? outDeviceTypes() : DeviceTypeSet({inDeviceType()});
+ }
- // see note at declaration of mStandby, mOutDevice and mInDevice
- bool standby() const { return mStandby; }
- const DeviceTypeSet outDeviceTypes() const {
- return getAudioDeviceTypes(mOutDeviceTypeAddrs);
- }
- audio_devices_t inDeviceType() const { return mInDeviceTypeAddr.mType; }
- DeviceTypeSet getDeviceTypes() const {
- return isOutput() ? outDeviceTypes() : DeviceTypeSet({inDeviceType()});
- }
+ const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const final {
+ return mOutDeviceTypeAddrs;
+ }
+ const AudioDeviceTypeAddr& inDeviceTypeAddr() const final {
+ return mInDeviceTypeAddr;
+ }
- const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const {
- return mOutDeviceTypeAddrs;
- }
- const AudioDeviceTypeAddr& inDeviceTypeAddr() const {
- return mInDeviceTypeAddr;
- }
+ bool isOutput() const final { return mIsOut; }
- bool isOutput() const { return mIsOut; }
+ bool isOffloadOrMmap() const final {
+ switch (mType) {
+ case OFFLOAD:
+ case MMAP_PLAYBACK:
+ case MMAP_CAPTURE:
+ return true;
+ default:
+ return false;
+ }
+ }
- bool isOffloadOrMmap() const {
- switch (mType) {
- case OFFLOAD:
- case MMAP_PLAYBACK:
- case MMAP_CAPTURE:
- return true;
- default:
- return false;
- }
- }
-
- virtual sp<StreamHalInterface> stream() const = 0;
-
- sp<IAfEffectHandle> createEffect_l(
+ sp<IAfEffectHandle> createEffect_l(
const sp<Client>& client,
const sp<media::IEffectClient>& effectClient,
int32_t priority,
@@ -420,7 +389,7 @@
status_t *status /*non-NULL*/,
bool pinned,
bool probe,
- bool notifyFramesProcessed);
+ bool notifyFramesProcessed) final;
// return values for hasAudioSession (bit field)
enum effect_state {
@@ -436,47 +405,40 @@
// bit-perfect track
};
- // get effect chain corresponding to session Id.
- sp<IAfEffectChain> getEffectChain(audio_session_t sessionId);
- // same as getEffectChain() but must be called with ThreadBase mutex locked
- sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const;
- std::vector<int> getEffectIds_l(audio_session_t sessionId);
- // add an effect chain to the chain list (mEffectChains)
- virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
- // remove an effect chain from the chain list (mEffectChains)
- virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) = 0;
+ // get effect chain corresponding to session Id.
+ sp<IAfEffectChain> getEffectChain(audio_session_t sessionId) const final;
+ // same as getEffectChain() but must be called with ThreadBase mutex locked
+ sp<IAfEffectChain> getEffectChain_l(audio_session_t sessionId) const final;
+ std::vector<int> getEffectIds_l(audio_session_t sessionId) const final;
+
// lock all effect chains Mutexes. Must be called before releasing the
// ThreadBase mutex before processing the mixer and effects. This guarantees the
// integrity of the chains during the process.
// Also sets the parameter 'effectChains' to current value of mEffectChains.
- void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains);
+ void lockEffectChains_l(Vector<sp<IAfEffectChain>>& effectChains) final;
// unlock effect chains after process
- void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains);
+ void unlockEffectChains(const Vector<sp<IAfEffectChain>>& effectChains) final;
// get a copy of mEffectChains vector
- Vector<sp<IAfEffectChain>> getEffectChains_l() const { return mEffectChains; };
+ Vector<sp<IAfEffectChain>> getEffectChains_l() const final { return mEffectChains; };
// set audio mode to all effect chains
- void setMode(audio_mode_t mode);
+ void setMode(audio_mode_t mode) final;
// get effect module with corresponding ID on specified audio session
- sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId);
- sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId);
+ sp<IAfEffectModule> getEffect(audio_session_t sessionId, int effectId) const final;
+ sp<IAfEffectModule> getEffect_l(audio_session_t sessionId, int effectId) const final;
// add and effect module. Also creates the effect chain is none exists for
// the effects audio session. Only called in a context of moving an effect
// from one thread to another
- status_t addEffect_l(const sp<IAfEffectModule>& effect);
+ status_t addEffect_l(const sp<IAfEffectModule>& effect) final;
// remove and effect module. Also removes the effect chain is this was the last
// effect
- void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false);
+ void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) final;
// disconnect an effect handle from module and destroy module if last handle
- void disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast);
+ void disconnectEffectHandle(IAfEffectHandle* handle, bool unpinIfLast) final;
// detach all tracks connected to an auxiliary effect
- virtual void detachAuxEffect_l(int effectId __unused) {}
- // returns a combination of:
- // - EFFECT_SESSION if effects on this audio session exist in one chain
- // - TRACK_SESSION if tracks on this audio session exist
- // - FAST_SESSION if fast tracks on this audio session exist
- // - SPATIALIZED_SESSION if spatialized tracks on this audio session exist
- virtual uint32_t hasAudioSession_l(audio_session_t sessionId) const = 0;
- uint32_t hasAudioSession(audio_session_t sessionId) const {
+ void detachAuxEffect_l(int /* effectId */) override {}
+ // TODO(b/291317898) - remove hasAudioSession_l below.
+ uint32_t hasAudioSession_l(audio_session_t sessionId) const override = 0;
+ uint32_t hasAudioSession(audio_session_t sessionId) const final {
Mutex::Autolock _l(mLock);
return hasAudioSession_l(sessionId);
}
@@ -488,7 +450,7 @@
result = EFFECT_SESSION;
}
for (size_t i = 0; i < tracks.size(); ++i) {
- const sp<TrackBase>& track = tracks[i];
+ const sp<IAfTrackBase>& track = tracks[i];
if (sessionId == track->sessionId()
&& !track->isInvalid() // not yet removed from tracks.
&& !track->isTerminated()) {
@@ -510,19 +472,17 @@
// the value returned by default implementation is not important as the
// strategy is only meaningful for PlaybackThread which implements this method
- virtual product_strategy_t getStrategyForSession_l(
- audio_session_t sessionId __unused) {
+ product_strategy_t getStrategyForSession_l(
+ audio_session_t /* sessionId */) const override {
return static_cast<product_strategy_t>(0);
}
// check if some effects must be suspended/restored when an effect is enabled
// or disabled
- void checkSuspendOnEffectEnabled(bool enabled,
+ void checkSuspendOnEffectEnabled(bool enabled,
audio_session_t sessionId,
- bool threadLocked);
+ bool threadLocked) final;
- virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
- virtual bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const = 0;
// Return a reference to a per-thread heap which can be used to allocate IMemory
// objects that will be read-only to client processes, read/write to mediaserver,
@@ -530,36 +490,35 @@
// The heap is per-thread rather than common across all threads, because
// clients can't be trusted not to modify the offset of the IMemory they receive.
// If a thread does not have such a heap, this method returns 0.
- virtual sp<MemoryDealer> readOnlyHeap() const { return 0; }
+ sp<MemoryDealer> readOnlyHeap() const override { return nullptr; }
- virtual sp<IMemory> pipeMemory() const { return 0; }
+ sp<IMemory> pipeMemory() const override { return nullptr; }
- void systemReady();
+ void systemReady() final;
- // checkEffectCompatibility_l() must be called with ThreadBase::mLock held
- virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
- audio_session_t sessionId) = 0;
+ void broadcast_l() final;
- void broadcast_l();
+ bool isTimestampCorrectionEnabled() const override { return false; }
- virtual bool isTimestampCorrectionEnabled() const { return false; }
+ bool isMsdDevice() const final { return mIsMsdDevice; }
- bool isMsdDevice() const { return mIsMsdDevice; }
-
- void dump(int fd, const Vector<String16>& args);
+ void dump(int fd, const Vector<String16>& args) override;
// deliver stats to mediametrics.
- void sendStatistics(bool force);
+ void sendStatistics(bool force) final;
+ Mutex& mutex() const final {
+ return mLock;
+ }
mutable Mutex mLock;
- void onEffectEnable(const sp<IAfEffectModule>& effect);
- void onEffectDisable();
+ void onEffectEnable(const sp<IAfEffectModule>& effect) final;
+ void onEffectDisable() final;
// invalidateTracksForAudioSession_l must be called with holding mLock.
- virtual void invalidateTracksForAudioSession_l(audio_session_t sessionId __unused) const { }
+ void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override {}
// Invalidate all the tracks with the given audio session.
- void invalidateTracksForAudioSession(audio_session_t sessionId) const {
+ void invalidateTracksForAudioSession(audio_session_t sessionId) const final {
Mutex::Autolock _l(mLock);
invalidateTracksForAudioSession_l(sessionId);
}
@@ -568,17 +527,15 @@
void invalidateTracksForAudioSession_l(audio_session_t sessionId,
const T& tracks) const {
for (size_t i = 0; i < tracks.size(); ++i) {
- const sp<TrackBase>& track = tracks[i];
+ const sp<IAfTrackBase>& track = tracks[i];
if (sessionId == track->sessionId()) {
track->invalidate();
}
}
}
- virtual bool isStreamInitialized() = 0;
-
- virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor);
- virtual void stopMelComputation_l();
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
+ void stopMelComputation_l() override;
protected:
@@ -602,7 +559,7 @@
// occurs when all suspend requests are cancelled.
void setEffectSuspended_l(const effect_uuid_t *type,
bool suspend,
- audio_session_t sessionId);
+ audio_session_t sessionId) final;
// updated mSuspendedSessions when an effect is suspended or restored
void updateSuspendedSessions_l(const effect_uuid_t *type,
bool suspend,
@@ -629,7 +586,7 @@
return INVALID_OPERATION;
}
public:
-// TODO(b/288339104) organize with publics
+// TODO(b/291317898) organize with publics
product_strategy_t getStrategyForStream(audio_stream_type_t stream) const;
protected:
@@ -639,15 +596,12 @@
{ }
virtual void dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
-
- friend class AudioFlinger; // for mEffectChains and mAudioManager
-
const type_t mType;
// Used by parameters, config events, addTrack_l, exit
Condition mWaitWorkCV;
- const sp<AudioFlinger> mAudioFlinger;
+ const sp<IAfThreadCallback> mAfThreadCallback;
ThreadMetrics mThreadMetrics;
const bool mIsOut;
@@ -784,7 +738,7 @@
bool isEmpty() const {
return mActiveTracks.isEmpty();
}
- ssize_t indexOf(const sp<T>& item) {
+ ssize_t indexOf(const sp<T>& item) const {
return mActiveTracks.indexOf(item);
}
sp<T> operator[](size_t index) const {
@@ -845,35 +799,14 @@
void dumpEffectChains_l(int fd, const Vector<String16>& args);
};
-class VolumeInterface {
- public:
-
- virtual ~VolumeInterface() {}
-
- virtual void setMasterVolume(float value) = 0;
- virtual void setMasterMute(bool muted) = 0;
- virtual void setStreamVolume(audio_stream_type_t stream, float value) = 0;
- virtual void setStreamMute(audio_stream_type_t stream, bool muted) = 0;
- virtual float streamVolume(audio_stream_type_t stream) const = 0;
-
-};
-
// --- PlaybackThread ---
-class PlaybackThread : public ThreadBase, public StreamOutHalInterfaceCallback,
- public VolumeInterface, public StreamOutHalInterfaceEventCallback {
+class PlaybackThread : public ThreadBase, public virtual IAfPlaybackThread,
+ public StreamOutHalInterfaceCallback,
+ public virtual VolumeInterface, public StreamOutHalInterfaceEventCallback {
public:
-
-#include "PlaybackTracks.h"
-
- enum mixer_state {
- MIXER_IDLE, // no active tracks
- MIXER_TRACKS_ENABLED, // at least one active track, but no track has any data ready
- MIXER_TRACKS_READY, // at least one active track, and at least one track has data
- MIXER_DRAIN_TRACK, // drain currently playing track
- MIXER_DRAIN_ALL, // fully drain the hardware
- // standby mode does not have an enum value
- // suspend by audio policy manager is orthogonal to mixer state
- };
+ sp<IAfPlaybackThread> asIAfPlaybackThread() final {
+ return sp<IAfPlaybackThread>::fromExisting(this);
+ }
// retry count before removing active track in case of underrun on offloaded thread:
// we need to make sure that AudioTrack client has enough time to send large buffers
@@ -881,7 +814,6 @@
// handled for offloaded tracks
static const int8_t kMaxTrackRetriesOffload = 20;
static const int8_t kMaxTrackStartupRetriesOffload = 100;
- static const int8_t kMaxTrackStopRetriesOffload = 2;
static constexpr uint32_t kMaxTracksPerUid = 40;
static constexpr size_t kMaxTracks = 256;
@@ -891,19 +823,23 @@
// for initial conditions or large delays.
static const nsecs_t kMaxNextBufferDelayNs = 100000000;
- PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ PlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
audio_io_handle_t id, type_t type, bool systemReady,
audio_config_base_t *mixerConfig = nullptr);
- virtual ~PlaybackThread();
+ ~PlaybackThread() override;
// Thread virtuals
- virtual bool threadLoop();
+ bool threadLoop() final;
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() override;
- virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
- audio_session_t sessionId);
+ status_t checkEffectCompatibility_l(
+ const effect_descriptor_t* desc, audio_session_t sessionId) final;
+
+ void addOutputTrack_l(const sp<IAfTrack>& track) final {
+ mTracks.add(track);
+ }
protected:
// Code snippets that were lifted up out of threadLoop()
@@ -913,14 +849,14 @@
virtual void threadLoop_drain();
virtual void threadLoop_standby();
virtual void threadLoop_exit();
- virtual void threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
+ virtual void threadLoop_removeTracks(const Vector<sp<IAfTrack>>& tracksToRemove);
// prepareTracks_l reads and writes mActiveTracks, and returns
// the pending set of tracks to remove via Vector 'tracksToRemove'. The caller
// is responsible for clearing or destroying this Vector later on, when it
// is safe to do so. That will drop the final ref count and destroy the tracks.
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove) = 0;
- void removeTracks_l(const Vector< sp<Track> >& tracksToRemove);
+ virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) = 0;
+ void removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove);
status_t handleVoipVolume_l(float *volume);
// StreamOutHalInterfaceCallback implementation
@@ -928,18 +864,21 @@
virtual void onDrainReady();
virtual void onError();
+public: // AsyncCallbackThread
void resetWriteBlocked(uint32_t sequence);
void resetDraining(uint32_t sequence);
+protected:
virtual bool waitingAsyncCallback();
virtual bool waitingAsyncCallback_l();
virtual bool shouldStandby_l();
virtual void onAddNewTrack_l();
+public: // AsyncCallbackThread
void onAsyncError(); // error reported by AsyncCallbackThread
-
+protected:
// StreamHalInterfaceCodecFormatCallback implementation
void onCodecFormatChanged(
- const std::basic_string<uint8_t>& metadataBs) override;
+ const std::basic_string<uint8_t>& metadataBs) final;
// ThreadBase virtuals
virtual void preExit();
@@ -954,29 +893,28 @@
virtual void setHalLatencyMode_l() {}
- void dumpInternals_l(int fd, const Vector<String16>& args) override;
- void dumpTracks_l(int fd, const Vector<String16>& args) override;
+ void dumpInternals_l(int fd, const Vector<String16>& args) override;
+ void dumpTracks_l(int fd, const Vector<String16>& args) final;
public:
- virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
+ status_t initCheck() const final { return mOutput == nullptr ? NO_INIT : NO_ERROR; }
// return estimated latency in milliseconds, as reported by HAL
- uint32_t latency() const;
+ uint32_t latency() const final;
// same, but lock must already be held
- uint32_t latency_l() const override;
+ uint32_t latency_l() const final;
// VolumeInterface
- virtual void setMasterVolume(float value);
- virtual void setMasterBalance(float balance);
- virtual void setMasterMute(bool muted);
- virtual void setStreamVolume(audio_stream_type_t stream, float value);
- virtual void setStreamMute(audio_stream_type_t stream, bool muted);
- virtual float streamVolume(audio_stream_type_t stream) const;
+ void setMasterVolume(float value) final;
+ void setMasterBalance(float balance) override;
+ void setMasterMute(bool muted) final;
+ void setStreamVolume(audio_stream_type_t stream, float value) final;
+ void setStreamMute(audio_stream_type_t stream, bool muted) final;
+ float streamVolume(audio_stream_type_t stream) const final;
+ void setVolumeForOutput_l(float left, float right) const final;
- void setVolumeForOutput_l(float left, float right) const override;
-
- sp<Track> createTrack_l(
+ sp<IAfTrack> createTrack_l(
const sp<Client>& client,
audio_stream_type_t streamType,
const audio_attributes_t& attr,
@@ -997,15 +935,20 @@
audio_port_handle_t portId,
const sp<media::IAudioTrackCallback>& callback,
bool isSpatialized,
- bool isBitPerfect);
+ bool isBitPerfect) final;
- AudioStreamOut* getOutput() const;
- AudioStreamOut* clearOutput();
- virtual sp<StreamHalInterface> stream() const;
+ bool isTrackActive(const sp<IAfTrack>& track) const final {
+ return mActiveTracks.indexOf(track) >= 0;
+ }
+
+ AudioStreamOut* getOutput_l() const final { return mOutput; }
+ AudioStreamOut* getOutput() const final;
+ AudioStreamOut* clearOutput() final;
+ sp<StreamHalInterface> stream() const final;
// a very large number of suspend() will eventually wraparound, but unlikely
- void suspend() { (void) android_atomic_inc(&mSuspended); }
- void restore()
+ void suspend() final { (void) android_atomic_inc(&mSuspended); }
+ void restore() final
{
// if restore() is done without suspend(), get back into
// range so that the next suspend() will operate correctly
@@ -1013,123 +956,127 @@
android_atomic_release_store(0, &mSuspended);
}
}
- bool isSuspended() const
+ bool isSuspended() const final
{ return android_atomic_acquire_load(&mSuspended) > 0; }
- virtual String8 getParameters(const String8& keys);
- virtual void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
- status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
+ String8 getParameters(const String8& keys);
+ void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
+ status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames) const final;
// Consider also removing and passing an explicit mMainBuffer initialization
- // parameter to AF::PlaybackThread::Track::Track().
- float *sinkBuffer() const {
+ // parameter to AF::IAfTrack::Track().
+ float* sinkBuffer() const final {
return reinterpret_cast<float *>(mSinkBuffer); };
- virtual void detachAuxEffect_l(int effectId);
- status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track>& track,
- int EffectId);
- status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track>& track,
- int EffectId);
+ void detachAuxEffect_l(int effectId) final;
- virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain);
- virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain);
- uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+ status_t attachAuxEffect(const sp<IAfTrack>& track, int EffectId) final;
+ status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) final;
+
+ status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final;
+ size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final;
+ uint32_t hasAudioSession_l(audio_session_t sessionId) const final {
return ThreadBase::hasAudioSession_l(sessionId, mTracks);
}
- virtual product_strategy_t getStrategyForSession_l(audio_session_t sessionId);
+ product_strategy_t getStrategyForSession_l(audio_session_t sessionId) const final;
- status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
- bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const override;
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
+ bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
// called with AudioFlinger lock held
- bool invalidateTracks_l(audio_stream_type_t streamType);
- bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds);
- virtual void invalidateTracks(audio_stream_type_t streamType);
+ bool invalidateTracks_l(audio_stream_type_t streamType) final;
+ bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final;
+ void invalidateTracks(audio_stream_type_t streamType) override;
// Invalidate tracks by a set of port ids. The port id will be removed from
// the given set if the corresponding track is found and invalidated.
- virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds);
+ void invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
- virtual size_t frameCount() const { return mNormalFrameCount; }
+ size_t frameCount() const final { return mNormalFrameCount; }
- audio_channel_mask_t mixerChannelMask() const override {
+ audio_channel_mask_t mixerChannelMask() const final {
return mMixerChannelMask;
}
- status_t getTimestamp_l(AudioTimestamp& timestamp);
+ status_t getTimestamp_l(AudioTimestamp& timestamp) final;
- void addPatchTrack(const sp<PatchTrack>& track);
- void deletePatchTrack(const sp<PatchTrack>& track);
+ void addPatchTrack(const sp<IAfPatchTrack>& track) final;
+ void deletePatchTrack(const sp<IAfPatchTrack>& track) final;
- virtual void toAudioPortConfig(struct audio_port_config *config);
+ void toAudioPortConfig(struct audio_port_config* config) final;
// Return the asynchronous signal wait time.
- virtual int64_t computeWaitTimeNs_l() const { return INT64_MAX; }
+ int64_t computeWaitTimeNs_l() const override { return INT64_MAX; }
// returns true if the track is allowed to be added to the thread.
- virtual bool isTrackAllowed_l(
+ bool isTrackAllowed_l(
audio_channel_mask_t channelMask __unused,
audio_format_t format __unused,
audio_session_t sessionId __unused,
- uid_t uid) const {
+ uid_t uid) const override {
return trackCountForUid_l(uid) < PlaybackThread::kMaxTracksPerUid
&& mTracks.size() < PlaybackThread::kMaxTracks;
}
- bool isTimestampCorrectionEnabled() const override {
+ bool isTimestampCorrectionEnabled() const final {
return audio_is_output_devices(mTimestampCorrectedDevice)
&& outDeviceTypes().count(mTimestampCorrectedDevice) != 0;
}
- virtual bool isStreamInitialized() {
+ bool isStreamInitialized() const final {
return !(mOutput == nullptr || mOutput->stream == nullptr);
}
- audio_channel_mask_t hapticChannelMask() const override {
+ audio_channel_mask_t hapticChannelMask() const final {
return mHapticChannelMask;
}
- bool supportsHapticPlayback() const {
+
+ uint32_t hapticChannelCount() const final {
+ return mHapticChannelCount;
+ }
+
+ bool supportsHapticPlayback() const final {
return (mHapticChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE;
}
- void setDownStreamPatch(const struct audio_patch *patch) {
+ void setDownStreamPatch(const struct audio_patch* patch) final {
Mutex::Autolock _l(mLock);
mDownStreamPatch = *patch;
}
- PlaybackThread::Track* getTrackById_l(audio_port_handle_t trackId);
+ IAfTrack* getTrackById_l(audio_port_handle_t trackId) final;
- bool hasMixer() const {
+ bool hasMixer() const final {
return mType == MIXER || mType == DUPLICATING || mType == SPATIALIZER;
}
- virtual status_t setRequestedLatencyMode(
- audio_latency_mode_t mode __unused) { return INVALID_OPERATION; }
+ status_t setRequestedLatencyMode(
+ audio_latency_mode_t /* mode */) override { return INVALID_OPERATION; }
- virtual status_t getSupportedLatencyModes(
- std::vector<audio_latency_mode_t>* modes __unused) {
+ status_t getSupportedLatencyModes(
+ std::vector<audio_latency_mode_t>* /* modes */) override {
return INVALID_OPERATION;
}
- virtual status_t setBluetoothVariableLatencyEnabled(bool enabled __unused) {
+ status_t setBluetoothVariableLatencyEnabled(bool /* enabled */) override{
return INVALID_OPERATION;
}
- void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
- void stopMelComputation_l() override;
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
+ void stopMelComputation_l() override;
- void setStandby() {
+ void setStandby() final {
Mutex::Autolock _l(mLock);
setStandby_l();
}
- void setStandby_l() {
+ void setStandby_l() final {
mStandby = true;
mHalStarted = false;
mKernelPositionOnStandby =
mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
}
- bool waitForHalStart() {
+ bool waitForHalStart() final {
Mutex::Autolock _l(mLock);
static const nsecs_t kWaitHalTimeoutNs = seconds(2);
nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
@@ -1244,7 +1191,6 @@
audio_channel_mask_t mMixerChannelMask = AUDIO_CHANNEL_NONE;
-private:
// mMasterMute is in both PlaybackThread and in AudioFlinger. When a
// PlaybackThread needs to find out if master-muted, it checks it's local
// copy rather than the one in AudioFlinger. This optimization saves a lock.
@@ -1258,8 +1204,7 @@
: mTimestampVerifier.DISCONTINUITY_MODE_CONTINUOUS;
}
-protected:
- ActiveTracks<Track> mActiveTracks;
+ ActiveTracks<IAfTrack> mActiveTracks;
// Time to sleep between cycles when:
virtual uint32_t activeSleepTimeUs() const; // mixer state MIXER_TRACKS_ENABLED
@@ -1269,7 +1214,7 @@
// No sleep in standby mode; waits on a condition
// Code snippets that are temporarily lifted up out of threadLoop() until the merge
- void checkSilentMode_l();
+ virtual void checkSilentMode_l() final; // consider unification with MMapThread
// Non-trivial for DUPLICATING only
virtual void saveOutputTracks() { }
@@ -1287,26 +1232,23 @@
audio_patch_handle_t *handle);
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
- bool usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL)
+ bool usesHwAvSync() const final { return mType == DIRECT && mOutput != nullptr
&& mHwSupportsPause
&& (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
uint32_t trackCountForUid_l(uid_t uid) const;
void invalidateTracksForAudioSession_l(
- audio_session_t sessionId) const override {
+ audio_session_t sessionId) const override {
ThreadBase::invalidateTracksForAudioSession_l(sessionId, mTracks);
}
-private:
-
- friend class AudioFlinger; // for numerous
-
DISALLOW_COPY_AND_ASSIGN(PlaybackThread);
- status_t addTrack_l(const sp<Track>& track);
- bool destroyTrack_l(const sp<Track>& track);
- void removeTrack_l(const sp<Track>& track);
+ status_t addTrack_l(const sp<IAfTrack>& track) final;
+ bool destroyTrack_l(const sp<IAfTrack>& track) final;
+
+ void removeTrack_l(const sp<IAfTrack>& track);
void readOutputParameters_l();
MetadataUpdate updateMetadata_l() final;
@@ -1364,9 +1306,10 @@
SortedVector<sp<T>> mTracks; // wrapped SortedVector.
};
- Tracks<Track> mTracks;
+ Tracks<IAfTrack> mTracks;
stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
+
AudioStreamOut *mOutput;
float mMasterVolume;
@@ -1421,19 +1364,20 @@
// Bit 0 is reset by the async callback thread calling resetDraining(). Out of sequence
// callbacks are ignored.
uint32_t mDrainSequence;
+
sp<AsyncCallbackThread> mCallbackThread;
Mutex mAudioTrackCbLock;
// Record of IAudioTrackCallback
- std::map<sp<Track>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;
+ std::map<sp<IAfTrack>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;
-private:
// The HAL output sink is treated as non-blocking, but current implementation is blocking
sp<NBAIO_Sink> mOutputSink;
// If a fast mixer is present, the blocking pipe sink, otherwise clear
sp<NBAIO_Sink> mPipeSink;
// The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink
sp<NBAIO_Sink> mNormalSink;
+
uint32_t mScreenState; // cached copy of gScreenState
// TODO: add comment and adjust size as needed
static const size_t kFastMixerLogSize = 8 * 1024;
@@ -1451,14 +1395,14 @@
int64_t mKernelPositionOnStandby = 0;
public:
- virtual bool hasFastMixer() const = 0;
- virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex __unused) const
- { FastTrackUnderruns dummy; return dummy; }
- const std::atomic<int64_t>& framesWritten() const { return mFramesWritten; }
+ FastTrackUnderruns getFastTrackUnderruns(size_t /* fastIndex */) const override
+ { return {}; }
+ const std::atomic<int64_t>& framesWritten() const final { return mFramesWritten; }
protected:
// accessed by both binder threads and within threadLoop(), lock on mutex needed
- unsigned mFastTrackAvailMask; // bit i set if fast track [i] is available
+ uint32_t& fastTrackAvailMask_l() final { return mFastTrackAvailMask; }
+ uint32_t mFastTrackAvailMask; // bit i set if fast track [i] is available
bool mHwSupportsPause;
bool mHwPaused;
bool mFlushPending;
@@ -1509,36 +1453,35 @@
class MixerThread : public PlaybackThread,
public StreamOutHalInterfaceLatencyModeCallback {
public:
- MixerThread(const sp<AudioFlinger>& audioFlinger,
+ MixerThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output,
audio_io_handle_t id,
bool systemReady,
type_t type = MIXER,
audio_config_base_t *mixerConfig = nullptr);
- virtual ~MixerThread();
+ ~MixerThread() override;
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() override;
// StreamOutHalInterfaceLatencyModeCallback
void onRecommendedLatencyModeChanged(
- std::vector<audio_latency_mode_t> modes) override;
+ std::vector<audio_latency_mode_t> modes) final;
// Thread virtuals
- virtual bool checkForNewParameter_l(const String8& keyValuePair,
- status_t& status);
+ bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final;
- virtual bool isTrackAllowed_l(
+ bool isTrackAllowed_l(
audio_channel_mask_t channelMask, audio_format_t format,
- audio_session_t sessionId, uid_t uid) const override;
+ audio_session_t sessionId, uid_t uid) const final;
protected:
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
- virtual uint32_t idleSleepTimeUs() const;
- virtual uint32_t suspendSleepTimeUs() const;
- virtual void cacheParameters_l();
+ mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) override;
+ uint32_t idleSleepTimeUs() const final;
+ uint32_t suspendSleepTimeUs() const final;
+ void cacheParameters_l() override;
- virtual void acquireWakeLock_l() {
+ void acquireWakeLock_l() final {
PlaybackThread::acquireWakeLock_l();
if (hasFastMixer()) {
mFastMixer->setBoottimeOffset(
@@ -1549,15 +1492,15 @@
void dumpInternals_l(int fd, const Vector<String16>& args) override;
// threadLoop snippets
- virtual ssize_t threadLoop_write();
- virtual void threadLoop_standby();
- virtual void threadLoop_mix();
- virtual void threadLoop_sleepTime();
- virtual uint32_t correctLatency_l(uint32_t latency) const;
+ ssize_t threadLoop_write() override;
+ void threadLoop_standby() override;
+ void threadLoop_mix() override;
+ void threadLoop_sleepTime() override;
+ uint32_t correctLatency_l(uint32_t latency) const final;
- virtual status_t createAudioPatch_l(const struct audio_patch *patch,
- audio_patch_handle_t *handle);
- virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
+ status_t createAudioPatch_l(
+ const struct audio_patch* patch, audio_patch_handle_t* handle) final;
+ status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final;
AudioMixer* mAudioMixer; // normal mixer
@@ -1633,17 +1576,21 @@
void setHalLatencyMode_l() override;
};
-class DirectOutputThread : public PlaybackThread {
+class DirectOutputThread : public PlaybackThread, public virtual IAfDirectOutputThread {
public:
- DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ sp<IAfDirectOutputThread> asIAfDirectOutputThread() final {
+ return sp<IAfDirectOutputThread>::fromExisting(this);
+ }
+
+ DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
audio_io_handle_t id, bool systemReady,
const audio_offload_info_t& offloadInfo)
- : DirectOutputThread(audioFlinger, output, id, DIRECT, systemReady, offloadInfo) { }
+ : DirectOutputThread(afThreadCallback, output, id, DIRECT, systemReady, offloadInfo) { }
virtual ~DirectOutputThread();
- status_t selectPresentation(int presentationId, int programId);
+ status_t selectPresentation(int presentationId, int programId) final;
// Thread virtuals
@@ -1663,7 +1610,7 @@
void dumpInternals_l(int fd, const Vector<String16>& args) override;
// threadLoop snippets
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
+ virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove);
virtual void threadLoop_mix();
virtual void threadLoop_sleepTime();
virtual void threadLoop_exit();
@@ -1676,16 +1623,16 @@
audioflinger::MonotonicFrameCounter mMonotonicFrameCounter; // for VolumeShaper
bool mVolumeShaperActive = false;
- DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ DirectOutputThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
const audio_offload_info_t& offloadInfo);
- void processVolume_l(Track *track, bool lastTrack);
+ void processVolume_l(IAfTrack *track, bool lastTrack);
bool isTunerStream() const { return (mOffloadInfo.content_id > 0); }
// prepareTracks_l() tells threadLoop_mix() the name of the single active track
- sp<Track> mActiveTrack;
+ sp<IAfTrack> mActiveTrack;
- wp<Track> mPreviousTrack; // used to detect track switch
+ wp<IAfTrack> mPreviousTrack; // used to detect track switch
// This must be initialized for initial condition of mMasterBalance = 0 (disabled).
float mMasterBalanceLeft = 1.f;
@@ -1717,7 +1664,7 @@
class OffloadThread : public DirectOutputThread {
public:
- OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+ OffloadThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut* output,
audio_io_handle_t id, bool systemReady,
const audio_offload_info_t& offloadInfo);
virtual ~OffloadThread() {};
@@ -1725,7 +1672,7 @@
protected:
// threadLoop snippets
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
+ virtual mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove);
virtual void threadLoop_exit();
virtual bool waitingAsyncCallback();
@@ -1743,11 +1690,8 @@
class AsyncCallbackThread : public Thread {
public:
-
explicit AsyncCallbackThread(const wp<PlaybackThread>& playbackThread);
- virtual ~AsyncCallbackThread();
-
// Thread virtuals
virtual bool threadLoop();
@@ -1776,16 +1720,21 @@
bool mAsyncError;
};
-class DuplicatingThread : public MixerThread {
+class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
public:
- DuplicatingThread(const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread,
+ DuplicatingThread(const sp<IAfThreadCallback>& afThreadCallback,
+ IAfPlaybackThread* mainThread,
audio_io_handle_t id, bool systemReady);
- virtual ~DuplicatingThread();
+ ~DuplicatingThread() override;
+
+ sp<IAfDuplicatingThread> asIAfDuplicatingThread() final {
+ return sp<IAfDuplicatingThread>::fromExisting(this);
+ }
// Thread virtuals
- void addOutputTrack(MixerThread* thread);
- void removeOutputTrack(MixerThread* thread);
- uint32_t waitTimeMs() const { return mWaitTimeMs; }
+ void addOutputTrack(IAfPlaybackThread* thread) final;
+ void removeOutputTrack(IAfPlaybackThread* thread) final;
+ uint32_t waitTimeMs() const final { return mWaitTimeMs; }
void sendMetadataToBackend_l(
const StreamOutHalInterface::SourceMetadata& metadata) override;
@@ -1812,8 +1761,8 @@
private:
uint32_t mWaitTimeMs;
- SortedVector < sp<OutputTrack> > outputTracks;
- SortedVector < sp<OutputTrack> > mOutputTracks;
+ SortedVector <sp<IAfOutputTrack>> outputTracks;
+ SortedVector <sp<IAfOutputTrack>> mOutputTracks;
public:
virtual bool hasFastMixer() const { return false; }
status_t threadloop_getHalTimestamp_l(
@@ -1836,23 +1785,22 @@
class SpatializerThread : public MixerThread {
public:
- SpatializerThread(const sp<AudioFlinger>& audioFlinger,
+ SpatializerThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamOut* output,
audio_io_handle_t id,
bool systemReady,
audio_config_base_t *mixerConfig);
- ~SpatializerThread() override {}
- bool hasFastMixer() const override { return false; }
+ bool hasFastMixer() const final { return false; }
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() final;
- status_t setRequestedLatencyMode(audio_latency_mode_t mode) override;
+ status_t setRequestedLatencyMode(audio_latency_mode_t mode) final;
protected:
- void checkOutputStageEffects() override;
- void setHalLatencyMode_l() override;
+ void checkOutputStageEffects() final;
+ void setHalLatencyMode_l() final;
private:
// Do not request a specific mode by default
@@ -1862,83 +1810,39 @@
};
// record thread
-class RecordThread : public ThreadBase
+class RecordThread : public IAfRecordThread, public ThreadBase
{
+ friend class ResamplerBufferProvider;
public:
+ sp<IAfRecordThread> asIAfRecordThread() final {
+ return sp<IAfRecordThread>::fromExisting(this);
+ }
- class RecordTrack;
-
- /* The ResamplerBufferProvider is used to retrieve recorded input data from the
- * RecordThread. It maintains local state on the relative position of the read
- * position of the RecordTrack compared with the RecordThread.
- */
- class ResamplerBufferProvider : public AudioBufferProvider
- {
- public:
- explicit ResamplerBufferProvider(RecordTrack* recordTrack) :
- mRecordTrack(recordTrack),
- mRsmpInUnrel(0), mRsmpInFront(0) { }
- virtual ~ResamplerBufferProvider() { }
-
- // called to set the ResamplerBufferProvider to head of the RecordThread data buffer,
- // skipping any previous data read from the hal.
- virtual void reset();
-
- /* Synchronizes RecordTrack position with the RecordThread.
- * Calculates available frames and handle overruns if the RecordThread
- * has advanced faster than the ResamplerBufferProvider has retrieved data.
- * TODO: why not do this for every getNextBuffer?
- *
- * Parameters
- * framesAvailable: pointer to optional output size_t to store record track
- * frames available.
- * hasOverrun: pointer to optional boolean, returns true if track has overrun.
- */
-
- virtual void sync(size_t *framesAvailable = NULL, bool *hasOverrun = NULL);
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
- int32_t getFront() const { return mRsmpInFront; }
- void setFront(int32_t front) { mRsmpInFront = front; }
- private:
- RecordTrack * const mRecordTrack;
- size_t mRsmpInUnrel; // unreleased frames remaining from
- // most recent getNextBuffer
- // for debug only
- int32_t mRsmpInFront; // next available frame
- // rolling counter that is never cleared
- };
-
-#include "RecordTracks.h"
-
- RecordThread(const sp<AudioFlinger>& audioFlinger,
+ RecordThread(const sp<IAfThreadCallback>& afThreadCallback,
AudioStreamIn *input,
audio_io_handle_t id,
bool systemReady
);
- virtual ~RecordThread();
+ ~RecordThread() override;
// no addTrack_l ?
- void destroyTrack_l(const sp<RecordTrack>& track);
- void removeTrack_l(const sp<RecordTrack>& track);
+ void destroyTrack_l(const sp<IAfRecordTrack>& track) final;
+ void removeTrack_l(const sp<IAfRecordTrack>& track) final;
// Thread virtuals
- virtual bool threadLoop();
- virtual void preExit();
+ bool threadLoop() final;
+ void preExit() final;
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() final;
- virtual status_t initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; }
+ status_t initCheck() const final { return mInput == nullptr ? NO_INIT : NO_ERROR; }
- virtual sp<MemoryDealer> readOnlyHeap() const { return mReadOnlyHeap; }
+ sp<MemoryDealer> readOnlyHeap() const final { return mReadOnlyHeap; }
- virtual sp<IMemory> pipeMemory() const { return mPipeMemory; }
+ sp<IMemory> pipeMemory() const final { return mPipeMemory; }
- sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
+ sp<IAfRecordTrack> createRecordTrack_l(
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t *pSampleRate,
@@ -1953,17 +1857,19 @@
pid_t tid,
status_t *status /*non-NULL*/,
audio_port_handle_t portId,
- int32_t maxSharedAudioHistoryMs);
+ int32_t maxSharedAudioHistoryMs) final;
- status_t start(RecordTrack* recordTrack,
+ status_t start(IAfRecordTrack* recordTrack,
AudioSystem::sync_event_t event,
- audio_session_t triggerSession);
+ audio_session_t triggerSession) final;
// ask the thread to stop the specified track, and
// return true if the caller should then do it's part of the stopping process
- bool stop(RecordTrack* recordTrack);
+ bool stop(IAfRecordTrack* recordTrack) final;
+ AudioStreamIn* getInput() const final { return mInput; }
+ AudioStreamIn* clearInput() final;
- AudioStreamIn* clearInput();
+ // TODO(b/291317898) Unify with IAfThreadBase
virtual sp<StreamHalInterface> stream() const;
@@ -1971,19 +1877,19 @@
status_t& status);
virtual void cacheParameters_l() {}
virtual String8 getParameters(const String8& keys);
- virtual void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+ void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
virtual status_t createAudioPatch_l(const struct audio_patch *patch,
audio_patch_handle_t *handle);
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
void updateOutDevices(const DeviceDescriptorBaseVector& outDevices) override;
void resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs) override;
- void addPatchTrack(const sp<PatchRecord>& record);
- void deletePatchTrack(const sp<PatchRecord>& record);
+ void addPatchTrack(const sp<IAfPatchRecord>& record) final;
+ void deletePatchTrack(const sp<IAfPatchRecord>& record) final;
void readInputParameters_l();
- virtual uint32_t getInputFramesLost();
+ uint32_t getInputFramesLost() const final;
virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain);
virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain);
@@ -2002,7 +1908,7 @@
static void syncStartEventCallback(const wp<audioflinger::SyncEvent>& event);
virtual size_t frameCount() const { return mFrameCount; }
- bool hasFastCapture() const { return mFastCapture != 0; }
+ bool hasFastCapture() const final { return mFastCapture != 0; }
virtual void toAudioPortConfig(struct audio_port_config *config);
virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
@@ -2013,20 +1919,20 @@
mActiveTracks.updatePowerState(this, true /* force */);
}
- void checkBtNrec();
+ void checkBtNrec() final;
// Sets the UID records silence
- void setRecordSilenced(audio_port_handle_t portId, bool silenced);
+ void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
- status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones);
-
- status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
- status_t setPreferredMicrophoneFieldDimension(float zoom);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final;
+ status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final;
+ status_t setPreferredMicrophoneFieldDimension(float zoom) final;
MetadataUpdate updateMetadata_l() override;
- bool fastTrackAvailable() const { return mFastTrackAvail; }
+ bool fastTrackAvailable() const final { return mFastTrackAvail; }
+ void setFastTrackAvailable(bool available) final { mFastTrackAvail = available; }
bool isTimestampCorrectionEnabled() const override {
// checks popcount for exactly one device.
@@ -2036,15 +1942,15 @@
&& inDeviceType() == mTimestampCorrectedDevice;
}
- status_t shareAudioHistory(const std::string& sharedAudioPackageName,
+ status_t shareAudioHistory(const std::string& sharedAudioPackageName,
audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
- int64_t sharedAudioStartMs = -1);
+ int64_t sharedAudioStartMs = -1) final;
status_t shareAudioHistory_l(const std::string& sharedAudioPackageName,
audio_session_t sharedSessionId = AUDIO_SESSION_NONE,
int64_t sharedAudioStartMs = -1);
- void resetAudioHistory_l();
+ void resetAudioHistory_l() final;
- virtual bool isStreamInitialized() {
+ bool isStreamInitialized() const final {
return !(mInput == nullptr || mInput->stream == nullptr);
}
@@ -2066,10 +1972,10 @@
AudioStreamIn *mInput;
Source *mSource;
- SortedVector < sp<RecordTrack> > mTracks;
+ SortedVector <sp<IAfRecordTrack>> mTracks;
// mActiveTracks has dual roles: it indicates the current active track(s), and
// is used together with mStartStopCond to indicate start()/stop() progress
- ActiveTracks<RecordTrack> mActiveTracks;
+ ActiveTracks<IAfRecordTrack> mActiveTracks;
Condition mStartStopCond;
@@ -2136,90 +2042,85 @@
audio_session_t mSharedAudioSessionId = AUDIO_SESSION_NONE;
};
-class MmapThread : public ThreadBase
+class MmapThread : public ThreadBase, public virtual IAfMmapThread
{
public:
-
-#include "MmapTracks.h"
-
- MmapThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ MmapThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, const sp<StreamHalInterface>& stream, bool systemReady,
bool isOut);
- virtual ~MmapThread();
- virtual void configure(const audio_attributes_t *attr,
+ void configure(const audio_attributes_t* attr,
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
audio_port_handle_t deviceId,
- audio_port_handle_t portId);
+ audio_port_handle_t portId) override;
- void disconnect();
+ void disconnect() final;
- // MmapStreamInterface
- status_t createMmapBuffer(int32_t minSizeFrames,
- struct audio_mmap_buffer_info *info);
- status_t getMmapPosition(struct audio_mmap_position *position);
+ // MmapStreamInterface for adapter.
+ status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final;
+ status_t getMmapPosition(struct audio_mmap_position* position) const override;
status_t start(const AudioClient& client,
const audio_attributes_t *attr,
- audio_port_handle_t *handle);
- status_t stop(audio_port_handle_t handle);
- status_t standby();
- virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNaos) = 0;
- virtual status_t reportData(const void* buffer, size_t frameCount);
+ audio_port_handle_t* handle) final;
+ status_t stop(audio_port_handle_t handle) final;
+ status_t standby() final;
+ status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
+ status_t reportData(const void* buffer, size_t frameCount) override;
// RefBase
- virtual void onFirstRef();
+ void onFirstRef() final;
// Thread virtuals
- virtual bool threadLoop();
+ bool threadLoop() final;
- virtual void threadLoop_exit();
- virtual void threadLoop_standby();
- virtual bool shouldStandby_l() { return false; }
- virtual status_t exitStandby_l() REQUIRES(mLock);
+ // Not in ThreadBase
+ virtual void threadLoop_exit() final;
+ virtual void threadLoop_standby() final;
+ virtual bool shouldStandby_l() final { return false; }
+ virtual status_t exitStandby_l() REQUIRES(mLock);
- virtual status_t initCheck() const { return (mHalStream == 0) ? NO_INIT : NO_ERROR; }
- virtual size_t frameCount() const { return mFrameCount; }
- virtual bool checkForNewParameter_l(const String8& keyValuePair,
- status_t& status);
- virtual String8 getParameters(const String8& keys);
- virtual void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
- audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+ status_t initCheck() const final { return mHalStream == nullptr ? NO_INIT : NO_ERROR; }
+ size_t frameCount() const final { return mFrameCount; }
+ bool checkForNewParameter_l(const String8& keyValuePair, status_t& status) final;
+ String8 getParameters(const String8& keys) final;
+ void ioConfigChanged(audio_io_config_event_t event, pid_t pid = 0,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) final;
void readHalParameters_l();
- virtual void cacheParameters_l() {}
- virtual status_t createAudioPatch_l(const struct audio_patch *patch,
- audio_patch_handle_t *handle);
- virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
- virtual void toAudioPortConfig(struct audio_port_config *config);
+ void cacheParameters_l() final {}
+ status_t createAudioPatch_l(
+ const struct audio_patch* patch, audio_patch_handle_t* handle) final;
+ status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final;
+ void toAudioPortConfig(struct audio_port_config* config) override;
- virtual sp<StreamHalInterface> stream() const { return mHalStream; }
- virtual status_t addEffectChain_l(const sp<IAfEffectChain>& chain);
- virtual size_t removeEffectChain_l(const sp<IAfEffectChain>& chain);
- virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
- audio_session_t sessionId);
+ sp<StreamHalInterface> stream() const final { return mHalStream; }
+ status_t addEffectChain_l(const sp<IAfEffectChain>& chain) final;
+ size_t removeEffectChain_l(const sp<IAfEffectChain>& chain) final;
+ status_t checkEffectCompatibility_l(
+ const effect_descriptor_t *desc, audio_session_t sessionId) final;
- uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
+ uint32_t hasAudioSession_l(audio_session_t sessionId) const override {
// Note: using mActiveTracks as no mTracks here.
return ThreadBase::hasAudioSession_l(sessionId, mActiveTracks);
}
- virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event);
- virtual bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const;
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
+ bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final;
- virtual void checkSilentMode_l() {}
- virtual void processVolume_l() {}
+ virtual void checkSilentMode_l() {} // cannot be const (RecordThread)
+ virtual void processVolume_l() {}
void checkInvalidTracks_l();
- virtual audio_stream_type_t streamType() { return AUDIO_STREAM_DEFAULT; }
-
- virtual void invalidateTracks(audio_stream_type_t streamType __unused) {}
- virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds __unused) {}
+ // Not in ThreadBase
+ virtual audio_stream_type_t streamType() const { return AUDIO_STREAM_DEFAULT; }
+ virtual void invalidateTracks(audio_stream_type_t /* streamType */) {}
+ void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override {}
// Sets the UID records silence
- virtual void setRecordSilenced(audio_port_handle_t portId __unused,
- bool silenced __unused) {}
+ void setRecordSilenced(
+ audio_port_handle_t /* portId */, bool /* silenced */) override {}
- virtual bool isStreamInitialized() { return false; }
+ bool isStreamInitialized() const override { return false; }
void setClientSilencedState_l(audio_port_handle_t portId, bool silenced) {
mClientSilencedStates[portId] = silenced;
@@ -2242,8 +2143,8 @@
}
protected:
- void dumpInternals_l(int fd, const Vector<String16>& args) override;
- void dumpTracks_l(int fd, const Vector<String16>& args) override;
+ void dumpInternals_l(int fd, const Vector<String16>& args) override;
+ void dumpTracks_l(int fd, const Vector<String16>& args) final;
/**
* @brief mDeviceId current device port unique identifier
@@ -2258,7 +2159,7 @@
sp<StreamHalInterface> mHalStream;
sp<DeviceHalInterface> mHalDevice;
AudioHwDevice* const mAudioHwDev;
- ActiveTracks<MmapTrack> mActiveTracks;
+ ActiveTracks<IAfMmapTrack> mActiveTracks;
float mHalVolFloat;
std::map<audio_port_handle_t, bool> mClientSilencedStates;
@@ -2266,89 +2167,98 @@
static constexpr int32_t kMaxNoCallbackWarnings = 5;
};
-class MmapPlaybackThread : public MmapThread, public VolumeInterface
-{
-
+class MmapPlaybackThread : public MmapThread, public IAfMmapPlaybackThread,
+ public virtual VolumeInterface {
public:
- MmapPlaybackThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ MmapPlaybackThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, AudioStreamOut *output, bool systemReady);
- virtual ~MmapPlaybackThread() {}
- virtual void configure(const audio_attributes_t *attr,
+ sp<IAfMmapPlaybackThread> asIAfMmapPlaybackThread() final {
+ return sp<IAfMmapPlaybackThread>::fromExisting(this);
+ }
+
+ void configure(const audio_attributes_t* attr,
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
audio_port_handle_t deviceId,
- audio_port_handle_t portId);
+ audio_port_handle_t portId) final;
- AudioStreamOut* clearOutput();
+ AudioStreamOut* clearOutput() final;
// VolumeInterface
- virtual void setMasterVolume(float value);
- virtual void setMasterMute(bool muted);
- virtual void setStreamVolume(audio_stream_type_t stream, float value);
- virtual void setStreamMute(audio_stream_type_t stream, bool muted);
- virtual float streamVolume(audio_stream_type_t stream) const;
+ void setMasterVolume(float value) final;
+ void setMasterBalance(float /* value */) final {} // Needs implementation?
+ void setMasterMute(bool muted) final;
+ void setStreamVolume(audio_stream_type_t stream, float value) final;
+ void setStreamMute(audio_stream_type_t stream, bool muted) final;
+ float streamVolume(audio_stream_type_t stream) const final;
void setMasterMute_l(bool muted) { mMasterMute = muted; }
- virtual void invalidateTracks(audio_stream_type_t streamType);
- void invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
+ void invalidateTracks(audio_stream_type_t streamType) final;
+ void invalidateTracks(std::set<audio_port_handle_t>& portIds) final;
- virtual audio_stream_type_t streamType() { return mStreamType; }
- virtual void checkSilentMode_l();
- void processVolume_l() override;
+ audio_stream_type_t streamType() const final { return mStreamType; }
+ void checkSilentMode_l() final;
+ void processVolume_l() final;
- MetadataUpdate updateMetadata_l() override;
+ MetadataUpdate updateMetadata_l() final;
- virtual void toAudioPortConfig(struct audio_port_config *config);
+ void toAudioPortConfig(struct audio_port_config* config) final;
- status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+ status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const final;
- virtual bool isStreamInitialized() {
+ bool isStreamInitialized() const final {
return !(mOutput == nullptr || mOutput->stream == nullptr);
}
- status_t reportData(const void* buffer, size_t frameCount) override;
+ status_t reportData(const void* buffer, size_t frameCount) final;
- void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
- void stopMelComputation_l() override;
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final;
+ void stopMelComputation_l() final;
protected:
- void dumpInternals_l(int fd, const Vector<String16>& args) override;
+ void dumpInternals_l(int fd, const Vector<String16>& args) final;
+ float streamVolume_l() const {
+ return mStreamTypes[mStreamType].volume;
+ }
+ bool streamMuted_l() const {
+ return mStreamTypes[mStreamType].mute;
+ }
+ stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
audio_stream_type_t mStreamType;
float mMasterVolume;
- float mStreamVolume;
bool mMasterMute;
- bool mStreamMute;
AudioStreamOut* mOutput;
mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
};
-class MmapCaptureThread : public MmapThread
+class MmapCaptureThread : public MmapThread, public IAfMmapCaptureThread
{
-
public:
- MmapCaptureThread(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+ MmapCaptureThread(const sp<IAfThreadCallback>& afThreadCallback, audio_io_handle_t id,
AudioHwDevice *hwDev, AudioStreamIn *input, bool systemReady);
- virtual ~MmapCaptureThread() {}
- AudioStreamIn* clearInput();
+ sp<IAfMmapCaptureThread> asIAfMmapCaptureThread() final {
+ return sp<IAfMmapCaptureThread>::fromExisting(this);
+ }
- status_t exitStandby_l() REQUIRES(mLock) override;
+ AudioStreamIn* clearInput() final;
- MetadataUpdate updateMetadata_l() override;
- void processVolume_l() override;
- void setRecordSilenced(audio_port_handle_t portId,
- bool silenced) override;
+ status_t exitStandby_l() REQUIRES(mLock) final;
- virtual void toAudioPortConfig(struct audio_port_config *config);
+ MetadataUpdate updateMetadata_l() final;
+ void processVolume_l() final;
+ void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
- status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+ void toAudioPortConfig(struct audio_port_config* config) final;
- virtual bool isStreamInitialized() {
+ status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const final;
+
+ bool isStreamInitialized() const final {
return !(mInput == nullptr || mInput->stream == nullptr);
}
@@ -2359,12 +2269,12 @@
class BitPerfectThread : public MixerThread {
public:
- BitPerfectThread(const sp<AudioFlinger>& audioflinger, AudioStreamOut *output,
+ BitPerfectThread(const sp<IAfThreadCallback>& afThreadCallback, AudioStreamOut *output,
audio_io_handle_t id, bool systemReady);
protected:
- mixer_state prepareTracks_l(Vector<sp<Track>> *tracksToRemove) override;
- void threadLoop_mix() override;
+ mixer_state prepareTracks_l(Vector<sp<IAfTrack>>* tracksToRemove) final;
+ void threadLoop_mix() final;
private:
bool mIsBitPerfect;
@@ -2372,4 +2282,4 @@
float mVolumeRight = 0.f;
};
-private:
+} // namespace android
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index dec49ba..5708c61 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -15,46 +15,26 @@
** limitations under the License.
*/
-#ifndef INCLUDING_FROM_AUDIOFLINGER_H
- #error This header file should only be included from AudioFlinger.h
-#endif
+#pragma once
+
+#include "Configuration.h" // TEE_SINK
+#include "IAfTrack.h"
+
+#include <afutils/NBAIO_Tee.h>
+#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
+#include <datapath/TrackMetrics.h>
+#include <mediautils/BatteryNotifier.h>
+
+#include <atomic> // avoid transitive dependency
+#include <list> // avoid transitive dependency
+#include <optional> // avoid transitive dependency
+
+namespace android {
// base for record and playback
-class TrackBase : public ExtendedAudioBufferProvider, public RefBase {
-
+class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
public:
- enum track_state : int32_t {
- IDLE,
- FLUSHED, // for PlaybackTracks only
- STOPPED,
- // next 2 states are currently used for fast tracks
- // and offloaded tracks only
- STOPPING_1, // waiting for first underrun
- STOPPING_2, // waiting for presentation complete
- RESUMING, // for PlaybackTracks only
- ACTIVE,
- PAUSING,
- PAUSED,
- STARTING_1, // for RecordTrack only
- STARTING_2, // for RecordTrack only
- };
-
- // where to allocate the data buffer
- enum alloc_type {
- ALLOC_CBLK, // allocate immediately after control block
- ALLOC_READONLY, // allocate from a separate read-only heap per thread
- ALLOC_PIPE, // do not allocate; use the pipe buffer
- ALLOC_LOCAL, // allocate a local buffer
- ALLOC_NONE, // do not allocate:use the buffer passed to TrackBase constructor
- };
-
- enum track_type {
- TYPE_DEFAULT,
- TYPE_OUTPUT,
- TYPE_PATCH,
- };
-
- TrackBase(ThreadBase *thread,
+ TrackBase(IAfThreadBase* thread,
const sp<Client>& client,
const audio_attributes_t& mAttr,
uint32_t sampleRate,
@@ -71,87 +51,79 @@
track_type type = TYPE_DEFAULT,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
std::string metricsId = {});
- virtual ~TrackBase();
- virtual status_t initCheck() const;
+ ~TrackBase() override;
+ status_t initCheck() const override;
+ sp<IMemory> getCblk() const final { return mCblkMemory; }
+ audio_track_cblk_t* cblk() const final { return mCblk; }
+ audio_session_t sessionId() const final { return mSessionId; }
+ uid_t uid() const final { return mUid; }
+ pid_t creatorPid() const final { return mCreatorPid; }
+ audio_port_handle_t portId() const final { return mPortId; }
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
+ track_state state() const final { return mState; }
+ void setState(track_state state) final { mState = state; }
+ sp<IMemory> getBuffers() const final { return mBufferMemory; }
+ void* buffer() const final { return mBuffer; }
+ size_t bufferSize() const final { return mBufferSize; }
- virtual status_t start(AudioSystem::sync_event_t event,
- audio_session_t triggerSession) = 0;
- virtual void stop() = 0;
- sp<IMemory> getCblk() const { return mCblkMemory; }
- audio_track_cblk_t* cblk() const { return mCblk; }
- audio_session_t sessionId() const { return mSessionId; }
- uid_t uid() const { return mUid; }
- pid_t creatorPid() const { return mCreatorPid; }
-
- audio_port_handle_t portId() const { return mPortId; }
- virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event);
-
- sp<IMemory> getBuffers() const { return mBufferMemory; }
- void* buffer() const { return mBuffer; }
- size_t bufferSize() const { return mBufferSize; }
- virtual bool isFastTrack() const = 0;
- virtual bool isDirect() const = 0;
- bool isOutputTrack() const { return (mType == TYPE_OUTPUT); }
- bool isPatchTrack() const { return (mType == TYPE_PATCH); }
- bool isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); }
-
- virtual void invalidate() {
+ bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); }
+ bool isPatchTrack() const final { return (mType == TYPE_PATCH); }
+ bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); }
+ void invalidate() override {
if (mIsInvalid) return;
mTrackMetrics.logInvalidate();
mIsInvalid = true;
}
- bool isInvalid() const { return mIsInvalid; }
+ bool isInvalid() const final { return mIsInvalid; }
+ void terminate() final { mTerminated = true; }
+ bool isTerminated() const final { return mTerminated; }
+ audio_attributes_t attributes() const final { return mAttr; }
+ bool isSpatialized() const override { return false; }
+ bool isBitPerfect() const override { return false; }
- void terminate() { mTerminated = true; }
- bool isTerminated() const { return mTerminated; }
+ wp<IAfThreadBase> thread() const final { return mThread; }
- audio_attributes_t attributes() const { return mAttr; }
-
- virtual bool isSpatialized() const { return false; }
-
- virtual bool isBitPerfect() const { return false; }
+ const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
#ifdef TEE_SINK
- void dumpTee(int fd, const std::string &reason) const {
- mTee.dump(fd, reason);
- }
+ void dumpTee(int fd, const std::string &reason) const final {
+ mTee.dump(fd, reason);
+ }
#endif
-
- /** returns the buffer contents size converted to time in milliseconds
- * for PCM Playback or Record streaming tracks. The return value is zero for
- * PCM static tracks and not defined for non-PCM tracks.
- *
- * This may be called without the thread lock.
- */
- virtual double bufferLatencyMs() const {
+ /** returns the buffer contents size converted to time in milliseconds
+ * for PCM Playback or Record streaming tracks. The return value is zero for
+ * PCM static tracks and not defined for non-PCM tracks.
+ *
+ * This may be called without the thread lock.
+ */
+ double bufferLatencyMs() const override {
return mServerProxy->framesReadySafe() * 1000. / sampleRate();
}
- /** returns whether the track supports server latency computation.
- * This is set in the constructor and constant throughout the track lifetime.
- */
+ /** returns whether the track supports server latency computation.
+ * This is set in the constructor and constant throughout the track lifetime.
+ */
+ bool isServerLatencySupported() const final { return mServerLatencySupported; }
- bool isServerLatencySupported() const { return mServerLatencySupported; }
-
- /** computes the server latency for PCM Playback or Record track
- * to the device sink/source. This is the time for the next frame in the track buffer
- * written or read from the server thread to the device source or sink.
- *
- * This may be called without the thread lock, but latencyMs and fromTrack
- * may be not be synchronized. For example PatchPanel may not obtain the
- * thread lock before calling.
- *
- * \param latencyMs on success is set to the latency in milliseconds of the
- * next frame written/read by the server thread to/from the track buffer
- * from the device source/sink.
- * \param fromTrack on success is set to true if latency was computed directly
- * from the track timestamp; otherwise set to false if latency was
- * estimated from the server timestamp.
- * fromTrack may be nullptr or omitted if not required.
- *
- * \returns OK or INVALID_OPERATION on failure.
- */
- status_t getServerLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+ /** computes the server latency for PCM Playback or Record track
+ * to the device sink/source. This is the time for the next frame in the track buffer
+ * written or read from the server thread to the device source or sink.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the server thread to/from the track buffer
+ * from the device source/sink.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
if (!isServerLatencySupported()) {
return INVALID_OPERATION;
}
@@ -170,25 +142,25 @@
return OK;
}
- /** computes the total client latency for PCM Playback or Record tracks
- * for the next client app access to the device sink/source; i.e. the
- * server latency plus the buffer latency.
- *
- * This may be called without the thread lock, but latencyMs and fromTrack
- * may be not be synchronized. For example PatchPanel may not obtain the
- * thread lock before calling.
- *
- * \param latencyMs on success is set to the latency in milliseconds of the
- * next frame written/read by the client app to/from the track buffer
- * from the device sink/source.
- * \param fromTrack on success is set to true if latency was computed directly
- * from the track timestamp; otherwise set to false if latency was
- * estimated from the server timestamp.
- * fromTrack may be nullptr or omitted if not required.
- *
- * \returns OK or INVALID_OPERATION on failure.
- */
- status_t getTrackLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+ /** computes the total client latency for PCM Playback or Record tracks
+ * for the next client app access to the device sink/source; i.e. the
+ * server latency plus the buffer latency.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the client app to/from the track buffer
+ * from the device sink/source.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
double serverLatencyMs;
status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
if (status == OK) {
@@ -197,21 +169,15 @@
return status;
}
- // TODO: Consider making this external.
- struct FrameTime {
- int64_t frames;
- int64_t timeNs;
- };
-
- // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
- void getKernelFrameTime(FrameTime *ft) const {
+ // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
+ void getKernelFrameTime(FrameTime* ft) const final {
*ft = mKernelFrameTime.load();
}
- audio_format_t format() const { return mFormat; }
- int id() const { return mId; }
+ audio_format_t format() const final { return mFormat; }
+ int id() const final { return mId; }
- const char *getTrackStateAsString() const {
+ const char* getTrackStateAsString() const final {
if (isTerminated()) {
return "TERMINATED";
}
@@ -245,19 +211,19 @@
// Called by the PlaybackThread to indicate that the track is becoming active
// and a new interval should start with a given device list.
- void logBeginInterval(const std::string& devices) {
+ void logBeginInterval(const std::string& devices) final {
mTrackMetrics.logBeginInterval(devices);
}
// Called by the PlaybackThread to indicate the track is no longer active.
- void logEndInterval() {
+ void logEndInterval() final {
mTrackMetrics.logEndInterval();
}
// Called to tally underrun frames in playback.
- virtual void tallyUnderrunFrames(size_t /* frames */) {}
+ void tallyUnderrunFrames(size_t /* frames */) override {}
- audio_channel_mask_t channelMask() const { return mChannelMask; }
+ audio_channel_mask_t channelMask() const final { return mChannelMask; }
/** @return true if the track has changed (metadata or volume) since
* the last time this function was called,
@@ -265,16 +231,16 @@
* false otherwise.
* Thread safe.
*/
- bool readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
+ bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
/** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
- void setMetadataHasChanged() { mChangeNotified.clear(); }
+ void setMetadataHasChanged() final { mChangeNotified.clear(); }
/**
* Called when a track moves to active state to record its contribution to battery usage.
* Track state transitions should eventually be handled within the track class.
*/
- void beginBatteryAttribution() {
+ void beginBatteryAttribution() final {
mBatteryStatsHolder.emplace(uid());
}
@@ -282,11 +248,10 @@
* Called when a track moves out of the active state to record its contribution
* to battery usage.
*/
- void endBatteryAttribution() {
+ void endBatteryAttribution() final {
mBatteryStatsHolder.reset();
}
-
protected:
DISALLOW_COPY_AND_ASSIGN(TrackBase);
@@ -302,31 +267,31 @@
}
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
// ExtendedAudioBufferProvider interface is only needed for Track,
// but putting it in TrackBase avoids the complexity of virtual inheritance
- virtual size_t framesReady() const { return SIZE_MAX; }
+ size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
uint32_t channelCount() const { return mChannelCount; }
- size_t frameSize() const { return mFrameSize; }
+ size_t frameSize() const final { return mFrameSize; }
- virtual uint32_t sampleRate() const { return mSampleRate; }
+ uint32_t sampleRate() const override { return mSampleRate; }
- bool isStopped() const {
+ bool isStopped() const final {
return (mState == STOPPED || mState == FLUSHED);
}
// for fast tracks and offloaded tracks only
- bool isStopping() const {
+ bool isStopping() const final {
return mState == STOPPING_1 || mState == STOPPING_2;
}
- bool isStopping_1() const {
+ bool isStopping_1() const final {
return mState == STOPPING_1;
}
- bool isStopping_2() const {
+ bool isStopping_2() const final {
return mState == STOPPING_2;
}
@@ -368,7 +333,7 @@
// true for Track, false for RecordTrack,
// this could be a track type if needed later
- const wp<ThreadBase> mThread;
+ const wp<IAfThreadBase> mThread;
const alloc_type mAllocType;
/*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
sp<IMemory> mCblkMemory;
@@ -434,37 +399,28 @@
std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder;
};
-// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
-// it provides buffer access methods that map those of a ClientProxy (see AudioTrackShared.h)
-class PatchProxyBufferProvider
+class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase
{
public:
-
- virtual ~PatchProxyBufferProvider() {}
-
- virtual bool producesBufferOnDemand() const = 0;
- virtual status_t obtainBuffer(Proxy::Buffer* buffer,
- const struct timespec *requested = NULL) = 0;
- virtual void releaseBuffer(Proxy::Buffer* buffer) = 0;
-};
-
-class PatchTrackBase : public PatchProxyBufferProvider
-{
-public:
- using Timeout = std::optional<std::chrono::nanoseconds>;
- PatchTrackBase(const sp<ClientProxy>& proxy, const ThreadBase& thread,
+ PatchTrackBase(const sp<ClientProxy>& proxy,
+ IAfThreadBase* thread,
const Timeout& timeout);
- void setPeerTimeout(std::chrono::nanoseconds timeout);
- template <typename T>
- void setPeerProxy(const sp<T> &proxy, bool holdReference) {
- mPeerReferenceHold = holdReference ? proxy : nullptr;
- mPeerProxy = proxy.get();
- }
- void clearPeerProxy() {
+ void setPeerTimeout(std::chrono::nanoseconds timeout) final;
+ void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final {
+ if (proxy) {
+ mPeerReferenceHold = holdReference ? proxy : nullptr;
+ mPeerProxy = proxy->asPatchProxyBufferProvider();
+ } else {
+ clearPeerProxy();
+ }
+ }
+ void clearPeerProxy() final {
mPeerReferenceHold.clear();
mPeerProxy = nullptr;
}
+ PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; }
+
bool producesBufferOnDemand() const override { return false; }
protected:
@@ -472,5 +428,6 @@
sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
PatchProxyBufferProvider* mPeerProxy = nullptr;
struct timespec mPeerTimeout{};
-
};
+
+} // namespace android
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 6350a57..1a00681 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -15,28 +15,33 @@
** limitations under the License.
*/
-
#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_AUDIO
-#include "Configuration.h"
-#include <linux/futex.h>
-#include <math.h>
-#include <sys/syscall.h>
+#include "MmapTracks.h"
+#include "PlaybackTracks.h"
+#include "RecordTracks.h"
+
+#include "Client.h"
+#include "IAfEffect.h"
+#include "IAfThread.h"
+#include "ResamplerBufferProvider.h"
+
+#include <audio_utils/minifloat.h>
+#include <media/AudioValidator.h>
+#include <media/RecordBufferConverter.h>
+#include <media/nbaio/Pipe.h>
+#include <media/nbaio/PipeReader.h>
+#include <mediautils/ServiceUtilities.h>
+#include <mediautils/SharedMemoryAllocator.h>
+#include <private/media/AudioTrackShared.h>
#include <utils/Log.h>
#include <utils/Trace.h>
-#include <private/media/AudioTrackShared.h>
-
-#include "AudioFlinger.h"
-
-#include <media/nbaio/Pipe.h>
-#include <media/nbaio/PipeReader.h>
-#include <media/AudioValidator.h>
-#include <media/RecordBufferConverter.h>
-#include <mediautils/ServiceUtilities.h>
-#include <audio_utils/minifloat.h>
+#include <linux/futex.h>
+#include <math.h>
+#include <sys/syscall.h>
// ----------------------------------------------------------------------------
@@ -76,8 +81,8 @@
static volatile int32_t nextTrackId = 55;
// TrackBase constructor must be called with AudioFlinger::mLock held
-AudioFlinger::ThreadBase::TrackBase::TrackBase(
- ThreadBase *thread,
+TrackBase::TrackBase(
+ IAfThreadBase *thread,
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t sampleRate,
@@ -94,7 +99,7 @@
track_type type,
audio_port_handle_t portId,
std::string metricsId)
- : RefBase(),
+ :
mThread(thread),
mAllocType(alloc),
mClient(client),
@@ -253,7 +258,7 @@
return attributionSource;
}
-status_t AudioFlinger::ThreadBase::TrackBase::initCheck() const
+status_t TrackBase::initCheck() const
{
status_t status;
if (mType == TYPE_OUTPUT || mType == TYPE_PATCH) {
@@ -264,7 +269,7 @@
return status;
}
-AudioFlinger::ThreadBase::TrackBase::~TrackBase()
+TrackBase::~TrackBase()
{
// delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
mServerProxy.clear();
@@ -272,7 +277,7 @@
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
if (mClient != 0) {
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
+ Mutex::Autolock _l(mClient->afClientCallback()->clientMutex());
// If the client's reference count drops to zero, the associated destructor
// must run with AudioFlinger lock held. Thus the explicit clear() rather than
// relying on the automatic clear() at end of scope.
@@ -289,7 +294,7 @@
// AudioBufferProvider interface
// getNextBuffer() = 0;
// This implementation of releaseBuffer() is used by Track and RecordTrack
-void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+void TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
#ifdef TEE_SINK
mTee.write(buffer->raw, buffer->frameCount);
@@ -303,29 +308,28 @@
mServerProxy->releaseBuffer(&buf);
}
-status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(
+status_t TrackBase::setSyncEvent(
const sp<audioflinger::SyncEvent>& event)
{
mSyncEvents.emplace_back(event);
return NO_ERROR;
}
-AudioFlinger::ThreadBase::PatchTrackBase::PatchTrackBase(const sp<ClientProxy>& proxy,
- const ThreadBase& thread,
- const Timeout& timeout)
+PatchTrackBase::PatchTrackBase(const sp<ClientProxy>& proxy,
+ IAfThreadBase* thread, const Timeout& timeout)
: mProxy(proxy)
{
if (timeout) {
setPeerTimeout(*timeout);
} else {
// Double buffer mixer
- uint64_t mixBufferNs = ((uint64_t)2 * thread.frameCount() * 1000000000) /
- thread.sampleRate();
+ uint64_t mixBufferNs = ((uint64_t)2 * thread->frameCount() * 1000000000) /
+ thread->sampleRate();
setPeerTimeout(std::chrono::nanoseconds{mixBufferNs});
}
}
-void AudioFlinger::ThreadBase::PatchTrackBase::setPeerTimeout(std::chrono::nanoseconds timeout) {
+void PatchTrackBase::setPeerTimeout(std::chrono::nanoseconds timeout) {
mPeerTimeout.tv_sec = timeout.count() / std::nano::den;
mPeerTimeout.tv_nsec = timeout.count() % std::nano::den;
}
@@ -339,7 +343,7 @@
class TrackHandle : public android::media::BnAudioTrack {
public:
- explicit TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track);
+ explicit TrackHandle(const sp<IAfTrack>& track);
~TrackHandle() override;
binder::Status getCblk(std::optional<media::SharedFileRegion>* _aidl_return) final;
@@ -373,20 +377,18 @@
const media::audio::common::AudioPlaybackRate& playbackRate) final;
private:
- const sp<AudioFlinger::PlaybackThread::Track> mTrack;
+ const sp<IAfTrack> mTrack;
};
/* static */
-sp<media::IAudioTrack> AudioFlinger::PlaybackThread::Track::createIAudioTrackAdapter(
- const sp<Track>& track) {
+sp<media::IAudioTrack> IAfTrack::createIAudioTrackAdapter(const sp<IAfTrack>& track) {
return sp<TrackHandle>::make(track);
}
-TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
+TrackHandle::TrackHandle(const sp<IAfTrack>& track)
: BnAudioTrack(),
mTrack(track)
{
- // TODO(b/288339104) binder thread priority change not needed.
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}
@@ -556,9 +558,8 @@
// -------------------------------
// static
-sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor>
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded(
- AudioFlinger::ThreadBase* thread,
+sp<OpPlayAudioMonitor> OpPlayAudioMonitor::createIfNeeded(
+ IAfThreadBase* thread,
const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id,
audio_stream_type_t streamType)
{
@@ -588,11 +589,10 @@
return sp<OpPlayAudioMonitor>::make(thread, attributionSource, attr.usage, id, uid);
}
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
- AudioFlinger::ThreadBase* thread,
- const AttributionSourceState& attributionSource,
- audio_usage_t usage, int id, uid_t uid)
- : mThread(wp<AudioFlinger::ThreadBase>::fromExisting(thread)),
+OpPlayAudioMonitor::OpPlayAudioMonitor(IAfThreadBase* thread,
+ const AttributionSourceState& attributionSource,
+ audio_usage_t usage, int id, uid_t uid)
+ : mThread(wp<IAfThreadBase>::fromExisting(thread)),
mHasOpPlayAudio(true),
mAttributionSource(attributionSource),
mUsage((int32_t)usage),
@@ -601,7 +601,7 @@
mPackageName(VALUE_OR_FATAL(aidl2legacy_string_view_String16(
attributionSource.packageName.value_or("")))) {}
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
+OpPlayAudioMonitor::~OpPlayAudioMonitor()
{
if (mOpCallback != 0) {
mAppOpsManager.stopWatchingMode(mOpCallback);
@@ -609,7 +609,7 @@
mOpCallback.clear();
}
-void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef()
+void OpPlayAudioMonitor::onFirstRef()
{
checkPlayAudioForUsage();
if (mAttributionSource.packageName.has_value()) {
@@ -619,14 +619,14 @@
}
}
-bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const {
+bool OpPlayAudioMonitor::hasOpPlayAudio() const {
return mHasOpPlayAudio.load();
}
// Note this method is never called (and never to be) for audio server / patch record track
// - not called from constructor due to check on UID,
// - not called from PlayAudioOpCallback because the callback is not installed in this case
-void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage()
+void OpPlayAudioMonitor::checkPlayAudioForUsage()
{
const bool hasAppOps = mAttributionSource.packageName.has_value()
&& mAppOpsManager.checkAudioOpNoThrow(
@@ -637,19 +637,19 @@
if (mHasOpPlayAudio.compare_exchange_strong(shouldChange, hasAppOps)) {
ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasAppOps ? "not " : "");
auto thread = mThread.promote();
- if (thread != nullptr && thread->type() == AudioFlinger::ThreadBase::OFFLOAD) {
+ if (thread != nullptr && thread->type() == IAfThreadBase::OFFLOAD) {
// Wake up Thread if offloaded, otherwise it may be several seconds for update.
- Mutex::Autolock _l(thread->mLock);
+ Mutex::Autolock _l(thread->mutex());
thread->broadcast_l();
}
}
}
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::PlayAudioOpCallback::PlayAudioOpCallback(
+OpPlayAudioMonitor::PlayAudioOpCallback::PlayAudioOpCallback(
const wp<OpPlayAudioMonitor>& monitor) : mMonitor(monitor)
{ }
-void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::PlayAudioOpCallback::opChanged(int32_t op,
+void OpPlayAudioMonitor::PlayAudioOpCallback::opChanged(int32_t op,
const String16& packageName) {
// we only have uid, so we need to check all package names anyway
UNUSED(packageName);
@@ -663,7 +663,7 @@
}
// static
-void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::getPackagesForUid(
+void OpPlayAudioMonitor::getPackagesForUid(
uid_t uid, Vector<String16>& packages)
{
PermissionController permissionController;
@@ -674,9 +674,57 @@
#undef LOG_TAG
#define LOG_TAG "AF::Track"
+/* static */
+sp<IAfTrack> IAfTrack::create(
+ IAfPlaybackThread* thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount,
+ void *buffer,
+ size_t bufferSize,
+ const sp<IMemory>& sharedBuffer,
+ audio_session_t sessionId,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ audio_output_flags_t flags,
+ track_type type,
+ audio_port_handle_t portId,
+ /** default behaviour is to start when there are as many frames
+ * ready as possible (aka. Buffer is full). */
+ size_t frameCountToBeReady,
+ float speed,
+ bool isSpatialized,
+ bool isBitPerfect) {
+ return sp<Track>::make(thread,
+ client,
+ streamType,
+ attr,
+ sampleRate,
+ format,
+ channelMask,
+ frameCount,
+ buffer,
+ bufferSize,
+ sharedBuffer,
+ sessionId,
+ creatorPid,
+ attributionSource,
+ flags,
+ type,
+ portId,
+ frameCountToBeReady,
+ speed,
+ isSpatialized,
+ isBitPerfect);
+}
+
// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
-AudioFlinger::PlaybackThread::Track::Track(
- PlaybackThread *thread,
+Track::Track(
+ IAfPlaybackThread* thread,
const sp<Client>& client,
audio_stream_type_t streamType,
const audio_attributes_t& attr,
@@ -710,7 +758,7 @@
type,
portId,
std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK) + std::to_string(portId)),
- mFillingUpStatus(FS_INVALID),
+ mFillingStatus(FS_INVALID),
// mRetryCount initialized later when needed
mSharedBuffer(sharedBuffer),
mStreamType(streamType),
@@ -767,15 +815,15 @@
// race with setSyncEvent(). However, if we call it, we cannot properly start
// static fast tracks (SoundPool) immediately after stopping.
//mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
- ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
- int i = __builtin_ctz(thread->mFastTrackAvailMask);
+ ALOG_ASSERT(thread->fastTrackAvailMask_l() != 0);
+ const int i = __builtin_ctz(thread->fastTrackAvailMask_l());
ALOG_ASSERT(0 < i && i < (int)FastMixerState::sMaxFastTracks);
// FIXME This is too eager. We allocate a fast track index before the
// fast track becomes active. Since fast tracks are a scarce resource,
// this means we are potentially denying other more important fast tracks from
// being created. It would be better to allocate the index dynamically.
mFastIndex = i;
- thread->mFastTrackAvailMask &= ~(1 << i);
+ thread->fastTrackAvailMask_l() &= ~(1 << i);
}
mServerLatencySupported = checkServerLatencySupported(format, flags);
@@ -800,7 +848,7 @@
mTrackMetrics.logConstructor(creatorPid, uid, id(), traits, streamType);
}
-AudioFlinger::PlaybackThread::Track::~Track()
+Track::~Track()
{
ALOGV("%s(%d)", __func__, mId);
@@ -813,7 +861,7 @@
}
}
-status_t AudioFlinger::PlaybackThread::Track::initCheck() const
+status_t Track::initCheck() const
{
status_t status = TrackBase::initCheck();
if (status == NO_ERROR && mCblk == nullptr) {
@@ -822,7 +870,7 @@
return status;
}
-void AudioFlinger::PlaybackThread::Track::destroy()
+void Track::destroy()
{
// NOTE: destroyTrack_l() can remove a strong reference to this Track
// by removing it from mTracks vector, so there is a risk that this Tracks's
@@ -835,10 +883,10 @@
sp<Track> keep(this);
{ // scope for mLock
bool wasActive = false;
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
wasActive = playbackThread->destroyTrack_l(this);
forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->destroy(); });
}
@@ -848,7 +896,7 @@
}
}
-void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
+void Track::appendDumpHeader(String8& result) const
{
result.appendFormat("Type Id Active Client Session Port Id S Flags "
" Format Chn mask SRate "
@@ -859,7 +907,7 @@
isServerLatencySupported() ? " Latency" : "");
}
-void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
+void Track::appendDump(String8& result, bool active) const
{
char trackType;
switch (mType) {
@@ -901,7 +949,7 @@
}
char fillingStatus;
- switch (mFillingUpStatus) {
+ switch (mFillingStatus) {
case FS_INVALID:
fillingStatus = 'I';
break;
@@ -987,12 +1035,12 @@
result.append("\n");
}
-uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
+uint32_t Track::sampleRate() const {
return mAudioTrackServerProxy->getSampleRate();
}
// AudioBufferProvider interface
-status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
{
ServerProxy::Buffer buf;
size_t desiredFrames = buffer->frameCount;
@@ -1010,14 +1058,14 @@
return status;
}
-void AudioFlinger::PlaybackThread::Track::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+void Track::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
interceptBuffer(*buffer);
TrackBase::releaseBuffer(buffer);
}
// TODO: compensate for time shift between HW modules.
-void AudioFlinger::PlaybackThread::Track::interceptBuffer(
+void Track::interceptBuffer(
const AudioBufferProvider::Buffer& sourceBuffer) {
auto start = std::chrono::steady_clock::now();
const size_t frameCount = sourceBuffer.frameCount;
@@ -1027,12 +1075,12 @@
// does not allow 0 frame size request contrary to getNextBuffer
}
for (auto& teePatch : mTeePatches) {
- RecordThread::PatchRecord* patchRecord = teePatch.patchRecord.get();
+ IAfPatchRecord* patchRecord = teePatch.patchRecord.get();
const size_t framesWritten = patchRecord->writeFrames(
sourceBuffer.i8, frameCount, mFrameSize);
const size_t framesLeft = frameCount - framesWritten;
ALOGW_IF(framesLeft != 0, "%s(%d) PatchRecord %d can not provide big enough "
- "buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->mId,
+ "buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->id(),
framesWritten, frameCount, framesLeft);
}
auto spent = ceil<std::chrono::microseconds>(std::chrono::steady_clock::now() - start);
@@ -1048,7 +1096,7 @@
// from a different thread than the one calling Proxy->obtainBuffer() and
// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the
// AudioTrackServerProxy so be especially careful calling with FastTracks.
-size_t AudioFlinger::PlaybackThread::Track::framesReady() const {
+size_t Track::framesReady() const {
if (mSharedBuffer != 0 && (isStopped() || isStopping())) {
// Static tracks return zero frames immediately upon stopping (for FastTracks).
// The remainder of the buffer is not drained.
@@ -1057,12 +1105,12 @@
return mAudioTrackServerProxy->framesReady();
}
-int64_t AudioFlinger::PlaybackThread::Track::framesReleased() const
+int64_t Track::framesReleased() const
{
return mAudioTrackServerProxy->framesReleased();
}
-void AudioFlinger::PlaybackThread::Track::onTimestamp(const ExtendedTimestamp ×tamp)
+void Track::onTimestamp(const ExtendedTimestamp ×tamp)
{
// This call comes from a FastTrack and should be kept lockless.
// The server side frames are already translated to client frames.
@@ -1079,14 +1127,14 @@
}
// Don't call for fast tracks; the framesReady() could result in priority inversion
-bool AudioFlinger::PlaybackThread::Track::isReady() const {
- if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
+bool Track::isReady() const {
+ if (mFillingStatus != FS_FILLING || isStopped() || isPausing()) {
return true;
}
if (isStopping()) {
if (framesReady() > 0) {
- mFillingUpStatus = FS_FILLED;
+ mFillingStatus = FS_FILLED;
}
return true;
}
@@ -1100,33 +1148,33 @@
if (framesReady() >= framesToBeReady || (mCblk->mFlags & CBLK_FORCEREADY)) {
ALOGV("%s(%d): consider track ready with %zu/%zu, target was %zu)",
__func__, mId, framesReady(), bufferSizeInFrames, framesToBeReady);
- mFillingUpStatus = FS_FILLED;
+ mFillingStatus = FS_FILLED;
android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
return true;
}
return false;
}
-status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
+status_t Track::start(AudioSystem::sync_event_t event __unused,
audio_session_t triggerSession __unused)
{
status_t status = NO_ERROR;
ALOGV("%s(%d): calling pid %d session %d",
__func__, mId, IPCThreadState::self()->getCallingPid(), mSessionId);
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
if (isOffloaded()) {
- Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
- Mutex::Autolock _lth(thread->mLock);
+ Mutex::Autolock _laf(thread->afThreadCallback()->mutex());
+ Mutex::Autolock _lth(thread->mutex());
sp<IAfEffectChain> ec = thread->getEffectChain_l(mSessionId);
- if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
+ if (thread->afThreadCallback()->isNonOffloadableGlobalEffectEnabled_l() ||
(ec != 0 && ec->isNonOffloadableEnabled())) {
invalidate();
return PERMISSION_DENIED;
}
}
- Mutex::Autolock _lth(thread->mLock);
+ Mutex::Autolock _lth(thread->mutex());
track_state state = mState;
// here the track could be either new, or restarted
// in both cases "unstop" the track
@@ -1158,7 +1206,7 @@
__func__, mId, (int)mThreadIoHandle);
}
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
// states to reset position info for pcm tracks
if (audio_is_linear_pcm(mFormat)
@@ -1226,7 +1274,8 @@
}
if (status == NO_ERROR) {
// send format to AudioManager for playback activity monitoring
- sp<IAudioManager> audioManager = thread->mAudioFlinger->getOrCreateAudioManager();
+ const sp<IAudioManager> audioManager =
+ thread->afThreadCallback()->getOrCreateAudioManager();
if (audioManager && mPortId != AUDIO_PORT_HANDLE_NONE) {
std::unique_ptr<os::PersistableBundle> bundle =
std::make_unique<os::PersistableBundle>();
@@ -1245,17 +1294,17 @@
return status;
}
-void AudioFlinger::PlaybackThread::Track::stop()
+void Track::stop()
{
ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
+ Mutex::Autolock _l(thread->mutex());
track_state state = mState;
if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
// If the track is not active (PAUSED and buffers full), flush buffers
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- if (playbackThread->mActiveTracks.indexOf(this) < 0) {
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
+ if (!playbackThread->isTrackActive(this)) {
reset();
mState = STOPPED;
} else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
@@ -1267,7 +1316,7 @@
// move to STOPPING_2 when drain completes and then STOPPED
mState = STOPPING_1;
if (isOffloaded()) {
- mRetryCount = PlaybackThread::kMaxTrackStopRetriesOffload;
+ mRetryCount = IAfPlaybackThread::kMaxTrackStopRetriesOffload;
}
}
playbackThread->broadcast_l();
@@ -1278,13 +1327,13 @@
}
}
-void AudioFlinger::PlaybackThread::Track::pause()
+void Track::pause()
{
ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
switch (mState) {
case STOPPING_1:
case STOPPING_2:
@@ -1315,18 +1364,18 @@
}
}
-void AudioFlinger::PlaybackThread::Track::flush()
+void Track::flush()
{
ALOGV("%s(%d)", __func__, mId);
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
// Flush the ring buffer now if the track is not active in the PlaybackThread.
// Otherwise the flush would not be done until the track is resumed.
// Requires FastTrack removal be BLOCK_UNTIL_ACKED
- if (playbackThread->mActiveTracks.indexOf(this) < 0) {
+ if (!playbackThread->isTrackActive(this)) {
(void)mServerProxy->flushBufferIfNeeded();
}
@@ -1365,7 +1414,7 @@
if (isDirect()) {
mFlushHwPending = true;
}
- if (playbackThread->mActiveTracks.indexOf(this) < 0) {
+ if (!playbackThread->isTrackActive(this)) {
reset();
}
}
@@ -1380,7 +1429,7 @@
}
// must be called with thread lock held
-void AudioFlinger::PlaybackThread::Track::flushAck()
+void Track::flushAck()
{
if (!isOffloaded() && !isDirect()) {
return;
@@ -1393,12 +1442,12 @@
mFlushHwPending = false;
}
-void AudioFlinger::PlaybackThread::Track::pauseAck()
+void Track::pauseAck()
{
mPauseHwPending = false;
}
-void AudioFlinger::PlaybackThread::Track::reset()
+void Track::reset()
{
// Do not reset twice to avoid discarding data written just after a flush and before
// the audioflinger thread detects the track is stopped.
@@ -1406,7 +1455,7 @@
// Force underrun condition to avoid false underrun callback until first data is
// written to buffer
android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
- mFillingUpStatus = FS_FILLING;
+ mFillingStatus = FS_FILLING;
mResetDone = true;
if (mState == FLUSHED) {
mState = IDLE;
@@ -1414,34 +1463,35 @@
}
}
-status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
+status_t Track::setParameters(const String8& keyValuePairs)
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread == 0) {
ALOGE("%s(%d): thread is dead", __func__, mId);
return FAILED_TRANSACTION;
- } else if ((thread->type() == ThreadBase::DIRECT) ||
- (thread->type() == ThreadBase::OFFLOAD)) {
+ } else if (thread->type() == IAfThreadBase::DIRECT
+ || thread->type() == IAfThreadBase::OFFLOAD) {
return thread->setParameters(keyValuePairs);
} else {
return PERMISSION_DENIED;
}
}
-status_t AudioFlinger::PlaybackThread::Track::selectPresentation(int presentationId,
+status_t Track::selectPresentation(int presentationId,
int programId) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread == 0) {
ALOGE("thread is dead");
return FAILED_TRANSACTION;
- } else if ((thread->type() == ThreadBase::DIRECT) || (thread->type() == ThreadBase::OFFLOAD)) {
- DirectOutputThread *directOutputThread = static_cast<DirectOutputThread*>(thread.get());
+ } else if (thread->type() == IAfThreadBase::DIRECT
+ || thread->type() == IAfThreadBase::OFFLOAD) {
+ auto directOutputThread = thread->asIAfDirectOutputThread().get();
return directOutputThread->selectPresentation(presentationId, programId);
}
return INVALID_OPERATION;
}
-VolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
+VolumeShaper::Status Track::applyVolumeShaper(
const sp<VolumeShaper::Configuration>& configuration,
const sp<VolumeShaper::Operation>& operation)
{
@@ -1449,16 +1499,16 @@
if (isOffloadedOrDirect()) {
// Signal thread to fetch new volume.
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
+ Mutex::Autolock _l(thread->mutex());
thread->broadcast_l();
}
}
return status;
}
-sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id)
+sp<VolumeShaper::State> Track::getVolumeShaperState(int id) const
{
// Note: We don't check if Thread exists.
@@ -1466,7 +1516,7 @@
return mVolumeHandler->getVolumeShaperState(id);
}
-void AudioFlinger::PlaybackThread::Track::setFinalVolume(float volumeLeft, float volumeRight)
+void Track::setFinalVolume(float volumeLeft, float volumeRight)
{
mFinalVolumeLeft = volumeLeft;
mFinalVolumeRight = volumeRight;
@@ -1482,7 +1532,7 @@
}
}
-void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backInserter) const
+void Track::copyMetadataTo(MetadataInserter& backInserter) const
{
// Do not forward metadata for PatchTrack with unspecified stream type
if (mStreamType == AUDIO_STREAM_PATCH) {
@@ -1554,7 +1604,7 @@
*backInserter++ = metadata;
}
-void AudioFlinger::PlaybackThread::Track::updateTeePatches_l() {
+void Track::updateTeePatches_l() {
if (mTeePatchesToUpdate.has_value()) {
forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->destroy(); });
mTeePatches = mTeePatchesToUpdate.value();
@@ -1566,14 +1616,14 @@
}
}
-void AudioFlinger::PlaybackThread::Track::setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) {
+void Track::setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) {
ALOGW_IF(mTeePatchesToUpdate.has_value(),
"%s, existing tee patches to update will be ignored", __func__);
mTeePatchesToUpdate = std::move(teePatchesToUpdate);
}
// must be called with player thread lock held
-void AudioFlinger::PlaybackThread::Track::processMuteEvent_l(const sp<
+void Track::processMuteEvent_l(const sp<
IAudioManager>& audioManager, mute_state_t muteState)
{
if (mMuteState == muteState) {
@@ -1605,31 +1655,32 @@
}
}
-status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
+status_t Track::getTimestamp(AudioTimestamp& timestamp)
{
if (!isOffloaded() && !isDirect()) {
return INVALID_OPERATION; // normal tracks handled through SSQ
}
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread == 0) {
return INVALID_OPERATION;
}
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
return playbackThread->getTimestamp_l(timestamp);
}
-status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
+status_t Track::attachAuxEffect(int EffectId)
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread == nullptr) {
return DEAD_OBJECT;
}
- sp<PlaybackThread> dstThread = (PlaybackThread *)thread.get();
- sp<PlaybackThread> srcThread; // srcThread is initialized by call to moveAuxEffectToIo()
- sp<AudioFlinger> af = mClient->audioFlinger();
+ auto dstThread = thread->asIAfPlaybackThread();
+ // srcThread is initialized by call to moveAuxEffectToIo()
+ sp<IAfPlaybackThread> srcThread;
+ const auto& af = mClient->afClientCallback();
status_t status = af->moveAuxEffectToIo(EffectId, dstThread, &srcThread);
if (EffectId != 0 && status == NO_ERROR) {
@@ -1645,14 +1696,14 @@
return status;
}
-void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
+void Track::setAuxBuffer(int EffectId, int32_t *buffer)
{
mAuxEffectId = EffectId;
mAuxBuffer = buffer;
}
// presentationComplete verified by frames, used by Mixed tracks.
-bool AudioFlinger::PlaybackThread::Track::presentationComplete(
+bool Track::presentationComplete(
int64_t framesWritten, size_t audioHalFrames)
{
// TODO: improve this based on FrameMap if it exists, to ensure full drain.
@@ -1695,7 +1746,7 @@
}
// presentationComplete checked by time, used by DirectTracks.
-bool AudioFlinger::PlaybackThread::Track::presentationComplete(uint32_t latencyMs)
+bool Track::presentationComplete(uint32_t latencyMs)
{
// For Offloaded or Direct tracks.
@@ -1727,14 +1778,14 @@
return false;
}
-void AudioFlinger::PlaybackThread::Track::notifyPresentationComplete()
+void Track::notifyPresentationComplete()
{
// This only triggers once. TODO: should we enforce this?
triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
mAudioTrackServerProxy->setStreamEndDone();
}
-void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
+void Track::triggerEvents(AudioSystem::sync_event_t type)
{
for (auto it = mSyncEvents.begin(); it != mSyncEvents.end();) {
if ((*it)->type() == type) {
@@ -1749,7 +1800,7 @@
// implement VolumeBufferProvider interface
-gain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
+gain_minifloat_packed_t Track::getVolumeLR() const
{
// called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
@@ -1774,7 +1825,7 @@
return vlr;
}
-status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(
+status_t Track::setSyncEvent(
const sp<audioflinger::SyncEvent>& event)
{
if (isTerminated() || mState == PAUSED ||
@@ -1790,19 +1841,19 @@
return NO_ERROR;
}
-void AudioFlinger::PlaybackThread::Track::invalidate()
+void Track::invalidate()
{
TrackBase::invalidate();
signalClientFlag(CBLK_INVALID);
}
-void AudioFlinger::PlaybackThread::Track::disable()
+void Track::disable()
{
// TODO(b/142394888): the filling status should also be reset to filling
signalClientFlag(CBLK_DISABLED);
}
-void AudioFlinger::PlaybackThread::Track::signalClientFlag(int32_t flag)
+void Track::signalClientFlag(int32_t flag)
{
// FIXME should use proxy, and needs work
audio_track_cblk_t* cblk = mCblk;
@@ -1812,25 +1863,25 @@
(void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
}
-void AudioFlinger::PlaybackThread::Track::signal()
+void Track::signal()
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- PlaybackThread *t = (PlaybackThread *)thread.get();
- Mutex::Autolock _l(t->mLock);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock _l(t->mutex());
t->broadcast_l();
}
}
-status_t AudioFlinger::PlaybackThread::Track::getDualMonoMode(audio_dual_mono_mode_t* mode)
+status_t Track::getDualMonoMode(audio_dual_mono_mode_t* mode) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- PlaybackThread *t = (PlaybackThread *)thread.get();
- Mutex::Autolock _l(t->mLock);
- status = t->mOutput->stream->getDualMonoMode(mode);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock _l(t->mutex());
+ status = t->getOutput_l()->stream->getDualMonoMode(mode);
ALOGD_IF((status == NO_ERROR) && (mDualMonoMode != *mode),
"%s: mode %d inconsistent", __func__, mDualMonoMode);
}
@@ -1838,15 +1889,15 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::setDualMonoMode(audio_dual_mono_mode_t mode)
+status_t Track::setDualMonoMode(audio_dual_mono_mode_t mode)
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- auto t = static_cast<PlaybackThread *>(thread.get());
- Mutex::Autolock lock(t->mLock);
- status = t->mOutput->stream->setDualMonoMode(mode);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock lock(t->mutex());
+ status = t->getOutput_l()->stream->setDualMonoMode(mode);
if (status == NO_ERROR) {
mDualMonoMode = mode;
}
@@ -1855,15 +1906,15 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::getAudioDescriptionMixLevel(float* leveldB)
+status_t Track::getAudioDescriptionMixLevel(float* leveldB) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- auto t = static_cast<PlaybackThread *>(thread.get());
- Mutex::Autolock lock(t->mLock);
- status = t->mOutput->stream->getAudioDescriptionMixLevel(leveldB);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock lock(t->mutex());
+ status = t->getOutput_l()->stream->getAudioDescriptionMixLevel(leveldB);
ALOGD_IF((status == NO_ERROR) && (mAudioDescriptionMixLevel != *leveldB),
"%s: level %.3f inconsistent", __func__, mAudioDescriptionMixLevel);
}
@@ -1871,15 +1922,15 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::setAudioDescriptionMixLevel(float leveldB)
+status_t Track::setAudioDescriptionMixLevel(float leveldB)
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- auto t = static_cast<PlaybackThread *>(thread.get());
- Mutex::Autolock lock(t->mLock);
- status = t->mOutput->stream->setAudioDescriptionMixLevel(leveldB);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock lock(t->mutex());
+ status = t->getOutput_l()->stream->setAudioDescriptionMixLevel(leveldB);
if (status == NO_ERROR) {
mAudioDescriptionMixLevel = leveldB;
}
@@ -1888,16 +1939,16 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::getPlaybackRateParameters(
- audio_playback_rate_t* playbackRate)
+status_t Track::getPlaybackRateParameters(
+ audio_playback_rate_t* playbackRate) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- auto t = static_cast<PlaybackThread *>(thread.get());
- Mutex::Autolock lock(t->mLock);
- status = t->mOutput->stream->getPlaybackRateParameters(playbackRate);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock lock(t->mutex());
+ status = t->getOutput_l()->stream->getPlaybackRateParameters(playbackRate);
ALOGD_IF((status == NO_ERROR) &&
!isAudioPlaybackRateEqual(mPlaybackRateParameters, *playbackRate),
"%s: playbackRate inconsistent", __func__);
@@ -1906,16 +1957,16 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::setPlaybackRateParameters(
+status_t Track::setPlaybackRateParameters(
const audio_playback_rate_t& playbackRate)
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
- auto t = static_cast<PlaybackThread *>(thread.get());
- Mutex::Autolock lock(t->mLock);
- status = t->mOutput->stream->setPlaybackRateParameters(playbackRate);
+ auto* const t = thread->asIAfPlaybackThread().get();
+ Mutex::Autolock lock(t->mutex());
+ status = t->getOutput_l()->stream->setPlaybackRateParameters(playbackRate);
if (status == NO_ERROR) {
mPlaybackRateParameters = playbackRate;
}
@@ -1925,7 +1976,7 @@
}
//To be called with thread lock held
-bool AudioFlinger::PlaybackThread::Track::isResumePending() {
+bool Track::isResumePending() const {
if (mState == RESUMING) {
return true;
}
@@ -1939,7 +1990,7 @@
}
//To be called with thread lock held
-void AudioFlinger::PlaybackThread::Track::resumeAck() {
+void Track::resumeAck() {
if (mState == RESUMING) {
mState = ACTIVE;
}
@@ -1953,7 +2004,7 @@
}
//To be called with thread lock held
-void AudioFlinger::PlaybackThread::Track::updateTrackFrameInfo(
+void Track::updateTrackFrameInfo(
int64_t trackFramesReleased, int64_t sinkFramesWritten,
uint32_t halSampleRate, const ExtendedTimestamp &timeStamp) {
// Make the kernel frametime available.
@@ -2033,14 +2084,14 @@
}
}
-bool AudioFlinger::PlaybackThread::Track::AudioVibrationController::setMute(bool muted) {
- sp<ThreadBase> thread = mTrack->mThread.promote();
+bool Track::AudioVibrationController::setMute(bool muted) {
+ const sp<IAfThreadBase> thread = mTrack->mThread.promote();
if (thread != 0) {
// Lock for updating mHapticPlaybackEnabled.
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
- && playbackThread->mHapticChannelCount > 0) {
+ && playbackThread->hapticChannelCount() > 0) {
ALOGD("%s, haptic playback was %s for track %d",
__func__, muted ? "muted" : "unmuted", mTrack->id());
mTrack->setHapticPlaybackEnabled(!muted);
@@ -2050,13 +2101,13 @@
return false;
}
-binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::mute(
+binder::Status Track::AudioVibrationController::mute(
/*out*/ bool *ret) {
*ret = setMute(true);
return binder::Status::ok();
}
-binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::unmute(
+binder::Status Track::AudioVibrationController::unmute(
/*out*/ bool *ret) {
*ret = setMute(false);
return binder::Status::ok();
@@ -2066,9 +2117,28 @@
#undef LOG_TAG
#define LOG_TAG "AF::OutputTrack"
-AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
- PlaybackThread *playbackThread,
- DuplicatingThread *sourceThread,
+/* static */
+sp<IAfOutputTrack> IAfOutputTrack::create(
+ IAfPlaybackThread* playbackThread,
+ IAfDuplicatingThread* sourceThread,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount,
+ const AttributionSourceState& attributionSource) {
+ return sp<OutputTrack>::make(
+ playbackThread,
+ sourceThread,
+ sampleRate,
+ format,
+ channelMask,
+ frameCount,
+ attributionSource);
+}
+
+OutputTrack::OutputTrack(
+ IAfPlaybackThread* playbackThread,
+ IAfDuplicatingThread* sourceThread,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
@@ -2085,7 +2155,7 @@
if (mCblk != NULL) {
mOutBuffer.frameCount = 0;
- playbackThread->mTracks.add(this);
+ playbackThread->addOutputTrack_l(this);
ALOGV("%s(): mCblk %p, mBuffer %p, "
"frameCount %zu, mChannelMask 0x%08x",
__func__, mCblk, mBuffer,
@@ -2103,13 +2173,13 @@
}
}
-AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
+OutputTrack::~OutputTrack()
{
clearBufferQueue();
// superclass destructor will now delete the server proxy and shared memory both refer to
}
-status_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
+status_t OutputTrack::start(AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
status_t status = Track::start(event, triggerSession);
@@ -2122,7 +2192,7 @@
return status;
}
-void AudioFlinger::PlaybackThread::OutputTrack::stop()
+void OutputTrack::stop()
{
Track::stop();
clearBufferQueue();
@@ -2130,11 +2200,11 @@
mActive = false;
}
-ssize_t AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
+ssize_t OutputTrack::write(void* data, uint32_t frames)
{
if (!mActive && frames != 0) {
- sp<ThreadBase> thread = mThread.promote();
- if (thread != nullptr && thread->standby()) {
+ const sp<IAfThreadBase> thread = mThread.promote();
+ if (thread != nullptr && thread->inStandby()) {
// preload one silent buffer to trigger mixer on start()
ClientProxy::Buffer buf { .mFrameCount = mClientProxy->getStartThresholdInFrames() };
status_t status = mClientProxy->obtainBuffer(&buf);
@@ -2152,7 +2222,7 @@
// If another OutputTrack has already started it can underrun but this is OK
// as only silence has been played so far and the retry count is very high on
// OutputTrack.
- auto pt = static_cast<PlaybackThread *>(thread.get());
+ auto* const pt = thread->asIAfPlaybackThread().get();
if (!pt->waitForHalStart()) {
ALOGW("%s(%d): timeout waiting for thread to exit standby", __func__, mId);
stop();
@@ -2241,8 +2311,8 @@
// If we could not write all frames, allocate a buffer and queue it for next time.
if (inBuffer.frameCount) {
- sp<ThreadBase> thread = mThread.promote();
- if (thread != 0 && !thread->standby()) {
+ const sp<IAfThreadBase> thread = mThread.promote();
+ if (thread != nullptr && !thread->inStandby()) {
queueBuffer(inBuffer);
}
}
@@ -2256,7 +2326,7 @@
return frames - inBuffer.frameCount; // number of frames consumed.
}
-void AudioFlinger::PlaybackThread::OutputTrack::queueBuffer(Buffer& inBuffer) {
+void OutputTrack::queueBuffer(Buffer& inBuffer) {
if (mBufferQueue.size() < kMaxOverFlowBuffers) {
Buffer *pInBuffer = new Buffer;
@@ -2279,13 +2349,13 @@
}
}
-void AudioFlinger::PlaybackThread::OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
+void OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
{
std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
backInserter = std::copy(mTrackMetadatas.begin(), mTrackMetadatas.end(), backInserter);
}
-void AudioFlinger::PlaybackThread::OutputTrack::setMetadatas(const SourceMetadatas& metadatas) {
+void OutputTrack::setMetadatas(const SourceMetadatas& metadatas) {
{
std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
mTrackMetadatas = metadatas;
@@ -2294,7 +2364,7 @@
setMetadataHasChanged();
}
-status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
+status_t OutputTrack::obtainBuffer(
AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
{
ClientProxy::Buffer buf;
@@ -2308,7 +2378,7 @@
return status;
}
-void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
+void OutputTrack::clearBufferQueue()
{
size_t size = mBufferQueue.size();
@@ -2320,7 +2390,7 @@
mBufferQueue.clear();
}
-void AudioFlinger::PlaybackThread::OutputTrack::restartIfDisabled()
+void OutputTrack::restartIfDisabled()
{
int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
if (mActive && (flags & CBLK_DISABLED)) {
@@ -2332,7 +2402,38 @@
#undef LOG_TAG
#define LOG_TAG "AF::PatchTrack"
-AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
+/* static */
+sp<IAfPatchTrack> IAfPatchTrack::create(
+ IAfPlaybackThread* playbackThread,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ void* buffer,
+ size_t bufferSize,
+ audio_output_flags_t flags,
+ const Timeout& timeout,
+ size_t frameCountToBeReady /** Default behaviour is to start
+ * as soon as possible to have
+ * the lowest possible latency
+ * even if it might glitch. */)
+{
+ return sp<PatchTrack>::make(
+ playbackThread,
+ streamType,
+ sampleRate,
+ channelMask,
+ format,
+ frameCount,
+ buffer,
+ bufferSize,
+ flags,
+ timeout,
+ frameCountToBeReady);
+}
+
+PatchTrack::PatchTrack(IAfPlaybackThread* playbackThread,
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
@@ -2351,7 +2452,7 @@
TYPE_PATCH, AUDIO_PORT_HANDLE_NONE, frameCountToBeReady),
PatchTrackBase(mCblk ? new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)
: nullptr,
- *playbackThread, timeout)
+ playbackThread, timeout)
{
ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
__func__, mId, sampleRate,
@@ -2359,12 +2460,12 @@
(int)(mPeerTimeout.tv_nsec / 1000000));
}
-AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
+PatchTrack::~PatchTrack()
{
ALOGV("%s(%d)", __func__, mId);
}
-size_t AudioFlinger::PlaybackThread::PatchTrack::framesReady() const
+size_t PatchTrack::framesReady() const
{
if (mPeerProxy && mPeerProxy->producesBufferOnDemand()) {
return std::numeric_limits<size_t>::max();
@@ -2373,7 +2474,7 @@
}
}
-status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
+status_t PatchTrack::start(AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
status_t status = Track::start(event, triggerSession);
@@ -2385,7 +2486,7 @@
}
// AudioBufferProvider interface
-status_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
+status_t PatchTrack::getNextBuffer(
AudioBufferProvider::Buffer* buffer)
{
ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
@@ -2411,7 +2512,7 @@
return status;
}
-void AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+void PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
Proxy::Buffer buf;
@@ -2421,7 +2522,7 @@
TrackBase::releaseBuffer(buffer); // Note: this is the base class.
}
-status_t AudioFlinger::PlaybackThread::PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
+status_t PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
const struct timespec *timeOut)
{
status_t status = NO_ERROR;
@@ -2438,7 +2539,7 @@
return status;
}
-void AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
+void PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
{
mProxy->releaseBuffer(buffer);
restartIfDisabled();
@@ -2447,23 +2548,23 @@
// If not, prevent an underrun from occurring by moving the track into FS_FILLING;
// this logic avoids glitches when suspending A2DP with AudioPlaybackCapture.
// TODO: perhaps underrun avoidance could be a track property checked in isReady() instead.
- if (mFillingUpStatus == FS_ACTIVE
+ if (mFillingStatus == FS_ACTIVE
&& audio_is_linear_pcm(mFormat)
&& !isOffloadedOrDirect()) {
- if (sp<ThreadBase> thread = mThread.promote();
+ if (const sp<IAfThreadBase> thread = mThread.promote();
thread != 0) {
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ auto* const playbackThread = thread->asIAfPlaybackThread().get();
const size_t frameCount = playbackThread->frameCount() * sampleRate()
/ playbackThread->sampleRate();
if (framesReady() < frameCount) {
ALOGD("%s(%d) Not enough data, wait for buffer to fill", __func__, mId);
- mFillingUpStatus = FS_FILLING;
+ mFillingStatus = FS_FILLING;
}
}
}
}
-void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
+void PatchTrack::restartIfDisabled()
{
if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
ALOGW("%s(%d): disabled due to previous underrun, restarting", __func__, mId);
@@ -2481,7 +2582,7 @@
class RecordHandle : public android::media::BnAudioRecord {
public:
- explicit RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack);
+ explicit RecordHandle(const sp<IAfRecordTrack>& recordTrack);
~RecordHandle() override;
binder::Status start(int /*AudioSystem::sync_event_t*/ event,
int /*audio_session_t*/ triggerSession) final;
@@ -2495,24 +2596,23 @@
const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) final;
private:
- const sp<AudioFlinger::RecordThread::RecordTrack> mRecordTrack;
+ const sp<IAfRecordTrack> mRecordTrack;
// for use from destructor
void stop_nonvirtual();
};
/* static */
-sp<media::IAudioRecord> AudioFlinger::RecordThread::RecordTrack::createIAudioRecordAdapter(
- const sp<RecordTrack>& recordTrack) {
+sp<media::IAudioRecord> IAfRecordTrack::createIAudioRecordAdapter(
+ const sp<IAfRecordTrack>& recordTrack) {
return sp<RecordHandle>::make(recordTrack);
}
RecordHandle::RecordHandle(
- const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
+ const sp<IAfRecordTrack>& recordTrack)
: BnAudioRecord(),
mRecordTrack(recordTrack)
{
- // TODO(b/288339104) binder thread priority change not needed.
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}
@@ -2566,9 +2666,47 @@
#undef LOG_TAG
#define LOG_TAG "AF::RecordTrack"
+
+/* static */
+sp<IAfRecordTrack> IAfRecordTrack::create(IAfRecordThread* thread,
+ const sp<Client>& client,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount,
+ void* buffer,
+ size_t bufferSize,
+ audio_session_t sessionId,
+ pid_t creatorPid,
+ const AttributionSourceState& attributionSource,
+ audio_input_flags_t flags,
+ track_type type,
+ audio_port_handle_t portId,
+ int32_t startFrames)
+{
+ return sp<RecordTrack>::make(
+ thread,
+ client,
+ attr,
+ sampleRate,
+ format,
+ channelMask,
+ frameCount,
+ buffer,
+ bufferSize,
+ sessionId,
+ creatorPid,
+ attributionSource,
+ flags,
+ type,
+ portId,
+ startFrames);
+}
+
// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
-AudioFlinger::RecordThread::RecordTrack::RecordTrack(
- RecordThread *thread,
+RecordTrack::RecordTrack(
+ IAfRecordThread* thread,
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t sampleRate,
@@ -2607,7 +2745,7 @@
if (!isDirect()) {
mRecordBufferConverter = new RecordBufferConverter(
- thread->mChannelMask, thread->mFormat, thread->mSampleRate,
+ thread->channelMask(), thread->format(), thread->sampleRate(),
channelMask, format, sampleRate);
// Check if the RecordBufferConverter construction was successful.
// If not, don't continue with construction.
@@ -2627,8 +2765,8 @@
mResamplerBufferProvider = new ResamplerBufferProvider(this);
if (flags & AUDIO_INPUT_FLAG_FAST) {
- ALOG_ASSERT(thread->mFastTrackAvail);
- thread->mFastTrackAvail = false;
+ ALOG_ASSERT(thread->fastTrackAvailable());
+ thread->setFastTrackAvailable(false);
} else {
// TODO: only Normal Record has timestamps (Fast Record does not).
mServerLatencySupported = checkServerLatencySupported(mFormat, flags);
@@ -2643,14 +2781,14 @@
mTrackMetrics.logConstructor(creatorPid, uid(), id());
}
-AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
+RecordTrack::~RecordTrack()
{
ALOGV("%s()", __func__);
delete mRecordBufferConverter;
delete mResamplerBufferProvider;
}
-status_t AudioFlinger::RecordThread::RecordTrack::initCheck() const
+status_t RecordTrack::initCheck() const
{
status_t status = TrackBase::initCheck();
if (status == NO_ERROR && mServerProxy == 0) {
@@ -2660,7 +2798,7 @@
}
// AudioBufferProvider interface
-status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
{
ServerProxy::Buffer buf;
buf.mFrameCount = buffer->frameCount;
@@ -2674,12 +2812,12 @@
return status;
}
-status_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
+status_t RecordTrack::start(AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
return recordThread->start(this, event, triggerSession);
} else {
ALOGW("%s track %d: thread was destroyed", __func__, portId());
@@ -2687,27 +2825,27 @@
}
}
-void AudioFlinger::RecordThread::RecordTrack::stop()
+void RecordTrack::stop()
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
if (recordThread->stop(this) && isExternalTrack()) {
AudioSystem::stopInput(mPortId);
}
}
}
-void AudioFlinger::RecordThread::RecordTrack::destroy()
+void RecordTrack::destroy()
{
- // see comments at AudioFlinger::PlaybackThread::Track::destroy()
+ // see comments at Track::destroy()
sp<RecordTrack> keep(this);
{
track_state priorState = mState;
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
- RecordThread *recordThread = (RecordThread *) thread.get();
+ Mutex::Autolock _l(thread->mutex());
+ auto* const recordThread = thread->asIAfRecordThread().get();
priorState = mState;
if (!mSharedAudioPackageName.empty()) {
recordThread->resetAudioHistory_l();
@@ -2738,7 +2876,7 @@
}
}
-void AudioFlinger::RecordThread::RecordTrack::invalidate()
+void RecordTrack::invalidate()
{
TrackBase::invalidate();
// FIXME should use proxy, and needs work
@@ -2750,7 +2888,7 @@
}
-void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
+void RecordTrack::appendDumpHeader(String8& result) const
{
result.appendFormat("Active Id Client Session Port Id S Flags "
" Format Chn mask SRate Source "
@@ -2758,7 +2896,7 @@
isServerLatencySupported() ? " Latency" : "");
}
-void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
+void RecordTrack::appendDump(String8& result, bool active) const
{
result.appendFormat("%c%5s %6d %6u %7u %7u %2s 0x%03X "
"%08X %08X %6u %6X "
@@ -2797,26 +2935,26 @@
}
// This is invoked by SyncEvent callback.
-void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(
+void RecordTrack::handleSyncStartEvent(
const sp<audioflinger::SyncEvent>& event)
{
size_t framesToDrop = 0;
- sp<ThreadBase> threadBase = mThread.promote();
+ const sp<IAfThreadBase> threadBase = mThread.promote();
if (threadBase != 0) {
// TODO: use actual buffer filling status instead of 2 buffers when info is available
// from audio HAL
- framesToDrop = threadBase->mFrameCount * 2;
+ framesToDrop = threadBase->frameCount() * 2;
}
mSynchronizedRecordState.onPlaybackFinished(event, framesToDrop);
}
-void AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
+void RecordTrack::clearSyncStartEvent()
{
mSynchronizedRecordState.clear();
}
-void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
+void RecordTrack::updateTrackFrameInfo(
int64_t trackFramesReleased, int64_t sourceFramesRead,
uint32_t halSampleRate, const ExtendedTimestamp ×tamp)
{
@@ -2856,40 +2994,40 @@
mServerLatencyMs.store(latencyMs);
}
-status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones)
+status_t RecordTrack::getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const
{
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
return recordThread->getActiveMicrophones(activeMicrophones);
} else {
return BAD_VALUE;
}
}
-status_t AudioFlinger::RecordThread::RecordTrack::setPreferredMicrophoneDirection(
+status_t RecordTrack::setPreferredMicrophoneDirection(
audio_microphone_direction_t direction) {
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
return recordThread->setPreferredMicrophoneDirection(direction);
} else {
return BAD_VALUE;
}
}
-status_t AudioFlinger::RecordThread::RecordTrack::setPreferredMicrophoneFieldDimension(float zoom) {
- sp<ThreadBase> thread = mThread.promote();
+status_t RecordTrack::setPreferredMicrophoneFieldDimension(float zoom) {
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
return recordThread->setPreferredMicrophoneFieldDimension(zoom);
} else {
return BAD_VALUE;
}
}
-status_t AudioFlinger::RecordThread::RecordTrack::shareAudioHistory(
+status_t RecordTrack::shareAudioHistory(
const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) {
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -2906,9 +3044,9 @@
return PERMISSION_DENIED;
}
- sp<ThreadBase> thread = mThread.promote();
+ const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- RecordThread *recordThread = (RecordThread *)thread.get();
+ auto* const recordThread = thread->asIAfRecordThread().get();
status_t status = recordThread->shareAudioHistory(
sharedAudioPackageName, mSessionId, sharedAudioStartMs);
if (status == NO_ERROR) {
@@ -2920,7 +3058,7 @@
}
}
-void AudioFlinger::RecordThread::RecordTrack::copyMetadataTo(MetadataInserter& backInserter) const
+void RecordTrack::copyMetadataTo(MetadataInserter& backInserter) const
{
// Do not forward PatchRecord metadata with unspecified audio source
@@ -2944,7 +3082,33 @@
#undef LOG_TAG
#define LOG_TAG "AF::PatchRecord"
-AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
+/* static */
+sp<IAfPatchRecord> IAfPatchRecord::create(
+ IAfRecordThread* recordThread,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ void *buffer,
+ size_t bufferSize,
+ audio_input_flags_t flags,
+ const Timeout& timeout,
+ audio_source_t source)
+{
+ return sp<PatchRecord>::make(
+ recordThread,
+ sampleRate,
+ channelMask,
+ format,
+ frameCount,
+ buffer,
+ bufferSize,
+ flags,
+ timeout,
+ source);
+}
+
+PatchRecord::PatchRecord(IAfRecordThread* recordThread,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_format_t format,
@@ -2961,7 +3125,7 @@
audioServerAttributionSource(getpid()), flags, TYPE_PATCH),
PatchTrackBase(mCblk ? new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true)
: nullptr,
- *recordThread, timeout)
+ recordThread, timeout)
{
ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
__func__, mId, sampleRate,
@@ -2969,7 +3133,7 @@
(int)(mPeerTimeout.tv_nsec / 1000000));
}
-AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
+PatchRecord::~PatchRecord()
{
ALOGV("%s(%d)", __func__, mId);
}
@@ -2993,7 +3157,7 @@
}
// static
-size_t AudioFlinger::RecordThread::PatchRecord::writeFrames(
+size_t PatchRecord::writeFrames(
AudioBufferProvider* dest, const void* src, size_t frameCount, size_t frameSize)
{
size_t framesWritten = writeFramesHelper(dest, src, frameCount, frameSize);
@@ -3008,7 +3172,7 @@
}
// AudioBufferProvider interface
-status_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
+status_t PatchRecord::getNextBuffer(
AudioBufferProvider::Buffer* buffer)
{
ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
@@ -3030,7 +3194,7 @@
return status;
}
-void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+void PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
Proxy::Buffer buf;
@@ -3040,13 +3204,13 @@
TrackBase::releaseBuffer(buffer);
}
-status_t AudioFlinger::RecordThread::PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
+status_t PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
const struct timespec *timeOut)
{
return mProxy->obtainBuffer(buffer, timeOut);
}
-void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
+void PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
{
mProxy->releaseBuffer(buffer);
}
@@ -3061,8 +3225,28 @@
return {ptr, free};
}
-AudioFlinger::RecordThread::PassthruPatchRecord::PassthruPatchRecord(
- RecordThread *recordThread,
+/* static */
+sp<IAfPatchRecord> IAfPatchRecord::createPassThru(
+ IAfRecordThread* recordThread,
+ uint32_t sampleRate,
+ audio_channel_mask_t channelMask,
+ audio_format_t format,
+ size_t frameCount,
+ audio_input_flags_t flags,
+ audio_source_t source)
+{
+ return sp<PassthruPatchRecord>::make(
+ recordThread,
+ sampleRate,
+ channelMask,
+ format,
+ frameCount,
+ flags,
+ source);
+}
+
+PassthruPatchRecord::PassthruPatchRecord(
+ IAfRecordThread* recordThread,
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_format_t format,
@@ -3078,18 +3262,18 @@
memset(mStubBuffer.get(), 0, mFrameCount * mFrameSize);
}
-sp<StreamInHalInterface> AudioFlinger::RecordThread::PassthruPatchRecord::obtainStream(
- sp<ThreadBase>* thread)
+sp<StreamInHalInterface> PassthruPatchRecord::obtainStream(
+ sp<IAfThreadBase>* thread)
{
*thread = mThread.promote();
if (!*thread) return nullptr;
- RecordThread *recordThread = static_cast<RecordThread*>((*thread).get());
- Mutex::Autolock _l(recordThread->mLock);
- return recordThread->mInput ? recordThread->mInput->stream : nullptr;
+ auto* const recordThread = (*thread)->asIAfRecordThread().get();
+ Mutex::Autolock _l(recordThread->mutex());
+ return recordThread->getInput() ? recordThread->getInput()->stream : nullptr;
}
// PatchProxyBufferProvider methods are called on DirectOutputThread
-status_t AudioFlinger::RecordThread::PassthruPatchRecord::obtainBuffer(
+status_t PassthruPatchRecord::obtainBuffer(
Proxy::Buffer* buffer, const struct timespec* timeOut)
{
if (mUnconsumedFrames) {
@@ -3107,7 +3291,7 @@
const size_t framesToRead = std::min(buffer->mFrameCount, mFrameCount);
buffer->mFrameCount = 0;
buffer->mRaw = nullptr;
- sp<ThreadBase> thread;
+ sp<IAfThreadBase> thread;
sp<StreamInHalInterface> stream = obtainStream(&thread);
if (!stream) return NO_INIT; // If there is no stream, RecordThread is not reading.
@@ -3155,7 +3339,7 @@
return result;
}
-void AudioFlinger::RecordThread::PassthruPatchRecord::releaseBuffer(Proxy::Buffer* buffer)
+void PassthruPatchRecord::releaseBuffer(Proxy::Buffer* buffer)
{
if (buffer->mFrameCount <= mUnconsumedFrames) {
mUnconsumedFrames -= buffer->mFrameCount;
@@ -3172,7 +3356,7 @@
// and 'releaseBuffer' are stubbed out and ignore their input.
// It's not possible to retrieve actual data here w/o blocking 'obtainBuffer'
// until we copy it.
-status_t AudioFlinger::RecordThread::PassthruPatchRecord::read(
+status_t PassthruPatchRecord::read(
void* buffer, size_t bytes, size_t* read)
{
bytes = std::min(bytes, mFrameCount * mFrameSize);
@@ -3191,15 +3375,15 @@
return 0;
}
-status_t AudioFlinger::RecordThread::PassthruPatchRecord::getCapturePosition(
+status_t PassthruPatchRecord::getCapturePosition(
int64_t* frames, int64_t* time)
{
- sp<ThreadBase> thread;
+ sp<IAfThreadBase> thread;
sp<StreamInHalInterface> stream = obtainStream(&thread);
return stream ? stream->getCapturePosition(frames, time) : NO_INIT;
}
-status_t AudioFlinger::RecordThread::PassthruPatchRecord::standby()
+status_t PassthruPatchRecord::standby()
{
// RecordThread issues 'standby' command in two major cases:
// 1. Error on read--this case is handled in 'obtainBuffer'.
@@ -3211,7 +3395,7 @@
}
// As the buffer gets filled in obtainBuffer, here we only simulate data consumption.
-status_t AudioFlinger::RecordThread::PassthruPatchRecord::getNextBuffer(
+status_t PassthruPatchRecord::getNextBuffer(
AudioBufferProvider::Buffer* buffer)
{
buffer->frameCount = mLastReadFrames;
@@ -3219,7 +3403,7 @@
return NO_ERROR;
}
-void AudioFlinger::RecordThread::PassthruPatchRecord::releaseBuffer(
+void PassthruPatchRecord::releaseBuffer(
AudioBufferProvider::Buffer* buffer)
{
buffer->frameCount = 0;
@@ -3230,7 +3414,32 @@
#undef LOG_TAG
#define LOG_TAG "AF::MmapTrack"
-AudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
+/* static */
+sp<IAfMmapTrack> IAfMmapTrack::create(IAfThreadBase* thread,
+ const audio_attributes_t& attr,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_session_t sessionId,
+ bool isOut,
+ const android::content::AttributionSourceState& attributionSource,
+ pid_t creatorPid,
+ audio_port_handle_t portId)
+{
+ return sp<MmapTrack>::make(
+ thread,
+ attr,
+ sampleRate,
+ format,
+ channelMask,
+ sessionId,
+ isOut,
+ attributionSource,
+ creatorPid,
+ portId);
+}
+
+MmapTrack::MmapTrack(IAfThreadBase* thread,
const audio_attributes_t& attr,
uint32_t sampleRate,
audio_format_t format,
@@ -3256,27 +3465,27 @@
mTrackMetrics.logConstructor(creatorPid, uid(), id());
}
-AudioFlinger::MmapThread::MmapTrack::~MmapTrack()
+MmapTrack::~MmapTrack()
{
}
-status_t AudioFlinger::MmapThread::MmapTrack::initCheck() const
+status_t MmapTrack::initCheck() const
{
return NO_ERROR;
}
-status_t AudioFlinger::MmapThread::MmapTrack::start(AudioSystem::sync_event_t event __unused,
+status_t MmapTrack::start(AudioSystem::sync_event_t event __unused,
audio_session_t triggerSession __unused)
{
return NO_ERROR;
}
-void AudioFlinger::MmapThread::MmapTrack::stop()
+void MmapTrack::stop()
{
}
// AudioBufferProvider interface
-status_t AudioFlinger::MmapThread::MmapTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t MmapTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
{
buffer->frameCount = 0;
buffer->raw = nullptr;
@@ -3284,21 +3493,20 @@
}
// ExtendedAudioBufferProvider interface
-size_t AudioFlinger::MmapThread::MmapTrack::framesReady() const {
+size_t MmapTrack::framesReady() const {
return 0;
}
-int64_t AudioFlinger::MmapThread::MmapTrack::framesReleased() const
+int64_t MmapTrack::framesReleased() const
{
return 0;
}
-void AudioFlinger::MmapThread::MmapTrack::onTimestamp(const ExtendedTimestamp ×tamp __unused)
+void MmapTrack::onTimestamp(const ExtendedTimestamp& timestamp __unused)
{
}
-void AudioFlinger::MmapThread::MmapTrack::processMuteEvent_l(const sp<
- IAudioManager>& audioManager, mute_state_t muteState)
+void MmapTrack::processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState)
{
if (mMuteState == muteState) {
// mute state did not change, do nothing
@@ -3329,13 +3537,13 @@
}
}
-void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
+void MmapTrack::appendDumpHeader(String8& result) const
{
result.appendFormat("Client Session Port Id Format Chn mask SRate Flags %s\n",
isOut() ? "Usg CT": "Source");
}
-void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
+void MmapTrack::appendDump(String8& result, bool active __unused) const
{
result.appendFormat("%6u %7u %7u %08X %08X %6u 0x%03X ",
mPid,
diff --git a/services/audioflinger/afutils/Android.bp b/services/audioflinger/afutils/Android.bp
index 1580b8f..5e29ce9 100644
--- a/services/audioflinger/afutils/Android.bp
+++ b/services/audioflinger/afutils/Android.bp
@@ -39,18 +39,24 @@
"AudioWatchdog.cpp",
"BufLog.cpp",
"NBAIO_Tee.cpp",
+ "Permission.cpp",
"PropertyUtils.cpp",
"TypedLogger.cpp",
+ "Vibrator.cpp",
],
shared_libs: [
+ "framework-permission-aidl-cpp",
+ "libaudioclient_aidl_conversion",
"libaudioutils",
"libbase",
+ "libbinder",
"libcutils", // property_get_int32
"liblog",
"libnbaio",
"libnblog",
"libutils",
+ "libvibrator",
],
static_libs: [
diff --git a/services/audioflinger/afutils/DumpTryLock.h b/services/audioflinger/afutils/DumpTryLock.h
new file mode 100644
index 0000000..c185a68
--- /dev/null
+++ b/services/audioflinger/afutils/DumpTryLock.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/Mutex.h>
+
+namespace android::afutils {
+
+inline bool dumpTryLock(Mutex& mutex)
+{
+ static constexpr int kDumpLockTimeoutNs = 1'000'000'000;
+ const status_t err = mutex.timedLock(kDumpLockTimeoutNs);
+ return err == NO_ERROR;
+}
+
+} // android::afutils
\ No newline at end of file
diff --git a/services/audioflinger/afutils/Permission.cpp b/services/audioflinger/afutils/Permission.cpp
new file mode 100644
index 0000000..35448e3
--- /dev/null
+++ b/services/audioflinger/afutils/Permission.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Permission"
+//#define LOG_NDEBUG 0
+
+#include "Permission.h"
+
+#include <binder/PermissionController.h>
+#include <media/AidlConversionCppNdk.h>
+#include <utils/Log.h>
+
+namespace android::afutils {
+
+// TODO b/182392769: use attribution source util
+content::AttributionSourceState checkAttributionSourcePackage(
+ const content::AttributionSourceState& attributionSource) {
+ Vector<String16> packages;
+ PermissionController{}.getPackagesForUid(attributionSource.uid, packages);
+
+ content::AttributionSourceState checkedAttributionSource = attributionSource;
+ if (!attributionSource.packageName.has_value()
+ || attributionSource.packageName.value().size() == 0) {
+ if (!packages.isEmpty()) {
+ checkedAttributionSource.packageName =
+ std::move(legacy2aidl_String16_string(packages[0]).value());
+ }
+ } else {
+ const String16 opPackageLegacy = VALUE_OR_FATAL(
+ aidl2legacy_string_view_String16(attributionSource.packageName.value_or("")));
+ if (std::find_if(packages.begin(), packages.end(),
+ [&opPackageLegacy](const auto& package) {
+ return opPackageLegacy == package; }) == packages.end()) {
+ ALOGW("The package name(%s) provided does not correspond to the uid %d",
+ attributionSource.packageName.value_or("").c_str(), attributionSource.uid);
+ }
+ }
+ return checkedAttributionSource;
+}
+
+} // namespace android::afutils
diff --git a/services/audioflinger/afutils/Permission.h b/services/audioflinger/afutils/Permission.h
new file mode 100644
index 0000000..97c7ff9
--- /dev/null
+++ b/services/audioflinger/afutils/Permission.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/content/AttributionSourceState.h>
+
+namespace android::afutils {
+
+content::AttributionSourceState checkAttributionSourcePackage(
+ const content::AttributionSourceState& attributionSource);
+
+} // namespace android::afutils
diff --git a/services/audioflinger/afutils/Vibrator.cpp b/services/audioflinger/afutils/Vibrator.cpp
new file mode 100644
index 0000000..25fcc6a
--- /dev/null
+++ b/services/audioflinger/afutils/Vibrator.cpp
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioFlinger::Vibrator"
+//#define LOG_NDEBUG 0
+
+#include "Vibrator.h"
+
+#include <android/os/IExternalVibratorService.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <mutex>
+
+namespace android::afutils {
+
+static sp<os::IExternalVibratorService> getExternalVibratorService() {
+ static std::mutex m;
+ static sp<os::IExternalVibratorService> sExternalVibratorService;
+
+ std::lock_guard l(m);
+ if (sExternalVibratorService == nullptr) {
+ const sp<IBinder> binder = defaultServiceManager()->getService(
+ String16("external_vibrator_service"));
+ if (binder != nullptr) {
+ sExternalVibratorService = interface_cast<os::IExternalVibratorService>(binder);
+ }
+ }
+ return sExternalVibratorService;
+}
+
+os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration) {
+ const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+ if (evs != nullptr) {
+ int32_t ret;
+ binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
+ if (status.isOk()) {
+ ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
+ return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
+ }
+ }
+ ALOGD("%s, start external vibration with intensity as MUTE due to %s",
+ __func__,
+ evs == nullptr ? "external vibration service not found"
+ : "error when querying intensity");
+ return os::HapticScale::MUTE;
+}
+
+void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
+ const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
+ if (evs != nullptr) {
+ ALOGD("%s, stop external vibration", __func__);
+ evs->onExternalVibrationStop(*externalVibration);
+ }
+}
+
+} // namespace android::afutils
diff --git a/services/audioflinger/afutils/Vibrator.h b/services/audioflinger/afutils/Vibrator.h
new file mode 100644
index 0000000..4354872
--- /dev/null
+++ b/services/audioflinger/afutils/Vibrator.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vibrator/ExternalVibration.h>
+#include <vibrator/ExternalVibrationUtils.h>
+
+namespace android::afutils {
+
+os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration);
+
+void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
+
+} // namespace android::afutils
diff --git a/services/audioflinger/datapath/AudioStreamIn.h b/services/audioflinger/datapath/AudioStreamIn.h
new file mode 100644
index 0000000..604a4e4
--- /dev/null
+++ b/services/audioflinger/datapath/AudioStreamIn.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "AudioHwDevice.h"
+#include <media/audiohal/DeviceHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+
+namespace android {
+
+// Abstraction for the Audio Source for the RecordThread (HAL or PassthruPatchRecord).
+struct Source {
+ virtual ~Source() = default;
+ // The following methods have the same signatures as in StreamHalInterface.
+ virtual status_t read(void* buffer, size_t bytes, size_t* read) = 0;
+ virtual status_t getCapturePosition(int64_t* frames, int64_t* time) = 0;
+ virtual status_t standby() = 0;
+};
+
+// AudioStreamIn is immutable, so its fields are const.
+// The methods must not be const to match StreamHalInterface signature.
+
+struct AudioStreamIn : public Source {
+ const AudioHwDevice* const audioHwDev;
+ const sp<StreamInHalInterface> stream;
+ const audio_input_flags_t flags;
+
+ AudioStreamIn(
+ const AudioHwDevice* dev, const sp<StreamInHalInterface>& in,
+ audio_input_flags_t flags)
+ : audioHwDev(dev), stream(in), flags(flags) {}
+
+ status_t read(void* buffer, size_t bytes, size_t* read) final {
+ return stream->read(buffer, bytes, read);
+ }
+
+ status_t getCapturePosition(int64_t* frames, int64_t* time) final {
+ return stream->getCapturePosition(frames, time);
+ }
+
+ status_t standby() final { return stream->standby(); }
+
+ sp<DeviceHalInterface> hwDev() const { return audioHwDev->hwDevice(); }
+};
+
+} // namespace android
diff --git a/services/audioflinger/datapath/ThreadMetrics.h b/services/audioflinger/datapath/ThreadMetrics.h
index 5493b3c..c643a57 100644
--- a/services/audioflinger/datapath/ThreadMetrics.h
+++ b/services/audioflinger/datapath/ThreadMetrics.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_AUDIO_THREADMETRICS_H
#define ANDROID_AUDIO_THREADMETRICS_H
+#include <media/MediaMetricsItem.h>
+
#include <mutex>
namespace android {
diff --git a/services/audioflinger/datapath/TrackMetrics.h b/services/audioflinger/datapath/TrackMetrics.h
index f3425df..2b44acb 100644
--- a/services/audioflinger/datapath/TrackMetrics.h
+++ b/services/audioflinger/datapath/TrackMetrics.h
@@ -20,6 +20,8 @@
#include <binder/IActivityManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <media/MediaMetricsItem.h>
+
#include <mutex>
namespace android {
diff --git a/services/audioflinger/datapath/VolumeInterface.h b/services/audioflinger/datapath/VolumeInterface.h
new file mode 100644
index 0000000..1564fe1
--- /dev/null
+++ b/services/audioflinger/datapath/VolumeInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+
+namespace android {
+
+class VolumeInterface : public virtual RefBase {
+public:
+ virtual void setMasterVolume(float value) = 0;
+ virtual void setMasterBalance(float balance) = 0;
+ virtual void setMasterMute(bool muted) = 0;
+ virtual void setStreamVolume(audio_stream_type_t stream, float value) = 0;
+ virtual void setStreamMute(audio_stream_type_t stream, bool muted) = 0;
+ // TODO(b/290699744) add "get" prefix for getter below.
+ virtual float streamVolume(audio_stream_type_t stream) const = 0;
+};
+
+} // namespace android
diff --git a/services/audioflinger/fastpath/FastMixerState.h b/services/audioflinger/fastpath/FastMixerState.h
index c70e42a..8ab6d25 100644
--- a/services/audioflinger/fastpath/FastMixerState.h
+++ b/services/audioflinger/fastpath/FastMixerState.h
@@ -35,7 +35,7 @@
class VolumeProvider {
public:
// The provider implementation is responsible for validating that the return value is in range.
- virtual gain_minifloat_packed_t getVolumeLR() = 0;
+ virtual gain_minifloat_packed_t getVolumeLR() const = 0;
protected:
VolumeProvider() = default;
virtual ~VolumeProvider() = default;
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 59eee52..d40bbcb 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -25,6 +25,10 @@
namespace android {
+class AudioInputCollection;
+class AudioInputDescriptor;
+class AudioPolicyClientInterface;
+
class EffectDescriptor : public RefBase
{
public:
@@ -40,6 +44,8 @@
int mId; // effect unique ID
audio_io_handle_t mIo; // io the effect is attached to
+ bool mIsOrphan = false; // on creation, effect is not yet attached but not yet orphan
+ bool mEnabledWhenMoved = false; // Backup enabled state before being moved
audio_session_t mSession; // audio session the effect is on
effect_descriptor_t mDesc; // effect descriptor
bool mEnabled; // enabled state: CPU load being used or not
@@ -69,12 +75,28 @@
void moveEffects(audio_session_t session,
audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput);
+ audio_io_handle_t dstOutput,
+ AudioPolicyClientInterface *clientInterface);
void moveEffects(const std::vector<int>& ids, audio_io_handle_t dstOutput);
+ void moveEffects(audio_session_t sessionId, audio_io_handle_t srcIo, audio_io_handle_t dstIo,
+ const AudioInputCollection *inputs, AudioPolicyClientInterface *clientInterface);
+ void moveEffectsForIo(audio_session_t sessionId, audio_io_handle_t dstIo,
+ const AudioInputCollection *inputs, AudioPolicyClientInterface *mClientInterface);
+ void putOrphanEffects(audio_session_t sessionId, audio_io_handle_t srcIo,
+ const AudioInputCollection *inputs, AudioPolicyClientInterface *clientInterface);
+ /**
+ * @brief Checks if an effect session was already attached to an io handle and return it if
+ * found. Check only for a given effect type if effectType is not null or for any effect
+ * otherwise.
+ * @param sessionId to consider.
+ * @param effectType to consider.
+ * @return ioHandle if found, AUDIO_IO_HANDLE_NONE otherwise.
+ */
audio_io_handle_t getIoForSession(audio_session_t sessionId,
const effect_uuid_t *effectType = nullptr);
-
+ bool hasOrphansForSession(audio_session_t sessionId);
+ EffectDescriptorCollection getOrphanEffectsForSession(audio_session_t sessionId) const;
void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 3f9c8b0..216d2eb 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -18,9 +18,15 @@
//#define LOG_NDEBUG 0
#include <android-base/stringprintf.h>
+
+#include "AudioInputDescriptor.h"
#include "EffectDescriptor.h"
#include <utils/String8.h>
+#include <AudioPolicyInterface.h>
+#include "AudioPolicyMix.h"
+#include "HwModule.h"
+
namespace android {
void EffectDescriptor::dump(String8 *dst, int spaces) const
@@ -175,30 +181,57 @@
return MAX_EFFECTS_MEMORY;
}
-void EffectDescriptorCollection::moveEffects(audio_session_t session,
- audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput)
+void EffectDescriptorCollection::moveEffects(audio_session_t sessionId, audio_io_handle_t srcIo,
+ audio_io_handle_t dstIo,
+ AudioPolicyClientInterface *clientInterface)
{
- ALOGV("%s session %d srcOutput %d dstOutput %d", __func__, session, srcOutput, dstOutput);
+ ALOGV("%s session %d srcIo %d dstIo %d", __func__, sessionId, srcIo, dstIo);
for (size_t i = 0; i < size(); i++) {
sp<EffectDescriptor> effect = valueAt(i);
- if (effect->mSession == session && effect->mIo == srcOutput) {
- effect->mIo = dstOutput;
+ if (effect->mSession == sessionId && effect->mIo == srcIo) {
+ effect->mIo = dstIo;
+ // Backup enable state before any updatePolicyState call
+ effect->mIsOrphan = (dstIo == AUDIO_IO_HANDLE_NONE);
+ }
+ }
+ clientInterface->moveEffects(sessionId, srcIo, dstIo);
+}
+
+void EffectDescriptorCollection::moveEffects(const std::vector<int>& ids, audio_io_handle_t dstIo)
+{
+ ALOGV("%s num effects %zu, first ID %d, dstIo %d",
+ __func__, ids.size(), ids.size() ? ids[0] : 0, dstIo);
+ for (size_t i = 0; i < size(); i++) {
+ sp<EffectDescriptor> effect = valueAt(i);
+ if (std::find(begin(ids), end(ids), effect->mId) != end(ids)) {
+ effect->mIo = dstIo;
+ effect->mIsOrphan = (dstIo == AUDIO_IO_HANDLE_NONE);
}
}
}
-void EffectDescriptorCollection::moveEffects(const std::vector<int>& ids,
- audio_io_handle_t dstOutput)
+bool EffectDescriptorCollection::hasOrphansForSession(audio_session_t sessionId)
{
- ALOGV("%s num effects %zu, first ID %d, dstOutput %d",
- __func__, ids.size(), ids.size() ? ids[0] : 0, dstOutput);
- for (size_t i = 0; i < size(); i++) {
+ for (size_t i = 0; i < size(); ++i) {
sp<EffectDescriptor> effect = valueAt(i);
- if (std::find(begin(ids), end(ids), effect->mId) != end(ids)) {
- effect->mIo = dstOutput;
+ if (effect->mSession == sessionId && effect->mIsOrphan) {
+ return true;
}
}
+ return false;
+}
+
+EffectDescriptorCollection EffectDescriptorCollection::getOrphanEffectsForSession(
+ audio_session_t sessionId) const
+{
+ EffectDescriptorCollection effects;
+ for (size_t i = 0; i < size(); i++) {
+ sp<EffectDescriptor> effect = valueAt(i);
+ if (effect->mSession == sessionId && effect->mIsOrphan) {
+ effects.add(keyAt(i), effect);
+ }
+ }
+ return effects;
}
audio_io_handle_t EffectDescriptorCollection::getIoForSession(audio_session_t sessionId,
@@ -214,6 +247,67 @@
return AUDIO_IO_HANDLE_NONE;
}
+void EffectDescriptorCollection::moveEffectsForIo(audio_session_t session,
+ audio_io_handle_t dstIo, const AudioInputCollection *inputs,
+ AudioPolicyClientInterface *clientInterface)
+{
+ // No src io: try to find from effect session the src Io to move from
+ audio_io_handle_t srcIo = getIoForSession(session);
+ if (hasOrphansForSession(session) || (srcIo != AUDIO_IO_HANDLE_NONE && srcIo != dstIo)) {
+ moveEffects(session, srcIo, dstIo, inputs, clientInterface);
+ }
+}
+
+void EffectDescriptorCollection::moveEffects(audio_session_t session,
+ audio_io_handle_t srcIo, audio_io_handle_t dstIo, const AudioInputCollection *inputs,
+ AudioPolicyClientInterface *clientInterface)
+{
+ if ((srcIo != AUDIO_IO_HANDLE_NONE && srcIo == dstIo)
+ || (srcIo == AUDIO_IO_HANDLE_NONE && !hasOrphansForSession(session))) {
+ return;
+ }
+ // Either we may find orphan effects for given session or effects for this session might have
+ // been assigned first to another input (it may happen when an input is released or recreated
+ // after client sets its preferred device)
+ EffectDescriptorCollection effectsToMove;
+ if (srcIo == AUDIO_IO_HANDLE_NONE) {
+ ALOGV("%s: restoring effects for session %d from orphan park to io=%d", __func__,
+ session, dstIo);
+ effectsToMove = getOrphanEffectsForSession(session);
+ } else {
+ ALOGV("%s: moving effects for session %d from io=%d to io=%d", __func__,
+ session, srcIo, dstIo);
+ sp<AudioInputDescriptor> previousInputDesc = inputs->valueFor(srcIo);
+ effectsToMove = getEffectsForIo(srcIo);
+ for (size_t i = 0; i < effectsToMove.size(); ++i) {
+ sp<EffectDescriptor> effect = effectsToMove.valueAt(i);
+ effect->mEnabledWhenMoved = effect->mEnabled;
+ previousInputDesc->trackEffectEnabled(effect, false);
+ }
+ }
+ moveEffects(session, srcIo, dstIo, clientInterface);
+
+ if (dstIo != AUDIO_IO_HANDLE_NONE) {
+ sp<AudioInputDescriptor> inputDesc = inputs->valueFor(dstIo);
+ for (size_t i = 0; i < effectsToMove.size(); ++i) {
+ sp<EffectDescriptor> effect = effectsToMove.valueAt(i);
+ inputDesc->trackEffectEnabled(effect, effect->mEnabledWhenMoved);
+ }
+ }
+}
+
+void EffectDescriptorCollection::putOrphanEffects(audio_session_t session,
+ audio_io_handle_t srcIo, const AudioInputCollection *inputs,
+ AudioPolicyClientInterface *clientInterface)
+{
+ if (getIoForSession(session) != srcIo) {
+ // Effect session not held by this client io handle
+ return;
+ }
+ ALOGV("%s: park effects for session %d and io=%d to orphans", __func__, session, srcIo);
+ moveEffects(session, srcIo, AUDIO_IO_HANDLE_NONE, inputs, clientInterface);
+}
+
EffectDescriptorCollection EffectDescriptorCollection::getEffectsForIo(audio_io_handle_t io) const
{
EffectDescriptorCollection effects;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8e8fc0a..f1f2048 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1325,10 +1325,15 @@
AudioProfileVector profiles;
status_t ret = getProfilesForDevices(outputDevices, profiles, *flags, false /*isInput*/);
if (ret == NO_ERROR && !profiles.empty()) {
- config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
- : *profiles[0]->getChannels().begin();
- config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
- : *profiles[0]->getSampleRates().begin();
+ const auto channels = profiles[0]->getChannels();
+ if (!channels.empty() && (channels.find(config->channel_mask) == channels.end())) {
+ config->channel_mask = *channels.begin();
+ }
+ const auto sampleRates = profiles[0]->getSampleRates();
+ if (!sampleRates.empty() &&
+ (sampleRates.find(config->sample_rate) == sampleRates.end())) {
+ config->sample_rate = *sampleRates.begin();
+ }
config->format = profiles[0]->getFormat();
}
return INVALID_OPERATION;
@@ -2645,6 +2650,7 @@
sp<AudioPolicyMix> policyMix;
sp<DeviceDescriptor> device;
sp<AudioInputDescriptor> inputDesc;
+ sp<AudioInputDescriptor> previousInputDesc;
sp<RecordClientDescriptor> clientDesc;
audio_port_handle_t requestedDeviceId = *selectedDeviceId;
uid_t uid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(attributionSource.uid));
@@ -2774,10 +2780,15 @@
status_t ret = getProfilesForDevices(
DeviceVector(device), profiles, flags, true /*isInput*/);
if (ret == NO_ERROR && !profiles.empty()) {
- config->channel_mask = profiles[0]->getChannels().empty() ? config->channel_mask
- : *profiles[0]->getChannels().begin();
- config->sample_rate = profiles[0]->getSampleRates().empty() ? config->sample_rate
- : *profiles[0]->getSampleRates().begin();
+ const auto channels = profiles[0]->getChannels();
+ if (!channels.empty() && (channels.find(config->channel_mask) == channels.end())) {
+ config->channel_mask = *channels.begin();
+ }
+ const auto sampleRates = profiles[0]->getSampleRates();
+ if (!sampleRates.empty() &&
+ (sampleRates.find(config->sample_rate) == sampleRates.end())) {
+ config->sample_rate = *sampleRates.begin();
+ }
config->format = profiles[0]->getFormat();
}
goto error;
@@ -2796,6 +2807,8 @@
requestedDeviceId, attributes.source, flags,
isSoundTrigger);
inputDesc = mInputs.valueFor(*input);
+ // Move (if found) effect for the client session to its input
+ mEffects.moveEffectsForIo(session, *input, &mInputs, mpClientInterface);
inputDesc->addClient(clientDesc);
ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d for port ID %d",
@@ -3105,7 +3118,7 @@
ALOGV("%s %d", __FUNCTION__, input);
inputDesc->removeClient(portId);
-
+ mEffects.putOrphanEffects(client->session(), input, &mInputs, mpClientInterface);
if (inputDesc->getClientCount() > 0) {
ALOGV("%s(%d) %zu clients remaining", __func__, portId, inputDesc->getClientCount());
return;
@@ -3467,8 +3480,8 @@
}
if (output != mMusicEffectOutput) {
- mEffects.moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
- mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
+ mEffects.moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output,
+ mpClientInterface);
mMusicEffectOutput = output;
}
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index f4fc8f1..c674909 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -7,26 +7,8 @@
default_applicable_licenses: ["frameworks_av_license"],
}
-cc_library_shared {
- name: "libaudiopolicyservice",
-
- defaults: [
- "latest_android_media_audio_common_types_cpp_shared",
- ],
-
- srcs: [
- "AudioPolicyClientImpl.cpp",
- "AudioPolicyEffects.cpp",
- "AudioPolicyInterfaceImpl.cpp",
- "AudioPolicyService.cpp",
- "CaptureStateNotifier.cpp",
- "Spatializer.cpp",
- "SpatializerPoseController.cpp",
- ],
-
- include_dirs: [
- "frameworks/av/services/audioflinger"
- ],
+cc_defaults {
+ name: "libaudiopolicyservice_dependencies",
shared_libs: [
"libactivitymanager_aidl",
@@ -41,7 +23,6 @@
"libaudioutils",
"libbinder",
"libcutils",
- "libeffectsconfig",
"libhardware_legacy",
"libheadtracking",
"libheadtracking-binding",
@@ -67,6 +48,36 @@
],
static_libs: [
+ "libeffectsconfig",
+ "libaudiopolicycomponents",
+ ]
+}
+
+cc_library {
+ name: "libaudiopolicyservice",
+
+ defaults: [
+ "libaudiopolicyservice_dependencies",
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
+ srcs: [
+ "AudioRecordClient.cpp",
+ "AudioPolicyClientImpl.cpp",
+ "AudioPolicyEffects.cpp",
+ "AudioPolicyInterfaceImpl.cpp",
+ "AudioPolicyService.cpp",
+ "CaptureStateNotifier.cpp",
+ "Spatializer.cpp",
+ "SpatializerPoseController.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/services/audioflinger"
+ ],
+
+
+ static_libs: [
"framework-permission-aidl-cpp",
],
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 70a1785..85b7ad9 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -44,10 +44,7 @@
AudioPolicyEffects::AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
// load xml config with effectsFactoryHal
status_t loadResult = loadAudioEffectConfig(effectsFactoryHal);
- if (loadResult == NO_ERROR) {
- mDefaultDeviceEffectFuture =
- std::async(std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
- } else if (loadResult < 0) {
+ if (loadResult < 0) {
ALOGW("Failed to query effect configuration, fallback to load .conf");
// load automatic audio effect modules
if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
@@ -60,6 +57,11 @@
}
}
+void AudioPolicyEffects::setDefaultDeviceEffects() {
+ mDefaultDeviceEffectFuture = std::async(
+ std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
+}
+
AudioPolicyEffects::~AudioPolicyEffects()
{
size_t i = 0;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 9f65a96..e17df48 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -117,6 +117,8 @@
// Remove the default stream effect from wherever it's attached.
status_t removeStreamDefaultEffect(audio_unique_id_t id);
+ void setDefaultDeviceEffects();
+
private:
void initDefaultDeviceEffects();
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 5d86e7c..a7b2a56 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include "AudioPolicyService.h"
+#include "AudioRecordClient.h"
#include "TypeConverter.h"
#include <media/AidlConversion.h>
#include <media/AudioPolicy.h>
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 5d22ed4..72fa245 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -34,6 +34,7 @@
#include <binder/IResultReceiver.h>
#include <utils/String16.h>
#include <utils/threads.h>
+#include "AudioRecordClient.h"
#include "AudioPolicyService.h"
#include <hardware_legacy/power.h>
#include <media/AidlConversion.h>
@@ -305,6 +306,9 @@
}
}
AudioSystem::audioPolicyReady();
+ // AudioFlinger will handle effect creation and register these effects on audio_policy
+ // service. Hence, audio_policy service must be ready.
+ audioPolicyEffects->setDefaultDeviceEffects();
}
void AudioPolicyService::unloadAudioPolicyManager()
@@ -1164,20 +1168,6 @@
return false;
}
-/* static */
-bool AudioPolicyService::isAppOpSource(audio_source_t source)
-{
- switch (source) {
- case AUDIO_SOURCE_FM_TUNER:
- case AUDIO_SOURCE_ECHO_REFERENCE:
- case AUDIO_SOURCE_REMOTE_SUBMIX:
- return false;
- default:
- break;
- }
- return true;
-}
-
void AudioPolicyService::setAppState_l(sp<AudioRecordClient> client, app_state_t state)
{
AutoCallerClear acc;
@@ -1878,109 +1868,6 @@
return binder::Status::ok();
}
-// ----------- AudioPolicyService::OpRecordAudioMonitor implementation ----------
-
-// static
-sp<AudioPolicyService::OpRecordAudioMonitor>
-AudioPolicyService::OpRecordAudioMonitor::createIfNeeded(
- const AttributionSourceState& attributionSource, const audio_attributes_t& attr,
- wp<AudioCommandThread> commandThread)
-{
- if (isAudioServerOrRootUid(attributionSource.uid)) {
- ALOGV("not silencing record for audio or root source %s",
- attributionSource.toString().c_str());
- return nullptr;
- }
-
- if (!AudioPolicyService::isAppOpSource(attr.source)) {
- ALOGD("not monitoring app op for uid %d and source %d",
- attributionSource.uid, attr.source);
- return nullptr;
- }
-
- if (!attributionSource.packageName.has_value()
- || attributionSource.packageName.value().size() == 0) {
- return nullptr;
- }
- return new OpRecordAudioMonitor(attributionSource, getOpForSource(attr.source), commandThread);
-}
-
-AudioPolicyService::OpRecordAudioMonitor::OpRecordAudioMonitor(
- const AttributionSourceState& attributionSource, int32_t appOp,
- wp<AudioCommandThread> commandThread) :
- mHasOp(true), mAttributionSource(attributionSource), mAppOp(appOp),
- mCommandThread(commandThread)
-{
-}
-
-AudioPolicyService::OpRecordAudioMonitor::~OpRecordAudioMonitor()
-{
- if (mOpCallback != 0) {
- mAppOpsManager.stopWatchingMode(mOpCallback);
- }
- mOpCallback.clear();
-}
-
-void AudioPolicyService::OpRecordAudioMonitor::onFirstRef()
-{
- checkOp();
- mOpCallback = new RecordAudioOpCallback(this);
- ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
- // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
- // since it controls the mic permission for legacy apps.
- mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
- mAttributionSource.packageName.value_or(""))),
- mOpCallback);
-}
-
-bool AudioPolicyService::OpRecordAudioMonitor::hasOp() const {
- return mHasOp.load();
-}
-
-// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
-// is updated in AppOp callback and in onFirstRef()
-// Note this method is never called (and never to be) for audio server / root track
-// due to the UID in createIfNeeded(). As a result for those record track, it's:
-// - not called from constructor,
-// - not called from RecordAudioOpCallback because the callback is not installed in this case
-void AudioPolicyService::OpRecordAudioMonitor::checkOp(bool updateUidStates)
-{
- // TODO: We need to always check AppOpsManager::OP_RECORD_AUDIO too
- // since it controls the mic permission for legacy apps.
- const int32_t mode = mAppOpsManager.checkOp(mAppOp,
- mAttributionSource.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
- mAttributionSource.packageName.value_or(""))));
- const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
- // verbose logging only log when appOp changed
- ALOGI_IF(hasIt != mHasOp.load(),
- "App op %d missing, %ssilencing record %s",
- mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
- mHasOp.store(hasIt);
-
- if (updateUidStates) {
- sp<AudioCommandThread> commandThread = mCommandThread.promote();
- if (commandThread != nullptr) {
- commandThread->updateUidStatesCommand();
- }
- }
-}
-
-AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
- const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
-{ }
-
-void AudioPolicyService::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
- const String16& packageName __unused) {
- sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
- if (monitor != NULL) {
- if (op != monitor->getOp()) {
- return;
- }
- monitor->checkOp(true);
- }
-}
-
-
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index d0cde64..94b48ea 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2009 The Android Open Source Project
*
@@ -28,7 +27,6 @@
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <binder/ActivityManager.h>
-#include <binder/AppOpsManager.h>
#include <binder/BinderService.h>
#include <binder/IUidObserver.h>
#include <system/audio.h>
@@ -64,6 +62,12 @@
// ----------------------------------------------------------------------------
+namespace media::audiopolicy {
+ class AudioRecordClient;
+}
+
+using ::android::media::audiopolicy::AudioRecordClient;
+
class AudioPolicyService :
public BinderService<AudioPolicyService>,
public media::BnAudioPolicyService,
@@ -401,7 +405,6 @@
// Handles binder shell commands
virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args);
- class AudioRecordClient;
// Sets whether the given UID records only silence
virtual void setAppState_l(sp<AudioRecordClient> client, app_state_t state) REQUIRES(mLock);
@@ -542,6 +545,7 @@
// Thread used to send audio config commands to audio flinger
// For audio config commands, it is necessary because audio flinger requires that the calling
// process (user) has permission to modify audio settings.
+ public:
class AudioCommandThread : public Thread {
class AudioCommand;
public:
@@ -732,6 +736,7 @@
wp<AudioPolicyService> mService;
};
+ private:
class AudioPolicyClient : public AudioPolicyClientInterface
{
public:
@@ -906,6 +911,7 @@
bool mAudioVolumeGroupCallbacksEnabled;
};
+ public:
class AudioClient : public virtual RefBase {
public:
AudioClient(const audio_attributes_t attributes,
@@ -927,82 +933,8 @@
const audio_port_handle_t deviceId; // selected input device port ID
bool active; // Playback/Capture is active or inactive
};
-
- // Checks and monitors app ops for AudioRecordClient
- class OpRecordAudioMonitor : public RefBase {
- public:
- ~OpRecordAudioMonitor() override;
- bool hasOp() const;
- int32_t getOp() const { return mAppOp; }
-
- static sp<OpRecordAudioMonitor> createIfNeeded(
- const AttributionSourceState& attributionSource,
- const audio_attributes_t& attr, wp<AudioCommandThread> commandThread);
-
private:
- OpRecordAudioMonitor(const AttributionSourceState& attributionSource, int32_t appOp,
- wp<AudioCommandThread> commandThread);
- void onFirstRef() override;
-
- AppOpsManager mAppOpsManager;
-
- class RecordAudioOpCallback : public BnAppOpsCallback {
- public:
- explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor);
- void opChanged(int32_t op, const String16& packageName) override;
-
- private:
- const wp<OpRecordAudioMonitor> mMonitor;
- };
-
- sp<RecordAudioOpCallback> mOpCallback;
- // called by RecordAudioOpCallback when the app op for this OpRecordAudioMonitor is updated
- // in AppOp callback and in onFirstRef()
- // updateUidStates is true when the silenced state of active AudioRecordClients must be
- // re-evaluated
- void checkOp(bool updateUidStates = false);
-
- std::atomic_bool mHasOp;
- const AttributionSourceState mAttributionSource;
- const int32_t mAppOp;
- wp<AudioCommandThread> mCommandThread;
- };
-
- // --- AudioRecordClient ---
- // Information about each registered AudioRecord client
- // (between calls to getInputForAttr() and releaseInput())
- class AudioRecordClient : public AudioClient {
- public:
- AudioRecordClient(const audio_attributes_t attributes,
- const audio_io_handle_t io,
- const audio_session_t session, audio_port_handle_t portId,
- const audio_port_handle_t deviceId,
- const AttributionSourceState& attributionSource,
- bool canCaptureOutput, bool canCaptureHotword,
- wp<AudioCommandThread> commandThread) :
- AudioClient(attributes, io, attributionSource,
- session, portId, deviceId), attributionSource(attributionSource),
- startTimeNs(0), canCaptureOutput(canCaptureOutput),
- canCaptureHotword(canCaptureHotword), silenced(false),
- mOpRecordAudioMonitor(
- OpRecordAudioMonitor::createIfNeeded(attributionSource,
- attributes, commandThread)) {}
- ~AudioRecordClient() override = default;
-
- bool hasOp() const {
- return mOpRecordAudioMonitor ? mOpRecordAudioMonitor->hasOp() : true;
- }
-
- const AttributionSourceState attributionSource; // attribution source of client
- nsecs_t startTimeNs;
- const bool canCaptureOutput;
- const bool canCaptureHotword;
- bool silenced;
-
- private:
- sp<OpRecordAudioMonitor> mOpRecordAudioMonitor;
- };
// --- AudioPlaybackClient ---
diff --git a/services/audiopolicy/service/AudioRecordClient.cpp b/services/audiopolicy/service/AudioRecordClient.cpp
new file mode 100644
index 0000000..de6a280
--- /dev/null
+++ b/services/audiopolicy/service/AudioRecordClient.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioRecordClient.h"
+#include "AudioPolicyService.h"
+
+namespace android::media::audiopolicy {
+
+using android::AudioPolicyService;
+
+namespace {
+bool isAppOpSource(audio_source_t source)
+{
+ switch (source) {
+ case AUDIO_SOURCE_FM_TUNER:
+ case AUDIO_SOURCE_ECHO_REFERENCE:
+ case AUDIO_SOURCE_REMOTE_SUBMIX:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+}
+
+// static
+sp<OpRecordAudioMonitor>
+OpRecordAudioMonitor::createIfNeeded(
+ const AttributionSourceState& attributionSource, const audio_attributes_t& attr,
+ wp<AudioPolicyService::AudioCommandThread> commandThread)
+{
+ if (isAudioServerOrRootUid(attributionSource.uid)) {
+ ALOGV("not silencing record for audio or root source %s",
+ attributionSource.toString().c_str());
+ return nullptr;
+ }
+
+ if (!isAppOpSource(attr.source)) {
+ ALOGD("not monitoring app op for uid %d and source %d",
+ attributionSource.uid, attr.source);
+ return nullptr;
+ }
+
+ if (!attributionSource.packageName.has_value()
+ || attributionSource.packageName.value().size() == 0) {
+ return nullptr;
+ }
+ return new OpRecordAudioMonitor(attributionSource, getOpForSource(attr.source), commandThread);
+}
+
+OpRecordAudioMonitor::OpRecordAudioMonitor(
+ const AttributionSourceState& attributionSource, int32_t appOp,
+ wp<AudioPolicyService::AudioCommandThread> commandThread) :
+ mHasOp(true), mAttributionSource(attributionSource), mAppOp(appOp),
+ mCommandThread(commandThread)
+{
+}
+
+OpRecordAudioMonitor::~OpRecordAudioMonitor()
+{
+ if (mOpCallback != 0) {
+ mAppOpsManager.stopWatchingMode(mOpCallback);
+ }
+ mOpCallback.clear();
+}
+
+void OpRecordAudioMonitor::onFirstRef()
+{
+ checkOp();
+ mOpCallback = new RecordAudioOpCallback(this);
+ ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
+ // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
+ // since it controls the mic permission for legacy apps.
+ mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
+ mAttributionSource.packageName.value_or(""))),
+ AppOpsManager::WATCH_FOREGROUND_CHANGES,
+ mOpCallback);
+}
+
+bool OpRecordAudioMonitor::hasOp() const {
+ return mHasOp.load();
+}
+
+// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
+// is updated in AppOp callback and in onFirstRef()
+// Note this method is never called (and never to be) for audio server / root track
+// due to the UID in createIfNeeded(). As a result for those record track, it's:
+// - not called from constructor,
+// - not called from RecordAudioOpCallback because the callback is not installed in this case
+void OpRecordAudioMonitor::checkOp(bool updateUidStates)
+{
+ // TODO: We need to always check AppOpsManager::OP_RECORD_AUDIO too
+ // since it controls the mic permission for legacy apps.
+ const int32_t mode = mAppOpsManager.checkOp(mAppOp,
+ mAttributionSource.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
+ mAttributionSource.packageName.value_or(""))));
+ const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
+ // verbose logging only log when appOp changed
+ ALOGI_IF(hasIt != mHasOp.load(),
+ "App op %d missing, %ssilencing record %s",
+ mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
+ mHasOp.store(hasIt);
+
+ if (updateUidStates) {
+ sp<AudioPolicyService::AudioCommandThread> commandThread = mCommandThread.promote();
+ if (commandThread != nullptr) {
+ commandThread->updateUidStatesCommand();
+ }
+ }
+}
+
+OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
+ const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
+{ }
+
+void OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
+ const String16& packageName __unused) {
+ sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
+ if (monitor != NULL) {
+ if (op != monitor->getOp()) {
+ return;
+ }
+ monitor->checkOp(true);
+ }
+}
+
+} // android::media::audiopolicy::internal
diff --git a/services/audiopolicy/service/AudioRecordClient.h b/services/audiopolicy/service/AudioRecordClient.h
new file mode 100644
index 0000000..d3be316
--- /dev/null
+++ b/services/audiopolicy/service/AudioRecordClient.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/content/AttributionSourceState.h>
+#include <binder/AppOpsManager.h>
+#include <system/audio.h>
+#include <utils/RefBase.h>
+
+#include <cstdint>
+
+#include "AudioPolicyService.h"
+
+namespace android::media::audiopolicy {
+
+using ::android::content::AttributionSourceState;
+
+// Checks and monitors app ops for AudioRecordClient
+class OpRecordAudioMonitor : public RefBase {
+public:
+ ~OpRecordAudioMonitor() override;
+ bool hasOp() const;
+ int32_t getOp() const { return mAppOp; }
+
+ static sp<OpRecordAudioMonitor> createIfNeeded(
+ const AttributionSourceState& attributionSource,
+ const audio_attributes_t& attr,
+ wp<AudioPolicyService::AudioCommandThread> commandThread);
+
+private:
+ OpRecordAudioMonitor(const AttributionSourceState& attributionSource, int32_t appOp,
+ wp<AudioPolicyService::AudioCommandThread> commandThread);
+
+ void onFirstRef() override;
+
+ AppOpsManager mAppOpsManager;
+
+ class RecordAudioOpCallback : public BnAppOpsCallback {
+ public:
+ explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor);
+ void opChanged(int32_t op, const String16& packageName) override;
+
+ private:
+ const wp<OpRecordAudioMonitor> mMonitor;
+ };
+
+ sp<RecordAudioOpCallback> mOpCallback;
+ // called by RecordAudioOpCallback when the app op for this OpRecordAudioMonitor is updated
+ // in AppOp callback and in onFirstRef()
+ // updateUidStates is true when the silenced state of active AudioRecordClients must be
+ // re-evaluated
+ void checkOp(bool updateUidStates = false);
+
+ std::atomic_bool mHasOp;
+ const AttributionSourceState mAttributionSource;
+ const int32_t mAppOp;
+ wp<AudioPolicyService::AudioCommandThread> mCommandThread;
+};
+
+// --- AudioRecordClient ---
+// Information about each registered AudioRecord client
+// (between calls to getInputForAttr() and releaseInput())
+class AudioRecordClient : public AudioPolicyService::AudioClient {
+public:
+ AudioRecordClient(const audio_attributes_t attributes,
+ const audio_io_handle_t io,
+ const audio_session_t session, audio_port_handle_t portId,
+ const audio_port_handle_t deviceId,
+ const AttributionSourceState& attributionSource,
+ bool canCaptureOutput, bool canCaptureHotword,
+ wp<AudioPolicyService::AudioCommandThread> commandThread) :
+ AudioClient(attributes, io, attributionSource,
+ session, portId, deviceId), attributionSource(attributionSource),
+ startTimeNs(0), canCaptureOutput(canCaptureOutput),
+ canCaptureHotword(canCaptureHotword), silenced(false),
+ mOpRecordAudioMonitor(
+ OpRecordAudioMonitor::createIfNeeded(attributionSource,
+ attributes, commandThread)) {}
+ ~AudioRecordClient() override = default;
+
+ bool hasOp() const {
+ return mOpRecordAudioMonitor ? mOpRecordAudioMonitor->hasOp() : true;
+ }
+
+ const AttributionSourceState attributionSource; // attribution source of client
+ nsecs_t startTimeNs;
+ const bool canCaptureOutput;
+ const bool canCaptureHotword;
+ bool silenced;
+
+private:
+ sp<OpRecordAudioMonitor> mOpRecordAudioMonitor;
+};
+
+}; // namespace android::media::audiopolicy::internal
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 15eae14..b56bb16 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1905,7 +1905,7 @@
audio_io_handle_t mOutput;
audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- audio_port_handle_t mPortId;
+ audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
AudioPolicyInterface::output_type_t mOutputType;
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
bool mIsSpatialized;
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index a45365a..84dcf26 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -35,9 +35,91 @@
],
}
-cc_library_shared {
+cc_defaults {
+ name: "libcameraservice_deps",
+
+ shared_libs: [
+ "libactivitymanager_aidl",
+ "libbase",
+ "libdl",
+ "libui",
+ "liblog",
+ "libutilscallstack",
+ "libutils",
+ "libbinder",
+ "libbinder_ndk",
+ "libactivitymanager_aidl",
+ "libpermission",
+ "libcutils",
+ "libexif",
+ "libmedia",
+ "libmediautils",
+ "libcamera_client",
+ "libcamera_metadata",
+ "libfmq",
+ "libgui",
+ "libhardware",
+ "libhidlbase",
+ "libimage_io",
+ "libjpeg",
+ "libultrahdr",
+ "libmedia_codeclist",
+ "libmedia_omx",
+ "libmemunreachable",
+ "libprocessgroup",
+ "libprocinfo",
+ "libsensorprivacy",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libxml2",
+ "libyuv",
+ "android.hardware.camera.common@1.0",
+ "android.hardware.camera.device@1.0",
+ "android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
+ "android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
+ "android.hardware.camera.device@3.6",
+ "android.hardware.camera.device@3.7",
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.graphics.common-V4-ndk",
+ "media_permission-aidl-cpp",
+ ],
+
+ static_libs: [
+ "android.frameworks.cameraservice.common@2.0",
+ "android.frameworks.cameraservice.service@2.0",
+ "android.frameworks.cameraservice.service@2.1",
+ "android.frameworks.cameraservice.service@2.2",
+ "android.frameworks.cameraservice.device@2.0",
+ "android.frameworks.cameraservice.device@2.1",
+ "android.frameworks.cameraservice.common-V1-ndk",
+ "android.frameworks.cameraservice.service-V1-ndk",
+ "android.frameworks.cameraservice.device-V1-ndk",
+ "android.hardware.camera.common-V1-ndk",
+ "android.hardware.camera.device-V2-ndk",
+ "android.hardware.camera.metadata-V2-ndk",
+ "android.hardware.camera.provider@2.4",
+ "android.hardware.camera.provider@2.5",
+ "android.hardware.camera.provider@2.6",
+ "android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V2-ndk",
+ "libaidlcommonsupport",
+ "libdynamic_depth",
+ "libprocessinfoservice_aidl",
+ "libbinderthreadstateutils",
+ "media_permission-aidl-cpp",
+ "libcameraservice_device_independent",
+ ],
+}
+
+cc_library {
name: "libcameraservice",
+ defaults: [
+ "libcameraservice_deps",
+ ],
// Camera service source
srcs: [
@@ -105,6 +187,7 @@
"utils/CameraThreadState.cpp",
"utils/CameraTraces.cpp",
"utils/AutoConditionLock.cpp",
+ "utils/SchedulingPolicyUtils.cpp",
"utils/SessionConfigurationUtils.cpp",
"utils/SessionConfigurationUtilsHidl.cpp",
"utils/SessionStatsBuilder.cpp",
@@ -119,73 +202,6 @@
"libmediametrics_headers",
],
- shared_libs: [
- "libactivitymanager_aidl",
- "libbase",
- "libdl",
- "libexif",
- "libui",
- "liblog",
- "libutilscallstack",
- "libutils",
- "libbinder",
- "libbinder_ndk",
- "libactivitymanager_aidl",
- "libpermission",
- "libcutils",
- "libmedia",
- "libmediautils",
- "libcamera_client",
- "libcamera_metadata",
- "libdynamic_depth",
- "libfmq",
- "libgui",
- "libhardware",
- "libhidlbase",
- "libimage_io",
- "libjpeg",
- "libultrahdr",
- "libmedia_codeclist",
- "libmedia_omx",
- "libmemunreachable",
- "libsensorprivacy",
- "libstagefright",
- "libstagefright_foundation",
- "libxml2",
- "libyuv",
- "android.frameworks.cameraservice.common@2.0",
- "android.frameworks.cameraservice.service@2.0",
- "android.frameworks.cameraservice.service@2.1",
- "android.frameworks.cameraservice.service@2.2",
- "android.frameworks.cameraservice.device@2.0",
- "android.frameworks.cameraservice.device@2.1",
- "android.frameworks.cameraservice.common-V1-ndk",
- "android.frameworks.cameraservice.service-V1-ndk",
- "android.frameworks.cameraservice.device-V1-ndk",
- "android.hardware.camera.common@1.0",
- "android.hardware.camera.provider@2.4",
- "android.hardware.camera.provider@2.5",
- "android.hardware.camera.provider@2.6",
- "android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
- "android.hardware.camera.device@3.2",
- "android.hardware.camera.device@3.3",
- "android.hardware.camera.device@3.4",
- "android.hardware.camera.device@3.5",
- "android.hardware.camera.device@3.6",
- "android.hardware.camera.device@3.7",
- "android.hardware.camera.device-V2-ndk",
- "media_permission-aidl-cpp",
- ],
-
- static_libs: [
- "libaidlcommonsupport",
- "libprocessinfoservice_aidl",
- "libbinderthreadstateutils",
- "media_permission-aidl-cpp",
- "libcameraservice_device_independent",
- ],
-
export_shared_lib_headers: [
"libbinder",
"libactivitymanager_aidl",
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index ffd38be..d9d8a3d 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -47,14 +47,14 @@
CameraFlashlight::~CameraFlashlight() {
}
-status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
+status_t CameraFlashlight::createFlashlightControl(const std::string& cameraId) {
ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
if (mFlashControl != NULL) {
return INVALID_OPERATION;
}
- if (mProviderManager->supportSetTorchMode(cameraId.string())) {
+ if (mProviderManager->supportSetTorchMode(cameraId)) {
mFlashControl = new ProviderFlashControl(mProviderManager);
} else {
ALOGE("Flashlight control not supported by this device!");
@@ -64,7 +64,7 @@
return OK;
}
-status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
+status_t CameraFlashlight::setTorchMode(const std::string& cameraId, bool enabled) {
if (!mFlashlightMapInitialized) {
ALOGE("%s: findFlashUnits() must be called before this method.",
__FUNCTION__);
@@ -72,7 +72,7 @@
}
ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__,
- cameraId.string(), enabled);
+ cameraId.c_str(), enabled);
status_t res = OK;
Mutex::Autolock l(mLock);
@@ -87,7 +87,7 @@
// TODO: Move torch status checks and state updates behind this CameraFlashlight lock
// to avoid other similar race conditions.
ALOGE("%s: Camera device %s is in use, cannot set torch mode.",
- __FUNCTION__, cameraId.string());
+ __FUNCTION__, cameraId.c_str());
return -EBUSY;
}
@@ -117,7 +117,7 @@
return res;
}
-status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const String8& cameraId,
+status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const std::string& cameraId,
int32_t torchStrength) {
if (!mFlashlightMapInitialized) {
ALOGE("%s: findFlashUnits() must be called before this method.",
@@ -126,13 +126,13 @@
}
ALOGV("%s: set torch strength of camera %s to %d", __FUNCTION__,
- cameraId.string(), torchStrength);
+ cameraId.c_str(), torchStrength);
status_t res = OK;
Mutex::Autolock l(mLock);
if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
ALOGE("%s: Camera device %s is in use, cannot be turned ON.",
- __FUNCTION__, cameraId.string());
+ __FUNCTION__, cameraId.c_str());
return -EBUSY;
}
@@ -148,7 +148,7 @@
}
-status_t CameraFlashlight::getTorchStrengthLevel(const String8& cameraId,
+status_t CameraFlashlight::getTorchStrengthLevel(const std::string& cameraId,
int32_t* torchStrength) {
status_t res = OK;
if (!mFlashlightMapInitialized) {
@@ -174,13 +174,13 @@
Mutex::Autolock l(mLock);
status_t res;
- std::vector<String8> cameraIds;
+ std::vector<std::string> cameraIds;
std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
int numberOfCameras = static_cast<int>(ids.size());
cameraIds.resize(numberOfCameras);
// No module, must be provider
for (size_t i = 0; i < cameraIds.size(); i++) {
- cameraIds[i] = String8(ids[i].c_str());
+ cameraIds[i] = ids[i];
}
mFlashControl.clear();
@@ -195,17 +195,17 @@
res = createFlashlightControl(id);
if (res) {
ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
- id.string());
+ id.c_str());
} else {
res = mFlashControl->hasFlashUnit(id, &hasFlash);
if (res == -EUSERS || res == -EBUSY) {
ALOGE("%s: failed to check if camera %s has a flash unit. Some "
"camera devices may be opened", __FUNCTION__,
- id.string());
+ id.c_str());
return res;
} else if (res) {
ALOGE("%s: failed to check if camera %s has a flash unit. %s"
- " (%d)", __FUNCTION__, id.string(), strerror(-res),
+ " (%d)", __FUNCTION__, id.c_str(), strerror(-res),
res);
}
@@ -218,12 +218,12 @@
return OK;
}
-bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
+bool CameraFlashlight::hasFlashUnit(const std::string& cameraId) {
Mutex::Autolock l(mLock);
return hasFlashUnitLocked(cameraId);
}
-bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
+bool CameraFlashlight::hasFlashUnitLocked(const std::string& cameraId) {
if (!mFlashlightMapInitialized) {
ALOGE("%s: findFlashUnits() must be called before this method.",
__FUNCTION__);
@@ -234,23 +234,23 @@
if (index == NAME_NOT_FOUND) {
// Might be external camera
ALOGW("%s: camera %s not present when findFlashUnits() was called",
- __FUNCTION__, cameraId.string());
+ __FUNCTION__, cameraId.c_str());
return false;
}
return mHasFlashlightMap.valueAt(index);
}
-bool CameraFlashlight::isBackwardCompatibleMode(const String8& cameraId) {
+bool CameraFlashlight::isBackwardCompatibleMode(const std::string& cameraId) {
bool backwardCompatibleMode = false;
if (mProviderManager != nullptr &&
- !mProviderManager->supportSetTorchMode(cameraId.string())) {
+ !mProviderManager->supportSetTorchMode(cameraId)) {
backwardCompatibleMode = true;
}
return backwardCompatibleMode;
}
-status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
+status_t CameraFlashlight::prepareDeviceOpen(const std::string& cameraId) {
ALOGV("%s: prepare for device open", __FUNCTION__);
Mutex::Autolock l(mLock);
@@ -270,10 +270,9 @@
std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
int numCameras = static_cast<int>(ids.size());
for (int i = 0; i < numCameras; i++) {
- String8 id8(ids[i].c_str());
- if (hasFlashUnitLocked(id8)) {
+ if (hasFlashUnitLocked(ids[i])) {
mCallbacks->onTorchStatusChanged(
- id8, TorchModeStatus::NOT_AVAILABLE);
+ ids[i], TorchModeStatus::NOT_AVAILABLE);
}
}
}
@@ -289,8 +288,8 @@
return OK;
}
-status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
- ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
+status_t CameraFlashlight::deviceClosed(const std::string& cameraId) {
+ ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.c_str());
Mutex::Autolock l(mLock);
if (!mFlashlightMapInitialized) {
@@ -302,7 +301,7 @@
ssize_t index = mOpenedCameraIds.indexOf(cameraId);
if (index == NAME_NOT_FOUND) {
ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
} else {
mOpenedCameraIds.removeAt(index);
}
@@ -316,10 +315,9 @@
std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
int numCameras = static_cast<int>(ids.size());
for (int i = 0; i < numCameras; i++) {
- String8 id8(ids[i].c_str());
- if (hasFlashUnitLocked(id8)) {
+ if (hasFlashUnitLocked(ids[i])) {
mCallbacks->onTorchStatusChanged(
- id8, TorchModeStatus::AVAILABLE_OFF);
+ ids[i], TorchModeStatus::AVAILABLE_OFF);
}
}
}
@@ -343,35 +341,35 @@
ProviderFlashControl::~ProviderFlashControl() {
}
-status_t ProviderFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) {
+status_t ProviderFlashControl::hasFlashUnit(const std::string& cameraId, bool *hasFlash) {
if (!hasFlash) {
return BAD_VALUE;
}
- *hasFlash = mProviderManager->hasFlashUnit(cameraId.string());
+ *hasFlash = mProviderManager->hasFlashUnit(cameraId);
return OK;
}
-status_t ProviderFlashControl::setTorchMode(const String8& cameraId, bool enabled) {
+status_t ProviderFlashControl::setTorchMode(const std::string& cameraId, bool enabled) {
ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
- cameraId.string(), enabled);
+ cameraId.c_str(), enabled);
- return mProviderManager->setTorchMode(cameraId.string(), enabled);
+ return mProviderManager->setTorchMode(cameraId, enabled);
}
-status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const String8& cameraId,
+status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const std::string& cameraId,
int32_t torchStrength) {
ALOGV("%s: change torch strength level of camera %s to %d", __FUNCTION__,
- cameraId.string(), torchStrength);
+ cameraId.c_str(), torchStrength);
- return mProviderManager->turnOnTorchWithStrengthLevel(cameraId.string(), torchStrength);
+ return mProviderManager->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
}
-status_t ProviderFlashControl::getTorchStrengthLevel(const String8& cameraId,
+status_t ProviderFlashControl::getTorchStrengthLevel(const std::string& cameraId,
int32_t* torchStrength) {
ALOGV("%s: get torch strength level of camera %s", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
- return mProviderManager->getTorchStrengthLevel(cameraId.string(), torchStrength);
+ return mProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
}
// ProviderFlashControl implementation ends
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 1703ddc..733c928 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H
#define ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H
+#include <string>
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
#include <utils/KeyedVector.h>
@@ -38,20 +39,21 @@
// cause the torch mode to be turned off in HAL v1 devices. If
// previously-on torch mode is turned off,
// callbacks.torch_mode_status_change() should be invoked.
- virtual status_t hasFlashUnit(const String8& cameraId,
+ virtual status_t hasFlashUnit(const std::string& cameraId,
bool *hasFlash) = 0;
// set the torch mode to on or off.
- virtual status_t setTorchMode(const String8& cameraId,
+ virtual status_t setTorchMode(const std::string& cameraId,
bool enabled) = 0;
// Change the brightness level of the torch. If the torch is OFF and
// torchStrength >= 1, then the torch will also be turned ON.
- virtual status_t turnOnTorchWithStrengthLevel(const String8& cameraId,
+ virtual status_t turnOnTorchWithStrengthLevel(const std::string& cameraId,
int32_t torchStrength) = 0;
// Returns the torch strength level.
- virtual status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength) = 0;
+ virtual status_t getTorchStrengthLevel(const std::string& cameraId,
+ int32_t* torchStrength) = 0;
};
/**
@@ -70,49 +72,49 @@
// Whether a camera device has a flash unit. Before findFlashUnits() is
// called, this function always returns false.
- bool hasFlashUnit(const String8& cameraId);
+ bool hasFlashUnit(const std::string& cameraId);
// set the torch mode to on or off.
- status_t setTorchMode(const String8& cameraId, bool enabled);
+ status_t setTorchMode(const std::string& cameraId, bool enabled);
// Change the torch strength level of the flash unit in torch mode.
- status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
+ status_t turnOnTorchWithStrengthLevel(const std::string& cameraId, int32_t torchStrength);
// Get the torch strength level
- status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
+ status_t getTorchStrengthLevel(const std::string& cameraId, int32_t* torchStrength);
// Notify CameraFlashlight that camera service is going to open a camera
// device. CameraFlashlight will free the resources that may cause the
// camera open to fail. Camera service must call this function before
// opening a camera device.
- status_t prepareDeviceOpen(const String8& cameraId);
+ status_t prepareDeviceOpen(const std::string& cameraId);
// Notify CameraFlashlight that camera service has closed a camera
// device. CameraFlashlight may invoke callbacks for torch mode
// available depending on the implementation.
- status_t deviceClosed(const String8& cameraId);
+ status_t deviceClosed(const std::string& cameraId);
private:
// create flashlight control based on camera module API and camera
// device API versions.
- status_t createFlashlightControl(const String8& cameraId);
+ status_t createFlashlightControl(const std::string& cameraId);
// mLock should be locked.
- bool hasFlashUnitLocked(const String8& cameraId);
+ bool hasFlashUnitLocked(const std::string& cameraId);
// Check if flash control is in backward compatible mode (simulated torch API by
// opening cameras)
- bool isBackwardCompatibleMode(const String8& cameraId);
+ bool isBackwardCompatibleMode(const std::string& cameraId);
sp<FlashControlBase> mFlashControl;
sp<CameraProviderManager> mProviderManager;
CameraProviderManager::StatusListener* mCallbacks;
- SortedVector<String8> mOpenedCameraIds;
+ SortedVector<std::string> mOpenedCameraIds;
// camera id -> if it has a flash unit
- KeyedVector<String8, bool> mHasFlashlightMap;
+ KeyedVector<std::string, bool> mHasFlashlightMap;
bool mFlashlightMapInitialized;
Mutex mLock; // protect CameraFlashlight API
@@ -127,10 +129,10 @@
virtual ~ProviderFlashControl();
// FlashControlBase
- status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
- status_t setTorchMode(const String8& cameraId, bool enabled);
- status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
- status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
+ status_t hasFlashUnit(const std::string& cameraId, bool *hasFlash);
+ status_t setTorchMode(const std::string& cameraId, bool enabled);
+ status_t turnOnTorchWithStrengthLevel(const std::string& cameraId, int32_t torchStrength);
+ status_t getTorchStrengthLevel(const std::string& cameraId, int32_t* torchStrength);
private:
sp<CameraProviderManager> mProviderManager;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 07b0279..6d3c7a5 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -24,6 +24,8 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
+#include <iostream>
+#include <sstream>
#include <string>
#include <sys/types.h>
#include <inttypes.h>
@@ -36,7 +38,6 @@
#include <aidl/AidlCameraService.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
#include <android/permission/PermissionChecker.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
@@ -71,6 +72,7 @@
#include <system/camera_metadata.h>
#include <binder/IServiceManager.h>
#include <binder/IActivityManager.h>
+#include <camera/StringUtils.h>
#include <system/camera.h>
@@ -87,11 +89,11 @@
const char* kActivityServiceName = "activity";
const char* kSensorPrivacyServiceName = "sensor_privacy";
const char* kAppopsServiceName = "appops";
+ const char* kProcessInfoServiceName = "processinfo";
}; // namespace anonymous
namespace android {
-using base::StringPrintf;
using binder::Status;
using namespace camera3;
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
@@ -116,28 +118,17 @@
android_atomic_write(level, &gLogLevel);
}
-// Convenience methods for constructing binder::Status objects for error returns
-
-#define STATUS_ERROR(errorCode, errorString) \
- binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
-
-#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
- binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
- __VA_ARGS__))
-
// ----------------------------------------------------------------------------
-static const String16 sDumpPermission("android.permission.DUMP");
-static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
-static const String16 sCameraPermission("android.permission.CAMERA");
-static const String16 sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
-static const String16
+static const std::string sDumpPermission("android.permission.DUMP");
+static const std::string sManageCameraPermission("android.permission.MANAGE_CAMERA");
+static const std::string sCameraPermission("android.permission.CAMERA");
+static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
+static const std::string
sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
-static const String16 sCameraOpenCloseListenerPermission(
+static const std::string sCameraOpenCloseListenerPermission(
"android.permission.CAMERA_OPEN_CLOSE_LISTENER");
-static const String16
+static const std::string
sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
// Constant integer for FGS Logging, used to denote the API type for logger
static const int LOG_FGS_CAMERA_API = 1;
@@ -145,12 +136,13 @@
static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
static constexpr int32_t kSystemNativeClientState =
ActivityManager::PROCESS_STATE_PERSISTENT_UI;
+static const std::string kServiceName("cameraserver");
-const String8 CameraService::kOfflineDevice("offline-");
-const String16 CameraService::kWatchAllClientsFlag("all");
+const std::string CameraService::kOfflineDevice("offline-");
+const std::string CameraService::kWatchAllClientsFlag("all");
// Set to keep track of logged service error events.
-static std::set<String8> sServiceErrorEventSet;
+static std::set<std::string> sServiceErrorEventSet;
CameraService::CameraService(
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
@@ -181,7 +173,7 @@
}
void CameraService::onServiceRegistration(const String16& name, const sp<IBinder>&) {
- if (name != String16(kAppopsServiceName)) {
+ if (name != toString16(kAppopsServiceName)) {
return;
}
@@ -219,9 +211,9 @@
// boot availability for cameraservice, use checkService which is
// non blocking and register for notifications
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->checkService(String16(kAppopsServiceName));
+ sp<IBinder> binder = sm->checkService(toString16(kAppopsServiceName));
if (!binder) {
- sm->registerForNotifications(String16(kAppopsServiceName), this);
+ sm->registerForNotifications(toString16(kAppopsServiceName), this);
} else {
mAppOps.setCameraAudioRestriction(mAudioRestriction);
}
@@ -257,8 +249,8 @@
if (res != OK) {
ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
__FUNCTION__, strerror(-res), res);
- logServiceError(String8::format("Unable to initialize camera provider manager"),
- ERROR_DISCONNECTED);
+ logServiceError("Unable to initialize camera provider manager",
+ ERROR_DISCONNECTED);
return res;
}
}
@@ -283,14 +275,12 @@
for (auto& cameraId : deviceIds) {
- String8 id8 = String8(cameraId.c_str());
- if (getCameraState(id8) == nullptr) {
- onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
+ if (getCameraState(cameraId) == nullptr) {
+ onDeviceStatusChanged(cameraId, CameraDeviceStatus::PRESENT);
}
if (unavailPhysicalIds.count(cameraId) > 0) {
for (const auto& physicalId : unavailPhysicalIds[cameraId]) {
- String8 physicalId8 = String8(physicalId.c_str());
- onDeviceStatusChanged(id8, physicalId8, CameraDeviceStatus::NOT_PRESENT);
+ onDeviceStatusChanged(cameraId, physicalId, CameraDeviceStatus::NOT_PRESENT);
}
}
}
@@ -310,7 +300,7 @@
return OK;
}
-void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status,
+void CameraService::broadcastTorchModeStatus(const std::string& cameraId, TorchModeStatus status,
SystemCameraKind systemCameraKind) {
Mutex::Autolock lock(mStatusListenerLock);
for (auto& i : mListenerList) {
@@ -321,7 +311,7 @@
continue;
}
auto ret = i->getListener()->onTorchStatusChanged(mapToInterface(status),
- String16{cameraId});
+ cameraId);
i->handleBinderStatus(ret, "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d",
__FUNCTION__, i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
}
@@ -343,7 +333,7 @@
mNormalDeviceIdsWithoutSystemCamera.clear();
for (auto &deviceId : normalDeviceIds) {
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
- if (getSystemCameraKind(String8(deviceId.c_str()), &deviceKind) != OK) {
+ if (getSystemCameraKind(deviceId, &deviceKind) != OK) {
ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, deviceId.c_str());
continue;
}
@@ -358,14 +348,15 @@
mNormalDeviceIdsWithoutSystemCamera.size());
}
-status_t CameraService::getSystemCameraKind(const String8& cameraId, SystemCameraKind *kind) const {
+status_t CameraService::getSystemCameraKind(const std::string& cameraId,
+ SystemCameraKind *kind) const {
auto state = getCameraState(cameraId);
if (state != nullptr) {
*kind = state->getSystemCameraKind();
return OK;
}
// Hidden physical camera ids won't have CameraState
- return mCameraProviderManager->getSystemCameraKind(cameraId.c_str(), kind);
+ return mCameraProviderManager->getSystemCameraKind(cameraId, kind);
}
void CameraService::updateCameraNumAndIds() {
@@ -388,9 +379,8 @@
for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) {
int facing = -1;
int orientation = 0;
- String8 cameraId8(cameraId.c_str());
int portraitRotation;
- getDeviceVersion(cameraId8, /*overrideToPortrait*/false, /*out*/&portraitRotation,
+ getDeviceVersion(cameraId, /*overrideToPortrait*/false, /*out*/&portraitRotation,
/*out*/&facing, /*out*/&orientation);
if (facing == -1) {
ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
@@ -422,8 +412,7 @@
}
}
-void CameraService::addStates(const String8 id) {
- std::string cameraId(id.c_str());
+void CameraService::addStates(const std::string& cameraId) {
CameraResourceCost cost;
status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
if (res != OK) {
@@ -438,61 +427,61 @@
}
std::vector<std::string> physicalCameraIds;
mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds);
- std::set<String8> conflicting;
+ std::set<std::string> conflicting;
for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
- conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
+ conflicting.emplace(cost.conflictingDevices[i]);
}
{
Mutex::Autolock lock(mCameraStatesLock);
- mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
+ mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost.resourceCost,
conflicting, deviceKind, physicalCameraIds));
}
- if (mFlashlight->hasFlashUnit(id)) {
+ if (mFlashlight->hasFlashUnit(cameraId)) {
Mutex::Autolock al(mTorchStatusMutex);
- mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+ mTorchStatusMap.add(cameraId, TorchModeStatus::AVAILABLE_OFF);
- broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF, deviceKind);
+ broadcastTorchModeStatus(cameraId, TorchModeStatus::AVAILABLE_OFF, deviceKind);
}
updateCameraNumAndIds();
- logDeviceAdded(id, "Device added");
+ logDeviceAdded(cameraId, "Device added");
}
-void CameraService::removeStates(const String8 id) {
+void CameraService::removeStates(const std::string& cameraId) {
updateCameraNumAndIds();
- if (mFlashlight->hasFlashUnit(id)) {
+ if (mFlashlight->hasFlashUnit(cameraId)) {
Mutex::Autolock al(mTorchStatusMutex);
- mTorchStatusMap.removeItem(id);
+ mTorchStatusMap.removeItem(cameraId);
}
{
Mutex::Autolock lock(mCameraStatesLock);
- mCameraStates.erase(id);
+ mCameraStates.erase(cameraId);
}
}
-void CameraService::onDeviceStatusChanged(const String8& id,
+void CameraService::onDeviceStatusChanged(const std::string& cameraId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
- id.string(), newHalStatus);
+ cameraId.c_str(), newHalStatus);
StatusInternal newStatus = mapToInternal(newHalStatus);
- std::shared_ptr<CameraState> state = getCameraState(id);
+ std::shared_ptr<CameraState> state = getCameraState(cameraId);
if (state == nullptr) {
if (newStatus == StatusInternal::PRESENT) {
ALOGI("%s: Unknown camera ID %s, a new camera is added",
- __FUNCTION__, id.string());
+ __FUNCTION__, cameraId.c_str());
// First add as absent to make sure clients are notified below
- addStates(id);
+ addStates(cameraId);
- updateStatus(newStatus, id);
+ updateStatus(newStatus, cameraId);
} else {
- ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
+ ALOGE("%s: Bad camera ID %s", __FUNCTION__, cameraId.c_str());
}
return;
}
@@ -505,12 +494,12 @@
}
if (newStatus == StatusInternal::NOT_PRESENT) {
- logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
+ logDeviceRemoved(cameraId, fmt::sprintf("Device status changed from %d to %d", oldStatus,
newStatus));
// Set the device status to NOT_PRESENT, clients will no longer be able to connect
// to this device until the status changes
- updateStatus(StatusInternal::NOT_PRESENT, id);
+ updateStatus(StatusInternal::NOT_PRESENT, cameraId);
sp<BasicClient> clientToDisconnectOnline, clientToDisconnectOffline;
{
@@ -522,28 +511,28 @@
// Remove online as well as offline client from the list of active clients,
// if they are present
- clientToDisconnectOnline = removeClientLocked(id);
- clientToDisconnectOffline = removeClientLocked(kOfflineDevice + id);
+ clientToDisconnectOnline = removeClientLocked(cameraId);
+ clientToDisconnectOffline = removeClientLocked(kOfflineDevice + cameraId);
}
- disconnectClient(id, clientToDisconnectOnline);
- disconnectClient(kOfflineDevice + id, clientToDisconnectOffline);
+ disconnectClient(cameraId, clientToDisconnectOnline);
+ disconnectClient(kOfflineDevice + cameraId, clientToDisconnectOffline);
- removeStates(id);
+ removeStates(cameraId);
} else {
if (oldStatus == StatusInternal::NOT_PRESENT) {
- logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
+ logDeviceAdded(cameraId, fmt::sprintf("Device status changed from %d to %d", oldStatus,
newStatus));
}
- updateStatus(newStatus, id);
+ updateStatus(newStatus, cameraId);
}
}
-void CameraService::onDeviceStatusChanged(const String8& id,
- const String8& physicalId,
+void CameraService::onDeviceStatusChanged(const std::string& id,
+ const std::string& physicalId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
- __FUNCTION__, id.string(), physicalId.string(), newHalStatus);
+ __FUNCTION__, id.c_str(), physicalId.c_str(), newHalStatus);
StatusInternal newStatus = mapToInternal(newHalStatus);
@@ -551,7 +540,7 @@
if (state == nullptr) {
ALOGE("%s: Physical camera id %s status change on a non-present ID %s",
- __FUNCTION__, physicalId.string(), id.string());
+ __FUNCTION__, physicalId.c_str(), id.c_str());
return;
}
@@ -559,7 +548,7 @@
if (logicalCameraStatus != StatusInternal::PRESENT &&
logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
- __FUNCTION__, physicalId.string(), newHalStatus, logicalCameraStatus);
+ __FUNCTION__, physicalId.c_str(), newHalStatus, logicalCameraStatus);
return;
}
@@ -571,21 +560,18 @@
}
if (updated) {
- String8 idCombo = id + " : " + physicalId;
+ std::string idCombo = id + " : " + physicalId;
if (newStatus == StatusInternal::PRESENT) {
- logDeviceAdded(idCombo,
- String8::format("Device status changed to %d", newStatus));
+ logDeviceAdded(idCombo, fmt::sprintf("Device status changed to %d", newStatus));
} else {
- logDeviceRemoved(idCombo,
- String8::format("Device status changed to %d", newStatus));
+ logDeviceRemoved(idCombo, fmt::sprintf("Device status changed to %d", newStatus));
}
// Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(id, &deviceKind) != OK) {
- ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.string());
+ ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.c_str());
return;
}
- String16 id16(id), physicalId16(physicalId);
Mutex::Autolock lock(mStatusListenerLock);
for (auto& listener : mListenerList) {
if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
@@ -595,7 +581,7 @@
continue;
}
auto ret = listener->getListener()->onPhysicalCameraStatusChanged(
- mapToInterface(newStatus), id16, physicalId16);
+ mapToInterface(newStatus), id, physicalId);
listener->handleBinderStatus(ret,
"%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d",
__FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
@@ -604,10 +590,10 @@
}
}
-void CameraService::disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect) {
+void CameraService::disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect) {
if (clientToDisconnect.get() != nullptr) {
ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
- __FUNCTION__, id.string());
+ __FUNCTION__, id.c_str());
// Notify the client of disconnection
clientToDisconnect->notifyError(
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
@@ -616,13 +602,13 @@
}
}
-void CameraService::onTorchStatusChanged(const String8& cameraId,
+void CameraService::onTorchStatusChanged(const std::string& cameraId,
TorchModeStatus newStatus) {
SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
if (res != OK) {
ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
return;
}
Mutex::Autolock al(mTorchStatusMutex);
@@ -630,34 +616,33 @@
}
-void CameraService::onTorchStatusChanged(const String8& cameraId,
+void CameraService::onTorchStatusChanged(const std::string& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
Mutex::Autolock al(mTorchStatusMutex);
onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
}
-void CameraService::broadcastTorchStrengthLevel(const String8& cameraId,
+void CameraService::broadcastTorchStrengthLevel(const std::string& cameraId,
int32_t newStrengthLevel) {
Mutex::Autolock lock(mStatusListenerLock);
for (auto& i : mListenerList) {
- auto ret = i->getListener()->onTorchStrengthLevelChanged(String16{cameraId},
- newStrengthLevel);
+ auto ret = i->getListener()->onTorchStrengthLevelChanged(cameraId, newStrengthLevel);
i->handleBinderStatus(ret,
"%s: Failed to trigger onTorchStrengthLevelChanged for %d:%d: %d", __FUNCTION__,
i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
}
}
-void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
+void CameraService::onTorchStatusChangedLocked(const std::string& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
- __FUNCTION__, cameraId.string(), newStatus);
+ __FUNCTION__, cameraId.c_str(), newStatus);
TorchModeStatus status;
status_t res = getTorchStatusLocked(cameraId, &status);
if (res) {
ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
- __FUNCTION__, cameraId.string(), strerror(-res), res);
+ __FUNCTION__, cameraId.c_str(), strerror(-res), res);
return;
}
if (status == newStatus) {
@@ -682,18 +667,18 @@
if (oldUid != newUid) {
// If the UID has changed, log the status and update current UID in mTorchUidMap
if (status == TorchModeStatus::AVAILABLE_ON) {
- notifier.noteFlashlightOff(cameraId, oldUid);
+ notifier.noteFlashlightOff(toString8(cameraId), oldUid);
}
if (newStatus == TorchModeStatus::AVAILABLE_ON) {
- notifier.noteFlashlightOn(cameraId, newUid);
+ notifier.noteFlashlightOn(toString8(cameraId), newUid);
}
iter->second.second = newUid;
} else {
// If the UID has not changed, log the status
if (newStatus == TorchModeStatus::AVAILABLE_ON) {
- notifier.noteFlashlightOn(cameraId, oldUid);
+ notifier.noteFlashlightOn(toString8(cameraId), oldUid);
} else {
- notifier.noteFlashlightOff(cameraId, oldUid);
+ notifier.noteFlashlightOff(toString8(cameraId), oldUid);
}
}
}
@@ -701,17 +686,100 @@
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}
-static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
+static bool isAutomotiveDevice() {
+ // Checks the property ro.hardware.type and returns true if it is
+ // automotive.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware.type", value, "");
+ return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
+static bool isAutomotivePrivilegedClient(int32_t uid) {
+ // Returns false if this is not an automotive device type.
+ if (!isAutomotiveDevice())
+ return false;
+
+ // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
+ // privileged client uid used for safety critical use cases such as
+ // rear view and surround view.
+ return uid == AID_AUTOMOTIVE_EVS;
+}
+
+bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const{
+ // Returns false if this is not an automotive device type.
+ if (!isAutomotiveDevice())
+ return false;
+
+ // Returns false if no camera id is provided.
+ if (cam_id.empty())
+ return false;
+
+ SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+ if (getSystemCameraKind(cam_id, &systemCameraKind) != OK) {
+ // This isn't a known camera ID, so it's not a system camera.
+ ALOGE("%s: Unknown camera id %s, ", __FUNCTION__, cam_id.c_str());
+ return false;
+ }
+
+ if (systemCameraKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) {
+ ALOGE("%s: camera id %s is not a system camera", __FUNCTION__, cam_id.c_str());
+ return false;
+ }
+
+ CameraMetadata cameraInfo;
+ status_t res = mCameraProviderManager->getCameraCharacteristics(
+ cam_id, false, &cameraInfo, false);
+ if (res != OK){
+ ALOGE("%s: Not able to get camera characteristics for camera id %s",__FUNCTION__,
+ cam_id.c_str());
+ return false;
+ }
+
+ camera_metadata_entry auto_location = cameraInfo.find(ANDROID_AUTOMOTIVE_LOCATION);
+ if (auto_location.count != 1)
+ return false;
+
+ uint8_t location = auto_location.data.u8[0];
+ if ((location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT) &&
+ (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR) &&
+ (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT) &&
+ (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool CameraService::checkPermission(const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) const{
+ if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+ // If cameraId is empty, then it means that this check is not used for the
+ // purpose of accessing a specific camera, hence grant permission just
+ // based on uid to the automotive privileged client.
+ if (cameraId.empty())
+ return true;
+ // If this call is used for accessing a specific camera then cam_id must be provided.
+ // In that case, only pre-grants the permission for accessing the exterior system only
+ // camera.
+ return isAutomotiveExteriorSystemCamera(cameraId);
+ }
+
permission::PermissionChecker permissionChecker;
+ return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
+ toString16(message), attributedOpCode)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+bool CameraService::hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid,
+ int callingUid) const{
AttributionSourceState attributionSource{};
attributionSource.pid = callingPid;
attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
- sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
- bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
- sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ bool checkPermissionForSystemCamera = checkPermission(cameraId,
+ sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
+ bool checkPermissionForCamera = checkPermission(cameraId,
+ sCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
return checkPermissionForSystemCamera && checkPermissionForCamera;
}
@@ -719,7 +787,7 @@
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
bool hasSystemCameraPermissions =
- hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
+ hasPermissionsForSystemCamera(std::string(), CameraThreadState::getCallingPid(),
CameraThreadState::getCallingUid());
switch (type) {
case CAMERA_TYPE_BACKWARD_COMPATIBLE:
@@ -750,19 +818,18 @@
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
std::string cameraIdStr = cameraIdIntToStrLocked(cameraId);
- if (shouldRejectSystemCameraConnection(String8(cameraIdStr.c_str()))) {
+ if (shouldRejectSystemCameraConnection(cameraIdStr)) {
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
"characteristics for system only device %s: ", cameraIdStr.c_str());
}
if (!mInitialized) {
- logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+ logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");
}
- bool hasSystemCameraPermissions =
- hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
- CameraThreadState::getCallingUid());
+ bool hasSystemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraId),
+ CameraThreadState::getCallingPid(), CameraThreadState::getCallingUid());
int cameraIdBound = mNumberOfCamerasWithoutSystemCamera;
if (hasSystemCameraPermissions) {
cameraIdBound = mNumberOfCameras;
@@ -775,13 +842,13 @@
Status ret = Status::ok();
int portraitRotation;
status_t err = mCameraProviderManager->getCameraInfo(
- cameraIdStr.c_str(), overrideToPortrait, &portraitRotation, cameraInfo);
+ cameraIdStr, overrideToPortrait, &portraitRotation, cameraInfo);
if (err != OK) {
ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Error retrieving camera info from device %d: %s (%d)", cameraId,
strerror(-err), err);
- logServiceError(String8::format("Error retrieving camera info from device %d",cameraId),
- ERROR_INVALID_OPERATION);
+ logServiceError(std::string("Error retrieving camera info from device ")
+ + std::to_string(cameraId), ERROR_INVALID_OPERATION);
}
return ret;
@@ -791,13 +858,12 @@
const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
auto callingPid = CameraThreadState::getCallingPid();
auto callingUid = CameraThreadState::getCallingUid();
- permission::PermissionChecker permissionChecker;
AttributionSourceState attributionSource{};
attributionSource.pid = callingPid;
attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
- sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ bool checkPermissionForSystemCamera = checkPermission(std::to_string(cameraIdInt),
+ sSystemCameraPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE);
if (checkPermissionForSystemCamera || getpid() == callingPid) {
deviceIds = &mNormalDeviceIds;
}
@@ -810,12 +876,12 @@
return (*deviceIds)[cameraIdInt];
}
-String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
+std::string CameraService::cameraIdIntToStr(int cameraIdInt) {
Mutex::Autolock lock(mServiceLock);
- return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
+ return cameraIdIntToStrLocked(cameraIdInt);
}
-Status CameraService::getCameraCharacteristics(const String16& cameraId,
+Status CameraService::getCameraCharacteristics(const std::string& cameraId,
int targetSdkVersion, bool overrideToPortrait, CameraMetadata* cameraInfo) {
ATRACE_CALL();
if (!cameraInfo) {
@@ -825,43 +891,41 @@
if (!mInitialized) {
ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
- logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+ logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");;
}
- if (shouldRejectSystemCameraConnection(String8(cameraId))) {
+ if (shouldRejectSystemCameraConnection(cameraId)) {
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
- "characteristics for system only device %s: ", String8(cameraId).string());
+ "characteristics for system only device %s: ", cameraId.c_str());
}
Status ret{};
-
- std::string cameraIdStr = String8(cameraId).string();
bool overrideForPerfClass =
SessionConfigurationUtils::targetPerfClassPrimaryCamera(mPerfClassPrimaryCameraIds,
- cameraIdStr, targetSdkVersion);
+ cameraId, targetSdkVersion);
status_t res = mCameraProviderManager->getCameraCharacteristics(
- cameraIdStr, overrideForPerfClass, cameraInfo, overrideToPortrait);
+ cameraId, overrideForPerfClass, cameraInfo, overrideToPortrait);
if (res != OK) {
if (res == NAME_NOT_FOUND) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to retrieve camera "
- "characteristics for unknown device %s: %s (%d)", String8(cameraId).string(),
+ "characteristics for unknown device %s: %s (%d)", cameraId.c_str(),
strerror(-res), res);
} else {
- logServiceError(String8::format("Unable to retrieve camera characteristics for "
- "device %s.", String8(cameraId).string()),ERROR_INVALID_OPERATION);
+ logServiceError(fmt::sprintf("Unable to retrieve camera characteristics for device %s.",
+ cameraId.c_str()), ERROR_INVALID_OPERATION);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
- "characteristics for device %s: %s (%d)", String8(cameraId).string(),
+ "characteristics for device %s: %s (%d)", cameraId.c_str(),
strerror(-res), res);
}
}
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
- if (getSystemCameraKind(String8(cameraId), &deviceKind) != OK) {
- ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, String8(cameraId).string());
+ if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
+ ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera kind "
- "for device %s", String8(cameraId).string());
+ "for device %s", cameraId.c_str());
}
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
@@ -869,24 +933,22 @@
// If it's not calling from cameraserver, check the permission only if
// android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
// it would've already been checked in shouldRejectSystemCameraConnection.
- permission::PermissionChecker permissionChecker;
AttributionSourceState attributionSource{};
attributionSource.pid = callingPid;
attributionSource.uid = callingUid;
- bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
- sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
if ((callingPid != getpid()) &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
!checkPermissionForCamera) {
res = cameraInfo->removePermissionEntries(
- mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
+ mCameraProviderManager->getProviderTagIdLocked(cameraId),
&tagsRemoved);
if (res != OK) {
cameraInfo->clear();
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to remove camera"
" characteristics needing camera permission for device %s: %s (%d)",
- String8(cameraId).string(), strerror(-res), res);
+ cameraId.c_str(), strerror(-res), res);
}
}
@@ -896,7 +958,7 @@
if (res != OK) {
cameraInfo->clear();
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Failed to insert camera "
- "keys needing permission for device %s: %s (%d)", String8(cameraId).string(),
+ "keys needing permission for device %s: %s (%d)", cameraId.c_str(),
strerror(-res), res);
}
}
@@ -904,7 +966,7 @@
return ret;
}
-Status CameraService::getTorchStrengthLevel(const String16& cameraId,
+Status CameraService::getTorchStrengthLevel(const std::string& cameraId,
int32_t* torchStrength) {
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
@@ -918,22 +980,21 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Strength level should not be null.");
}
- status_t res = mCameraProviderManager->getTorchStrengthLevel(String8(cameraId).string(),
- torchStrength);
+ status_t res = mCameraProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
if (res != OK) {
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve torch "
- "strength level for device %s: %s (%d)", String8(cameraId).string(),
+ "strength level for device %s: %s (%d)", cameraId.c_str(),
strerror(-res), res);
}
ALOGI("%s: Torch strength level is: %d", __FUNCTION__, *torchStrength);
return Status::ok();
}
-String8 CameraService::getFormattedCurrentTime() {
+std::string CameraService::getFormattedCurrentTime() {
time_t now = time(nullptr);
char formattedTime[64];
strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
- return String8(formattedTime);
+ return std::string(formattedTime);
}
Status CameraService::getCameraVendorTagDescriptor(
@@ -971,7 +1032,7 @@
BasicClient::BasicClient::sCameraService = nullptr;
}
-std::pair<int, IPCTransport> CameraService::getDeviceVersion(const String8& cameraId,
+std::pair<int, IPCTransport> CameraService::getDeviceVersion(const std::string& cameraId,
bool overrideToPortrait, int* portraitRotation, int* facing, int* orientation) {
ATRACE_CALL();
@@ -980,18 +1041,17 @@
status_t res;
hardware::hidl_version maxVersion{0,0};
IPCTransport transport = IPCTransport::INVALID;
- res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
- &maxVersion, &transport);
+ res = mCameraProviderManager->getHighestSupportedVersion(cameraId, &maxVersion, &transport);
if (res != OK || transport == IPCTransport::INVALID) {
ALOGE("%s: Unable to get highest supported version for camera id %s", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
return std::make_pair(-1, IPCTransport::INVALID) ;
}
deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
hardware::CameraInfo info;
if (facing) {
- res = mCameraProviderManager->getCameraInfo(cameraId.string(), overrideToPortrait,
+ res = mCameraProviderManager->getCameraInfo(cameraId, overrideToPortrait,
portraitRotation, &info);
if (res != OK) {
return std::make_pair(-1, IPCTransport::INVALID);
@@ -1023,8 +1083,8 @@
}
Status CameraService::makeClient(const sp<CameraService>& cameraService,
- const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
- const std::optional<String16>& featureId, const String8& cameraId,
+ const sp<IInterface>& cameraCb, const std::string& packageName, bool systemNativeClient,
+ const std::optional<std::string>& featureId, const std::string& cameraId,
int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
apiLevel effectiveApiLevel, bool overrideForPerfClass, bool overrideToPortrait,
@@ -1038,7 +1098,7 @@
ALOGE("Camera using old HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
"Camera device \"%s\" HAL version %d no longer supported",
- cameraId.string(), deviceVersion);
+ cameraId.c_str(), deviceVersion);
break;
case CAMERA_DEVICE_API_VERSION_3_0:
case CAMERA_DEVICE_API_VERSION_3_1:
@@ -1054,13 +1114,14 @@
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Camera device \"%s\" has unknown HAL version %d",
- cameraId.string(), deviceVersion);
+ cameraId.c_str(), deviceVersion);
}
}
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
- packageName, featureId, cameraId, api1CameraId, facing, sensorOrientation,
+ packageName, featureId, cameraId,
+ api1CameraId, facing, sensorOrientation,
clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
forceSlowJpegMode);
ALOGI("%s: Camera1 API (legacy), override to portrait %d, forceSlowJpegMode %d",
@@ -1077,18 +1138,18 @@
return Status::ok();
}
-String8 CameraService::toString(std::set<userid_t> intSet) {
- String8 s("");
+std::string CameraService::toString(std::set<userid_t> intSet) {
+ std::ostringstream s;
bool first = true;
for (userid_t i : intSet) {
if (first) {
- s.appendFormat("%d", i);
+ s << std::to_string(i);
first = false;
} else {
- s.appendFormat(", %d", i);
+ s << ", " << std::to_string(i);
}
}
- return s;
+ return std::move(s.str());
}
int32_t CameraService::mapToInterface(TorchModeStatus status) {
@@ -1154,13 +1215,12 @@
Status CameraService::initializeShimMetadata(int cameraId) {
int uid = CameraThreadState::getCallingUid();
- String16 internalPackageName("cameraserver");
- String8 id = String8::format("%d", cameraId);
+ std::string cameraIdStr = std::to_string(cameraId);
Status ret = Status::ok();
sp<Client> tmp = nullptr;
if (!(ret = connectHelper<ICameraClient,Client>(
- sp<ICameraClient>{nullptr}, id, cameraId,
- internalPackageName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
+ sp<ICameraClient>{nullptr}, cameraIdStr, cameraId,
+ kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__, /*overrideToPortrait*/ true,
/*forceSlowJpegMode*/false, /*out*/ tmp)
@@ -1183,17 +1243,17 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
}
- String8 id = String8::format("%d", cameraId);
+ std::string cameraIdStr = std::to_string(cameraId);
// Check if we already have parameters
{
// Scope for service lock
Mutex::Autolock lock(mServiceLock);
- auto cameraState = getCameraState(id);
+ auto cameraState = getCameraState(cameraIdStr);
if (cameraState == nullptr) {
- ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
+ ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Invalid camera ID: %s", id.string());
+ "Invalid camera ID: %s", cameraIdStr.c_str());
}
CameraParameters p = cameraState->getShimParams();
if (!p.isEmpty()) {
@@ -1214,11 +1274,11 @@
{
// Scope for service lock
Mutex::Autolock lock(mServiceLock);
- auto cameraState = getCameraState(id);
+ auto cameraState = getCameraState(cameraIdStr);
if (cameraState == nullptr) {
- ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, id.string());
+ ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Invalid camera ID: %s", id.string());
+ "Invalid camera ID: %s", cameraIdStr.c_str());
}
CameraParameters p = cameraState->getShimParams();
if (!p.isEmpty()) {
@@ -1244,12 +1304,13 @@
}
}
-static status_t getUidForPackage(String16 packageName, int userId, /*inout*/uid_t& uid, int err) {
+static status_t getUidForPackage(const std::string &packageName, int userId, /*inout*/uid_t& uid,
+ int err) {
PermissionController pc;
- uid = pc.getPackageUid(packageName, 0);
+ uid = pc.getPackageUid(toString16(packageName), 0);
if (uid <= 0) {
- ALOGE("Unknown package: '%s'", String8(packageName).string());
- dprintf(err, "Unknown package: '%s'\n", String8(packageName).string());
+ ALOGE("Unknown package: '%s'", packageName.c_str());
+ dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
return BAD_VALUE;
}
@@ -1263,8 +1324,8 @@
return NO_ERROR;
}
-Status CameraService::validateConnectLocked(const String8& cameraId,
- const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
+Status CameraService::validateConnectLocked(const std::string& cameraId,
+ const std::string& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
/*out*/int& originalClientPid) const {
#ifdef __BRILLO__
@@ -1286,14 +1347,14 @@
ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
callingPid);
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
- "No camera HAL module available to open camera device \"%s\"", cameraId.string());
+ "No camera HAL module available to open camera device \"%s\"", cameraId.c_str());
}
if (getCameraState(cameraId) == nullptr) {
ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
- cameraId.string());
+ cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
- "No camera device with ID \"%s\" available", cameraId.string());
+ "No camera device with ID \"%s\" available", cameraId.c_str());
}
status_t err = checkIfDeviceIsUsable(cameraId);
@@ -1302,19 +1363,18 @@
case -ENODEV:
case -EBUSY:
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
- "No camera device with ID \"%s\" currently available", cameraId.string());
+ "No camera device with ID \"%s\" currently available", cameraId.c_str());
default:
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
- "Unknown error connecting to ID \"%s\"", cameraId.string());
+ "Unknown error connecting to ID \"%s\"", cameraId.c_str());
}
}
return Status::ok();
}
-Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
- const String8& clientName8, int& clientUid, int& clientPid,
+Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
+ const std::string& clientName, int& clientUid, int& clientPid,
/*out*/int& originalClientPid) const {
- permission::PermissionChecker permissionChecker;
AttributionSourceState attributionSource{};
int callingPid = CameraThreadState::getCallingPid();
@@ -1329,8 +1389,8 @@
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Untrusted caller (calling PID %d, UID %d) trying to "
"forward camera access to camera %s for client %s (PID %d, UID %d)",
- callingPid, callingUid, cameraId.string(),
- clientName8.string(), clientUid, clientPid);
+ callingPid, callingUid, cameraId.c_str(),
+ clientName.c_str(), clientUid, clientPid);
}
// Check if we can trust clientPid
@@ -1342,21 +1402,21 @@
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Untrusted caller (calling PID %d, UID %d) trying to "
"forward camera access to camera %s for client %s (PID %d, UID %d)",
- callingPid, callingUid, cameraId.string(),
- clientName8.string(), clientUid, clientPid);
+ callingPid, callingUid, cameraId.c_str(),
+ clientName.c_str(), clientUid, clientPid);
}
if (shouldRejectSystemCameraConnection(cameraId)) {
ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" is"
- "available", cameraId.string());
+ "available", cameraId.c_str());
}
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
- ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.string());
+ ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "No camera device with ID \"%s\""
- "found while trying to query device kind", cameraId.string());
+ "found while trying to query device kind", cameraId.c_str());
}
@@ -1365,36 +1425,40 @@
// android.permission.SYSTEM_CAMERA for system only camera devices).
attributionSource.pid = clientPid;
attributionSource.uid = clientUid;
- attributionSource.packageName = clientName8;
- bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
- sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ attributionSource.packageName = clientName;
+ bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission, attributionSource,
+ std::string(), AppOpsManager::OP_NONE);
if (callingPid != getpid() &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
- clientName8.string(), clientUid, clientPid, cameraId.string());
+ clientName.c_str(), clientUid, clientPid, cameraId.c_str());
}
// Make sure the UID is in an active state to use the camera
- if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
+ if (!mUidPolicy->isUidActive(callingUid, clientName)) {
int32_t procState = mUidPolicy->getProcState(callingUid);
ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_DISABLED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background ("
"calling UID %d proc state %" PRId32 ")",
- clientName8.string(), clientUid, clientPid, cameraId.string(),
+ clientName.c_str(), clientUid, clientPid, cameraId.c_str(),
callingUid, procState);
}
- // If sensor privacy is enabled then prevent access to the camera
- if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+
+ // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
+ // such as rear view and surround view cannot be disabled and are exempt from sensor privacy
+ // policy. In all other cases,if sensor privacy is enabled then prevent access to the camera.
+ if ((!isAutomotivePrivilegedClient(callingUid) ||
+ !isAutomotiveExteriorSystemCamera(cameraId)) &&
+ mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled");
return STATUS_ERROR_FMT(ERROR_DISABLED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy "
- "is enabled", clientName8.string(), clientUid, clientPid, cameraId.string());
+ "is enabled", clientName.c_str(), clientUid, clientPid, cameraId.c_str());
}
// Only use passed in clientPid to check permission. Use calling PID as the client PID that's
@@ -1410,32 +1474,32 @@
(mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
"device user %d, currently allowed device users: %s)", callingPid, clientUserId,
- toString(mAllowedUsers).string());
+ toString(mAllowedUsers).c_str());
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Callers from device user %d are not currently allowed to connect to camera \"%s\"",
- clientUserId, cameraId.string());
+ clientUserId, cameraId.c_str());
}
return Status::ok();
}
-status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
+status_t CameraService::checkIfDeviceIsUsable(const std::string& cameraId) const {
auto cameraState = getCameraState(cameraId);
int callingPid = CameraThreadState::getCallingPid();
if (cameraState == nullptr) {
ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
- cameraId.string());
+ cameraId.c_str());
return -ENODEV;
}
StatusInternal currentStatus = cameraState->getStatus();
if (currentStatus == StatusInternal::NOT_PRESENT) {
ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
- callingPid, cameraId.string());
+ callingPid, cameraId.c_str());
return -ENODEV;
} else if (currentStatus == StatusInternal::ENUMERATING) {
ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
- callingPid, cameraId.string());
+ callingPid, cameraId.c_str());
return -EBUSY;
}
@@ -1452,13 +1516,13 @@
auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
- String8(client->getPackageName()));
+ client->getPackageName());
if (evicted.size() > 0) {
// This should never happen - clients should already have been removed in disconnect
for (auto& i : evicted) {
ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
- __FUNCTION__, i->getKey().string());
+ __FUNCTION__, i->getKey().c_str());
}
LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
@@ -1476,12 +1540,12 @@
}
}
-status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
- apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
- int oomScoreOffset, bool systemNativeClient,
+status_t CameraService::handleEvictionsLocked(const std::string& cameraId, int clientPid,
+ apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback,
+ const std::string& packageName, int oomScoreOffset, bool systemNativeClient,
/*out*/
sp<BasicClient>* client,
- std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
+ std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial) {
ATRACE_CALL();
status_t ret = NO_ERROR;
std::vector<DescriptorPtr> evictedClients;
@@ -1508,52 +1572,66 @@
}
}
- // Get current active client PIDs
- std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
- ownerPids.push_back(clientPid);
-
- std::vector<int> priorityScores(ownerPids.size());
- std::vector<int> states(ownerPids.size());
-
- // Get priority scores of all active PIDs
- status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
- ownerPids.size(), &ownerPids[0], /*out*/&states[0],
- /*out*/&priorityScores[0]);
- if (err != OK) {
- ALOGE("%s: Priority score query failed: %d",
- __FUNCTION__, err);
- return err;
- }
-
- // Update all active clients' priorities
- std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
- for (size_t i = 0; i < ownerPids.size() - 1; i++) {
- pidToPriorityMap.emplace(ownerPids[i],
- resource_policy::ClientPriority(priorityScores[i], states[i],
- /* isVendorClient won't get copied over*/ false,
- /* oomScoreOffset won't get copied over*/ 0));
- }
- mActiveClientManager.updatePriorities(pidToPriorityMap);
-
// Get state for the given cameraId
auto state = getCameraState(cameraId);
if (state == nullptr) {
ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
- clientPid, cameraId.string());
+ clientPid, cameraId.c_str());
// Should never get here because validateConnectLocked should have errored out
return BAD_VALUE;
}
- int32_t actualScore = priorityScores[priorityScores.size() - 1];
- int32_t actualState = states[states.size() - 1];
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->checkService(String16(kProcessInfoServiceName));
+ if (!binder && isAutomotivePrivilegedClient(CameraThreadState::getCallingUid())) {
+ // If processinfo service is not available and the client is automotive privileged
+ // client used for safety critical uses cases such as rear-view and surround-view which
+ // needs to be available before android boot completes, then use the hardcoded values
+ // for the process state and priority score. As this scenario is before android system
+ // services are up and client is native client, hence using NATIVE_ADJ as the priority
+ // score and state as PROCESS_STATE_BOUND_TOP as such automotive apps need to be
+ // visible on the top.
+ clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
+ sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
+ state->getConflicting(), resource_policy::NATIVE_ADJ, clientPid,
+ ActivityManager::PROCESS_STATE_BOUND_TOP, oomScoreOffset, systemNativeClient);
+ } else {
+ // Get current active client PIDs
+ std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
+ ownerPids.push_back(clientPid);
- // Make descriptor for incoming client. We store the oomScoreOffset
- // since we might need it later on new handleEvictionsLocked and
- // ProcessInfoService would not take that into account.
- clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
- sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
- state->getConflicting(), actualScore, clientPid, actualState,
- oomScoreOffset, systemNativeClient);
+ std::vector<int> priorityScores(ownerPids.size());
+ std::vector<int> states(ownerPids.size());
+
+ // Get priority scores of all active PIDs
+ status_t err = ProcessInfoService::getProcessStatesScoresFromPids(ownerPids.size(),
+ &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]);
+ if (err != OK) {
+ ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err);
+ return err;
+ }
+
+ // Update all active clients' priorities
+ std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
+ for (size_t i = 0; i < ownerPids.size() - 1; i++) {
+ pidToPriorityMap.emplace(ownerPids[i],
+ resource_policy::ClientPriority(priorityScores[i], states[i],
+ /* isVendorClient won't get copied over*/ false,
+ /* oomScoreOffset won't get copied over*/ 0));
+ }
+ mActiveClientManager.updatePriorities(pidToPriorityMap);
+
+ int32_t actualScore = priorityScores[priorityScores.size() - 1];
+ int32_t actualState = states[states.size() - 1];
+
+ // Make descriptor for incoming client. We store the oomScoreOffset
+ // since we might need it later on new handleEvictionsLocked and
+ // ProcessInfoService would not take that into account.
+ clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
+ sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
+ state->getConflicting(), actualScore, clientPid, actualState,
+ oomScoreOffset, systemNativeClient);
+ }
resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
@@ -1567,25 +1645,25 @@
" priority).", clientPid);
sp<BasicClient> clientSp = clientDescriptor->getValue();
- String8 curTime = getFormattedCurrentTime();
+ std::string curTime = getFormattedCurrentTime();
auto incompatibleClients =
mActiveClientManager.getIncompatibleClients(clientDescriptor);
- String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
- "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
- cameraId.string(), packageName.string(), clientPid,
+ std::string msg = fmt::sprintf("%s : DENIED connect device %s client for package %s "
+ "(PID %d, score %d state %d) due to eviction policy", curTime.c_str(),
+ cameraId.c_str(), packageName.c_str(), clientPid,
clientPriority.getScore(), clientPriority.getState());
for (auto& i : incompatibleClients) {
- msg.appendFormat("\n - Blocked by existing device %s client for package %s"
+ msg += fmt::sprintf("\n - Blocked by existing device %s client for package %s"
"(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
- i->getKey().string(),
- String8{i->getValue()->getPackageName()}.string(),
+ i->getKey().c_str(),
+ i->getValue()->getPackageName().c_str(),
i->getOwnerId(), i->getPriority().getScore(),
i->getPriority().getState());
ALOGE(" Conflicts with: Device %s, client package %s (PID %"
- PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
- String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
+ PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().c_str(),
+ i->getValue()->getPackageName().c_str(), i->getOwnerId(),
i->getPriority().getScore(), i->getPriority().getState());
}
@@ -1614,17 +1692,17 @@
}
ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
- i->getKey().string());
+ i->getKey().c_str());
evictedClients.push_back(i);
// Log the clients evicted
- logEvent(String8::format("EVICT device %s client held by package %s (PID"
+ logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID"
" %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
" package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
- i->getKey().string(), String8{clientSp->getPackageName()}.string(),
+ i->getKey().c_str(), clientSp->getPackageName().c_str(),
i->getOwnerId(), i->getPriority().getScore(),
- i->getPriority().getState(), cameraId.string(),
- packageName.string(), clientPid, clientPriority.getScore(),
+ i->getPriority().getState(), cameraId.c_str(),
+ packageName.c_str(), clientPid, clientPriority.getScore(),
clientPriority.getState()));
// Notify the client of disconnection
@@ -1650,18 +1728,18 @@
for (const auto& i : evictedClients) {
ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
- __FUNCTION__, i->getKey().string(), i->getOwnerId());
+ __FUNCTION__, i->getKey().c_str(), i->getOwnerId());
ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
if (ret == TIMED_OUT) {
ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
- "current clients:\n%s", __FUNCTION__, i->getKey().string(),
- mActiveClientManager.toString().string());
+ "current clients:\n%s", __FUNCTION__, i->getKey().c_str(),
+ mActiveClientManager.toString().c_str());
return -EBUSY;
}
if (ret != NO_ERROR) {
ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
- "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
- ret, mActiveClientManager.toString().string());
+ "current clients:\n%s", __FUNCTION__, i->getKey().c_str(), strerror(-ret),
+ ret, mActiveClientManager.toString().c_str());
return ret;
}
}
@@ -1683,7 +1761,7 @@
Status CameraService::connect(
const sp<ICameraClient>& cameraClient,
int api1CameraId,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
int clientUid,
int clientPid,
int targetSdkVersion,
@@ -1695,16 +1773,16 @@
ATRACE_CALL();
Status ret = Status::ok();
- String8 id = cameraIdIntToStr(api1CameraId);
+ std::string cameraIdStr = cameraIdIntToStr(api1CameraId);
sp<Client> client = nullptr;
- ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
- clientPackageName,/*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
+ ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
+ clientPackageName, /*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
/*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
overrideToPortrait, forceSlowJpegMode, /*out*/client);
if(!ret.isOk()) {
- logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
- ret.toString8());
+ logRejected(cameraIdStr, CameraThreadState::getCallingPid(), clientPackageName,
+ toStdString(ret.toString8()));
return ret;
}
@@ -1729,13 +1807,13 @@
// have android.permission.SYSTEM_CAMERA permissions.
if (!isVendorListener && (systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA ||
(systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
- !hasPermissionsForSystemCamera(clientPid, clientUid)))) {
+ !hasPermissionsForSystemCamera(std::string(), clientPid, clientUid)))) {
return true;
}
return false;
}
-bool CameraService::shouldRejectSystemCameraConnection(const String8& cameraId) const {
+bool CameraService::shouldRejectSystemCameraConnection(const std::string& cameraId) const {
// Rules for rejection:
// 1) If cameraserver tries to access this camera device, accept the
// connection.
@@ -1769,7 +1847,7 @@
// characteristics) even if clients don't have android.permission.CAMERA. We do not want the
// same behavior for system camera devices.
if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
- !hasPermissionsForSystemCamera(cPid, cUid)) {
+ !hasPermissionsForSystemCamera(cameraId, cPid, cUid)) {
ALOGW("Rejecting access to system only camera %s, inadequete permissions",
cameraId.c_str());
return true;
@@ -1780,9 +1858,9 @@
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
- const String16& cameraId,
- const String16& clientPackageName,
- const std::optional<String16>& clientFeatureId,
+ const std::string& cameraId,
+ const std::string& clientPackageName,
+ const std::optional<std::string>& clientFeatureId,
int clientUid, int oomScoreOffset, int targetSdkVersion,
bool overrideToPortrait,
/*out*/
@@ -1790,25 +1868,24 @@
ATRACE_CALL();
Status ret = Status::ok();
- String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
- String16 clientPackageNameAdj = clientPackageName;
+ std::string clientPackageNameAdj = clientPackageName;
int callingPid = CameraThreadState::getCallingPid();
bool systemNativeClient = false;
if (doesClientHaveSystemUid() && (clientPackageNameAdj.size() == 0)) {
std::string systemClient =
- StringPrintf("client.pid<%d>", CameraThreadState::getCallingPid());
- clientPackageNameAdj = String16(systemClient.c_str());
+ fmt::sprintf("client.pid<%d>", CameraThreadState::getCallingPid());
+ clientPackageNameAdj = systemClient;
systemNativeClient = true;
}
if (oomScoreOffset < 0) {
- String8 msg =
- String8::format("Cannot increase the priority of a client %s pid %d for "
- "camera id %s", String8(clientPackageNameAdj).string(), callingPid,
- id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg =
+ fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
+ "camera id %s", clientPackageNameAdj.c_str(), callingPid,
+ cameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
userid_t clientUserId = multiuser_get_user_id(clientUid);
@@ -1817,33 +1894,35 @@
clientUserId = multiuser_get_user_id(callingUid);
}
- if (mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
- String8 msg =
- String8::format("Camera disabled by device policy");
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_DISABLED, msg.string());
+ // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
+ // such as rear view and surround view cannot be disabled.
+ if ((!isAutomotivePrivilegedClient(callingUid) || !isAutomotiveExteriorSystemCamera(cameraId))
+ && mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
+ std::string msg = "Camera disabled by device policy";
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_DISABLED, msg.c_str());
}
// enforce system camera permissions
- if (oomScoreOffset > 0 &&
- !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid()) &&
- !isTrustedCallingUid(CameraThreadState::getCallingUid())) {
- String8 msg =
- String8::format("Cannot change the priority of a client %s pid %d for "
+ if (oomScoreOffset > 0
+ && !hasPermissionsForSystemCamera(cameraId, callingPid,
+ CameraThreadState::getCallingUid())
+ && !isTrustedCallingUid(CameraThreadState::getCallingUid())) {
+ std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
"camera id %s without SYSTEM_CAMERA permissions",
- String8(clientPackageNameAdj).string(), callingPid, id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.string());
+ clientPackageNameAdj.c_str(), callingPid, cameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
}
- ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
- /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient,clientFeatureId,
+ ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb,
+ cameraId, /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient, clientFeatureId,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
targetSdkVersion, overrideToPortrait, /*forceSlowJpegMode*/false,
/*out*/client);
if(!ret.isOk()) {
- logRejected(id, callingPid, String8(clientPackageNameAdj), ret.toString8());
+ logRejected(cameraId, callingPid, clientPackageNameAdj, toStdString(ret.toString8()));
return ret;
}
@@ -1874,11 +1953,11 @@
return ret;
}
-String16 CameraService::getPackageNameFromUid(int clientUid) {
- String16 packageName("");
+std::string CameraService::getPackageNameFromUid(int clientUid) {
+ std::string packageName("");
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16(kPermissionServiceName));
+ sp<IBinder> binder = sm->getService(toString16(kPermissionServiceName));
if (binder == 0) {
ALOGE("Cannot get permission service");
// Return empty package name and the further interaction
@@ -1899,22 +1978,24 @@
}
// Arbitrarily pick the first name in the list
- packageName = packages[0];
+ packageName = toStdString(packages[0]);
return packageName;
}
template<class CALLBACK, class CLIENT>
-Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
- const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
+Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
+ int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
+ const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode,
/*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
bool isNonSystemNdk = false;
- String16 clientPackageName;
+ std::string clientPackageName;
+ int packageUid = (clientUid == USE_CALLING_UID) ?
+ CameraThreadState::getCallingUid() : clientUid;
if (clientPackageNameMaybe.size() <= 0) {
// NDK calls don't come with package names, but we need one for various cases.
// Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
@@ -1922,21 +2003,17 @@
// same permissions, so picking any associated package name is sufficient. For some
// other cases, this may give inaccurate names for clients in logs.
isNonSystemNdk = true;
- int packageUid = (clientUid == USE_CALLING_UID) ?
- CameraThreadState::getCallingUid() : clientUid;
clientPackageName = getPackageNameFromUid(packageUid);
} else {
clientPackageName = clientPackageNameMaybe;
}
- String8 clientName8(clientPackageName);
-
int originalClientPid = 0;
int packagePid = (clientPid == USE_CALLING_PID) ?
CameraThreadState::getCallingPid() : clientPid;
ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
- "Camera API version %d", packagePid, clientName8.string(), cameraId.string(),
+ "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
static_cast<int>(effectiveApiLevel));
nsecs_t openTimeNs = systemTime();
@@ -1955,11 +2032,11 @@
, clientPid);
return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
"Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
- cameraId.string(), clientName8.string(), clientPid);
+ cameraId.c_str(), clientPackageName.c_str(), clientPid);
}
// Enforce client permissions and do basic validity checks
- if(!(ret = validateConnectLocked(cameraId, clientName8,
+ if(!(ret = validateConnectLocked(cameraId, clientPackageName,
/*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
return ret;
}
@@ -1976,27 +2053,27 @@
status_t err;
sp<BasicClient> clientTmp = nullptr;
- std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
+ std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>> partial;
if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
- IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, systemNativeClient,
- /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
+ IInterface::asBinder(cameraCb), clientPackageName, oomScoreOffset,
+ systemNativeClient, /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
switch (err) {
case -ENODEV:
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
"No camera device with ID \"%s\" currently available",
- cameraId.string());
+ cameraId.c_str());
case -EBUSY:
return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
"Higher-priority client using camera, ID \"%s\" currently unavailable",
- cameraId.string());
+ cameraId.c_str());
case -EUSERS:
return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
"Too many cameras already open, cannot open camera \"%s\"",
- cameraId.string());
+ cameraId.c_str());
default:
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Unexpected error %s (%d) opening camera \"%s\"",
- strerror(-err), err, cameraId.string());
+ strerror(-err), err, cameraId.c_str());
}
}
@@ -2014,17 +2091,17 @@
getDeviceVersion(cameraId, overrideToPortrait, /*out*/&portraitRotation,
/*out*/&facing, /*out*/&orientation);
if (facing == -1) {
- ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.string());
+ ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
- "Unable to get camera device \"%s\" facing", cameraId.string());
+ "Unable to get camera device \"%s\" facing", cameraId.c_str());
}
sp<BasicClient> tmp = nullptr;
bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
- mPerfClassPrimaryCameraIds, cameraId.string(), targetSdkVersion);
+ mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion);
if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
- clientFeatureId, cameraId, api1CameraId, facing, orientation,
- clientPid, clientUid, getpid(),
+ clientFeatureId, cameraId, api1CameraId, facing,
+ orientation, clientPid, clientUid, getpid(),
deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
overrideToPortrait, forceSlowJpegMode,
/*out*/&tmp)).isOk()) {
@@ -2035,7 +2112,7 @@
LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
__FUNCTION__);
- String8 monitorTags = isClientWatched(client.get()) ? mMonitorTags : String8("");
+ std::string monitorTags = isClientWatched(client.get()) ? mMonitorTags : std::string();
err = client->initialize(mCameraProviderManager, monitorTags);
if (err != OK) {
ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
@@ -2046,24 +2123,24 @@
switch(err) {
case BAD_VALUE:
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
+ "Illegal argument to HAL module for camera \"%s\"", cameraId.c_str());
case -EBUSY:
return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
- "Camera \"%s\" is already open", cameraId.string());
+ "Camera \"%s\" is already open", cameraId.c_str());
case -EUSERS:
return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
"Too many cameras already open, cannot open camera \"%s\"",
- cameraId.string());
+ cameraId.c_str());
case PERMISSION_DENIED:
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
- "No permission to open camera \"%s\"", cameraId.string());
+ "No permission to open camera \"%s\"", cameraId.c_str());
case -EACCES:
return STATUS_ERROR_FMT(ERROR_DISABLED,
- "Camera \"%s\" disabled by policy", cameraId.string());
+ "Camera \"%s\" disabled by policy", cameraId.c_str());
case -ENODEV:
default:
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
- "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
+ "Failed to initialize camera \"%s\": %s (%d)", cameraId.c_str(),
strerror(-err), err);
}
}
@@ -2080,7 +2157,7 @@
cameraState->setShimParams(params);
} else {
ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
- __FUNCTION__, cameraId.string());
+ __FUNCTION__, cameraId.c_str());
}
}
@@ -2122,32 +2199,38 @@
clientPackageName));
}
- // Set camera muting behavior
- bool isCameraPrivacyEnabled =
- mSensorPrivacyPolicy->isCameraPrivacyEnabled();
- if (client->supportsCameraMute()) {
- client->setCameraMute(
- mOverrideCameraMuteMode || isCameraPrivacyEnabled);
- } else if (isCameraPrivacyEnabled) {
- // no camera mute supported, but privacy is on! => disconnect
- ALOGI("Camera mute not supported for package: %s, camera id: %s",
- String8(client->getPackageName()).string(), cameraId.string());
- // Do not hold mServiceLock while disconnecting clients, but
- // retain the condition blocking other clients from connecting
- // in mServiceLockWrapper if held.
- mServiceLock.unlock();
- // Clear caller identity temporarily so client disconnect PID
- // checks work correctly
- int64_t token = CameraThreadState::clearCallingIdentity();
- // Note AppOp to trigger the "Unblock" dialog
- client->noteAppOp();
- client->disconnect();
- CameraThreadState::restoreCallingIdentity(token);
- // Reacquire mServiceLock
- mServiceLock.lock();
+ // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use
+ // cases such as rear view and surround view cannot be disabled and are exempt from camera
+ // privacy policy.
+ if ((!isAutomotivePrivilegedClient(packageUid) ||
+ !isAutomotiveExteriorSystemCamera(cameraId))) {
+ // Set camera muting behavior.
+ bool isCameraPrivacyEnabled =
+ mSensorPrivacyPolicy->isCameraPrivacyEnabled();
+ if (client->supportsCameraMute()) {
+ client->setCameraMute(
+ mOverrideCameraMuteMode || isCameraPrivacyEnabled);
+ } else if (isCameraPrivacyEnabled) {
+ // no camera mute supported, but privacy is on! => disconnect
+ ALOGI("Camera mute not supported for package: %s, camera id: %s",
+ client->getPackageName().c_str(), cameraId.c_str());
+ // Do not hold mServiceLock while disconnecting clients, but
+ // retain the condition blocking other clients from connecting
+ // in mServiceLockWrapper if held.
+ mServiceLock.unlock();
+ // Clear caller identity temporarily so client disconnect PID
+ // checks work correctly
+ int64_t token = CameraThreadState::clearCallingIdentity();
+ // Note AppOp to trigger the "Unblock" dialog
+ client->noteAppOp();
+ client->disconnect();
+ CameraThreadState::restoreCallingIdentity(token);
+ // Reacquire mServiceLock
+ mServiceLock.lock();
- return STATUS_ERROR_FMT(ERROR_DISABLED,
- "Camera \"%s\" disabled due to camera mute", cameraId.string());
+ return STATUS_ERROR_FMT(ERROR_DISABLED,
+ "Camera \"%s\" disabled due to camera mute", cameraId.c_str());
+ }
}
if (shimUpdateOnly) {
@@ -2185,7 +2268,7 @@
if(res != OK) {
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
"No camera device with ID \"%s\" currently available",
- mInjectionExternalCamId.string());
+ mInjectionExternalCamId.c_str());
}
res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
if (res != OK) {
@@ -2193,7 +2276,7 @@
}
} else {
ALOGE("%s: Internal camera ID = %s 's client does not exist!",
- __FUNCTION__, mInjectionInternalCamId.string());
+ __FUNCTION__, mInjectionInternalCamId.c_str());
res = NO_INIT;
mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res);
}
@@ -2203,7 +2286,8 @@
return ret;
}
-status_t CameraService::addOfflineClient(String8 cameraId, sp<BasicClient> offlineClient) {
+status_t CameraService::addOfflineClient(const std::string &cameraId,
+ sp<BasicClient> offlineClient) {
if (offlineClient.get() == nullptr) {
return BAD_VALUE;
}
@@ -2232,7 +2316,7 @@
const auto& onlinePriority = onlineClientDesc->getPriority();
auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
- /*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
+ /*conflictingKeys*/ std::set<std::string>(), onlinePriority.getScore(),
onlineClientDesc->getOwnerId(), onlinePriority.getState(),
// native clients don't have offline processing support.
/*ommScoreOffset*/ 0, /*systemNativeClient*/false);
@@ -2248,7 +2332,8 @@
return BAD_VALUE;
}
- String8 monitorTags = isClientWatched(offlineClient.get()) ? mMonitorTags : String8("");
+ std::string monitorTags = isClientWatched(offlineClient.get())
+ ? mMonitorTags : std::string();
auto err = offlineClient->initialize(mCameraProviderManager, monitorTags);
if (err != OK) {
ALOGE("%s: Could not initialize offline client.", __FUNCTION__);
@@ -2259,7 +2344,7 @@
if (evicted.size() > 0) {
for (auto& i : evicted) {
ALOGE("%s: Invalid state: Offline client for camera %s was not removed ",
- __FUNCTION__, i->getKey().string());
+ __FUNCTION__, i->getKey().c_str());
}
LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, offline clients not evicted "
@@ -2270,7 +2355,7 @@
logConnectedOffline(offlineClientDesc->getKey(),
static_cast<int>(offlineClientDesc->getOwnerId()),
- String8(offlineClient->getPackageName()));
+ offlineClient->getPackageName());
sp<IBinder> remoteCallback = offlineClient->getRemote();
if (remoteCallback != nullptr) {
@@ -2281,8 +2366,8 @@
return OK;
}
-Status CameraService::turnOnTorchWithStrengthLevel(const String16& cameraId, int32_t torchStrength,
- const sp<IBinder>& clientBinder) {
+Status CameraService::turnOnTorchWithStrengthLevel(const std::string& cameraId,
+ int32_t torchStrength, const sp<IBinder>& clientBinder) {
Mutex::Autolock lock(mServiceLock);
ATRACE_CALL();
@@ -2292,60 +2377,59 @@
"Torch client binder in null.");
}
- String8 id = String8(cameraId.string());
int uid = CameraThreadState::getCallingUid();
- if (shouldRejectSystemCameraConnection(id)) {
+ if (shouldRejectSystemCameraConnection(cameraId)) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to change the strength level"
- "for system only device %s: ", id.string());
+ "for system only device %s: ", cameraId.c_str());
}
// verify id is valid
- auto state = getCameraState(id);
+ auto state = getCameraState(cameraId);
if (state == nullptr) {
- ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
+ ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera ID \"%s\" is a not valid camera ID", id.string());
+ "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
}
StatusInternal cameraStatus = state->getStatus();
if (cameraStatus != StatusInternal::NOT_AVAILABLE &&
cameraStatus != StatusInternal::PRESENT) {
- ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(),
+ ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
(int)cameraStatus);
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera ID \"%s\" is a not valid camera ID", id.string());
+ "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
}
{
Mutex::Autolock al(mTorchStatusMutex);
TorchModeStatus status;
- status_t err = getTorchStatusLocked(id, &status);
+ status_t err = getTorchStatusLocked(cameraId, &status);
if (err != OK) {
if (err == NAME_NOT_FOUND) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera \"%s\" does not have a flash unit", id.string());
+ "Camera \"%s\" does not have a flash unit", cameraId.c_str());
}
ALOGE("%s: getting current torch status failed for camera %s",
- __FUNCTION__, id.string());
+ __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Error changing torch strength level for camera \"%s\": %s (%d)",
- id.string(), strerror(-err), err);
+ cameraId.c_str(), strerror(-err), err);
}
if (status == TorchModeStatus::NOT_AVAILABLE) {
if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
ALOGE("%s: torch mode of camera %s is not available because "
- "camera is in use.", __FUNCTION__, id.string());
+ "camera is in use.", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
"Torch for camera \"%s\" is not available due to an existing camera user",
- id.string());
+ cameraId.c_str());
} else {
ALOGE("%s: torch mode of camera %s is not available due to "
- "insufficient resources", __FUNCTION__, id.string());
+ "insufficient resources", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
"Torch for camera \"%s\" is not available due to insufficient resources",
- id.string());
+ cameraId.c_str());
}
}
}
@@ -2356,44 +2440,44 @@
}
// Check if the current torch strength level is same as the new one.
bool shouldSkipTorchStrengthUpdates = mCameraProviderManager->shouldSkipTorchStrengthUpdate(
- id.string(), torchStrength);
+ cameraId, torchStrength);
- status_t err = mFlashlight->turnOnTorchWithStrengthLevel(id, torchStrength);
+ status_t err = mFlashlight->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
if (err != OK) {
int32_t errorCode;
- String8 msg;
+ std::string msg;
switch (err) {
case -ENOSYS:
- msg = String8::format("Camera \"%s\" has no flashlight.",
- id.string());
+ msg = fmt::sprintf("Camera \"%s\" has no flashlight.",
+ cameraId.c_str());
errorCode = ERROR_ILLEGAL_ARGUMENT;
break;
case -EBUSY:
- msg = String8::format("Camera \"%s\" is in use",
- id.string());
+ msg = fmt::sprintf("Camera \"%s\" is in use",
+ cameraId.c_str());
errorCode = ERROR_CAMERA_IN_USE;
break;
case -EINVAL:
- msg = String8::format("Torch strength level %d is not within the "
+ msg = fmt::sprintf("Torch strength level %d is not within the "
"valid range.", torchStrength);
errorCode = ERROR_ILLEGAL_ARGUMENT;
break;
default:
- msg = String8::format("Changing torch strength level failed.");
+ msg = "Changing torch strength level failed.";
errorCode = ERROR_INVALID_OPERATION;
}
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(errorCode, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(errorCode, msg.c_str());
}
{
// update the link to client's death
// Store the last client that turns on each camera's torch mode.
Mutex::Autolock al(mTorchClientMapMutex);
- ssize_t index = mTorchClientMap.indexOfKey(id);
+ ssize_t index = mTorchClientMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
- mTorchClientMap.add(id, clientBinder);
+ mTorchClientMap.add(cameraId, clientBinder);
} else {
mTorchClientMap.valueAt(index)->unlinkToDeath(this);
mTorchClientMap.replaceValueAt(index, clientBinder);
@@ -2402,16 +2486,15 @@
}
int clientPid = CameraThreadState::getCallingPid();
- const char *id_cstr = id.c_str();
ALOGI("%s: Torch strength for camera id %s changed to %d for client PID %d",
- __FUNCTION__, id_cstr, torchStrength, clientPid);
+ __FUNCTION__, cameraId.c_str(), torchStrength, clientPid);
if (!shouldSkipTorchStrengthUpdates) {
- broadcastTorchStrengthLevel(id, torchStrength);
+ broadcastTorchStrengthLevel(cameraId, torchStrength);
}
return Status::ok();
}
-Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
+Status CameraService::setTorchMode(const std::string& cameraId, bool enabled,
const sp<IBinder>& clientBinder) {
Mutex::Autolock lock(mServiceLock);
@@ -2422,58 +2505,58 @@
"Torch client Binder is null");
}
- String8 id = String8(cameraId.string());
int uid = CameraThreadState::getCallingUid();
- if (shouldRejectSystemCameraConnection(id)) {
+ if (shouldRejectSystemCameraConnection(cameraId)) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode"
- " for system only device %s: ", id.string());
+ " for system only device %s: ", cameraId.c_str());
}
// verify id is valid.
- auto state = getCameraState(id);
+ auto state = getCameraState(cameraId);
if (state == nullptr) {
- ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
+ ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera ID \"%s\" is a not valid camera ID", id.string());
+ "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
}
StatusInternal cameraStatus = state->getStatus();
if (cameraStatus != StatusInternal::PRESENT &&
cameraStatus != StatusInternal::NOT_AVAILABLE) {
- ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(), (int)cameraStatus);
+ ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
+ (int)cameraStatus);
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera ID \"%s\" is a not valid camera ID", id.string());
+ "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
}
{
Mutex::Autolock al(mTorchStatusMutex);
TorchModeStatus status;
- status_t err = getTorchStatusLocked(id, &status);
+ status_t err = getTorchStatusLocked(cameraId, &status);
if (err != OK) {
if (err == NAME_NOT_FOUND) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera \"%s\" does not have a flash unit", id.string());
+ "Camera \"%s\" does not have a flash unit", cameraId.c_str());
}
ALOGE("%s: getting current torch status failed for camera %s",
- __FUNCTION__, id.string());
+ __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
- "Error updating torch status for camera \"%s\": %s (%d)", id.string(),
+ "Error updating torch status for camera \"%s\": %s (%d)", cameraId.c_str(),
strerror(-err), err);
}
if (status == TorchModeStatus::NOT_AVAILABLE) {
if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
ALOGE("%s: torch mode of camera %s is not available because "
- "camera is in use", __FUNCTION__, id.string());
+ "camera is in use", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
"Torch for camera \"%s\" is not available due to an existing camera user",
- id.string());
+ cameraId.c_str());
} else {
ALOGE("%s: torch mode of camera %s is not available due to "
- "insufficient resources", __FUNCTION__, id.string());
+ "insufficient resources", __FUNCTION__, cameraId.c_str());
return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
"Torch for camera \"%s\" is not available due to insufficient resources",
- id.string());
+ cameraId.c_str());
}
}
}
@@ -2485,40 +2568,40 @@
updateTorchUidMapLocked(cameraId, uid);
}
- status_t err = mFlashlight->setTorchMode(id, enabled);
+ status_t err = mFlashlight->setTorchMode(cameraId, enabled);
if (err != OK) {
int32_t errorCode;
- String8 msg;
+ std::string msg;
switch (err) {
case -ENOSYS:
- msg = String8::format("Camera \"%s\" has no flashlight",
- id.string());
+ msg = fmt::sprintf("Camera \"%s\" has no flashlight",
+ cameraId.c_str());
errorCode = ERROR_ILLEGAL_ARGUMENT;
break;
case -EBUSY:
- msg = String8::format("Camera \"%s\" is in use",
- id.string());
+ msg = fmt::sprintf("Camera \"%s\" is in use",
+ cameraId.c_str());
errorCode = ERROR_CAMERA_IN_USE;
break;
default:
- msg = String8::format(
+ msg = fmt::sprintf(
"Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
- id.string(), enabled, strerror(-err), err);
+ cameraId.c_str(), enabled, strerror(-err), err);
errorCode = ERROR_INVALID_OPERATION;
}
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- logServiceError(msg,errorCode);
- return STATUS_ERROR(errorCode, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ logServiceError(msg, errorCode);
+ return STATUS_ERROR(errorCode, msg.c_str());
}
{
// update the link to client's death
Mutex::Autolock al(mTorchClientMapMutex);
- ssize_t index = mTorchClientMap.indexOfKey(id);
+ ssize_t index = mTorchClientMap.indexOfKey(cameraId);
if (enabled) {
if (index == NAME_NOT_FOUND) {
- mTorchClientMap.add(id, clientBinder);
+ mTorchClientMap.add(cameraId, clientBinder);
} else {
mTorchClientMap.valueAt(index)->unlinkToDeath(this);
mTorchClientMap.replaceValueAt(index, clientBinder);
@@ -2530,21 +2613,20 @@
}
int clientPid = CameraThreadState::getCallingPid();
- const char *id_cstr = id.c_str();
- const char *torchState = enabled ? "on" : "off";
- ALOGI("Torch for camera id %s turned %s for client PID %d", id_cstr, torchState, clientPid);
- logTorchEvent(id_cstr, torchState , clientPid);
+ std::string torchState = enabled ? "on" : "off";
+ ALOGI("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
+ torchState.c_str(), clientPid);
+ logTorchEvent(cameraId, torchState, clientPid);
return Status::ok();
}
-void CameraService::updateTorchUidMapLocked(const String16& cameraId, int uid) {
- String8 id = String8(cameraId.string());
- if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
- mTorchUidMap[id].first = uid;
- mTorchUidMap[id].second = uid;
+void CameraService::updateTorchUidMapLocked(const std::string& cameraId, int uid) {
+ if (mTorchUidMap.find(cameraId) == mTorchUidMap.end()) {
+ mTorchUidMap[cameraId].first = uid;
+ mTorchUidMap[cameraId].second = uid;
} else {
// Set the pending UID
- mTorchUidMap[id].first = uid;
+ mTorchUidMap[cameraId].first = uid;
}
}
@@ -2557,7 +2639,7 @@
if (pid != selfPid) {
// Ensure we're being called by system_server, or similar process with
// permissions to notify the camera service about system events
- if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+ if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
const int uid = CameraThreadState::getCallingUid();
ALOGE("Permission Denial: cannot send updates to camera service about system"
" events from pid=%d, uid=%d", pid, uid);
@@ -2631,7 +2713,7 @@
if (pid != selfPid) {
// Ensure we're being called by system_server, or similar process with
// permissions to notify the camera service about system events
- if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+ if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
const int uid = CameraThreadState::getCallingUid();
ALOGE("Permission Denial: cannot send updates to camera service about device"
" state changes from pid=%d, uid=%d", pid, uid);
@@ -2662,7 +2744,7 @@
if (callingPid != selfPid) {
// Ensure we're being called by system_server, or similar process with
// permissions to notify the camera service about system events
- if (!checkCallingPermission(sCameraSendSystemEventsPermission)) {
+ if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
const int uid = CameraThreadState::getCallingUid();
ALOGE("Permission Denial: cannot send updates to camera service about orientation"
" changes from pid=%d, uid=%d", callingPid, uid);
@@ -2704,7 +2786,7 @@
if (!mInitialized) {
ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
- logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
+ logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");
}
@@ -2716,8 +2798,7 @@
std::vector<std::string> validCombination;
for (auto &cameraId : combination) {
// if the camera state is not present, skip
- String8 cameraIdStr(cameraId.c_str());
- auto state = getCameraState(cameraIdStr);
+ auto state = getCameraState(cameraId);
if (state == nullptr) {
ALOGW("%s: camera id %s does not exist", __FUNCTION__, cameraId.c_str());
continue;
@@ -2726,7 +2807,7 @@
if (status == StatusInternal::NOT_PRESENT || status == StatusInternal::ENUMERATING) {
continue;
}
- if (shouldRejectSystemCameraConnection(cameraIdStr)) {
+ if (shouldRejectSystemCameraConnection(cameraId)) {
continue;
}
validCombination.push_back(cameraId);
@@ -2755,13 +2836,11 @@
// Check for camera permissions
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
- permission::PermissionChecker permissionChecker;
AttributionSourceState attributionSource{};
attributionSource.pid = callingPid;
attributionSource.uid = callingUid;
- bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
- sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ bool checkPermissionForCamera = checkPermission(std::string(),
+ sCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
if ((callingPid != getpid()) && !checkPermissionForCamera) {
ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
@@ -2774,7 +2853,7 @@
cameraIdsAndSessionConfigurations, mPerfClassPrimaryCameraIds,
targetSdkVersion, isSupported);
if (res != OK) {
- logServiceError(String8::format("Unable to query session configuration support"),
+ logServiceError("Unable to query session configuration support",
ERROR_INVALID_OPERATION);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query session configuration "
"support %s (%d)", strerror(-res), res);
@@ -2809,13 +2888,13 @@
auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
- permission::PermissionChecker permissionChecker;
AttributionSourceState attributionSource{};
attributionSource.uid = clientUid;
attributionSource.pid = clientPid;
- bool openCloseCallbackAllowed = permissionChecker.checkPermissionForPreflight(
- sCameraOpenCloseListenerPermission, attributionSource, String16(),
- AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+
+ bool openCloseCallbackAllowed = checkPermission(std::string(),
+ sCameraOpenCloseListenerPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE);
Mutex::Autolock lock(mServiceLock);
@@ -2834,11 +2913,11 @@
openCloseCallbackAllowed);
auto ret = serviceListener->initialize(isProcessLocalTest);
if (ret != NO_ERROR) {
- String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
+ std::string msg = fmt::sprintf("Failed to initialize service listener: %s (%d)",
strerror(-ret), ret);
- logServiceError(msg,ERROR_ILLEGAL_ARGUMENT);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logServiceError(msg, ERROR_ILLEGAL_ARGUMENT);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
// The listener still needs to be added to the list of listeners, regardless of what
// permissions the listener process has / whether it is a vendor listener. Since it might be
@@ -2853,7 +2932,7 @@
for (auto& i : mCameraStates) {
cameraStatuses->emplace_back(i.first,
mapToInterface(i.second->getStatus()), i.second->getUnavailablePhysicalIds(),
- openCloseCallbackAllowed ? i.second->getClientPackage() : String8::empty());
+ openCloseCallbackAllowed ? i.second->getClientPackage() : std::string());
}
}
// Remove the camera statuses that should be hidden from the client, we do
@@ -2872,9 +2951,9 @@
clientUid);}), cameraStatuses->end());
//cameraStatuses will have non-eligible camera ids removed.
- std::set<String16> idsChosenForCallback;
+ std::set<std::string> idsChosenForCallback;
for (const auto &s : *cameraStatuses) {
- idsChosenForCallback.insert(String16(s.cameraId));
+ idsChosenForCallback.insert(s.cameraId);
}
/*
@@ -2884,7 +2963,7 @@
{
Mutex::Autolock al(mTorchStatusMutex);
for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
- String16 id = String16(mTorchStatusMap.keyAt(i).string());
+ const std::string &id = mTorchStatusMap.keyAt(i);
// The camera id is visible to the client. Fine to send torch
// callback.
if (idsChosenForCallback.find(id) != idsChosenForCallback.end()) {
@@ -2926,7 +3005,7 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
}
-Status CameraService::getLegacyParameters(int cameraId, /*out*/String16* parameters) {
+Status CameraService::getLegacyParameters(int cameraId, /*out*/std::string* parameters) {
ATRACE_CALL();
ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
@@ -2945,37 +3024,34 @@
}
String8 shimParamsString8 = shimParams.flatten();
- String16 shimParamsString16 = String16(shimParamsString8);
- *parameters = shimParamsString16;
+ *parameters = toStdString(shimParamsString8);
return ret;
}
-Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
+Status CameraService::supportsCameraApi(const std::string& cameraId, int apiVersion,
/*out*/ bool *isSupported) {
ATRACE_CALL();
- const String8 id = String8(cameraId);
-
- ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
+ ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
switch (apiVersion) {
case API_VERSION_1:
case API_VERSION_2:
break;
default:
- String8 msg = String8::format("Unknown API version %d", apiVersion);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Unknown API version %d", apiVersion);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
int portraitRotation;
- auto deviceVersionAndTransport = getDeviceVersion(id, false, &portraitRotation);
+ auto deviceVersionAndTransport = getDeviceVersion(cameraId, false, &portraitRotation);
if (deviceVersionAndTransport.first == -1) {
- String8 msg = String8::format("Unknown camera ID %s", id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Unknown camera ID %s", cameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
int deviceVersion = deviceVersionAndTransport.first;
@@ -2985,11 +3061,11 @@
case CAMERA_DEVICE_API_VERSION_3_1:
if (apiVersion == API_VERSION_2) {
ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without "
- "shim", __FUNCTION__, id.string(), deviceVersion);
+ "shim", __FUNCTION__, cameraId.c_str(), deviceVersion);
*isSupported = false;
} else { // if (apiVersion == API_VERSION_1) {
ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always "
- "supported", __FUNCTION__, id.string());
+ "supported", __FUNCTION__, cameraId.c_str());
*isSupported = true;
}
break;
@@ -3000,14 +3076,14 @@
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_7:
ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
- __FUNCTION__, id.string());
+ __FUNCTION__, cameraId.c_str());
*isSupported = true;
break;
default: {
- String8 msg = String8::format("Unknown device version %x for device %s",
- deviceVersion, id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Unknown device version %x for device %s",
+ deviceVersion, cameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.c_str());
}
}
} else {
@@ -3016,27 +3092,25 @@
return Status::ok();
}
-Status CameraService::isHiddenPhysicalCamera(const String16& cameraId,
+Status CameraService::isHiddenPhysicalCamera(const std::string& cameraId,
/*out*/ bool *isSupported) {
ATRACE_CALL();
- const String8 id = String8(cameraId);
-
- ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
- *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(id.string());
+ ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
+ *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(cameraId);
return Status::ok();
}
Status CameraService::injectCamera(
- const String16& packageName, const String16& internalCamId,
- const String16& externalCamId,
+ const std::string& packageName, const std::string& internalCamId,
+ const std::string& externalCamId,
const sp<ICameraInjectionCallback>& callback,
/*out*/
sp<ICameraInjectionSession>* cameraInjectionSession) {
ATRACE_CALL();
- if (!checkCallingPermission(sCameraInjectExternalCameraPermission)) {
+ if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) {
const int pid = CameraThreadState::getCallingPid();
const int uid = CameraThreadState::getCallingUid();
ALOGE("Permission Denial: can't inject camera pid=%d, uid=%d", pid, uid);
@@ -3047,13 +3121,13 @@
ALOGV(
"%s: Package name = %s, Internal camera ID = %s, External camera ID = "
"%s",
- __FUNCTION__, String8(packageName).string(),
- String8(internalCamId).string(), String8(externalCamId).string());
+ __FUNCTION__, packageName.c_str(),
+ internalCamId.c_str(), externalCamId.c_str());
{
Mutex::Autolock lock(mInjectionParametersLock);
- mInjectionInternalCamId = String8(internalCamId);
- mInjectionExternalCamId = String8(externalCamId);
+ mInjectionInternalCamId = internalCamId;
+ mInjectionExternalCamId = externalCamId;
mInjectionStatusListener->addListener(callback);
*cameraInjectionSession = new CameraInjectionSession(this);
status_t res = NO_ERROR;
@@ -3068,7 +3142,7 @@
if(res != OK) {
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
"No camera device with ID \"%s\" currently available",
- mInjectionExternalCamId.string());
+ mInjectionExternalCamId.c_str());
}
res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
if(res != OK) {
@@ -3083,7 +3157,7 @@
}
Status CameraService::reportExtensionSessionStats(
- const hardware::CameraExtensionSessionStats& stats, String16* sessionKey /*out*/) {
+ const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/) {
ALOGV("%s: reported %s", __FUNCTION__, stats.toString().c_str());
*sessionKey = mCameraServiceProxyWrapper->updateExtensionStats(stats);
return Status::ok();
@@ -3150,7 +3224,7 @@
}
std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
- const String8& cameraId) const {
+ const std::string& cameraId) const {
std::shared_ptr<CameraState> state;
{
Mutex::Autolock lock(mCameraStatesLock);
@@ -3162,12 +3236,12 @@
return state;
}
-sp<CameraService::BasicClient> CameraService::removeClientLocked(const String8& cameraId) {
+sp<CameraService::BasicClient> CameraService::removeClientLocked(const std::string& cameraId) {
// Remove from active clients list
auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
if (clientDescriptorPtr == nullptr) {
ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
return sp<BasicClient>{nullptr};
}
@@ -3222,16 +3296,14 @@
evicted.push_back(clientSp);
- String8 curTime = getFormattedCurrentTime();
-
ALOGE("Evicting conflicting client for camera ID %s due to user change",
- i->getKey().string());
+ i->getKey().c_str());
// Log the clients evicted
- logEvent(String8::format("EVICT device %s client held by package %s (PID %"
+ logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID %"
PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due"
- " to user switch.", i->getKey().string(),
- String8{clientSp->getPackageName()}.string(),
+ " to user switch.", i->getKey().c_str(),
+ clientSp->getPackageName().c_str(),
i->getOwnerId(), i->getPriority().getScore(),
i->getPriority().getState()));
@@ -3254,12 +3326,12 @@
mServiceLock.lock();
}
-void CameraService::logEvent(const char* event) {
- String8 curTime = getFormattedCurrentTime();
+void CameraService::logEvent(const std::string &event) {
+ std::string curTime = getFormattedCurrentTime();
Mutex::Autolock l(mLogLock);
- String8 msg = String8::format("%s : %s", curTime.string(), event);
+ std::string msg = curTime + " : " + event;
// For service error events, print the msg only once.
- if(!msg.contains("SERVICE ERROR")) {
+ if (msg.find("SERVICE ERROR") != std::string::npos) {
mEventLog.add(msg);
} else if(sServiceErrorEventSet.find(msg) == sServiceErrorEventSet.end()) {
// Error event not added to the dumpsys log before
@@ -3268,77 +3340,78 @@
}
}
-void CameraService::logDisconnected(const char* cameraId, int clientPid,
- const char* clientPackage) {
+void CameraService::logDisconnected(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage) {
// Log the clients evicted
- logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
- clientPackage, clientPid));
+ logEvent(fmt::sprintf("DISCONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
+ clientPackage.c_str(), clientPid));
}
-void CameraService::logDisconnectedOffline(const char* cameraId, int clientPid,
- const char* clientPackage) {
+void CameraService::logDisconnectedOffline(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage) {
// Log the clients evicted
- logEvent(String8::format("DISCONNECT offline device %s client for package %s (PID %d)",
- cameraId, clientPackage, clientPid));
+ logEvent(fmt::sprintf("DISCONNECT offline device %s client for package %s (PID %d)",
+ cameraId.c_str(), clientPackage.c_str(), clientPid));
}
-void CameraService::logConnected(const char* cameraId, int clientPid,
- const char* clientPackage) {
+void CameraService::logConnected(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage) {
// Log the clients evicted
- logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
- clientPackage, clientPid));
+ logEvent(fmt::sprintf("CONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
+ clientPackage.c_str(), clientPid));
}
-void CameraService::logConnectedOffline(const char* cameraId, int clientPid,
- const char* clientPackage) {
+void CameraService::logConnectedOffline(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage) {
// Log the clients evicted
- logEvent(String8::format("CONNECT offline device %s client for package %s (PID %d)", cameraId,
- clientPackage, clientPid));
+ logEvent(fmt::sprintf("CONNECT offline device %s client for package %s (PID %d)",
+ cameraId.c_str(), clientPackage.c_str(), clientPid));
}
-void CameraService::logRejected(const char* cameraId, int clientPid,
- const char* clientPackage, const char* reason) {
+void CameraService::logRejected(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage, const std::string &reason) {
// Log the client rejected
- logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
- cameraId, clientPackage, clientPid, reason));
+ logEvent(fmt::sprintf("REJECT device %s client for package %s (PID %d), reason: (%s)",
+ cameraId.c_str(), clientPackage.c_str(), clientPid, reason.c_str()));
}
-void CameraService::logTorchEvent(const char* cameraId, const char *torchState, int clientPid) {
+void CameraService::logTorchEvent(const std::string &cameraId, const std::string &torchState,
+ int clientPid) {
// Log torch event
- logEvent(String8::format("Torch for camera id %s turned %s for client PID %d", cameraId,
- torchState, clientPid));
+ logEvent(fmt::sprintf("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
+ torchState.c_str(), clientPid));
}
void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
const std::set<userid_t>& newUserIds) {
- String8 newUsers = toString(newUserIds);
- String8 oldUsers = toString(oldUserIds);
+ std::string newUsers = toString(newUserIds);
+ std::string oldUsers = toString(oldUserIds);
if (oldUsers.size() == 0) {
oldUsers = "<None>";
}
// Log the new and old users
- logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
- oldUsers.string(), newUsers.string()));
+ logEvent(fmt::sprintf("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
+ oldUsers.c_str(), newUsers.c_str()));
}
-void CameraService::logDeviceRemoved(const char* cameraId, const char* reason) {
+void CameraService::logDeviceRemoved(const std::string &cameraId, const std::string &reason) {
// Log the device removal
- logEvent(String8::format("REMOVE device %s, reason: (%s)", cameraId, reason));
+ logEvent(fmt::sprintf("REMOVE device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
}
-void CameraService::logDeviceAdded(const char* cameraId, const char* reason) {
+void CameraService::logDeviceAdded(const std::string &cameraId, const std::string &reason) {
// Log the device removal
- logEvent(String8::format("ADD device %s, reason: (%s)", cameraId, reason));
+ logEvent(fmt::sprintf("ADD device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
}
-void CameraService::logClientDied(int clientPid, const char* reason) {
+void CameraService::logClientDied(int clientPid, const std::string &reason) {
// Log the device removal
- logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason));
+ logEvent(fmt::sprintf("DIED client(s) with PID %d, reason: (%s)", clientPid, reason.c_str()));
}
-void CameraService::logServiceError(const char* msg, int errorCode) {
- String8 curTime = getFormattedCurrentTime();
- logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(-errorCode)));
+void CameraService::logServiceError(const std::string &msg, int errorCode) {
+ logEvent(fmt::sprintf("SERVICE ERROR: %s : %d (%s)", msg.c_str(), errorCode,
+ strerror(-errorCode)));
}
status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
@@ -3458,9 +3531,9 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
- const String16& clientPackageName, bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraIdStr,
+ const std::string& clientPackageName, bool systemNativeClient,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraIdStr,
int api1CameraId, int cameraFacing, int sensorOrientation,
int clientPid, uid_t clientUid,
int servicePid, bool overrideToPortrait) :
@@ -3496,8 +3569,8 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& clientPackageName, bool nativeClient,
- const std::optional<String16>& clientFeatureId, const String8& cameraIdStr,
+ const std::string& clientPackageName, bool nativeClient,
+ const std::optional<std::string>& clientFeatureId, const std::string& cameraIdStr,
int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid, bool overrideToPortrait):
mDestructionStarted(false),
@@ -3548,9 +3621,9 @@
mDisconnected = true;
sCameraService->removeByClient(this);
- sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
+ sCameraService->logDisconnected(mCameraIdStr, mClientPid, mClientPackageName);
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
- mCameraIdStr.c_str());
+ mCameraIdStr);
sp<IBinder> remote = getRemote();
if (remote != nullptr) {
@@ -3560,7 +3633,7 @@
finishCameraOps();
// Notify flashlight that a camera device is closed.
sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
- ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.string(),
+ ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.c_str(),
mClientPid);
// client shouldn't be able to call into us anymore
@@ -3584,7 +3657,7 @@
return OK;
}
-status_t CameraService::BasicClient::startWatchingTags(const String8&, int) {
+status_t CameraService::BasicClient::startWatchingTags(const std::string&, int) {
// Can't watch tags directly, must go through CameraService::startWatchingTags
return OK;
}
@@ -3599,7 +3672,7 @@
return OK;
}
-String16 CameraService::BasicClient::getPackageName() const {
+std::string CameraService::BasicClient::getPackageName() const {
return mClientPackageName;
}
@@ -3656,7 +3729,7 @@
status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) {
if (mode == AppOpsManager::MODE_ERRORED) {
ALOGI("Camera %s: Access for \"%s\" has been revoked",
- mCameraIdStr.string(), String8(mClientPackageName).string());
+ mCameraIdStr.c_str(), mClientPackageName.c_str());
return PERMISSION_DENIED;
} else if (!mUidIsTrusted && mode == AppOpsManager::MODE_IGNORED) {
// If the calling Uid is trusted (a native service), the AppOpsManager could
@@ -3672,7 +3745,7 @@
// capabilities are unknown.
if (!isUidActive || !isCameraPrivacyEnabled) {
ALOGI("Camera %s: Access for \"%s\" has been restricted",
- mCameraIdStr.string(), String8(mClientPackageName).string());
+ mCameraIdStr.c_str(), mClientPackageName.c_str());
// Return the same error as for device policy manager rejection
return -EACCES;
}
@@ -3685,18 +3758,18 @@
{
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
- __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+ __FUNCTION__, mClientPackageName.c_str(), mClientUid);
}
if (mAppOpsManager != nullptr) {
// Notify app ops that the camera is not available
mOpsCallback = new OpsCallback(this);
mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
- mClientPackageName, mOpsCallback);
+ toString16(mClientPackageName), mOpsCallback);
// Just check for camera acccess here on open - delay startOp until
// camera frames start streaming in startCameraStreamingOps
int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName);
+ toString16(mClientPackageName));
status_t res = handleAppOpMode(mode);
if (res != OK) {
return res;
@@ -3729,12 +3802,13 @@
}
ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d",
- __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+ __FUNCTION__, mClientPackageName.c_str(), mClientUid);
if (mAppOpsManager != nullptr) {
int32_t mode = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId,
- String16("start camera ") + String16(mCameraIdStr));
+ toString16(mClientPackageName), /*startIfModeDefault*/ false,
+ toString16(mClientFeatureId),
+ toString16("start camera ") + toString16(mCameraIdStr));
status_t res = handleAppOpMode(mode);
if (res != OK) {
return res;
@@ -3750,14 +3824,14 @@
ATRACE_CALL();
ALOGV("%s: Start camera noteAppOp, package name = %s, client UID = %d",
- __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+ __FUNCTION__, mClientPackageName.c_str(), mClientUid);
// noteAppOp is only used for when camera mute is not supported, in order
// to trigger the sensor privacy "Unblock" dialog
if (mAppOpsManager != nullptr) {
int32_t mode = mAppOpsManager->noteOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName, mClientFeatureId,
- String16("start camera ") + String16(mCameraIdStr));
+ toString16(mClientPackageName), toString16(mClientFeatureId),
+ toString16("start camera ") + toString16(mCameraIdStr));
status_t res = handleAppOpMode(mode);
if (res != OK) {
return res;
@@ -3781,7 +3855,7 @@
if (mAppOpsManager != nullptr) {
mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName, mClientFeatureId);
+ toString16(mClientPackageName), toString16(mClientFeatureId));
mOpsStreaming = false;
}
@@ -3837,7 +3911,7 @@
int32_t res;
res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
- mClientUid, mClientPackageName);
+ mClientUid, toString16(mClientPackageName));
ALOGV("checkOp returns: %d, %s ", res,
res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
@@ -3845,15 +3919,15 @@
"UNKNOWN");
if (res == AppOpsManager::MODE_ERRORED) {
- ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
- String8(mClientPackageName).string());
+ ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.c_str(),
+ mClientPackageName.c_str());
block();
} else if (res == AppOpsManager::MODE_IGNORED) {
bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName);
bool isCameraPrivacyEnabled =
sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled();
ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d",
- mCameraIdStr.string(), String8(mClientPackageName).string(),
+ mCameraIdStr.c_str(), mClientPackageName.c_str(),
mUidIsTrusted, isUidActive);
// If the calling Uid is trusted (a native service), or the client Uid is active (WAR for
// b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as
@@ -3934,7 +4008,7 @@
| ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE
| ActivityManager::UID_OBSERVER_PROC_OOM_ADJ,
ActivityManager::PROCESS_STATE_UNKNOWN,
- String16("cameraserver"), emptyUidArray, 0, mObserverToken);
+ toString16(kServiceName), emptyUidArray, 0, mObserverToken);
if (res == OK) {
mRegistered = true;
ALOGV("UidPolicy: Registered with ActivityManager");
@@ -3944,7 +4018,7 @@
}
void CameraService::UidPolicy::onServiceRegistration(const String16& name, const sp<IBinder>&) {
- if (name != String16(kActivityServiceName)) {
+ if (name != toString16(kActivityServiceName)) {
return;
}
@@ -3956,9 +4030,9 @@
// If not available then register for notifications, instead of blocking
// till the service is ready
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->checkService(String16(kActivityServiceName));
+ sp<IBinder> binder = sm->checkService(toString16(kActivityServiceName));
if (!binder) {
- sm->registerForNotifications(String16(kActivityServiceName), this);
+ sm->registerForNotifications(toString16(kActivityServiceName), this);
} else {
registerWithActivityManager();
}
@@ -4077,7 +4151,7 @@
monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ;
monitoredUid.refCount = 1;
it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first;
- status_t res = mAm.addUidToObserver(mObserverToken, String16("cameraserver"), uid);
+ status_t res = mAm.addUidToObserver(mObserverToken, toString16(kServiceName), uid);
if (res != OK) {
ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res);
}
@@ -4098,7 +4172,7 @@
it->second.refCount--;
if (it->second.refCount == 0) {
mMonitoredUids.erase(it);
- status_t res = mAm.removeUidFromObserver(mObserverToken, String16("cameraserver"), uid);
+ status_t res = mAm.removeUidFromObserver(mObserverToken, toString16(kServiceName), uid);
if (res != OK) {
ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res);
}
@@ -4110,7 +4184,7 @@
}
}
-bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
+bool CameraService::UidPolicy::isUidActive(uid_t uid, const std::string &callingPackage) {
Mutex::Autolock _l(mUidLock);
return isUidActiveLocked(uid, callingPackage);
}
@@ -4118,7 +4192,7 @@
static const int64_t kPollUidActiveTimeoutTotalMillis = 300;
static const int64_t kPollUidActiveTimeoutMillis = 50;
-bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
+bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, const std::string &callingPackage) {
// Non-app UIDs are considered always active
// If activity manager is unreachable, assume everything is active
if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -4145,7 +4219,7 @@
// some polling which should happen pretty rarely anyway as the race is hard
// to hit.
active = mActiveUids.find(uid) != mActiveUids.end();
- if (!active) active = am.isUidActive(uid, callingPackage);
+ if (!active) active = am.isUidActive(uid, toString16(callingPackage));
if (active) {
break;
}
@@ -4185,12 +4259,12 @@
return procState;
}
-void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
- String16 callingPackage, bool active) {
+void CameraService::UidPolicy::addOverrideUid(uid_t uid,
+ const std::string &callingPackage, bool active) {
updateOverrideUid(uid, callingPackage, active, true);
}
-void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
+void CameraService::UidPolicy::removeOverrideUid(uid_t uid, const std::string &callingPackage) {
updateOverrideUid(uid, callingPackage, false, false);
}
@@ -4201,7 +4275,7 @@
mActiveUids.clear();
}
-void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
+void CameraService::UidPolicy::updateOverrideUid(uid_t uid, const std::string &callingPackage,
bool active, bool insert) {
bool wasActive = false;
bool isActive = false;
@@ -4244,7 +4318,7 @@
void CameraService::SensorPrivacyPolicy::onServiceRegistration(const String16& name,
const sp<IBinder>&) {
- if (name != String16(kSensorPrivacyServiceName)) {
+ if (name != toString16(kSensorPrivacyServiceName)) {
return;
}
@@ -4255,9 +4329,9 @@
// Use checkservice to see if the sensor_privacy service is available
// If service is not available then register for notification
sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->checkService(String16(kSensorPrivacyServiceName));
+ sp<IBinder> binder = sm->checkService(toString16(kSensorPrivacyServiceName));
if (!binder) {
- sm->registerForNotifications(String16(kSensorPrivacyServiceName),this);
+ sm->registerForNotifications(toString16(kSensorPrivacyServiceName),this);
} else {
registerWithSensorPrivacyManager();
}
@@ -4321,8 +4395,8 @@
// CameraState
// ----------------------------------------------------------------------------
-CameraService::CameraState::CameraState(const String8& id, int cost,
- const std::set<String8>& conflicting, SystemCameraKind systemCameraKind,
+CameraService::CameraState::CameraState(const std::string& id, int cost,
+ const std::set<std::string>& conflicting, SystemCameraKind systemCameraKind,
const std::vector<std::string>& physicalCameras) : mId(id),
mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {}
@@ -4334,9 +4408,9 @@
return mStatus;
}
-std::vector<String8> CameraService::CameraState::getUnavailablePhysicalIds() const {
+std::vector<std::string> CameraService::CameraState::getUnavailablePhysicalIds() const {
Mutex::Autolock lock(mStatusLock);
- std::vector<String8> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
+ std::vector<std::string> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
return res;
}
@@ -4352,14 +4426,10 @@
return mCost;
}
-std::set<String8> CameraService::CameraState::getConflicting() const {
+std::set<std::string> CameraService::CameraState::getConflicting() const {
return mConflicting;
}
-String8 CameraService::CameraState::getId() const {
- return mId;
-}
-
SystemCameraKind CameraService::CameraState::getSystemCameraKind() const {
return mSystemCameraKind;
}
@@ -4369,24 +4439,24 @@
!= mPhysicalCameras.end();
}
-bool CameraService::CameraState::addUnavailablePhysicalId(const String8& physicalId) {
+bool CameraService::CameraState::addUnavailablePhysicalId(const std::string& physicalId) {
Mutex::Autolock lock(mStatusLock);
auto result = mUnavailablePhysicalIds.insert(physicalId);
return result.second;
}
-bool CameraService::CameraState::removeUnavailablePhysicalId(const String8& physicalId) {
+bool CameraService::CameraState::removeUnavailablePhysicalId(const std::string& physicalId) {
Mutex::Autolock lock(mStatusLock);
auto count = mUnavailablePhysicalIds.erase(physicalId);
return count > 0;
}
-void CameraService::CameraState::setClientPackage(const String8& clientPackage) {
+void CameraService::CameraState::setClientPackage(const std::string& clientPackage) {
Mutex::Autolock lock(mStatusLock);
mClientPackage = clientPackage;
}
-String8 CameraService::CameraState::getClientPackage() const {
+std::string CameraService::CameraState::getClientPackage() const {
Mutex::Autolock lock(mStatusLock);
return mClientPackage;
}
@@ -4396,23 +4466,23 @@
// ----------------------------------------------------------------------------
void CameraService::ClientEventListener::onClientAdded(
- const resource_policy::ClientDescriptor<String8,
+ const resource_policy::ClientDescriptor<std::string,
sp<CameraService::BasicClient>>& descriptor) {
const auto& basicClient = descriptor.getValue();
if (basicClient.get() != nullptr) {
BatteryNotifier& notifier(BatteryNotifier::getInstance());
- notifier.noteStartCamera(descriptor.getKey(),
+ notifier.noteStartCamera(toString8(descriptor.getKey()),
static_cast<int>(basicClient->getClientUid()));
}
}
void CameraService::ClientEventListener::onClientRemoved(
- const resource_policy::ClientDescriptor<String8,
+ const resource_policy::ClientDescriptor<std::string,
sp<CameraService::BasicClient>>& descriptor) {
const auto& basicClient = descriptor.getValue();
if (basicClient.get() != nullptr) {
BatteryNotifier& notifier(BatteryNotifier::getInstance());
- notifier.noteStopCamera(descriptor.getKey(),
+ notifier.noteStopCamera(toString8(descriptor.getKey()),
static_cast<int>(basicClient->getClientUid()));
}
}
@@ -4429,7 +4499,7 @@
CameraService::CameraClientManager::~CameraClientManager() {}
sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
- const String8& id) const {
+ const std::string& id) const {
auto descriptor = get(id);
if (descriptor == nullptr) {
return sp<BasicClient>{nullptr};
@@ -4437,56 +4507,57 @@
return descriptor->getValue();
}
-String8 CameraService::CameraClientManager::toString() const {
+std::string CameraService::CameraClientManager::toString() const {
auto all = getAll();
- String8 ret("[");
+ std::ostringstream ret;
+ ret << "[";
bool hasAny = false;
for (auto& i : all) {
hasAny = true;
- String8 key = i->getKey();
+ std::string key = i->getKey();
int32_t cost = i->getCost();
int32_t pid = i->getOwnerId();
int32_t score = i->getPriority().getScore();
int32_t state = i->getPriority().getState();
auto conflicting = i->getConflicting();
auto clientSp = i->getValue();
- String8 packageName;
+ std::string packageName;
userid_t clientUserId = 0;
if (clientSp.get() != nullptr) {
- packageName = String8{clientSp->getPackageName()};
+ packageName = clientSp->getPackageName();
uid_t clientUid = clientSp->getClientUid();
clientUserId = multiuser_get_user_id(clientUid);
}
- ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
- PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
+ ret << fmt::sprintf("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
+ PRId32 ", State: %" PRId32, key.c_str(), cost, pid, score, state);
if (clientSp.get() != nullptr) {
- ret.appendFormat("User Id: %d, ", clientUserId);
+ ret << fmt::sprintf("User Id: %d, ", clientUserId);
}
if (packageName.size() != 0) {
- ret.appendFormat("Client Package Name: %s", packageName.string());
+ ret << fmt::sprintf("Client Package Name: %s", packageName.c_str());
}
- ret.append(", Conflicting Client Devices: {");
+ ret << ", Conflicting Client Devices: {";
for (auto& j : conflicting) {
- ret.appendFormat("%s, ", j.string());
+ ret << fmt::sprintf("%s, ", j.c_str());
}
- ret.append("})");
+ ret << "})";
}
- if (hasAny) ret.append("\n");
- ret.append("]\n");
- return ret;
+ if (hasAny) ret << "\n";
+ ret << "]\n";
+ return std::move(ret.str());
}
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
- const String8& key, const sp<BasicClient>& value, int32_t cost,
- const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
+ const std::string& key, const sp<BasicClient>& value, int32_t cost,
+ const std::set<std::string>& conflictingKeys, int32_t score, int32_t ownerId,
int32_t state, int32_t oomScoreOffset, bool systemNativeClient) {
int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score;
- int32_t state_adj = systemNativeClient ? kSystemNativeClientState: state;
+ int32_t state_adj = systemNativeClient ? kSystemNativeClientState : state;
- return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
+ return std::make_shared<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>(
key, value, cost, conflictingKeys, score_adj, ownerId, state_adj,
systemNativeClient, oomScoreOffset);
}
@@ -4525,7 +4596,7 @@
}
void CameraService::InjectionStatusListener::notifyInjectionError(
- String8 injectedCamId, status_t err) {
+ const std::string &injectedCamId, status_t err) {
if (mCameraInjectionCallback == nullptr) {
ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr");
return;
@@ -4536,37 +4607,37 @@
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_SESSION);
ALOGE("No camera device with ID \"%s\" currently available!",
- injectedCamId.string());
+ injectedCamId.c_str());
break;
case -EBUSY:
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_SESSION);
ALOGE("Higher-priority client using camera, ID \"%s\" currently unavailable!",
- injectedCamId.string());
+ injectedCamId.c_str());
break;
case DEAD_OBJECT:
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_SESSION);
ALOGE("Camera ID \"%s\" object is dead!",
- injectedCamId.string());
+ injectedCamId.c_str());
break;
case INVALID_OPERATION:
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_SESSION);
ALOGE("Camera ID \"%s\" encountered an operating or internal error!",
- injectedCamId.string());
+ injectedCamId.c_str());
break;
case UNKNOWN_TRANSACTION:
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED);
ALOGE("Camera ID \"%s\" method doesn't support!",
- injectedCamId.string());
+ injectedCamId.c_str());
break;
default:
mCameraInjectionCallback->onInjectionError(
ICameraInjectionCallback::ERROR_INJECTION_INVALID_ERROR);
ALOGE("Unexpected error %s (%d) opening camera \"%s\"!",
- strerror(-err), err, injectedCamId.string());
+ strerror(-err), err, injectedCamId.c_str());
}
}
@@ -4642,10 +4713,10 @@
Mutex::Autolock l(mCameraStatesLock);
// Start collecting the info for open sessions and store it in temp file.
for (const auto& state : mCameraStates) {
- String8 cameraId = state.first;
+ std::string cameraId = state.first;
auto clientDescriptor = mActiveClientManager.get(cameraId);
if (clientDescriptor != nullptr) {
- dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+ dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
// Log the current open session info before device is disconnected.
dumpOpenSessionClientLogs(mMemFd, args, cameraId);
}
@@ -4656,7 +4727,7 @@
status_t CameraService::dump(int fd, const Vector<String16>& args) {
ATRACE_CALL();
- if (checkCallingPermission(sDumpPermission) == false) {
+ if (checkCallingPermission(toString16(sDumpPermission)) == false) {
dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
CameraThreadState::getCallingPid(),
CameraThreadState::getCallingUid());
@@ -4685,9 +4756,9 @@
for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
dprintf(fd, " Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
}
- String8 activeClientString = mActiveClientManager.toString();
- dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
- dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
+ std::string activeClientString = mActiveClientManager.toString();
+ dprintf(fd, "Active Camera Clients:\n%s", activeClientString.c_str());
+ dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).c_str());
if (mStreamUseCaseOverrides.size() > 0) {
dprintf(fd, "Active stream use case overrides:");
for (int64_t useCaseOverride : mStreamUseCaseOverrides) {
@@ -4705,18 +4776,18 @@
int argSize = args.size();
for (int i = 0; i < argSize; i++) {
- if (args[i] == TagMonitor::kMonitorOption) {
+ if (args[i] == toString16(TagMonitor::kMonitorOption)) {
if (i + 1 < argSize) {
- mMonitorTags = String8(args[i + 1]);
+ mMonitorTags = toStdString(args[i + 1]);
}
break;
}
}
for (auto& state : mCameraStates) {
- String8 cameraId = state.first;
+ const std::string &cameraId = state.first;
- dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+ dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
CameraParameters p = state.second->getShimParams();
if (!p.isEmpty()) {
@@ -4767,8 +4838,8 @@
if (args[i] == verboseOption) {
// change logging level
if (i + 1 >= n) continue;
- String8 levelStr(args[i+1]);
- int level = atoi(levelStr.string());
+ std::string levelStr = toStdString(args[i+1]);
+ int level = atoi(levelStr.c_str());
dprintf(fd, "\nSetting log level to %d.\n", level);
setLogLevel(level);
} else if (args[i] == unreachableOption) {
@@ -4814,11 +4885,11 @@
}
void CameraService::dumpOpenSessionClientLogs(int fd,
- const Vector<String16>& args, const String8& cameraId) {
+ const Vector<String16>& args, const std::string& cameraId) {
auto clientDescriptor = mActiveClientManager.get(cameraId);
dprintf(fd, " %s : Device %s is open. Client instance dump:\n",
- getFormattedCurrentTime().string(),
- cameraId.string());
+ getFormattedCurrentTime().c_str(),
+ cameraId.c_str());
dprintf(fd, " Client priority score: %d state: %d\n",
clientDescriptor->getPriority().getScore(),
clientDescriptor->getPriority().getState());
@@ -4826,14 +4897,14 @@
auto client = clientDescriptor->getValue();
dprintf(fd, " Client package: %s\n",
- String8(client->getPackageName()).string());
+ client->getPackageName().c_str());
client->dumpClient(fd, args);
}
-void CameraService::dumpClosedSessionClientLogs(int fd, const String8& cameraId) {
+void CameraService::dumpClosedSessionClientLogs(int fd, const std::string& cameraId) {
dprintf(fd, " Device %s is closed, no client instance\n",
- cameraId.string());
+ cameraId.c_str());
}
void CameraService::dumpEventLog(int fd) {
@@ -4841,7 +4912,7 @@
Mutex::Autolock l(mLogLock);
for (const auto& msg : mEventLog) {
- dprintf(fd, " %s\n", msg.string());
+ dprintf(fd, " %s\n", msg.c_str());
}
if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
@@ -4852,7 +4923,7 @@
dprintf(fd, "\n");
}
-void CameraService::cacheClientTagDumpIfNeeded(const char *cameraId, BasicClient* client) {
+void CameraService::cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient* client) {
Mutex::Autolock lock(mLogLock);
if (!isClientWatchedLocked(client)) { return; }
@@ -4861,34 +4932,26 @@
if (dumpVector.empty()) { return; }
- std::string dumpString;
+ std::ostringstream dumpString;
- String8 currentTime = getFormattedCurrentTime();
- dumpString += "Cached @ ";
- dumpString += currentTime.string();
- dumpString += "\n"; // First line is the timestamp of when client is cached.
-
-
- const String16 &packageName = client->getPackageName();
-
- String8 packageName8 = String8(packageName);
- const char *printablePackageName = packageName8.lockBuffer(packageName.size());
-
+ std::string currentTime = getFormattedCurrentTime();
+ dumpString << "Cached @ ";
+ dumpString << currentTime;
+ dumpString << "\n"; // First line is the timestamp of when client is cached.
size_t i = dumpVector.size();
// Store the string in reverse order (latest last)
while (i > 0) {
i--;
- dumpString += cameraId;
- dumpString += ":";
- dumpString += printablePackageName;
- dumpString += " ";
- dumpString += dumpVector[i]; // implicitly ends with '\n'
+ dumpString << cameraId;
+ dumpString << ":";
+ dumpString << client->getPackageName();
+ dumpString << " ";
+ dumpString << dumpVector[i]; // implicitly ends with '\n'
}
- packageName8.unlockBuffer();
- mWatchedClientsDumpCache[packageName] = dumpString;
+ mWatchedClientsDumpCache[client->getPackageName()] = dumpString.str();
}
void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
@@ -4896,7 +4959,7 @@
for (size_t i = 0; i < mTorchClientMap.size(); i++) {
if (mTorchClientMap[i] == who) {
// turn off the torch mode that was turned on by dead client
- String8 cameraId = mTorchClientMap.keyAt(i);
+ std::string cameraId = mTorchClientMap.keyAt(i);
status_t res = mFlashlight->setTorchMode(cameraId, false);
if (res) {
ALOGE("%s: torch client died but couldn't turn off torch: "
@@ -4916,7 +4979,7 @@
* binder driver
*/
// PID here is approximate and can be wrong.
- logClientDied(CameraThreadState::getCallingPid(), String8("Binder died unexpectedly"));
+ logClientDied(CameraThreadState::getCallingPid(), "Binder died unexpectedly");
// check torch client
handleTorchClientBinderDied(who);
@@ -4931,11 +4994,11 @@
__FUNCTION__);
}
-void CameraService::updateStatus(StatusInternal status, const String8& cameraId) {
+void CameraService::updateStatus(StatusInternal status, const std::string& cameraId) {
updateStatus(status, cameraId, {});
}
-void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
+void CameraService::updateStatus(StatusInternal status, const std::string& cameraId,
std::initializer_list<StatusInternal> rejectSourceStates) {
// Do not lock mServiceLock here or can get into a deadlock from
// connect() -> disconnect -> updateStatus
@@ -4944,14 +5007,14 @@
if (state == nullptr) {
ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
return;
}
// Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
- ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.string());
+ ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
return;
}
@@ -4962,7 +5025,7 @@
// of the listeners with both the mStatusLock and mStatusListenerLock held
state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind,
&logicalCameraIds]
- (const String8& cameraId, StatusInternal status) {
+ (const std::string& cameraId, StatusInternal status) {
if (status != StatusInternal::ENUMERATING) {
// Update torch status if it has a flash unit.
@@ -4981,7 +5044,7 @@
}
Mutex::Autolock lock(mStatusListenerLock);
- notifyPhysicalCameraStatusLocked(mapToInterface(status), String16(cameraId),
+ notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId,
logicalCameraIds, deviceKind);
for (auto& listener : mListenerList) {
@@ -4994,7 +5057,7 @@
continue;
}
auto ret = listener->getListener()->onStatusChanged(mapToInterface(status),
- String16(cameraId));
+ cameraId);
listener->handleBinderStatus(ret,
"%s: Failed to trigger onStatusChanged callback for %d:%d: %d",
__FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
@@ -5003,18 +5066,18 @@
});
}
-void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
- const String16& clientPackageName) {
+void CameraService::updateOpenCloseStatus(const std::string& cameraId, bool open,
+ const std::string& clientPackageName) {
auto state = getCameraState(cameraId);
if (state == nullptr) {
ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
- cameraId.string());
+ cameraId.c_str());
return;
}
if (open) {
- state->setClientPackage(String8(clientPackageName));
+ state->setClientPackage(clientPackageName);
} else {
- state->setClientPackage(String8::empty());
+ state->setClientPackage(std::string());
}
Mutex::Autolock lock(mStatusListenerLock);
@@ -5025,11 +5088,10 @@
}
binder::Status ret;
- String16 cameraId64(cameraId);
if (open) {
- ret = it->getListener()->onCameraOpened(cameraId64, clientPackageName);
+ ret = it->getListener()->onCameraOpened(cameraId, clientPackageName);
} else {
- ret = it->getListener()->onCameraClosed(cameraId64);
+ ret = it->getListener()->onCameraClosed(cameraId);
}
it->handleBinderStatus(ret,
@@ -5040,7 +5102,7 @@
template<class Func>
void CameraService::CameraState::updateStatus(StatusInternal status,
- const String8& cameraId,
+ const std::string& cameraId,
std::initializer_list<StatusInternal> rejectSourceStates,
Func onStatusUpdatedLocked) {
Mutex::Autolock lock(mStatusLock);
@@ -5052,7 +5114,7 @@
}
ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
- cameraId.string(), oldStatus, status);
+ cameraId.c_str(), oldStatus, status);
if (oldStatus == StatusInternal::NOT_PRESENT &&
(status != StatusInternal::PRESENT &&
@@ -5072,7 +5134,7 @@
for (auto& rejectStatus : rejectSourceStates) {
if (oldStatus == rejectStatus) {
ALOGV("%s: Rejecting status transition for Camera ID %s, since the source "
- "state was was in one of the bad states.", __FUNCTION__, cameraId.string());
+ "state was was in one of the bad states.", __FUNCTION__, cameraId.c_str());
mStatus = oldStatus;
return;
}
@@ -5082,7 +5144,7 @@
}
status_t CameraService::getTorchStatusLocked(
- const String8& cameraId,
+ const std::string& cameraId,
TorchModeStatus *status) const {
if (!status) {
return BAD_VALUE;
@@ -5097,7 +5159,7 @@
return OK;
}
-status_t CameraService::setTorchStatusLocked(const String8& cameraId,
+status_t CameraService::setTorchStatusLocked(const std::string& cameraId,
TorchModeStatus status) {
ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
@@ -5108,20 +5170,20 @@
return OK;
}
-std::list<String16> CameraService::getLogicalCameras(
- const String8& physicalCameraId) {
- std::list<String16> retList;
+std::list<std::string> CameraService::getLogicalCameras(
+ const std::string& physicalCameraId) {
+ std::list<std::string> retList;
Mutex::Autolock lock(mCameraStatesLock);
for (const auto& state : mCameraStates) {
- if (state.second->containsPhysicalCamera(physicalCameraId.c_str())) {
- retList.emplace_back(String16(state.first));
+ if (state.second->containsPhysicalCamera(physicalCameraId)) {
+ retList.emplace_back(state.first);
}
}
return retList;
}
void CameraService::notifyPhysicalCameraStatusLocked(int32_t status,
- const String16& physicalCameraId, const std::list<String16>& logicalCameraIds,
+ const std::string& physicalCameraId, const std::list<std::string>& logicalCameraIds,
SystemCameraKind deviceKind) {
// mStatusListenerLock is expected to be locked
for (const auto& logicalCameraId : logicalCameraIds) {
@@ -5132,7 +5194,7 @@
if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
listener->getListenerPid(), listener->getListenerUid())) {
ALOGV("Skipping discovery callback for system-only camera device %s",
- String8(physicalCameraId).c_str());
+ physicalCameraId.c_str());
continue;
}
auto ret = listener->getListener()->onPhysicalCameraStatusChanged(status,
@@ -5172,44 +5234,44 @@
// NOTE: This is a remote API - make sure all args are validated
status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
- if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
+ if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) {
return PERMISSION_DENIED;
}
if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
return BAD_VALUE;
}
- if (args.size() >= 3 && args[0] == String16("set-uid-state")) {
+ if (args.size() >= 3 && args[0] == toString16("set-uid-state")) {
return handleSetUidState(args, err);
- } else if (args.size() >= 2 && args[0] == String16("reset-uid-state")) {
+ } else if (args.size() >= 2 && args[0] == toString16("reset-uid-state")) {
return handleResetUidState(args, err);
- } else if (args.size() >= 2 && args[0] == String16("get-uid-state")) {
+ } else if (args.size() >= 2 && args[0] == toString16("get-uid-state")) {
return handleGetUidState(args, out, err);
- } else if (args.size() >= 2 && args[0] == String16("set-rotate-and-crop")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-rotate-and-crop")) {
return handleSetRotateAndCrop(args);
- } else if (args.size() >= 1 && args[0] == String16("get-rotate-and-crop")) {
+ } else if (args.size() >= 1 && args[0] == toString16("get-rotate-and-crop")) {
return handleGetRotateAndCrop(out);
- } else if (args.size() >= 2 && args[0] == String16("set-autoframing")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-autoframing")) {
return handleSetAutoframing(args);
- } else if (args.size() >= 1 && args[0] == String16("get-autoframing")) {
+ } else if (args.size() >= 1 && args[0] == toString16("get-autoframing")) {
return handleGetAutoframing(out);
- } else if (args.size() >= 2 && args[0] == String16("set-image-dump-mask")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-image-dump-mask")) {
return handleSetImageDumpMask(args);
- } else if (args.size() >= 1 && args[0] == String16("get-image-dump-mask")) {
+ } else if (args.size() >= 1 && args[0] == toString16("get-image-dump-mask")) {
return handleGetImageDumpMask(out);
- } else if (args.size() >= 2 && args[0] == String16("set-camera-mute")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-camera-mute")) {
return handleSetCameraMute(args);
- } else if (args.size() >= 2 && args[0] == String16("set-stream-use-case-override")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-stream-use-case-override")) {
return handleSetStreamUseCaseOverrides(args);
- } else if (args.size() >= 1 && args[0] == String16("clear-stream-use-case-override")) {
+ } else if (args.size() >= 1 && args[0] == toString16("clear-stream-use-case-override")) {
handleClearStreamUseCaseOverrides();
return OK;
- } else if (args.size() >= 1 && args[0] == String16("set-zoom-override")) {
+ } else if (args.size() >= 1 && args[0] == toString16("set-zoom-override")) {
return handleSetZoomOverride(args);
- } else if (args.size() >= 2 && args[0] == String16("watch")) {
+ } else if (args.size() >= 2 && args[0] == toString16("watch")) {
return handleWatchCommand(args, in, out);
- } else if (args.size() >= 2 && args[0] == String16("set-watchdog")) {
+ } else if (args.size() >= 2 && args[0] == toString16("set-watchdog")) {
return handleSetCameraServiceWatchdog(args);
- } else if (args.size() == 1 && args[0] == String16("help")) {
+ } else if (args.size() == 1 && args[0] == toString16("help")) {
printHelp(out);
return OK;
}
@@ -5218,19 +5280,19 @@
}
status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
- String16 packageName = args[1];
+ std::string packageName = toStdString(args[1]);
bool active = false;
- if (args[2] == String16("active")) {
+ if (args[2] == toString16("active")) {
active = true;
- } else if ((args[2] != String16("idle"))) {
- ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
+ } else if ((args[2] != toString16("idle"))) {
+ ALOGE("Expected active or idle but got: '%s'", toStdString(args[2]).c_str());
return BAD_VALUE;
}
int userId = 0;
- if (args.size() >= 5 && args[3] == String16("--user")) {
- userId = atoi(String8(args[4]));
+ if (args.size() >= 5 && args[3] == toString16("--user")) {
+ userId = atoi(toStdString(args[4]).c_str());
}
uid_t uid;
@@ -5243,11 +5305,11 @@
}
status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
- String16 packageName = args[1];
+ std::string packageName = toStdString(args[1]);
int userId = 0;
- if (args.size() >= 4 && args[2] == String16("--user")) {
- userId = atoi(String8(args[3]));
+ if (args.size() >= 4 && args[2] == toString16("--user")) {
+ userId = atoi(toStdString(args[3]).c_str());
}
uid_t uid;
@@ -5260,11 +5322,11 @@
}
status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
- String16 packageName = args[1];
+ std::string packageName = toStdString(args[1]);
int userId = 0;
- if (args.size() >= 4 && args[2] == String16("--user")) {
- userId = atoi(String8(args[3]));
+ if (args.size() >= 4 && args[2] == toString16("--user")) {
+ userId = atoi(toStdString(args[3]).c_str());
}
uid_t uid;
@@ -5280,7 +5342,7 @@
}
status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) {
- int rotateValue = atoi(String8(args[1]));
+ int rotateValue = atoi(toStdString(args[1]).c_str());
if (rotateValue < ANDROID_SCALER_ROTATE_AND_CROP_NONE ||
rotateValue > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
Mutex::Autolock lock(mServiceLock);
@@ -5304,7 +5366,7 @@
status_t CameraService::handleSetAutoframing(const Vector<String16>& args) {
char* end;
- int autoframingValue = (int) strtol(String8(args[1]), &end, /*base=*/10);
+ int autoframingValue = (int) strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
if ((*end != '\0') ||
(autoframingValue != ANDROID_CONTROL_AUTOFRAMING_OFF &&
autoframingValue != ANDROID_CONTROL_AUTOFRAMING_ON &&
@@ -5331,7 +5393,7 @@
}
status_t CameraService::handleSetCameraServiceWatchdog(const Vector<String16>& args) {
- int enableWatchdog = atoi(String8(args[1]));
+ int enableWatchdog = atoi(toStdString(args[1]).c_str());
if (enableWatchdog < 0 || enableWatchdog > 1) return BAD_VALUE;
@@ -5367,11 +5429,11 @@
status_t CameraService::handleSetImageDumpMask(const Vector<String16>& args) {
char *endPtr;
errno = 0;
- String8 maskString8 = String8(args[1]);
- long maskValue = strtol(maskString8.c_str(), &endPtr, 10);
+ std::string maskString = toStdString(args[1]);
+ long maskValue = strtol(maskString.c_str(), &endPtr, 10);
if (errno != 0) return BAD_VALUE;
- if (endPtr != maskString8.c_str() + maskString8.size()) return BAD_VALUE;
+ if (endPtr != maskString.c_str() + maskString.size()) return BAD_VALUE;
if (maskValue < 0 || maskValue > 1) return BAD_VALUE;
Mutex::Autolock lock(mServiceLock);
@@ -5388,7 +5450,7 @@
}
status_t CameraService::handleSetCameraMute(const Vector<String16>& args) {
- int muteValue = strtol(String8(args[1]), nullptr, 10);
+ int muteValue = strtol(toStdString(args[1]).c_str(), nullptr, 10);
if (errno != 0) return BAD_VALUE;
if (muteValue < 0 || muteValue > 1) return BAD_VALUE;
@@ -5415,23 +5477,23 @@
std::vector<int64_t> useCasesOverride;
for (size_t i = 1; i < args.size(); i++) {
int64_t useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
- String8 arg8 = String8(args[i]);
- if (arg8 == "DEFAULT") {
+ std::string arg = toStdString(args[i]);
+ if (arg == "DEFAULT") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
- } else if (arg8 == "PREVIEW") {
+ } else if (arg == "PREVIEW") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW;
- } else if (arg8 == "STILL_CAPTURE") {
+ } else if (arg == "STILL_CAPTURE") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE;
- } else if (arg8 == "VIDEO_RECORD") {
+ } else if (arg == "VIDEO_RECORD") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD;
- } else if (arg8 == "PREVIEW_VIDEO_STILL") {
+ } else if (arg == "PREVIEW_VIDEO_STILL") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL;
- } else if (arg8 == "VIDEO_CALL") {
+ } else if (arg == "VIDEO_CALL") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
- } else if (arg8 == "CROPPED_RAW") {
+ } else if (arg == "CROPPED_RAW") {
useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW;
} else {
- ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg8.c_str());
+ ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg.c_str());
return BAD_VALUE;
}
useCasesOverride.push_back(useCase);
@@ -5450,7 +5512,7 @@
status_t CameraService::handleSetZoomOverride(const Vector<String16>& args) {
char* end;
- int zoomOverrideValue = strtol(String8(args[1]), &end, /*base=*/10);
+ int zoomOverrideValue = strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
if ((*end != '\0') ||
(zoomOverrideValue != -1 &&
zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF &&
@@ -5477,15 +5539,15 @@
}
status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
- if (args.size() >= 3 && args[1] == String16("start")) {
+ if (args.size() >= 3 && args[1] == toString16("start")) {
return startWatchingTags(args, outFd);
- } else if (args.size() == 2 && args[1] == String16("stop")) {
+ } else if (args.size() == 2 && args[1] == toString16("stop")) {
return stopWatchingTags(outFd);
- } else if (args.size() == 2 && args[1] == String16("dump")) {
+ } else if (args.size() == 2 && args[1] == toString16("dump")) {
return printWatchedTags(outFd);
- } else if (args.size() >= 2 && args[1] == String16("live")) {
+ } else if (args.size() >= 2 && args[1] == toString16("live")) {
return printWatchedTagsUntilInterrupt(args, inFd, outFd);
- } else if (args.size() == 2 && args[1] == String16("clear")) {
+ } else if (args.size() == 2 && args[1] == toString16("clear")) {
return clearCachedMonitoredTagDumps(outFd);
}
dprintf(outFd, "Camera service watch commands:\n"
@@ -5506,7 +5568,7 @@
Mutex::Autolock lock(mLogLock);
size_t tagsIdx; // index of '-m'
String16 tags("");
- for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != String16("-m"); tagsIdx++);
+ for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != toString16("-m"); tagsIdx++);
if (tagsIdx < args.size() - 1) {
tags = args[tagsIdx + 1];
} else {
@@ -5515,16 +5577,17 @@
}
size_t clientsIdx; // index of '-c'
- String16 clients = kWatchAllClientsFlag; // watch all clients if no clients are provided
- for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != String16("-c");
+ // watch all clients if no clients are provided
+ String16 clients = toString16(kWatchAllClientsFlag);
+ for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != toString16("-c");
clientsIdx++);
if (clientsIdx < args.size() - 1) {
clients = args[clientsIdx + 1];
}
- parseClientsToWatchLocked(String8(clients));
+ parseClientsToWatchLocked(toStdString(clients));
// track tags to initialize future clients with the monitoring information
- mMonitorTags = String8(tags);
+ mMonitorTags = toStdString(tags);
bool serviceLock = tryLock(mServiceLock);
int numWatchedClients = 0;
@@ -5548,7 +5611,7 @@
status_t CameraService::stopWatchingTags(int outFd) {
// clear mMonitorTags to prevent new clients from monitoring tags at initialization
Mutex::Autolock lock(mLogLock);
- mMonitorTags = String8::empty();
+ mMonitorTags = "";
mWatchedClientPackages.clear();
mWatchedClientsDumpCache.clear();
@@ -5576,7 +5639,7 @@
status_t CameraService::printWatchedTags(int outFd) {
Mutex::Autolock logLock(mLogLock);
- std::set<String16> connectedMonitoredClients;
+ std::set<std::string> connectedMonitoredClients;
bool printedSomething = false; // tracks if any monitoring information was printed
// (from either cached or active clients)
@@ -5599,17 +5662,14 @@
}
// Print tag dumps for active client
- const String8 &cameraId = clientDescriptor->getKey();
- String8 packageName8 = String8(client->getPackageName());
- const char *printablePackageName = packageName8.lockBuffer(packageName8.size());
- dprintf(outFd, "Client: %s (active)\n", printablePackageName);
+ const std::string &cameraId = clientDescriptor->getKey();
+ dprintf(outFd, "Client: %s (active)\n", client->getPackageName().c_str());
while(printIdx > 0) {
printIdx--;
- dprintf(outFd, "%s:%s %s", cameraId.string(), printablePackageName,
+ dprintf(outFd, "%s:%s %s", cameraId.c_str(), client->getPackageName().c_str(),
dumpVector[printIdx].c_str());
}
dprintf(outFd, "\n");
- packageName8.unlockBuffer();
printedSomething = true;
connectedMonitoredClients.emplace(client->getPackageName());
@@ -5618,12 +5678,12 @@
// Print entries in mWatchedClientsDumpCache for clients that are not connected
for (const auto &kv: mWatchedClientsDumpCache) {
- const String16 &package = kv.first;
+ const std::string &package = kv.first;
if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) {
continue;
}
- dprintf(outFd, "Client: %s (cached)\n", String8(package).string());
+ dprintf(outFd, "Client: %s (cached)\n", package.c_str());
dprintf(outFd, "%s\n", kv.second.c_str());
printedSomething = true;
}
@@ -5637,8 +5697,8 @@
// Print all events in vector `events' that came after lastPrintedEvent
void printNewWatchedEvents(int outFd,
- const char *cameraId,
- const String16 &packageName,
+ const std::string &cameraId,
+ const std::string &packageName,
const std::vector<std::string> &events,
const std::string &lastPrintedEvent) {
if (events.empty()) { return; }
@@ -5652,17 +5712,13 @@
if (lastPrintedIdx == 0) { return; } // early exit if no new event in `events`
- String8 packageName8(packageName);
- const char *printablePackageName = packageName8.lockBuffer(packageName8.size());
-
// print events in chronological order (latest event last)
size_t idxToPrint = lastPrintedIdx;
do {
idxToPrint--;
- dprintf(outFd, "%s:%s %s", cameraId, printablePackageName, events[idxToPrint].c_str());
+ dprintf(outFd, "%s:%s %s", cameraId.c_str(), packageName.c_str(),
+ events[idxToPrint].c_str());
} while (idxToPrint != 0);
-
- packageName8.unlockBuffer();
}
// Returns true if adb shell cmd watch should be interrupted based on data in inFd. The watch
@@ -5739,12 +5795,12 @@
long refreshTimeoutMs = 1000L; // refresh every 1s by default
if (args.size() > 2) {
size_t intervalIdx; // index of '-n'
- for (intervalIdx = 2; intervalIdx < args.size() && String16("-n") != args[intervalIdx];
+ for (intervalIdx = 2; intervalIdx < args.size() && toString16("-n") != args[intervalIdx];
intervalIdx++);
size_t intervalValIdx = intervalIdx + 1;
if (intervalValIdx < args.size()) {
- refreshTimeoutMs = strtol(String8(args[intervalValIdx].string()), nullptr, 10);
+ refreshTimeoutMs = strtol(toStdString(args[intervalValIdx]).c_str(), nullptr, 10);
if (errno) { return BAD_VALUE; }
}
}
@@ -5753,7 +5809,7 @@
refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs;
dprintf(outFd, "Press return to exit...\n\n");
- std::map<String16, std::string> packageNameToLastEvent;
+ std::map<std::string, std::string> packageNameToLastEvent;
while (true) {
bool serviceLock = tryLock(mServiceLock);
@@ -5768,7 +5824,7 @@
if (client.get() == nullptr) { continue; }
if (!isClientWatchedLocked(client.get())) { continue; }
- const String16 &packageName = client->getPackageName();
+ const std::string &packageName = client->getPackageName();
// This also initializes the map entries with an empty string
const std::string& lastPrintedEvent = packageNameToLastEvent[packageName];
@@ -5776,15 +5832,12 @@
client->dumpWatchedEventsToVector(latestEvents);
if (!latestEvents.empty()) {
- String8 cameraId = clientDescriptor->getKey();
- const char *printableCameraId = cameraId.lockBuffer(cameraId.size());
printNewWatchedEvents(outFd,
- printableCameraId,
+ clientDescriptor->getKey(),
packageName,
latestEvents,
lastPrintedEvent);
packageNameToLastEvent[packageName] = latestEvents[0];
- cameraId.unlockBuffer();
}
}
if (shouldInterruptWatchCommand(inFd, outFd, refreshTimeoutMs)) {
@@ -5794,17 +5847,14 @@
return OK;
}
-void CameraService::parseClientsToWatchLocked(String8 clients) {
+void CameraService::parseClientsToWatchLocked(const std::string &clients) {
mWatchedClientPackages.clear();
- const char *allSentinel = String8(kWatchAllClientsFlag).string();
+ std::istringstream iss(clients);
+ std::string nextClient;
- char *tokenized = clients.lockBuffer(clients.size());
- char *savePtr;
- char *nextClient = strtok_r(tokenized, ",", &savePtr);
-
- while (nextClient != nullptr) {
- if (strcmp(nextClient, allSentinel) == 0) {
+ while (std::getline(iss, nextClient, ',')) {
+ if (nextClient == kWatchAllClientsFlag) {
// Don't need to track any other package if 'all' is present
mWatchedClientPackages.clear();
mWatchedClientPackages.emplace(kWatchAllClientsFlag);
@@ -5813,9 +5863,7 @@
// track package names
mWatchedClientPackages.emplace(nextClient);
- nextClient = strtok_r(nullptr, ",", &savePtr);
}
- clients.unlockBuffer();
}
status_t CameraService::printHelp(int out) {
@@ -5879,13 +5927,13 @@
return mode;
}
-status_t CameraService::checkIfInjectionCameraIsPresent(const String8& externalCamId,
+status_t CameraService::checkIfInjectionCameraIsPresent(const std::string& externalCamId,
sp<BasicClient> clientSp) {
std::unique_ptr<AutoConditionLock> lock =
AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
status_t res = NO_ERROR;
if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) {
- ALOGW("Device %s is not usable!", externalCamId.string());
+ ALOGW("Device %s is not usable!", externalCamId.c_str());
mInjectionStatusListener->notifyInjectionError(
externalCamId, UNKNOWN_TRANSACTION);
clientSp->notifyError(
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3214d4c..b1ff6a5 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
+#include <android/content/AttributionSourceState.h>
#include <android/hardware/BnCameraService.h>
#include <android/hardware/BnSensorPrivacyListener.h>
#include <android/hardware/ICameraServiceListener.h>
@@ -119,19 +120,19 @@
/////////////////////////////////////////////////////////////////////
// HAL Callbacks - implements CameraProviderManager::StatusListener
- virtual void onDeviceStatusChanged(const String8 &cameraId,
+ virtual void onDeviceStatusChanged(const std::string &cameraId,
CameraDeviceStatus newHalStatus) override;
- virtual void onDeviceStatusChanged(const String8 &cameraId,
- const String8 &physicalCameraId,
+ virtual void onDeviceStatusChanged(const std::string &cameraId,
+ const std::string &physicalCameraId,
CameraDeviceStatus newHalStatus) override;
// This method may hold CameraProviderManager::mInterfaceMutex as a part
// of calling getSystemCameraKind() internally. Care should be taken not to
// directly / indirectly call this from callers who also hold
// mInterfaceMutex.
- virtual void onTorchStatusChanged(const String8& cameraId,
+ virtual void onTorchStatusChanged(const std::string& cameraId,
TorchModeStatus newStatus) override;
// Does not hold CameraProviderManager::mInterfaceMutex.
- virtual void onTorchStatusChanged(const String8& cameraId,
+ virtual void onTorchStatusChanged(const std::string& cameraId,
TorchModeStatus newStatus,
SystemCameraKind kind) override;
virtual void onNewProviderRegistered() override;
@@ -142,7 +143,7 @@
virtual binder::Status getCameraInfo(int cameraId, bool overrideToPortrait,
hardware::CameraInfo* cameraInfo) override;
- virtual binder::Status getCameraCharacteristics(const String16& cameraId,
+ virtual binder::Status getCameraCharacteristics(const std::string& cameraId,
int targetSdkVersion, bool overrideToPortrait, CameraMetadata* cameraInfo) override;
virtual binder::Status getCameraVendorTagDescriptor(
/*out*/
@@ -152,15 +153,16 @@
hardware::camera2::params::VendorTagDescriptorCache* cache);
virtual binder::Status connect(const sp<hardware::ICameraClient>& cameraClient,
- int32_t cameraId, const String16& clientPackageName,
+ int32_t cameraId, const std::string& clientPackageName,
int32_t clientUid, int clientPid, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode,
/*out*/
sp<hardware::ICamera>* device) override;
virtual binder::Status connectDevice(
- const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
- const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
+ const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
+ const std::string& cameraId,
+ const std::string& clientPackageName, const std::optional<std::string>& clientFeatureId,
int32_t clientUid, int scoreOffset, int targetSdkVersion, bool overrideToPortrait,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -182,15 +184,15 @@
virtual binder::Status getLegacyParameters(
int32_t cameraId,
/*out*/
- String16* parameters);
+ std::string* parameters);
- virtual binder::Status setTorchMode(const String16& cameraId, bool enabled,
+ virtual binder::Status setTorchMode(const std::string& cameraId, bool enabled,
const sp<IBinder>& clientBinder);
- virtual binder::Status turnOnTorchWithStrengthLevel(const String16& cameraId,
+ virtual binder::Status turnOnTorchWithStrengthLevel(const std::string& cameraId,
int32_t torchStrength, const sp<IBinder>& clientBinder);
- virtual binder::Status getTorchStrengthLevel(const String16& cameraId,
+ virtual binder::Status getTorchStrengthLevel(const std::string& cameraId,
int32_t* torchStrength);
virtual binder::Status notifySystemEvent(int32_t eventId,
@@ -202,24 +204,24 @@
// OK = supports api of that version, -EOPNOTSUPP = does not support
virtual binder::Status supportsCameraApi(
- const String16& cameraId, int32_t apiVersion,
+ const std::string& cameraId, int32_t apiVersion,
/*out*/
bool *isSupported);
virtual binder::Status isHiddenPhysicalCamera(
- const String16& cameraId,
+ const std::string& cameraId,
/*out*/
bool *isSupported);
virtual binder::Status injectCamera(
- const String16& packageName, const String16& internalCamId,
- const String16& externalCamId,
+ const std::string& packageName, const std::string& internalCamId,
+ const std::string& externalCamId,
const sp<hardware::camera2::ICameraInjectionCallback>& callback,
/*out*/
sp<hardware::camera2::ICameraInjectionSession>* cameraInjectionSession);
virtual binder::Status reportExtensionSessionStats(
- const hardware::CameraExtensionSessionStats& stats, String16* sessionKey /*out*/);
+ const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/);
// Extra permissions checks
virtual status_t onTransact(uint32_t code, const Parcel& data,
@@ -242,7 +244,7 @@
void cacheDump();
// Register an offline client for a given active camera id
- status_t addOfflineClient(String8 cameraId, sp<BasicClient> offlineClient);
+ status_t addOfflineClient(const std::string &cameraId, sp<BasicClient> offlineClient);
/////////////////////////////////////////////////////////////////////
// Client functionality
@@ -261,7 +263,7 @@
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
- std::pair<int, IPCTransport> getDeviceVersion(const String8& cameraId,
+ std::pair<int, IPCTransport> getDeviceVersion(const std::string& cameraId,
bool overrideToPortrait, int* portraitRotation,
int* facing = nullptr, int* orientation = nullptr);
@@ -289,7 +291,7 @@
friend class CameraService;
public:
virtual status_t initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) = 0;
+ const std::string& monitorTags) = 0;
virtual binder::Status disconnect();
// because we can't virtually inherit IInterface, which breaks
@@ -310,12 +312,12 @@
// Internal dump method to be called by CameraService
virtual status_t dumpClient(int fd, const Vector<String16>& args) = 0;
- virtual status_t startWatchingTags(const String8 &tags, int outFd);
+ virtual status_t startWatchingTags(const std::string &tags, int outFd);
virtual status_t stopWatchingTags(int outFd);
virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
// Return the package name for this client
- virtual String16 getPackageName() const;
+ virtual std::string getPackageName() const;
// Return the camera facing for this client
virtual int getCameraFacing() const;
@@ -383,7 +385,7 @@
// The injection camera session to replace the internal camera
// session.
- virtual status_t injectCamera(const String8& injectedCamId,
+ virtual status_t injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) = 0;
// Stop the injection camera and restore to internal camera session.
@@ -392,10 +394,10 @@
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool nativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraIdStr,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraIdStr,
int cameraFacing,
int sensorOrientation,
int clientPid,
@@ -413,12 +415,12 @@
// these are initialized in the constructor.
static sp<CameraService> sCameraService;
- const String8 mCameraIdStr;
+ const std::string mCameraIdStr;
const int mCameraFacing;
const int mOrientation;
- String16 mClientPackageName;
+ std::string mClientPackageName;
bool mSystemNativeClient;
- std::optional<String16> mClientFeatureId;
+ std::optional<std::string> mClientFeatureId;
pid_t mClientPid;
const uid_t mClientUid;
const pid_t mServicePid;
@@ -505,10 +507,10 @@
// Interface used by CameraService
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraIdStr,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraIdStr,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -552,13 +554,13 @@
*/
class ClientEventListener {
public:
- void onClientAdded(const resource_policy::ClientDescriptor<String8,
+ void onClientAdded(const resource_policy::ClientDescriptor<std::string,
sp<CameraService::BasicClient>>& descriptor);
- void onClientRemoved(const resource_policy::ClientDescriptor<String8,
+ void onClientRemoved(const resource_policy::ClientDescriptor<std::string,
sp<CameraService::BasicClient>>& descriptor);
}; // class ClientEventListener
- typedef std::shared_ptr<resource_policy::ClientDescriptor<String8,
+ typedef std::shared_ptr<resource_policy::ClientDescriptor<std::string,
sp<CameraService::BasicClient>>> DescriptorPtr;
/**
@@ -569,7 +571,7 @@
* This class manages the eviction behavior for the camera clients. See the parent class
* implementation in utils/ClientManager for the specifics of this behavior.
*/
- class CameraClientManager : public resource_policy::ClientManager<String8,
+ class CameraClientManager : public resource_policy::ClientManager<std::string,
sp<CameraService::BasicClient>, ClientEventListener> {
public:
CameraClientManager();
@@ -579,18 +581,19 @@
* Return a strong pointer to the active BasicClient for this camera ID, or an empty
* if none exists.
*/
- sp<CameraService::BasicClient> getCameraClient(const String8& id) const;
+ sp<CameraService::BasicClient> getCameraClient(const std::string& id) const;
/**
* Return a string describing the current state.
*/
- String8 toString() const;
+ std::string toString() const;
/**
* Make a ClientDescriptor object wrapping the given BasicClient strong pointer.
*/
- static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
- int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
+ static DescriptorPtr makeClientDescriptor(const std::string& key,
+ const sp<BasicClient>& value, int32_t cost,
+ const std::set<std::string>& conflictingKeys, int32_t score,
int32_t ownerId, int32_t state, int oomScoreOffset, bool systemNativeClient);
/**
@@ -607,6 +610,13 @@
int32_t updateAudioRestrictionLocked();
private:
+ /**
+ * Returns true if the device is an automotive device and cameraId is system
+ * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
+ * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+ * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
+ */
+ bool isAutomotiveExteriorSystemCamera(const std::string& cameraId) const;
// TODO: b/263304156 update this to make use of a death callback for more
// robust/fault tolerant logging
@@ -623,6 +633,22 @@
}
/**
+ * Pre-grants the permission if the attribution source uid is for an automotive
+ * privileged client. Otherwise uses system service permission checker to check
+ * for the appropriate permission. If this function is called for accessing a specific
+ * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
+ * privileged client so that permission is pre-granted only to access system camera device
+ * which is located outside of the vehicle body frame because camera located inside the vehicle
+ * cabin would need user permission.
+ */
+ bool checkPermission(const std::string& cameraId, const std::string& permission,
+ const content::AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) const;
+
+ bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid)
+ const;
+
+ /**
* Typesafe version of device status, containing both the HAL-layer and the service interface-
* layer values.
*/
@@ -650,7 +676,7 @@
* Make a new CameraState and set the ID, cost, and conflicting devices using the values
* returned in the HAL's camera_info struct for each device.
*/
- CameraState(const String8& id, int cost, const std::set<String8>& conflicting,
+ CameraState(const std::string& id, int cost, const std::set<std::string>& conflicting,
SystemCameraKind deviceKind, const std::vector<std::string>& physicalCameras);
virtual ~CameraState();
@@ -664,7 +690,7 @@
/**
* This function updates the status for this camera device, unless the given status
* is in the given list of rejected status states, and execute the function passed in
- * with a signature onStatusUpdateLocked(const String8&, int32_t)
+ * with a signature onStatusUpdateLocked(const std::string&, int32_t)
* if the status has changed.
*
* This method is idempotent, and will not result in the function passed to
@@ -673,7 +699,7 @@
*/
template<class Func>
void updateStatus(StatusInternal status,
- const String8& cameraId,
+ const std::string& cameraId,
std::initializer_list<StatusInternal> rejectSourceStates,
Func onStatusUpdatedLocked);
@@ -696,12 +722,7 @@
/**
* Return a set of the IDs of conflicting devices advertised by the HAL for this device.
*/
- std::set<String8> getConflicting() const;
-
- /**
- * Return the ID of this camera device.
- */
- String8 getId() const;
+ std::set<std::string> getConflicting() const;
/**
* Return the kind (SystemCameraKind) of this camera device.
@@ -717,28 +738,28 @@
/**
* Add/Remove the unavailable physical camera ID.
*/
- bool addUnavailablePhysicalId(const String8& physicalId);
- bool removeUnavailablePhysicalId(const String8& physicalId);
+ bool addUnavailablePhysicalId(const std::string& physicalId);
+ bool removeUnavailablePhysicalId(const std::string& physicalId);
/**
* Set and get client package name.
*/
- void setClientPackage(const String8& clientPackage);
- String8 getClientPackage() const;
+ void setClientPackage(const std::string& clientPackage);
+ std::string getClientPackage() const;
/**
* Return the unavailable physical ids for this device.
*
* This method acquires mStatusLock.
*/
- std::vector<String8> getUnavailablePhysicalIds() const;
+ std::vector<std::string> getUnavailablePhysicalIds() const;
private:
- const String8 mId;
+ const std::string mId;
StatusInternal mStatus; // protected by mStatusLock
const int mCost;
- std::set<String8> mConflicting;
- std::set<String8> mUnavailablePhysicalIds;
- String8 mClientPackage;
+ std::set<std::string> mConflicting;
+ std::set<std::string> mUnavailablePhysicalIds;
+ std::string mClientPackage;
mutable Mutex mStatusLock;
CameraParameters mShimParams;
const SystemCameraKind mSystemCameraKind;
@@ -758,7 +779,7 @@
void registerSelf();
void unregisterSelf();
- bool isUidActive(uid_t uid, String16 callingPackage);
+ bool isUidActive(uid_t uid, const std::string &callingPackage);
int32_t getProcState(uid_t uid);
// IUidObserver
@@ -769,8 +790,8 @@
int32_t capability) override;
void onUidProcAdjChanged(uid_t uid, int adj) override;
- void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
- void removeOverrideUid(uid_t uid, String16 callingPackage);
+ void addOverrideUid(uid_t uid, const std::string &callingPackage, bool active);
+ void removeOverrideUid(uid_t uid, const std::string &callingPackage);
void registerMonitorUid(uid_t uid, bool openCamera);
void unregisterMonitorUid(uid_t uid, bool closeCamera);
@@ -781,9 +802,10 @@
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
- bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+ bool isUidActiveLocked(uid_t uid, const std::string &callingPackage);
int32_t getProcStateLocked(uid_t uid);
- void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
+ void updateOverrideUid(uid_t uid, const std::string &callingPackage, bool active,
+ bool insert);
void registerWithActivityManager();
struct MonitoredUid {
@@ -853,8 +875,8 @@
// Add/remove a new camera to camera and torch state lists or remove an unplugged one
// Caller must not hold mServiceLock
- void addStates(const String8 id);
- void removeStates(const String8 id);
+ void addStates(const std::string& id);
+ void removeStates(const std::string& id);
// Check if we can connect, before we acquire the service lock.
// The returned originalClientPid is the PID of the original process that wants to connect to
@@ -863,36 +885,37 @@
// originalClientPid and clientPid are usually the same except when the application uses
// mediaserver to connect to camera (using MediaRecorder to connect to camera). In that case,
// clientPid is the PID of mediaserver and originalClientPid is the PID of the application.
- binder::Status validateConnectLocked(const String8& cameraId, const String8& clientName8,
+ binder::Status validateConnectLocked(const std::string& cameraId, const std::string& clientName,
/*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const;
- binder::Status validateClientPermissionsLocked(const String8& cameraId, const String8& clientName8,
- /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const;
+ binder::Status validateClientPermissionsLocked(const std::string& cameraId,
+ const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid,
+ /*out*/int& originalClientPid) const;
// Handle active client evictions, and update service state.
// Only call with with mServiceLock held.
- status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
- apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
- int scoreOffset, bool systemNativeClient,
+ status_t handleEvictionsLocked(const std::string& cameraId, int clientPid,
+ apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback,
+ const std::string& packageName, int scoreOffset, bool systemNativeClient,
/*out*/
sp<BasicClient>* client,
- std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
+ std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial);
// Should an operation attempt on a cameraId be rejected ? (this can happen
// under various conditions. For example if a camera device is advertised as
// system only or hidden secure camera, amongst possible others.
- bool shouldRejectSystemCameraConnection(const String8 & cameraId) const;
+ bool shouldRejectSystemCameraConnection(const std::string& cameraId) const;
// Should a device status update be skipped for a particular camera device ? (this can happen
// under various conditions. For example if a camera device is advertised as
// system only or hidden secure camera, amongst possible others.
- static bool shouldSkipStatusUpdates(SystemCameraKind systemCameraKind, bool isVendorListener,
+ bool shouldSkipStatusUpdates(SystemCameraKind systemCameraKind, bool isVendorListener,
int clientPid, int clientUid);
// Gets the kind of camera device (i.e public, hidden secure or system only)
// getSystemCameraKind() needs mInterfaceMutex which might lead to deadlocks
// if held along with mStatusListenerLock (depending on lock ordering, b/141756275), it is
// recommended that we don't call this function with mStatusListenerLock held.
- status_t getSystemCameraKind(const String8& cameraId, SystemCameraKind *kind) const;
+ status_t getSystemCameraKind(const std::string& cameraId, SystemCameraKind *kind) const;
// Update the set of API1Compatible camera devices without including system
// cameras and secure cameras. This is used for hiding system only cameras
@@ -908,13 +931,13 @@
// as for legacy apps we will toggle the app op for all packages in the UID.
// The caveat is that the operation may be attributed to the wrong package and
// stats based on app ops may be slightly off.
- String16 getPackageNameFromUid(int clientUid);
+ std::string getPackageNameFromUid(int clientUid);
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
- binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
- const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
+ binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
+ int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
+ const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
bool overrideToPortrait, bool forceSlowJpegMode,
/*out*/sp<CLIENT>& device);
@@ -926,37 +949,38 @@
std::shared_ptr<WaitableMutexWrapper> mServiceLockWrapper;
// Return NO_ERROR if the device with a give ID can be connected to
- status_t checkIfDeviceIsUsable(const String8& cameraId) const;
+ status_t checkIfDeviceIsUsable(const std::string& cameraId) const;
// Container for managing currently active application-layer clients
CameraClientManager mActiveClientManager;
// Adds client logs during open session to the file pointed by fd.
- void dumpOpenSessionClientLogs(int fd, const Vector<String16>& args, const String8& cameraId);
+ void dumpOpenSessionClientLogs(int fd, const Vector<String16>& args,
+ const std::string& cameraId);
// Adds client logs during closed session to the file pointed by fd.
- void dumpClosedSessionClientLogs(int fd, const String8& cameraId);
+ void dumpClosedSessionClientLogs(int fd, const std::string& cameraId);
// Mapping from camera ID -> state for each device, map is protected by mCameraStatesLock
- std::map<String8, std::shared_ptr<CameraState>> mCameraStates;
+ std::map<std::string, std::shared_ptr<CameraState>> mCameraStates;
// Mutex guarding mCameraStates map
mutable Mutex mCameraStatesLock;
// Circular buffer for storing event logging for dumps
- RingBuffer<String8> mEventLog;
+ RingBuffer<std::string> mEventLog;
Mutex mLogLock;
// set of client package names to watch. if this set contains 'all', then all clients will
// be watched. Access should be guarded by mLogLock
- std::set<String16> mWatchedClientPackages;
+ std::set<std::string> mWatchedClientPackages;
// cache of last monitored tags dump immediately before the client disconnects. If a client
// re-connects, its entry is not updated until it disconnects again. Access should be guarded
// by mLogLock
- std::map<String16, std::string> mWatchedClientsDumpCache;
+ std::map<std::string, std::string> mWatchedClientsDumpCache;
// The last monitored tags set by client
- String8 mMonitorTags;
+ std::string mMonitorTags;
// Currently allowed user IDs
std::set<userid_t> mAllowedUsers;
@@ -966,7 +990,7 @@
*
* This acquires mCameraStatesLock.
*/
- std::shared_ptr<CameraService::CameraState> getCameraState(const String8& cameraId) const;
+ std::shared_ptr<CameraService::CameraState> getCameraState(const std::string& cameraId) const;
/**
* Evict client who's remote binder has died. Returns true if this client was in the active
@@ -997,7 +1021,7 @@
* Returns the underlying camera Id string mapped to a camera id int
* Empty string is returned when the cameraIdInt is invalid.
*/
- String8 cameraIdIntToStr(int cameraIdInt);
+ std::string cameraIdIntToStr(int cameraIdInt);
/**
* Returns the underlying camera Id string mapped to a camera id int
@@ -1011,7 +1035,7 @@
*
* This method must be called with mServiceLock held.
*/
- sp<CameraService::BasicClient> removeClientLocked(const String8& cameraId);
+ sp<CameraService::BasicClient> removeClientLocked(const std::string& cameraId);
/**
* Handle a notification that the current device user has changed.
@@ -1021,39 +1045,41 @@
/**
* Add an event log message.
*/
- void logEvent(const char* event);
+ void logEvent(const std::string &event);
/**
* Add an event log message that a client has been disconnected.
*/
- void logDisconnected(const char* cameraId, int clientPid, const char* clientPackage);
+ void logDisconnected(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage);
/**
* Add an event log message that a client has been disconnected from offline device.
*/
- void logDisconnectedOffline(const char* cameraId, int clientPid, const char* clientPackage);
+ void logDisconnectedOffline(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage);
/**
* Add an event log message that an offline client has been connected.
*/
- void logConnectedOffline(const char* cameraId, int clientPid,
- const char* clientPackage);
+ void logConnectedOffline(const std::string &cameraId, int clientPid,
+ const std::string &clientPackage);
/**
* Add an event log message that a client has been connected.
*/
- void logConnected(const char* cameraId, int clientPid, const char* clientPackage);
+ void logConnected(const std::string &cameraId, int clientPid, const std::string &clientPackage);
/**
* Add an event log message that a client's connect attempt has been rejected.
*/
- void logRejected(const char* cameraId, int clientPid, const char* clientPackage,
- const char* reason);
+ void logRejected(const std::string &cameraId, int clientPid, const std::string &clientPackage,
+ const std::string &reason);
/**
* Add an event log message when a client calls setTorchMode succesfully.
*/
- void logTorchEvent(const char* cameraId, const char *torchState, int clientPid);
+ void logTorchEvent(const std::string &cameraId, const std::string &torchState, int clientPid);
/**
* Add an event log message that the current device user has been switched.
@@ -1064,30 +1090,30 @@
/**
* Add an event log message that a device has been removed by the HAL
*/
- void logDeviceRemoved(const char* cameraId, const char* reason);
+ void logDeviceRemoved(const std::string &cameraId, const std::string &reason);
/**
* Add an event log message that a device has been added by the HAL
*/
- void logDeviceAdded(const char* cameraId, const char* reason);
+ void logDeviceAdded(const std::string &cameraId, const std::string &reason);
/**
* Add an event log message that a client has unexpectedly died.
*/
- void logClientDied(int clientPid, const char* reason);
+ void logClientDied(int clientPid, const std::string &reason);
/**
* Add a event log message that a serious service-level error has occured
* The errorCode should be one of the Android Errors
*/
- void logServiceError(const char* msg, int errorCode);
+ void logServiceError(const std::string &msg, int errorCode);
/**
* Dump the event log to an FD
*/
void dumpEventLog(int fd);
- void cacheClientTagDumpIfNeeded(const char *cameraId, BasicClient *client);
+ void cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient *client);
/**
* This method will acquire mServiceLock
@@ -1203,18 +1229,19 @@
* This method acquires mStatusLock and mStatusListenerLock.
*/
void updateStatus(StatusInternal status,
- const String8& cameraId,
+ const std::string& cameraId,
std::initializer_list<StatusInternal>
rejectedSourceStates);
void updateStatus(StatusInternal status,
- const String8& cameraId);
+ const std::string& cameraId);
/**
* Update the opened/closed status of the given camera id.
*
* This method acqiures mStatusListenerLock.
*/
- void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName);
+ void updateOpenCloseStatus(const std::string& cameraId, bool open,
+ const std::string& packageName);
// flashlight control
sp<CameraFlashlight> mFlashlight;
@@ -1225,38 +1252,38 @@
// guard mTorchUidMap
Mutex mTorchUidMapMutex;
// camera id -> torch status
- KeyedVector<String8, TorchModeStatus>
+ KeyedVector<std::string, TorchModeStatus>
mTorchStatusMap;
// camera id -> torch client binder
// only store the last client that turns on each camera's torch mode
- KeyedVector<String8, sp<IBinder>> mTorchClientMap;
+ KeyedVector<std::string, sp<IBinder>> mTorchClientMap;
// camera id -> [incoming uid, current uid] pair
- std::map<String8, std::pair<int, int>> mTorchUidMap;
+ std::map<std::string, std::pair<int, int>> mTorchUidMap;
// check and handle if torch client's process has died
void handleTorchClientBinderDied(const wp<IBinder> &who);
// handle torch mode status change and invoke callbacks. mTorchStatusMutex
// should be locked.
- void onTorchStatusChangedLocked(const String8& cameraId,
+ void onTorchStatusChangedLocked(const std::string& cameraId,
TorchModeStatus newStatus,
SystemCameraKind systemCameraKind);
// get a camera's torch status. mTorchStatusMutex should be locked.
- status_t getTorchStatusLocked(const String8 &cameraId,
+ status_t getTorchStatusLocked(const std::string &cameraId,
TorchModeStatus *status) const;
// set a camera's torch status. mTorchStatusMutex should be locked.
- status_t setTorchStatusLocked(const String8 &cameraId,
+ status_t setTorchStatusLocked(const std::string &cameraId,
TorchModeStatus status);
// notify physical camera status when the physical camera is public.
// Expects mStatusListenerLock to be locked.
- void notifyPhysicalCameraStatusLocked(int32_t status, const String16& physicalCameraId,
- const std::list<String16>& logicalCameraIds, SystemCameraKind deviceKind);
+ void notifyPhysicalCameraStatusLocked(int32_t status, const std::string& physicalCameraId,
+ const std::list<std::string>& logicalCameraIds, SystemCameraKind deviceKind);
// get list of logical cameras which are backed by physicalCameraId
- std::list<String16> getLogicalCameras(const String8& physicalCameraId);
+ std::list<std::string> getLogicalCameras(const std::string& physicalCameraId);
// IBinder::DeathRecipient implementation
@@ -1348,7 +1375,7 @@
// Parses comma separated clients list and adds them to mWatchedClientPackages.
// Does not acquire mLogLock before modifying mWatchedClientPackages. It is the caller's
// responsibility to acquire mLogLock before calling this function.
- void parseClientsToWatchLocked(String8 clients);
+ void parseClientsToWatchLocked(const std::string &clients);
// Prints the shell command help
status_t printHelp(int out);
@@ -1365,39 +1392,37 @@
/**
* Get the current system time as a formatted string.
*/
- static String8 getFormattedCurrentTime();
+ static std::string getFormattedCurrentTime();
static binder::Status makeClient(const sp<CameraService>& cameraService,
- const sp<IInterface>& cameraCb, const String16& packageName,
- bool systemNativeClient, const std::optional<String16>& featureId,
- const String8& cameraId, int api1CameraId, int facing, int sensorOrientation,
+ const sp<IInterface>& cameraCb, const std::string& packageName,
+ bool systemNativeClient, const std::optional<std::string>& featureId,
+ const std::string& cameraId, int api1CameraId, int facing, int sensorOrientation,
int clientPid, uid_t clientUid, int servicePid,
std::pair<int, IPCTransport> deviceVersionAndIPCTransport, apiLevel effectiveApiLevel,
bool overrideForPerfClass, bool overrideToPortrait, bool forceSlowJpegMode,
/*out*/sp<BasicClient>* client);
- status_t checkCameraAccess(const String16& opPackageName);
-
- static String8 toString(std::set<userid_t> intSet);
+ static std::string toString(std::set<userid_t> intSet);
static int32_t mapToInterface(TorchModeStatus status);
static StatusInternal mapToInternal(CameraDeviceStatus status);
static int32_t mapToInterface(StatusInternal status);
- void broadcastTorchModeStatus(const String8& cameraId,
+ void broadcastTorchModeStatus(const std::string& cameraId,
TorchModeStatus status, SystemCameraKind systemCameraKind);
- void broadcastTorchStrengthLevel(const String8& cameraId, int32_t newTorchStrengthLevel);
+ void broadcastTorchStrengthLevel(const std::string& cameraId, int32_t newTorchStrengthLevel);
- void disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect);
+ void disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect);
// Regular online and offline devices must not be in conflict at camera service layer.
// Use separate keys for offline devices.
- static const String8 kOfflineDevice;
+ static const std::string kOfflineDevice;
// Sentinel value to be stored in `mWatchedClientsPackages` to indicate that all clients should
// be watched.
- static const String16 kWatchAllClientsFlag;
+ static const std::string kWatchAllClientsFlag;
// TODO: right now each BasicClient holds one AppOpsManager instance.
// We can refactor the code so all of clients share this instance
@@ -1438,7 +1463,7 @@
void addListener(const sp<hardware::camera2::ICameraInjectionCallback>& callback);
void removeListener();
- void notifyInjectionError(String8 injectedCamId, status_t err);
+ void notifyInjectionError(const std::string &injectedCamId, status_t err);
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder>& who);
@@ -1467,15 +1492,15 @@
// When injecting the camera, it will check whether the injecting camera status is unavailable.
// If it is, the disconnect function will be called to to prevent camera access on the device.
- status_t checkIfInjectionCameraIsPresent(const String8& externalCamId,
+ status_t checkIfInjectionCameraIsPresent(const std::string& externalCamId,
sp<BasicClient> clientSp);
void clearInjectionParameters();
// This is the existing camera id being replaced.
- String8 mInjectionInternalCamId;
+ std::string mInjectionInternalCamId;
// This is the external camera Id replacing the internalId.
- String8 mInjectionExternalCamId;
+ std::string mInjectionExternalCamId;
bool mInjectionInitPending = false;
// Guard mInjectionInternalCamId and mInjectionInitPending.
Mutex mInjectionParametersLock;
@@ -1483,7 +1508,7 @@
// Track the folded/unfoled device state. 0 == UNFOLDED, 4 == FOLDED
int64_t mDeviceState;
- void updateTorchUidMapLocked(const String16& cameraId, int uid);
+ void updateTorchUidMapLocked(const std::string& cameraId, int uid);
};
} // namespace android
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.h b/services/camera/libcameraservice/CameraServiceWatchdog.h
index de6ac9e..9f25865 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.h
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.h
@@ -32,7 +32,6 @@
#include <chrono>
#include <thread>
#include <time.h>
-#include <utils/String8.h>
#include <utils/Thread.h>
#include <utils/Log.h>
#include <unordered_map>
@@ -58,13 +57,13 @@
};
public:
- explicit CameraServiceWatchdog(const String8 &cameraId,
+ explicit CameraServiceWatchdog(const std::string &cameraId,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
mCameraId(cameraId), mPause(true), mMaxCycles(kMaxCycles),
mCycleLengthMs(kCycleLengthMs), mEnabled(true),
mCameraServiceProxyWrapper(cameraServiceProxyWrapper) {};
- explicit CameraServiceWatchdog (const String8 &cameraId, size_t maxCycles,
+ explicit CameraServiceWatchdog (const std::string &cameraId, size_t maxCycles,
uint32_t cycleLengthMs, bool enabled,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
mCameraId(cameraId), mPause(true), mMaxCycles(maxCycles),
@@ -151,7 +150,7 @@
Mutex mWatchdogLock; // Lock for condition variable
Mutex mEnabledLock; // Lock for enabled status
Condition mWatchdogCondition; // Condition variable for stop/start
- String8 mCameraId; // Camera Id the watchdog belongs to
+ std::string mCameraId; // Camera Id the watchdog belongs to
bool mPause; // True if tid map is empty
uint32_t mMaxCycles; // Max cycles
uint32_t mCycleLengthMs; // Length of time elapsed per cycle
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.cpp b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
index 4232a81..a62f6de 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraService.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
@@ -86,7 +86,7 @@
if (_aidl_return == nullptr) { return fromSStatus(SStatus::ILLEGAL_ARGUMENT); }
::android::CameraMetadata cameraMetadata;
- UStatus ret = mCameraService->getCameraCharacteristics(String16(in_cameraId.c_str()),
+ UStatus ret = mCameraService->getCameraCharacteristics(in_cameraId,
mVndkVersion,
/* overrideToPortrait= */ false,
&cameraMetadata);
@@ -140,8 +140,8 @@
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
binder::Status serviceRet = mCameraService->connectDevice(
callbacks,
- String16(in_cameraId.c_str()),
- String16(""),
+ in_cameraId,
+ std::string(),
/* clientFeatureId= */{},
hardware::ICameraService::USE_CALLING_UID,
/* scoreOffset= */ 0,
@@ -249,7 +249,7 @@
[this](const hardware::CameraStatus& s) {
bool supportsHAL3 = false;
binder::Status sRet =
- mCameraService->supportsCameraApi(String16(s.cameraId),
+ mCameraService->supportsCameraApi(s.cameraId,
UICameraService::API_VERSION_2, &supportsHAL3);
return !sRet.isOk() || !supportsHAL3;
}), cameraStatusAndIds->end());
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
index e183063..d7ab0d9 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
@@ -18,6 +18,7 @@
#include <aidl/AidlUtils.h>
#include <aidl/android/frameworks/cameraservice/common/Status.h>
#include <aidl/android/frameworks/cameraservice/service/CameraStatusAndId.h>
+#include <camera/StringUtils.h>
namespace android::frameworks::cameraservice::service::implementation {
@@ -27,34 +28,31 @@
using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
binder::Status AidlCameraServiceListener::onStatusChanged(
- int32_t status, const ::android::String16& cameraId) {
+ int32_t status, const std::string& cameraId) {
SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
- std::string sCameraId = String8(cameraId).string();
- auto ret = mBase->onStatusChanged(sStatus, sCameraId);
+ auto ret = mBase->onStatusChanged(sStatus, cameraId);
LOG_STATUS_ERROR_IF_NOT_OK(ret, "onStatusChanged")
return binder::Status::ok();
}
binder::Status AidlCameraServiceListener::onPhysicalCameraStatusChanged(
- int32_t status, const ::android::String16& cameraId,
- const ::android::String16& physicalCameraId) {
+ int32_t status, const std::string& cameraId,
+ const std::string& physicalCameraId) {
SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
- std::string sCameraId = String8(cameraId).string();
- std::string sPhysicalCameraId = String8(physicalCameraId).string();
- auto ret = mBase->onPhysicalCameraStatusChanged(sStatus, sCameraId, sPhysicalCameraId);
+ auto ret = mBase->onPhysicalCameraStatusChanged(sStatus, cameraId, physicalCameraId);
LOG_STATUS_ERROR_IF_NOT_OK(ret, "onPhysicalCameraStatusChanged")
return binder::Status::ok();
}
::android::binder::Status AidlCameraServiceListener::onTorchStatusChanged(
- int32_t, const ::android::String16&) {
+ int32_t, const std::string&) {
// We don't implement onTorchStatusChanged
return binder::Status::ok();
}
::android::binder::Status AidlCameraServiceListener::onTorchStrengthLevelChanged(
- const ::android::String16&, int32_t) {
+ const std::string&, int32_t) {
// We don't implement onTorchStrengthLevelChanged
return binder::Status::ok();
}
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
index 906dd8e..6483fe1 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
@@ -45,25 +45,25 @@
~AidlCameraServiceListener() = default;
::android::binder::Status onStatusChanged(int32_t status,
- const ::android::String16& cameraId) override;
+ const std::string& cameraId) override;
::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
- const ::android::String16& cameraId,
- const ::android::String16& physicalCameraId) override;
+ const std::string& cameraId,
+ const std::string& physicalCameraId) override;
::android::binder::Status onTorchStatusChanged(
- int32_t status, const ::android::String16& cameraId) override;
+ int32_t status, const std::string& cameraId) override;
::android::binder::Status onTorchStrengthLevelChanged(
- const ::android::String16& cameraId, int32_t newStrengthLevel) override;
+ const std::string& cameraId, int32_t newStrengthLevel) override;
binder::Status onCameraAccessPrioritiesChanged() override {
// TODO: no implementation yet.
return binder::Status::ok();
}
- binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
- const ::android::String16& /*clientPackageId*/) override {
+ binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageId*/) override {
// empty implementation
return binder::Status::ok();
}
- binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) override {
+ binder::Status onCameraClosed(const std::string& /*cameraId*/) override {
// empty implementation
return binder::Status::ok();
}
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index 1b8e53b..7291c5f 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -22,6 +22,7 @@
#include <device3/Camera3StreamInterface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <mediautils/AImageReaderUtils.h>
+#include <camera/StringUtils.h>
namespace android::hardware::cameraservice::utils::conversion::aidl {
@@ -80,9 +81,8 @@
iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(nh)));
native_handle_delete(nh);
}
- String16 physicalCameraId16(src.physicalCameraId.c_str());
UOutputConfiguration outputConfiguration(
- iGBPs, convertFromAidl(src.rotation), physicalCameraId16,
+ iGBPs, convertFromAidl(src.rotation), src.physicalCameraId,
src.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
(windowHandles.size() > 1));
return outputConfiguration;
@@ -175,7 +175,7 @@
dst.frameNumber = src.frameNumber;
dst.partialResultCount = src.partialResultCount;
dst.errorStreamId = src.errorStreamId;
- dst.errorPhysicalCameraId = String8(src.errorPhysicalCameraId).string();
+ dst.errorPhysicalCameraId = src.errorPhysicalCameraId;
return dst;
}
@@ -217,7 +217,7 @@
SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo & src,
std::shared_ptr<CaptureResultMetadataQueue> & fmq) {
SPhysicalCaptureResultInfo dst;
- dst.physicalCameraId = String8(src.mPhysicalCameraId).string();
+ dst.physicalCameraId = src.mPhysicalCameraId;
const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
// Try using fmq at first.
@@ -242,12 +242,12 @@
size_t i = 0;
for (const auto &statusAndId : src) {
auto &a = (*dst)[i++];
- a.cameraId = statusAndId.cameraId.c_str();
+ a.cameraId = statusAndId.cameraId;
a.deviceStatus = convertCameraStatusToAidl(statusAndId.status);
size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
- a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
+ a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
}
}
}
@@ -302,4 +302,4 @@
return OK;
}
-} // namespace android::hardware::cameraservice::utils::conversion::aidl
\ No newline at end of file
+} // namespace android::hardware::cameraservice::utils::conversion::aidl
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 8348cd9..4876195 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -18,11 +18,14 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <sstream>
+
#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
@@ -53,9 +56,9 @@
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraDeviceId,
+ const std::string& clientPackageName,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraDeviceId,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -83,7 +86,8 @@
l.mParameters.isSlowJpegModeForced = forceSlowJpegMode;
}
-status_t Camera2Client::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
+status_t Camera2Client::initialize(sp<CameraProviderManager> manager,
+ const std::string& monitorTags) {
return initializeImpl(manager, monitorTags);
}
@@ -103,7 +107,7 @@
}
template<typename TProviderPtr>
-status_t Camera2Client::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags)
+status_t Camera2Client::initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags)
{
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
@@ -135,16 +139,11 @@
CameraUtils::getRotationTransform(staticInfo, OutputConfiguration::MIRROR_MODE_AUTO,
&mRotateAndCropPreviewTransform);
- String8 threadName;
-
mStreamingProcessor = new StreamingProcessor(this);
- threadName = String8::format("C2-%d-StreamProc",
- mCameraId);
+ std::string threadName = std::string("C2-") + std::to_string(mCameraId);
mFrameProcessor = new FrameProcessor(mDevice, this);
- threadName = String8::format("C2-%d-FrameProc",
- mCameraId);
- res = mFrameProcessor->run(threadName.string());
+ res = mFrameProcessor->run((threadName + "-FrameProc").c_str());
if (res != OK) {
ALOGE("%s: Unable to start frame processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -152,9 +151,7 @@
}
mCaptureSequencer = new CaptureSequencer(this);
- threadName = String8::format("C2-%d-CaptureSeq",
- mCameraId);
- res = mCaptureSequencer->run(threadName.string());
+ res = mCaptureSequencer->run((threadName + "-CaptureSeq").c_str());
if (res != OK) {
ALOGE("%s: Unable to start capture sequencer thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -162,9 +159,7 @@
}
mJpegProcessor = new JpegProcessor(this, mCaptureSequencer);
- threadName = String8::format("C2-%d-JpegProc",
- mCameraId);
- res = mJpegProcessor->run(threadName.string());
+ res = mJpegProcessor->run((threadName + "-JpegProc").c_str());
if (res != OK) {
ALOGE("%s: Unable to start jpeg processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -172,10 +167,7 @@
}
mZslProcessor = new ZslProcessor(this, mCaptureSequencer);
-
- threadName = String8::format("C2-%d-ZslProc",
- mCameraId);
- res = mZslProcessor->run(threadName.string());
+ res = mZslProcessor->run((threadName + "-ZslProc").c_str());
if (res != OK) {
ALOGE("%s: Unable to start zsl processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -183,9 +175,7 @@
}
mCallbackProcessor = new CallbackProcessor(this);
- threadName = String8::format("C2-%d-CallbkProc",
- mCameraId);
- res = mCallbackProcessor->run(threadName.string());
+ res = mCallbackProcessor->run((threadName + "-CallbkProc").c_str());
if (res != OK) {
ALOGE("%s: Unable to start callback processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -218,47 +208,47 @@
}
status_t Camera2Client::dumpClient(int fd, const Vector<String16>& args) {
- String8 result;
- result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n", mCameraId,
+ std::ostringstream result;
+ result << fmt::sprintf("Client2[%d] (%p) PID: %d, dump:\n", mCameraId,
(getRemoteCallback() != NULL ?
- (IInterface::asBinder(getRemoteCallback()).get()) : NULL),
+ (void *) (IInterface::asBinder(getRemoteCallback()).get()) : NULL),
mClientPid);
- result.append(" State: ");
-#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
+ result << " State: ";
+#define CASE_APPEND_ENUM(x) case x: result << #x "\n"; break;
const Parameters& p = mParameters.unsafeAccess();
- result.append(Parameters::getStateName(p.state));
+ result << Parameters::getStateName(p.state);
- result.append("\n Current parameters:\n");
- result.appendFormat(" Preview size: %d x %d\n",
+ result << "\n Current parameters:\n";
+ result << fmt::sprintf(" Preview size: %d x %d\n",
p.previewWidth, p.previewHeight);
- result.appendFormat(" Preview FPS range: %d - %d\n",
+ result << fmt::sprintf(" Preview FPS range: %d - %d\n",
p.previewFpsRange[0], p.previewFpsRange[1]);
- result.appendFormat(" Preview HAL pixel format: 0x%x\n",
+ result << fmt::sprintf(" Preview HAL pixel format: 0x%x\n",
p.previewFormat);
- result.appendFormat(" Preview transform: %x\n",
+ result << fmt::sprintf(" Preview transform: %x\n",
p.previewTransform);
- result.appendFormat(" Picture size: %d x %d\n",
+ result << fmt::sprintf(" Picture size: %d x %d\n",
p.pictureWidth, p.pictureHeight);
- result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
+ result << fmt::sprintf(" Jpeg thumbnail size: %d x %d\n",
p.jpegThumbSize[0], p.jpegThumbSize[1]);
- result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
+ result << fmt::sprintf(" Jpeg quality: %d, thumbnail quality: %d\n",
p.jpegQuality, p.jpegThumbQuality);
- result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
- result.appendFormat(" GPS tags %s\n",
+ result << fmt::sprintf(" Jpeg rotation: %d\n", p.jpegRotation);
+ result << fmt::sprintf(" GPS tags %s\n",
p.gpsEnabled ? "enabled" : "disabled");
if (p.gpsEnabled) {
- result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
+ result << fmt::sprintf(" GPS lat x long x alt: %f x %f x %f\n",
p.gpsCoordinates[0], p.gpsCoordinates[1],
p.gpsCoordinates[2]);
- result.appendFormat(" GPS timestamp: %" PRId64 "\n",
+ result << fmt::sprintf(" GPS timestamp: %" PRId64 "\n",
p.gpsTimestamp);
- result.appendFormat(" GPS processing method: %s\n",
+ result << fmt::sprintf(" GPS processing method: %s\n",
p.gpsProcessingMethod.string());
}
- result.append(" White balance mode: ");
+ result << " White balance mode: ";
switch (p.wbMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_AUTO)
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_INCANDESCENT)
@@ -268,10 +258,10 @@
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT)
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_TWILIGHT)
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_MODE_SHADE)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Effect mode: ");
+ result << " Effect mode: ";
switch (p.effectMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_OFF)
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_MONO)
@@ -282,22 +272,22 @@
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD)
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD)
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MODE_AQUA)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Antibanding mode: ");
+ result << " Antibanding mode: ";
switch (p.antibandingMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO)
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF)
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ)
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Scene mode: ");
+ result << " Scene mode: ";
switch (p.sceneMode) {
case ANDROID_CONTROL_SCENE_MODE_DISABLED:
- result.append("AUTO\n"); break;
+ result << "AUTO\n"; break;
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY)
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
@@ -314,10 +304,10 @@
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Flash mode: ");
+ result << " Flash mode: ";
switch (p.flashMode) {
CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
@@ -325,10 +315,10 @@
CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Focus mode: ");
+ result << " Focus mode: ";
switch (p.focusMode) {
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
@@ -338,10 +328,10 @@
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Focus state: ");
+ result << " Focus state: ";
switch (p.focusState) {
CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_INACTIVE)
CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN)
@@ -350,12 +340,12 @@
CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN)
CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED)
CASE_APPEND_ENUM(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED)
- default: result.append("UNKNOWN\n");
+ default: result << "UNKNOWN\n";
}
- result.append(" Focusing areas:\n");
+ result << " Focusing areas:\n";
for (size_t i = 0; i < p.focusingAreas.size(); i++) {
- result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
+ result << fmt::sprintf(" [ (%d, %d, %d, %d), weight %d ]\n",
p.focusingAreas[i].left,
p.focusingAreas[i].top,
p.focusingAreas[i].right,
@@ -363,16 +353,16 @@
p.focusingAreas[i].weight);
}
- result.appendFormat(" Exposure compensation index: %d\n",
+ result << fmt::sprintf(" Exposure compensation index: %d\n",
p.exposureCompensation);
- result.appendFormat(" AE lock %s, AWB lock %s\n",
+ result << fmt::sprintf(" AE lock %s, AWB lock %s\n",
p.autoExposureLock ? "enabled" : "disabled",
p.autoWhiteBalanceLock ? "enabled" : "disabled" );
- result.appendFormat(" Metering areas:\n");
+ result << " Metering areas:\n";
for (size_t i = 0; i < p.meteringAreas.size(); i++) {
- result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
+ result << fmt::sprintf(" [ (%d, %d, %d, %d), weight %d ]\n",
p.meteringAreas[i].left,
p.meteringAreas[i].top,
p.meteringAreas[i].right,
@@ -380,54 +370,56 @@
p.meteringAreas[i].weight);
}
- result.appendFormat(" Zoom index: %d\n", p.zoom);
- result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
+ result << fmt::sprintf(" Zoom index: %d\n", p.zoom);
+ result << fmt::sprintf(" Video size: %d x %d\n", p.videoWidth,
p.videoHeight);
- result.appendFormat(" Recording hint is %s\n",
+ result << fmt::sprintf(" Recording hint is %s\n",
p.recordingHint ? "set" : "not set");
- result.appendFormat(" Video stabilization is %s\n",
+ result << fmt::sprintf(" Video stabilization is %s\n",
p.videoStabilization ? "enabled" : "disabled");
- result.appendFormat(" Selected still capture FPS range: %d - %d\n",
+ result << fmt::sprintf(" Selected still capture FPS range: %d - %d\n",
p.fastInfo.bestStillCaptureFpsRange[0],
p.fastInfo.bestStillCaptureFpsRange[1]);
- result.appendFormat(" Use zero shutter lag: %s\n",
+ result << fmt::sprintf(" Use zero shutter lag: %s\n",
p.useZeroShutterLag() ? "yes" : "no");
- result.append(" Current streams:\n");
- result.appendFormat(" Preview stream ID: %d\n",
+ result << " Current streams:\n";
+ result << fmt::sprintf(" Preview stream ID: %d\n",
getPreviewStreamId());
- result.appendFormat(" Capture stream ID: %d\n",
+ result << fmt::sprintf(" Capture stream ID: %d\n",
getCaptureStreamId());
- result.appendFormat(" Recording stream ID: %d\n",
+ result << fmt::sprintf(" Recording stream ID: %d\n",
getRecordingStreamId());
- result.append(" Quirks for this camera:\n");
+ result << " Quirks for this camera:\n";
bool haveQuirk = false;
if (p.quirks.triggerAfWithAuto) {
- result.appendFormat(" triggerAfWithAuto\n");
+ result << " triggerAfWithAuto\n";
haveQuirk = true;
}
if (p.quirks.useZslFormat) {
- result.appendFormat(" useZslFormat\n");
+ result << " useZslFormat\n";
haveQuirk = true;
}
if (p.quirks.meteringCropRegion) {
- result.appendFormat(" meteringCropRegion\n");
+ result << " meteringCropRegion\n";
haveQuirk = true;
}
if (p.quirks.partialResults) {
- result.appendFormat(" usePartialResult\n");
+ result << " usePartialResult\n";
haveQuirk = true;
}
if (!haveQuirk) {
- result.appendFormat(" none\n");
+ result << " none\n";
}
- write(fd, result.string(), result.size());
+ std::string resultStr = std::move(result.str());
+
+ write(fd, resultStr.c_str(), resultStr.size());
mStreamingProcessor->dump(fd, args);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 6bdb644..fe12690 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -107,9 +107,9 @@
Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraDeviceId,
+ const std::string& clientPackageName,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraDeviceId,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -123,7 +123,7 @@
virtual ~Camera2Client();
virtual status_t initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) override;
+ const std::string& monitorTags) override;
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -248,7 +248,7 @@
status_t overrideVideoSnapshotSize(Parameters ¶ms);
template<typename TProviderPtr>
- status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+ status_t initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
bool isZslEnabledInStillTemplate();
// The current rotate & crop mode passed by camera service
diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
index ee764ec..17db20b 100644
--- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
@@ -158,7 +158,7 @@
res = device->createStream(mCallbackWindow,
params.previewWidth, params.previewHeight, callbackFormat,
HAL_DATASPACE_V0_JFIF, CAMERA_STREAM_ROTATION_0, &mCallbackStreamId,
- String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+ std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
if (res != OK) {
ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
"%s (%d)", __FUNCTION__, mId,
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 4c9b7ed..0b5e03f 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -23,6 +23,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
+#include <camera/StringUtils.h>
#include "api1/Camera2Client.h"
#include "api1/client2/CaptureSequencer.h"
@@ -174,19 +175,19 @@
void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
- String8 result;
+ std::string result;
if (mCaptureRequest.entryCount() != 0) {
result = " Capture request:\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
mCaptureRequest.dump(fd, 2, 6);
} else {
result = " Capture request: undefined\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
}
- result = String8::format(" Current capture state: %s\n",
+ result = fmt::sprintf(" Current capture state: %s\n",
kStateNames[mCaptureState]);
- result.append(" Latest captured frame:\n");
- write(fd, result.string(), result.size());
+ result += " Latest captured frame:\n";
+ write(fd, result.c_str(), result.size());
mNewFrame.dump(fd, 2, 6);
}
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index 467108d..eb00bf8 100755
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -83,7 +83,7 @@
}
// Find out buffer size for JPEG
- ssize_t maxJpegSize = device->getJpegBufferSize(device->infoPhysical(String8("")),
+ ssize_t maxJpegSize = device->getJpegBufferSize(device->infoPhysical(""),
params.pictureWidth, params.pictureHeight);
if (maxJpegSize <= 0) {
ALOGE("%s: Camera %d: Jpeg buffer size (%zu) is invalid ",
@@ -157,7 +157,7 @@
params.pictureWidth, params.pictureHeight,
HAL_PIXEL_FORMAT_BLOB, HAL_DATASPACE_V0_JFIF,
CAMERA_STREAM_ROTATION_0, &mCaptureStreamId,
- String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+ std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
if (res != OK) {
ALOGE("%s: Camera %d: Can't create output stream for capture: "
"%s (%d)", __FUNCTION__, mId,
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 2d3597c..ff71e6b 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -31,6 +31,7 @@
#include <gui/BufferItem.h>
#include <gui/Surface.h>
#include <media/hardware/HardwareAPI.h>
+#include <camera/StringUtils.h>
#include "common/CameraDeviceBase.h"
#include "api1/Camera2Client.h"
@@ -198,7 +199,7 @@
res = device->createStream(mPreviewWindow,
params.previewWidth, params.previewHeight,
CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
- CAMERA_STREAM_ROTATION_0, &mPreviewStreamId, String8(),
+ CAMERA_STREAM_ROTATION_0, &mPreviewStreamId, std::string(),
std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
if (res != OK) {
ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
@@ -385,7 +386,7 @@
params.videoWidth, params.videoHeight,
params.videoFormat, params.videoDataSpace,
CAMERA_STREAM_ROTATION_0, &mRecordingStreamId,
- String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+ std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
if (res != OK) {
ALOGE("%s: Camera %d: Can't create output stream for recording: "
"%s (%d)", __FUNCTION__, mId,
@@ -585,21 +586,21 @@
}
status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
- String8 result;
+ std::string result;
- result.append(" Current requests:\n");
+ result += " Current requests:\n";
if (mPreviewRequest.entryCount() != 0) {
- result.append(" Preview request:\n");
- write(fd, result.string(), result.size());
+ result += " Preview request:\n";
+ write(fd, result.c_str(), result.size());
mPreviewRequest.dump(fd, 2, 6);
result.clear();
} else {
- result.append(" Preview request: undefined\n");
+ result += " Preview request: undefined\n";
}
if (mRecordingRequest.entryCount() != 0) {
result = " Recording request:\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
mRecordingRequest.dump(fd, 2, 6);
result.clear();
} else {
@@ -609,11 +610,11 @@
const char* streamTypeString[] = {
"none", "preview", "record"
};
- result.append(String8::format(" Active request: %s (paused: %s)\n",
- streamTypeString[mActiveRequest],
- mPaused ? "yes" : "no"));
+ result += fmt::sprintf(" Active request: %s (paused: %s\n",
+ streamTypeString[mActiveRequest],
+ mPaused ? "yes" : "no");
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
return OK;
}
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 1321e6b..d6c2415 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -30,6 +30,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <gui/Surface.h>
+#include <camera/StringUtils.h>
#include "common/CameraDeviceBase.h"
#include "api1/Camera2Client.h"
@@ -255,13 +256,13 @@
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new RingBufferConsumer(consumer, GRALLOC_USAGE_HW_CAMERA_ZSL,
mBufferQueueDepth);
- mProducer->setName(String8("Camera2-ZslRingBufferConsumer"));
+ mProducer->setName("Camera2-ZslRingBufferConsumer");
sp<Surface> outSurface = new Surface(producer);
res = device->createStream(outSurface, params.fastInfo.usedZslSize.width,
params.fastInfo.usedZslSize.height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
HAL_DATASPACE_UNKNOWN, CAMERA_STREAM_ROTATION_0, &mZslStreamId,
- String8(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
+ std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
if (res != OK) {
ALOGE("%s: Camera %d: Can't create ZSL stream: "
"%s (%d)", __FUNCTION__, client->getCameraId(),
@@ -680,12 +681,12 @@
void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
Mutex::Autolock l(mInputMutex);
if (!mLatestCapturedRequest.isEmpty()) {
- String8 result(" Latest ZSL capture request:\n");
- write(fd, result.string(), result.size());
+ std::string result = " Latest ZSL capture request:\n";
+ write(fd, result.c_str(), result.size());
mLatestCapturedRequest.dump(fd, 2, 6);
} else {
- String8 result(" Latest ZSL capture request: none yet\n");
- write(fd, result.string(), result.size());
+ std::string result = " Latest ZSL capture request: none yet\n";
+ write(fd, result.c_str(), result.size());
}
dumpZslQueue(fd);
}
@@ -706,12 +707,12 @@
}
void ZslProcessor::dumpZslQueue(int fd) const {
- String8 header("ZSL queue contents:");
- String8 indent(" ");
- ALOGV("%s", header.string());
+ std::string header = "ZSL queue contents:";
+ std::string indent = " ";
+ ALOGV("%s", header.c_str());
if (fd != -1) {
header = indent + header + "\n";
- write(fd, header.string(), header.size());
+ write(fd, header.c_str(), header.size());
}
for (size_t i = 0; i < mZslQueue.size(); i++) {
const ZslPair &queueEntry = mZslQueue[i];
@@ -725,13 +726,13 @@
entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
if (entry.count > 0) frameAeState = entry.data.u8[0];
}
- String8 result =
- String8::format(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
+ std::string result =
+ fmt::sprintf(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
bufferTimestamp, frameTimestamp, frameAeState);
- ALOGV("%s", result.string());
+ ALOGV("%s", result.c_str());
if (fd != -1) {
result = indent + result + "\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
}
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 38c615d..c60f327 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -26,6 +26,7 @@
#include <gui/Surface.h>
#include <camera/camera2/CaptureRequest.h>
#include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
#include "common/CameraDeviceBase.h"
#include "device3/Camera3Device.h"
@@ -42,12 +43,12 @@
#define STATUS_ERROR(errorCode, errorString) \
binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
+ fmt::sprintf("%s:%d: %s", __FUNCTION__, __LINE__, errorString).c_str())
#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
- __VA_ARGS__))
+ fmt::sprintf("%s:%d: " errorString, __FUNCTION__, __LINE__, \
+ __VA_ARGS__).c_str())
namespace android {
using namespace camera2;
@@ -57,10 +58,10 @@
CameraDeviceClientBase::CameraDeviceClientBase(
const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
[[maybe_unused]] int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -88,10 +89,10 @@
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
int cameraFacing,
int sensorOrientation,
int clientPid,
@@ -109,16 +110,17 @@
mOverrideForPerfClass(overrideForPerfClass) {
ATRACE_CALL();
- ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
+ ALOGI("CameraDeviceClient %s: Opened", cameraId.c_str());
}
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) {
+ const std::string& monitorTags) {
return initializeImpl(manager, monitorTags);
}
template<typename TProviderPtr>
-status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
+status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr,
+ const std::string& monitorTags) {
ATRACE_CALL();
status_t res;
@@ -127,10 +129,9 @@
return res;
}
- String8 threadName;
mFrameProcessor = new FrameProcessorBase(mDevice);
- threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
- res = mFrameProcessor->run(threadName.string());
+ std::string threadName = std::string("CDU-") + mCameraIdStr + "-FrameProc";
+ res = mFrameProcessor->run(threadName.c_str());
if (res != OK) {
ALOGE("%s: Unable to start frame processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -188,13 +189,13 @@
mProviderManager = providerPtr;
// Cache physical camera ids corresponding to this device and also the high
// resolution sensors in this device + physical camera ids
- mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
+ mProviderManager->isLogicalCamera(mCameraIdStr, &mPhysicalCameraIds);
if (supportsUltraHighResolutionCapture(mCameraIdStr)) {
- mHighResolutionSensors.insert(mCameraIdStr.string());
+ mHighResolutionSensors.insert(mCameraIdStr);
}
for (auto &physicalId : mPhysicalCameraIds) {
- if (supportsUltraHighResolutionCapture(String8(physicalId.c_str()))) {
- mHighResolutionSensors.insert(physicalId.c_str());
+ if (supportsUltraHighResolutionCapture(physicalId)) {
+ mHighResolutionSensors.insert(physicalId);
}
}
return OK;
@@ -222,7 +223,7 @@
if (idx == NAME_NOT_FOUND) {
ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
" we have not called createStream on",
- __FUNCTION__, mCameraIdStr.string());
+ __FUNCTION__, mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request targets Surface that is not part of current capture session");
} else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
@@ -239,7 +240,7 @@
(*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
ALOGV("%s: Camera %s: Appending output stream %d surface %d to request",
- __FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
+ __FUNCTION__, mCameraIdStr.c_str(), streamSurfaceId.streamId(),
streamSurfaceId.surfaceId());
if (currentStreamId != nullptr) {
@@ -282,7 +283,7 @@
if (requests.empty()) {
ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
- __FUNCTION__, mCameraIdStr.string());
+ __FUNCTION__, mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
}
@@ -295,19 +296,19 @@
if (request.mIsReprocess) {
if (!mInputStream.configured) {
ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"No input configured for camera %s but request is for reprocessing",
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
} else if (streaming) {
ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Repeating reprocess requests not supported");
} else if (request.mPhysicalCameraSettings.size() > 1) {
ALOGE("%s: Camera %s: reprocess requests not supported for "
"multiple physical cameras.", __FUNCTION__,
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Reprocess requests not supported for multiple cameras");
}
@@ -315,23 +316,23 @@
if (request.mPhysicalCameraSettings.empty()) {
ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request doesn't contain any settings");
}
//The first capture settings should always match the logical camera id
- String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
+ const std::string &logicalId = request.mPhysicalCameraSettings.begin()->id;
if (mDevice->getId() != logicalId) {
ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
- mCameraIdStr.string());
+ mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Invalid camera request settings");
}
if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
ALOGE("%s: Camera %s: Requests must have at least one surface target. "
- "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
+ "Rejecting request.", __FUNCTION__, mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request has no output targets");
}
@@ -357,9 +358,9 @@
ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
if (index >= 0) {
- String8 requestedPhysicalId(
- mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
- requestedPhysicalIds.push_back(requestedPhysicalId.string());
+ const std::string &requestedPhysicalId =
+ mConfiguredOutputs.valueAt(index).getPhysicalCameraId();
+ requestedPhysicalIds.push_back(requestedPhysicalId);
dynamicProfileBitmap |=
mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
} else {
@@ -375,7 +376,7 @@
if (index < 0) {
ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
" we have not called createStream on: stream %d",
- __FUNCTION__, mCameraIdStr.string(), streamId);
+ __FUNCTION__, mCameraIdStr.c_str(), streamId);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request targets Surface that is not part of current capture session");
}
@@ -384,7 +385,7 @@
if ((size_t)surfaceIdx >= gbps.size()) {
ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
" we have not called createStream on: stream %d, surfaceIdx %d",
- __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
+ __FUNCTION__, mCameraIdStr.c_str(), streamId, surfaceIdx);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request targets Surface has invalid surface index");
}
@@ -394,9 +395,9 @@
return res;
}
- String8 requestedPhysicalId(
- mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
- requestedPhysicalIds.push_back(requestedPhysicalId.string());
+ const std::string &requestedPhysicalId =
+ mConfiguredOutputs.valueAt(index).getPhysicalCameraId();
+ requestedPhysicalIds.push_back(requestedPhysicalId);
dynamicProfileBitmap |=
mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
}
@@ -418,7 +419,7 @@
} else {
ALOGE("%s: Camera %s: Tried to submit a request with a surfaces that"
" reference an unsupported dynamic range profile combination"
- " 0x%" PRIx64 "!", __FUNCTION__, mCameraIdStr.string(),
+ " 0x%" PRIx64 "!", __FUNCTION__, mCameraIdStr.c_str(),
dynamicProfileBitmap);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request targets an unsupported dynamic range profile"
@@ -427,7 +428,7 @@
} else {
ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
" references unsupported dynamic range profile 0x%x!",
- __FUNCTION__, mCameraIdStr.string(), i);
+ __FUNCTION__, mCameraIdStr.c_str(), i);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request targets 10-bit Surface with unsupported dynamic range"
" profile");
@@ -439,7 +440,7 @@
for (const auto& it : request.mPhysicalCameraSettings) {
if (it.settings.isEmpty()) {
ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
- __FUNCTION__, mCameraIdStr.string());
+ __FUNCTION__, mCameraIdStr.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request settings are empty");
}
@@ -462,7 +463,7 @@
}
}
- String8 physicalId(it.id.c_str());
+ const std::string &physicalId = it.id;
bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
mSupportedPhysicalRequestKeys.end();
@@ -474,7 +475,7 @@
it.id);
if (found == requestedPhysicalIds.end()) {
ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
- __FUNCTION__, mCameraIdStr.string(), physicalId.string());
+ __FUNCTION__, mCameraIdStr.c_str(), physicalId.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Invalid physical camera id");
}
@@ -520,7 +521,7 @@
&(submitInfo->mRequestId), /*size*/1);
loopCounter++; // loopCounter starts from 1
ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
- __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
+ __FUNCTION__, mCameraIdStr.c_str(), submitInfo->mRequestId,
loopCounter, requests.size());
metadataRequestList.push_back(physicalSettingsList);
@@ -543,12 +544,12 @@
err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
&(submitInfo->mLastFrameNumber));
if (err != OK) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Got error %s (%d) after trying to set streaming request",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ mCameraIdStr.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
- msg.string());
+ msg.c_str());
} else {
Mutex::Autolock idLock(mStreamingRequestIdLock);
mStreamingRequestId = submitInfo->mRequestId;
@@ -557,17 +558,17 @@
err = mDevice->captureList(metadataRequestList, surfaceMapList,
&(submitInfo->mLastFrameNumber));
if (err != OK) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Got error %s (%d) after trying to submit capture request",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ mCameraIdStr.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
- msg.string());
+ msg.c_str());
}
ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
}
- ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
+ ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.c_str());
return res;
}
@@ -591,22 +592,22 @@
Mutex::Autolock idLock(mStreamingRequestIdLock);
if (mStreamingRequestId != requestId) {
- String8 msg = String8::format("Camera %s: Canceling request ID %d doesn't match "
- "current request ID %d", mCameraIdStr.string(), requestId, mStreamingRequestId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Canceling request ID %d doesn't match "
+ "current request ID %d", mCameraIdStr.c_str(), requestId, mStreamingRequestId);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
err = mDevice->clearStreamingRequest(lastFrameNumber);
if (err == OK) {
ALOGV("%s: Camera %s: Successfully cleared streaming request",
- __FUNCTION__, mCameraIdStr.string());
+ __FUNCTION__, mCameraIdStr.c_str());
mStreamingRequestId = REQUEST_ID_NONE;
} else {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error clearing streaming request: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
+ mCameraIdStr.c_str(), strerror(-err), err);
}
return res;
@@ -631,9 +632,9 @@
if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
if (offlineStreamIds == nullptr) {
- String8 msg = String8::format("Invalid offline stream ids");
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = "Invalid offline stream ids";
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
Mutex::Autolock icl(mBinderSerializationLock);
@@ -650,15 +651,15 @@
status_t err = mDevice->configureStreams(sessionParams, operatingMode);
if (err == BAD_VALUE) {
- String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
- mCameraIdStr.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Unsupported set of inputs/outputs provided",
+ mCameraIdStr.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
} else if (err != OK) {
- String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Error configuring streams: %s (%d)",
+ mCameraIdStr.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
} else {
offlineStreamIds->clear();
mDevice->getOfflineStreamIds(offlineStreamIds);
@@ -667,10 +668,10 @@
for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
err = mCompositeStreamMap.valueAt(i)->configureStream();
if (err != OK) {
- String8 msg = String8::format("Camera %s: Error configuring composite "
- "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Error configuring composite "
+ "streams: %s (%d)", mCameraIdStr.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
break;
}
@@ -729,35 +730,36 @@
}
if (status == nullptr) {
- String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf( "Camera %s: Invalid status!", mCameraIdStr.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
*status = false;
- camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+ camera3::metadataGetter getMetadata = [this](const std::string &id,
+ bool /*overrideForPerfClass*/) {
return mDevice->infoPhysical(id);};
- ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
+ ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.c_str(),
sessionConfiguration, mOverrideForPerfClass, getMetadata, status);
switch (ret) {
case OK:
// Expected, do nothing.
break;
case INVALID_OPERATION: {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Session configuration query not supported!",
- mCameraIdStr.string());
- ALOGD("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ mCameraIdStr.c_str());
+ ALOGD("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
break;
default: {
- String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
+ std::string msg = fmt::sprintf( "Camera %s: Error: %s (%d)", mCameraIdStr.c_str(),
strerror(-ret), ret);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
+ msg.c_str());
}
}
@@ -809,10 +811,10 @@
}
if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
- " stream created yet", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no such"
+ " stream created yet", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
}
@@ -820,10 +822,10 @@
status_t err = mDevice->deleteStream(streamId);
if (err != OK) {
- String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when deleting stream %d",
- mCameraIdStr.string(), strerror(-err), err, streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Unexpected error %s (%d) when deleting stream "
+ "%d", mCameraIdStr.c_str(), strerror(-err), err, streamId);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
} else {
if (isInput) {
mInputStream.configured = false;
@@ -843,11 +845,11 @@
status_t ret;
if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
!= OK) {
- String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
- "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
- streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Unexpected error %s (%d) when "
+ "deleting composite stream %d", mCameraIdStr.c_str(), strerror(-err),
+ err, streamId);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
mCompositeStreamMap.removeItemsAt(compositeIndex);
}
@@ -880,7 +882,7 @@
size_t numBufferProducers = bufferProducers.size();
bool deferredConsumer = outputConfiguration.isDeferred();
bool isShared = outputConfiguration.isShared();
- String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
+ const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
bool isMultiResolution = outputConfiguration.isMultiResolution();
int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
@@ -923,10 +925,11 @@
sp<IBinder> binder = IInterface::asBinder(bufferProducer);
ssize_t index = mStreamMap.indexOfKey(binder);
if (index != NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
- "(ID %zd)", mCameraIdStr.string(), index);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+ std::string msg = std::string("Camera ") + mCameraIdStr
+ + ": Surface already has a stream created for it (ID "
+ + std::to_string(index) + ")";
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.c_str());
}
sp<Surface> surface;
@@ -994,7 +997,7 @@
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
- mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
+ mCameraIdStr.c_str(), streamInfo.width, streamInfo.height, streamInfo.format,
streamInfo.dataSpace, strerror(-err), err);
} else {
int i = 0;
@@ -1010,20 +1013,19 @@
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
" (%d x %d) with format 0x%x.",
- __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
+ __FUNCTION__, mCameraIdStr.c_str(), streamId, streamInfo.width,
streamInfo.height, streamInfo.format);
// Set transform flags to ensure preview to be rotated correctly.
res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);
// Fill in mHighResolutionCameraIdToStreamIdSet map
- const String8 &cameraIdUsed =
+ const std::string &cameraIdUsed =
physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
- const char *cameraIdUsedCStr = cameraIdUsed.string();
// Only needed for high resolution sensors
- if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
+ if (mHighResolutionSensors.find(cameraIdUsed) !=
mHighResolutionSensors.end()) {
- mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
+ mHighResolutionCameraIdToStreamIdSet[cameraIdUsed].insert(streamId);
}
*newStreamId = streamId;
@@ -1063,8 +1065,8 @@
int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
std::vector<sp<Surface>> noSurface;
std::vector<int> surfaceIds;
- String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
- const String8 &cameraIdUsed =
+ const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
+ const std::string &cameraIdUsed =
physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
// Here, we override sensor pixel modes
std::unordered_set<int32_t> overriddenSensorPixelModesUsed;
@@ -1093,7 +1095,7 @@
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
- mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
+ mCameraIdStr.c_str(), width, height, format, dataSpace, strerror(-err), err);
} else {
// Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
// a separate list to track. Once the deferred surface is set, this id will be
@@ -1110,18 +1112,17 @@
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
- __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
+ __FUNCTION__, mCameraIdStr.c_str(), streamId, width, height, format);
// Set transform flags to ensure preview to be rotated correctly.
res = setStreamTransformLocked(streamId, outputConfiguration.getMirrorMode());
*newStreamId = streamId;
// Fill in mHighResolutionCameraIdToStreamIdSet
- const char *cameraIdUsedCStr = cameraIdUsed.string();
// Only needed for high resolution sensors
- if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
+ if (mHighResolutionSensors.find(cameraIdUsed) !=
mHighResolutionSensors.end()) {
- mHighResolutionCameraIdToStreamIdSet[cameraIdUsed.string()].insert(streamId);
+ mHighResolutionCameraIdToStreamIdSet[cameraIdUsed].insert(streamId);
}
}
return res;
@@ -1145,10 +1146,10 @@
err = mDevice->setStreamTransform(streamId, transform);
if (err != OK) {
- String8 msg = String8::format("Failed to set stream transform (stream id %d)",
+ std::string msg = fmt::sprintf("Failed to set stream transform (stream id %d)",
streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
return res;
@@ -1173,10 +1174,10 @@
}
if (mInputStream.configured) {
- String8 msg = String8::format("Camera %s: Already has an input stream "
- "configured (ID %d)", mCameraIdStr.string(), mInputStream.id);
- ALOGE("%s: %s", __FUNCTION__, msg.string() );
- return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Already has an input stream "
+ "configured (ID %d)", mCameraIdStr.c_str(), mInputStream.id);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str() );
+ return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.c_str());
}
int streamId = -1;
@@ -1189,12 +1190,12 @@
mInputStream.id = streamId;
ALOGV("%s: Camera %s: Successfully created a new input stream ID %d",
- __FUNCTION__, mCameraIdStr.string(), streamId);
+ __FUNCTION__, mCameraIdStr.c_str(), streamId);
*newStreamId = streamId;
} else {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
- "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.string(),
+ "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.c_str(),
strerror(-err), err);
}
@@ -1219,9 +1220,9 @@
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error getting input Surface: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
+ mCameraIdStr.c_str(), strerror(-err), err);
} else {
- inputSurface->name = String16("CameraInput");
+ inputSurface->name = toString16("CameraInput");
inputSurface->graphicBufferProducer = producer;
}
return res;
@@ -1242,7 +1243,7 @@
const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
outputConfiguration.getGraphicBufferProducers();
- String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
+ const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
auto producerCount = bufferProducers.size();
if (producerCount == 0) {
@@ -1329,12 +1330,12 @@
case -EBUSY:
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Error updating stream: %s (%d)",
- mCameraIdStr.string(), strerror(ret), ret);
+ mCameraIdStr.c_str(), strerror(ret), ret);
break;
default:
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error updating stream: %s (%d)",
- mCameraIdStr.string(), strerror(ret), ret);
+ mCameraIdStr.c_str(), strerror(ret), ret);
break;
}
} else {
@@ -1350,7 +1351,7 @@
mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
ALOGV("%s: Camera %s: Successful stream ID %d update",
- __FUNCTION__, mCameraIdStr.string(), streamId);
+ __FUNCTION__, mCameraIdStr.c_str(), streamId);
}
return res;
@@ -1385,12 +1386,12 @@
} else if (err == BAD_VALUE) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Template ID %d is invalid or not supported: %s (%d)",
- mCameraIdStr.string(), templateId, strerror(-err), err);
+ mCameraIdStr.c_str(), templateId, strerror(-err), err);
} else {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error creating default request for template %d: %s (%d)",
- mCameraIdStr.string(), templateId, strerror(-err), err);
+ mCameraIdStr.c_str(), templateId, strerror(-err), err);
}
return res;
}
@@ -1437,17 +1438,17 @@
// FIXME: Also need check repeating burst.
Mutex::Autolock idLock(mStreamingRequestIdLock);
if (mStreamingRequestId != REQUEST_ID_NONE) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Try to waitUntilIdle when there are active streaming requests",
- mCameraIdStr.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ mCameraIdStr.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
status_t err = mDevice->waitUntilDrained();
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error waiting to drain: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
+ mCameraIdStr.c_str(), strerror(-err), err);
}
ALOGV("%s Done", __FUNCTION__);
return res;
@@ -1473,7 +1474,8 @@
status_t err = mDevice->flush(lastFrameNumber);
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
- "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
+ "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.c_str(), strerror(-err),
+ err);
}
return res;
}
@@ -1497,10 +1499,10 @@
}
if (index == NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
- "with that ID exists", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+ "with that ID exists", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
// Also returns BAD_VALUE if stream ID was not valid, or stream already
@@ -1509,10 +1511,10 @@
if (err == BAD_VALUE) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Stream %d has already been used, and cannot be prepared",
- mCameraIdStr.string(), streamId);
+ mCameraIdStr.c_str(), streamId);
} else if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
- "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+ "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
strerror(-err), err);
}
return res;
@@ -1537,17 +1539,17 @@
}
if (index == NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
- "with that ID exists", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+ "with that ID exists", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (maxCount <= 0) {
- String8 msg = String8::format("Camera %s: maxCount (%d) must be greater than 0",
- mCameraIdStr.string(), maxCount);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: maxCount (%d) must be greater than 0",
+ mCameraIdStr.c_str(), maxCount);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
// Also returns BAD_VALUE if stream ID was not valid, or stream already
@@ -1556,10 +1558,10 @@
if (err == BAD_VALUE) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Stream %d has already been used, and cannot be prepared",
- mCameraIdStr.string(), streamId);
+ mCameraIdStr.c_str(), streamId);
} else if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
- "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+ "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
strerror(-err), err);
}
@@ -1585,10 +1587,10 @@
}
if (index == NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
- "with that ID exists", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Invalid stream ID (%d) specified, no stream "
+ "with that ID exists", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
// Also returns BAD_VALUE if stream ID was not valid or if the stream is in
@@ -1597,10 +1599,10 @@
if (err == BAD_VALUE) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Stream %d is still in use, cannot be torn down",
- mCameraIdStr.string(), streamId);
+ mCameraIdStr.c_str(), streamId);
} else if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
- "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.string(), streamId,
+ "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.c_str(), streamId,
strerror(-err), err);
}
@@ -1618,7 +1620,7 @@
const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
outputConfiguration.getGraphicBufferProducers();
- String8 physicalId(outputConfiguration.getPhysicalCameraId());
+ const std::string &physicalId = outputConfiguration.getPhysicalCameraId();
if (bufferProducers.size() == 0) {
ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
@@ -1643,17 +1645,17 @@
}
if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
- String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
- "(ID %d)", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: deferred surface is set to a unknown stream"
+ "(ID %d)", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (mStreamInfoMap[streamId].finalized) {
- String8 msg = String8::format("Camera %s: finalizeOutputConfigurations has been called"
- " on stream ID %d", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: finalizeOutputConfigurations has been called"
+ " on stream ID %d", mCameraIdStr.c_str(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (!mDevice.get()) {
@@ -1673,7 +1675,7 @@
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
if (index != NAME_NOT_FOUND) {
ALOGV("Camera %s: Surface already has a stream created "
- " for it (ID %zd)", mCameraIdStr.string(), index);
+ " for it (ID %zd)", mCameraIdStr.c_str(), index);
continue;
}
@@ -1716,11 +1718,11 @@
} else if (err == NO_INIT) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Deferred surface is invalid: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
+ mCameraIdStr.c_str(), strerror(-err), err);
} else {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error setting output stream deferred surface: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
+ mCameraIdStr.c_str(), strerror(-err), err);
}
return res;
@@ -1732,10 +1734,10 @@
if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
if (!isValidAudioRestriction(mode)) {
- String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
- mCameraIdStr.string(), mode);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: invalid audio restriction mode %d",
+ mCameraIdStr.c_str(), mode);
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
Mutex::Autolock icl(mBinderSerializationLock);
@@ -1814,15 +1816,15 @@
}
if (offlineOutputIds.empty()) {
- String8 msg = String8::format("Offline surfaces must not be empty");
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = "Offline surfaces must not be empty";
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (session == nullptr) {
- String8 msg = String8::format("Invalid offline session");
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = "Invalid offline session";
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
std::vector<int32_t> offlineStreamIds;
@@ -1831,17 +1833,17 @@
for (const auto& streamId : offlineOutputIds) {
ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
if (index == NAME_NOT_FOUND) {
- String8 msg = String8::format("Offline surface with id: %d is not registered",
+ std::string msg = fmt::sprintf("Offline surface with id: %d is not registered",
streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (!mStreamInfoMap[streamId].supportsOffline) {
- String8 msg = String8::format("Offline surface with id: %d doesn't support "
+ std::string msg = fmt::sprintf("Offline surface with id: %d doesn't support "
"offline mode", streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
Mutex::Autolock l(mCompositeLock);
@@ -1878,7 +1880,7 @@
if (ret != OK) {
return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Error switching to offline mode: %s (%d)",
- mCameraIdStr.string(), strerror(ret), ret);
+ mCameraIdStr.c_str(), strerror(ret), ret);
}
sp<CameraOfflineSessionClient> offlineClient;
@@ -1903,7 +1905,7 @@
} else {
// In case we failed to register the offline client, ensure that it still initialized
// so that all failing requests can return back correctly once the object is released.
- offlineClient->initialize(nullptr /*cameraProviderManager*/, String8()/*monitorTags*/);
+ offlineClient->initialize(nullptr /*cameraProviderManager*/, std::string()/*monitorTags*/);
switch(ret) {
case BAD_VALUE:
@@ -1930,7 +1932,7 @@
status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
dprintf(fd, " CameraDeviceClient[%s] (%p) dump:\n",
- mCameraIdStr.string(),
+ mCameraIdStr.c_str(),
(getRemoteCallback() != NULL ?
IInterface::asBinder(getRemoteCallback()).get() : NULL) );
dprintf(fd, " Current client UID %u\n", mClientUid);
@@ -1963,7 +1965,7 @@
return dumpDevice(fd, args);
}
-status_t CameraDeviceClient::startWatchingTags(const String8 &tags, int out) {
+status_t CameraDeviceClient::startWatchingTags(const std::string &tags, int out) {
sp<CameraDeviceBase> device = mDevice;
if (!device) {
dprintf(out, " Device is detached.");
@@ -2087,16 +2089,16 @@
if (mDevice == 0) return;
nsecs_t startTime = systemTime();
- ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
+ ALOGV("Camera %s: Stopping processors", mCameraIdStr.c_str());
if (mFrameProcessor.get() != nullptr) {
mFrameProcessor->removeListener(
camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID, /*listener*/this);
mFrameProcessor->requestExit();
- ALOGV("Camera %s: Waiting for threads", mCameraIdStr.string());
+ ALOGV("Camera %s: Waiting for threads", mCameraIdStr.c_str());
mFrameProcessor->join();
- ALOGV("Camera %s: Disconnecting device", mCameraIdStr.string());
+ ALOGV("Camera %s: Disconnecting device", mCameraIdStr.c_str());
}
// WORKAROUND: HAL refuses to disconnect while there's streams in flight
@@ -2202,7 +2204,7 @@
entry = metadata.find(ANDROID_LED_TRANSMIT);
if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
String16 permissionString =
- String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
+ toString16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
if (!checkCallingPermission(permissionString)) {
const int uid = CameraThreadState::getCallingUid();
ALOGE("Permission Denial: "
@@ -2228,7 +2230,7 @@
if (tempId == nullptr) {
ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Camera %s: Invalid template argument", mCameraIdStr.string());
+ "Camera %s: Invalid template argument", mCameraIdStr.c_str());
return ret;
}
switch(templateId) {
@@ -2253,21 +2255,21 @@
default:
ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Camera %s: Template ID %d is invalid or not supported",
- mCameraIdStr.string(), templateId);
+ mCameraIdStr.c_str(), templateId);
return ret;
}
return ret;
}
-const CameraMetadata &CameraDeviceClient::getStaticInfo(const String8 &cameraId) {
+const CameraMetadata &CameraDeviceClient::getStaticInfo(const std::string &cameraId) {
if (mDevice->getId() == cameraId) {
return mDevice->info();
}
return mDevice->infoPhysical(cameraId);
}
-bool CameraDeviceClient::supportsUltraHighResolutionCapture(const String8 &cameraId) {
+bool CameraDeviceClient::supportsUltraHighResolutionCapture(const std::string &cameraId) {
const CameraMetadata &deviceInfo = getStaticInfo(cameraId);
return SessionConfigurationUtils::supportsUltraHighResolutionCapture(deviceInfo);
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 1533cf5..45c904a 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,10 +50,10 @@
protected:
CameraDeviceClientBase(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -181,10 +181,10 @@
CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool clientPackageOverride,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
int cameraFacing,
int sensorOrientation,
int clientPid,
@@ -195,7 +195,7 @@
virtual ~CameraDeviceClient();
virtual status_t initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) override;
+ const std::string& monitorTags) override;
virtual status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
@@ -211,7 +211,7 @@
virtual status_t dumpClient(int fd, const Vector<String16>& args);
- virtual status_t startWatchingTags(const String8 &tags, int out);
+ virtual status_t startWatchingTags(const std::string &tags, int out);
virtual status_t stopWatchingTags(int out);
virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
@@ -245,12 +245,12 @@
// Calculate the ANativeWindow transform from android.sensor.orientation
status_t getRotationTransformLocked(int mirrorMode, /*out*/int32_t* transform);
- bool supportsUltraHighResolutionCapture(const String8 &cameraId);
+ bool supportsUltraHighResolutionCapture(const std::string &cameraId);
bool isSensorPixelModeConsistent(const std::list<int> &streamIdList,
const CameraMetadata &settings);
- const CameraMetadata &getStaticInfo(const String8 &cameraId);
+ const CameraMetadata &getStaticInfo(const std::string &cameraId);
private:
// StreamSurfaceId encapsulates streamId + surfaceId for a particular surface.
@@ -289,7 +289,7 @@
std::vector<int32_t> mSupportedPhysicalRequestKeys;
template<typename TProviderPtr>
- status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+ status_t initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
/** Utility members */
binder::Status checkPidStatus(const char* checkLocation);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 86a0ebc..99bdb0e 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -21,12 +21,13 @@
#include "CameraOfflineSessionClient.h"
#include "utils/CameraThreadState.h"
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
namespace android {
using binder::Status;
-status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const String8&) {
+status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const std::string&) {
ATRACE_CALL();
if (mFrameProcessor.get() != nullptr) {
@@ -42,14 +43,13 @@
if (mOfflineSession.get() == nullptr) {
ALOGE("%s: Camera %s: No valid offline session",
- __FUNCTION__, mCameraIdStr.string());
+ __FUNCTION__, mCameraIdStr.c_str());
return NO_INIT;
}
- String8 threadName;
mFrameProcessor = new camera2::FrameProcessorBase(mOfflineSession);
- threadName = String8::format("Offline-%s-FrameProc", mCameraIdStr.string());
- res = mFrameProcessor->run(threadName.string());
+ std::string threadName = fmt::sprintf("Offline-%s-FrameProc", mCameraIdStr.c_str());
+ res = mFrameProcessor->run(threadName.c_str());
if (res != OK) {
ALOGE("%s: Unable to start frame processor thread: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -65,7 +65,7 @@
res = mOfflineSession->initialize(weakThis);
if (res != OK) {
ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
- __FUNCTION__, mCameraIdStr.string(), strerror(-res), res);
+ __FUNCTION__, mCameraIdStr.c_str(), strerror(-res), res);
return res;
}
@@ -119,14 +119,14 @@
}
status_t CameraOfflineSessionClient::dumpClient(int fd, const Vector<String16>& args) {
- String8 result;
+ std::string result;
result = " Offline session dump:\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
if (mOfflineSession.get() == nullptr) {
result = " *** Offline session is detached\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
return NO_ERROR;
}
@@ -134,15 +134,15 @@
auto res = mOfflineSession->dump(fd);
if (res != OK) {
- result = String8::format(" Error dumping offline session: %s (%d)",
+ result = fmt::sprintf(" Error dumping offline session: %s (%d)",
strerror(-res), res);
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
}
return OK;
}
-status_t CameraOfflineSessionClient::startWatchingTags(const String8 &tags, int outFd) {
+status_t CameraOfflineSessionClient::startWatchingTags(const std::string &tags, int outFd) {
return BasicClient::startWatchingTags(tags, outFd);
}
@@ -171,7 +171,7 @@
mDisconnected = true;
sCameraService->removeByClient(this);
- sCameraService->logDisconnectedOffline(mCameraIdStr, mClientPid, String8(mClientPackageName));
+ sCameraService->logDisconnectedOffline(mCameraIdStr, mClientPid, mClientPackageName);
sp<IBinder> remote = getRemote();
if (remote != nullptr) {
@@ -186,7 +186,7 @@
finishCameraOps();
ALOGI("%s: Disconnected client for offline camera %s for PID %d", __FUNCTION__,
- mCameraIdStr.string(), mClientPid);
+ mCameraIdStr.c_str(), mClientPid);
// client shouldn't be able to call into us anymore
mClientPid = 0;
@@ -231,7 +231,7 @@
ATRACE_CALL();
{
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
- __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+ __FUNCTION__, mClientPackageName.c_str(), mClientUid);
}
if (mAppOpsManager != nullptr) {
@@ -240,14 +240,14 @@
int32_t res;
// TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
- mClientPackageName, mOpsCallback);
+ toString16(mClientPackageName), mOpsCallback);
// TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
- mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+ mClientUid, toString16(mClientPackageName), /*startIfModeDefault*/ false);
if (res == AppOpsManager::MODE_ERRORED) {
ALOGI("Offline Camera %s: Access for \"%s\" has been revoked",
- mCameraIdStr.string(), String8(mClientPackageName).string());
+ mCameraIdStr.c_str(), mClientPackageName.c_str());
return PERMISSION_DENIED;
}
@@ -255,7 +255,7 @@
// return MODE_IGNORED. Do not treat such case as error.
if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
ALOGI("Offline Camera %s: Access for \"%s\" has been restricted",
- mCameraIdStr.string(), String8(mClientPackageName).string());
+ mCameraIdStr.c_str(), mClientPackageName.c_str());
// Return the same error as for device policy manager rejection
return -EACCES;
}
@@ -278,7 +278,7 @@
if (mAppOpsManager != nullptr) {
// TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION
mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName);
+ toString16(mClientPackageName));
mOpsActive = false;
}
}
@@ -368,10 +368,10 @@
CaptureResultExtras());
}
-status_t CameraOfflineSessionClient::injectCamera(const String8& injectedCamId,
+status_t CameraOfflineSessionClient::injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) {
ALOGV("%s: This client doesn't support the injection camera. injectedCamId: %s providerPtr: %p",
- __FUNCTION__, injectedCamId.string(), manager.get());
+ __FUNCTION__, injectedCamId.c_str(), manager.get());
return OK;
}
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index ad763f9..70bad03 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -47,9 +47,9 @@
sp<CameraOfflineSessionBase> session,
const KeyedVector<sp<IBinder>, sp<CompositeStream>>& offlineCompositeStreamMap,
const sp<ICameraDeviceCallbacks>& remoteCallback,
- const String16& clientPackageName,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraIdStr, int cameraFacing, int sensorOrientation,
+ const std::string& clientPackageName,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraIdStr, int cameraFacing, int sensorOrientation,
int clientPid, uid_t clientUid, int servicePid) :
CameraService::BasicClient(
cameraService,
@@ -73,12 +73,12 @@
status_t dumpClient(int /*fd*/, const Vector<String16>& /*args*/) override;
- status_t startWatchingTags(const String8 &tags, int outFd) override;
+ status_t startWatchingTags(const std::string &tags, int outFd) override;
status_t stopWatchingTags(int outFd) override;
status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
status_t initialize(sp<CameraProviderManager> /*manager*/,
- const String8& /*monitorTags*/) override;
+ const std::string& /*monitorTags*/) override;
status_t setRotateAndCropOverride(uint8_t rotateAndCrop) override;
@@ -117,7 +117,7 @@
void notifyPrepared(int streamId) override;
void notifyRequestQueueEmpty() override;
void notifyRepeatingRequestError(long lastFrameNumber) override;
- status_t injectCamera(const String8& injectedCamId,
+ status_t injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) override;
status_t stopInjection() override;
diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp
index 4ed1c28..8f53458 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/CompositeStream.cpp
@@ -46,7 +46,7 @@
status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int * id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> * surfaceIds,
int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
index a551d11..1b7fc6e 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.h
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -43,7 +43,7 @@
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int streamSetId, bool isShared, bool isMultiResolution, int32_t colorSpace,
@@ -57,7 +57,7 @@
// Create and register all internal camera streams.
virtual status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
index 737c2b5..1bd0b85 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -20,6 +20,7 @@
#include <aidl/android/hardware/camera/device/CameraBlob.h>
#include <aidl/android/hardware/camera/device/CameraBlobId.h>
+#include <camera/StringUtils.h>
#include "api1/client2/JpegProcessor.h"
#include "common/CameraProviderManager.h"
@@ -495,17 +496,17 @@
status_t err;
int format;
if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
- String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+ std::string msg = fmt::sprintf("Failed to query Surface format: %s (%d)", strerror(-err),
err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return false;
}
int dataspace;
if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
- String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+ std::string msg = fmt::sprintf("Failed to query Surface dataspace: %s (%d)", strerror(-err),
err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return false;
}
@@ -578,7 +579,7 @@
status_t DepthCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int /*streamSetId*/, bool /*isShared*/, int32_t /*colorSpace*/,
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h
index fbe99dd..f797f9c 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.h
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h
@@ -50,7 +50,7 @@
// CompositeStream overrides
status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 694aff3..8144792 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -29,6 +29,7 @@
#include <gui/Surface.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include <mediadrm/ICrypto.h>
#include <media/MediaCodecBuffer.h>
@@ -98,17 +99,17 @@
status_t err;
int format;
if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
- String8 msg = String8::format("Failed to query Surface format: %s (%d)", strerror(-err),
+ std::string msg = fmt::sprintf("Failed to query Surface format: %s (%d)", strerror(-err),
err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return false;
}
int dataspace;
if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE, &dataspace)) != OK) {
- String8 msg = String8::format("Failed to query Surface dataspace: %s (%d)", strerror(-err),
+ std::string msg = fmt::sprintf("Failed to query Surface dataspace: %s (%d)", strerror(-err),
err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return false;
}
@@ -117,7 +118,7 @@
status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int /*streamSetId*/, bool /*isShared*/, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 602a247..b539cdd 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -45,7 +45,7 @@
status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, int32_t colorSpace,
int64_t dynamicProfile, int64_t streamUseCase, bool useReadoutTimestamp) override;
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
index 6588470..988446b 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
@@ -548,7 +548,7 @@
status_t JpegRCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int /*streamSetId*/, bool /*isShared*/, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.h b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
index 3dfed30..016d57c 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.h
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
@@ -47,7 +47,7 @@
// CompositeStream overrides
status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
- camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+ camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds,
int streamSetId, bool isShared, int32_t colorSpace,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6e10f30..a54ba9b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -28,6 +28,7 @@
#include <gui/Surface.h>
#include <camera/CameraSessionStats.h>
+#include <camera/StringUtils.h>
#include "common/Camera2ClientBase.h"
@@ -49,10 +50,10 @@
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -69,8 +70,8 @@
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mDeviceActive(false), mApi1CameraId(api1CameraId)
{
- ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
- String8(clientPackageName).string(), clientPid, clientUid);
+ ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.c_str(),
+ clientPackageName.c_str(), clientPid, clientUid);
mInitialClientPid = clientPid;
mOverrideForPerfClass = overrideForPerfClass;
@@ -91,21 +92,21 @@
template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) {
+ const std::string& monitorTags) {
return initializeImpl(manager, monitorTags);
}
template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
- const String8& monitorTags) {
+ const std::string& monitorTags) {
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
- TClientBase::mCameraIdStr.string());
+ TClientBase::mCameraIdStr.c_str());
status_t res;
IPCTransport providerTransport = IPCTransport::INVALID;
- res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr.string(),
+ res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr,
&providerTransport);
if (res != OK) {
return res;
@@ -125,19 +126,19 @@
break;
default:
ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
- TClientBase::mCameraIdStr.string());
+ TClientBase::mCameraIdStr.c_str());
return NO_INIT;
}
if (mDevice == NULL) {
ALOGE("%s: Camera %s: No device connected",
- __FUNCTION__, TClientBase::mCameraIdStr.string());
+ __FUNCTION__, TClientBase::mCameraIdStr.c_str());
return NO_INIT;
}
res = mDevice->initialize(providerPtr, monitorTags);
if (res != OK) {
ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
- __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
+ __FUNCTION__, TClientBase::mCameraIdStr.c_str(), strerror(-res), res);
return res;
}
@@ -152,7 +153,7 @@
res = mDevice->setNotifyCallback(weakThis);
if (res != OK) {
ALOGE("%s: Camera %s: Unable to set notify callback: %s (%d)",
- __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
+ __FUNCTION__, TClientBase::mCameraIdStr.c_str(), strerror(-res), res);
return res;
}
@@ -183,30 +184,30 @@
}
ALOGI("%s: Client object's dtor for Camera Id %s completed. Client was: %s (PID %d, UID %u)",
- __FUNCTION__, TClientBase::mCameraIdStr.string(),
- String8(TClientBase::mClientPackageName).string(),
+ __FUNCTION__, TClientBase::mCameraIdStr.c_str(),
+ TClientBase::mClientPackageName.c_str(),
mInitialClientPid, TClientBase::mClientUid);
}
template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::dumpClient(int fd,
const Vector<String16>& args) {
- String8 result;
- result.appendFormat("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
- TClientBase::mCameraIdStr.string(),
+ std::string result;
+ result += fmt::sprintf("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
+ TClientBase::mCameraIdStr.c_str(),
(TClientBase::getRemoteCallback() != NULL ?
- IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
+ (void *)IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
TClientBase::mClientPid);
- result.append(" State: ");
+ result += " State: ";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
// TODO: print dynamic/request section from most recent requests
return dumpDevice(fd, args);
}
template <typename TClientBase>
-status_t Camera2ClientBase<TClientBase>::startWatchingTags(const String8 &tags, int out) {
+status_t Camera2ClientBase<TClientBase>::startWatchingTags(const std::string &tags, int out) {
sp<CameraDeviceBase> device = mDevice;
if (!device) {
dprintf(out, " Device is detached");
@@ -241,23 +242,23 @@
status_t Camera2ClientBase<TClientBase>::dumpDevice(
int fd,
const Vector<String16>& args) {
- String8 result;
+ std::string result;
result = " Device dump:\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
sp<CameraDeviceBase> device = mDevice;
if (!device.get()) {
result = " *** Device is detached\n";
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
return NO_ERROR;
}
status_t res = device->dump(fd, args);
if (res != OK) {
- result = String8::format(" Error dumping device: %s (%d)",
+ result = fmt::sprintf(" Error dumping device: %s (%d)",
strerror(-res), res);
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
}
return NO_ERROR;
@@ -284,23 +285,23 @@
template <typename TClientBase>
binder::Status Camera2ClientBase<TClientBase>::disconnectImpl() {
ATRACE_CALL();
- ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.string());
+ ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.c_str());
Mutex::Autolock icl(mBinderSerializationLock);
- ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.string());
+ ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.c_str());
binder::Status res = binder::Status::ok();
// Allow both client and the media server to disconnect at all times
int callingPid = CameraThreadState::getCallingPid();
if (callingPid != TClientBase::mClientPid &&
callingPid != TClientBase::mServicePid) return res;
- ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
+ ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.c_str());
// Before detaching the device, cache the info from current open session.
// The disconnected check avoids duplication of info and also prevents
// deadlock while acquiring service lock in cacheDump.
if (!TClientBase::mDisconnected) {
- ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.string());
+ ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.c_str());
Camera2ClientBase::getCameraService()->cacheDump();
}
@@ -308,7 +309,7 @@
CameraService::BasicClient::disconnect();
- ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.string());
+ ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.c_str());
return res;
}
@@ -318,7 +319,7 @@
if (mDevice == 0) return;
mDevice->disconnect();
- ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string());
+ ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.c_str());
}
template <typename TClientBase>
@@ -334,7 +335,7 @@
ALOGE("%s: Camera %s: Connection attempt from pid %d; "
"current locked to pid %d",
__FUNCTION__,
- TClientBase::mCameraIdStr.string(),
+ TClientBase::mCameraIdStr.c_str(),
CameraThreadState::getCallingPid(),
TClientBase::mClientPid);
return BAD_VALUE;
@@ -365,8 +366,7 @@
return;
}
- String8 physicalId8(physicalId.c_str());
- auto physicalCameraMetadata = mDevice->infoPhysical(physicalId8);
+ auto physicalCameraMetadata = mDevice->infoPhysical(physicalId);
auto orientationEntry = physicalCameraMetadata.find(ANDROID_SENSOR_ORIENTATION);
if (orientationEntry.count == 1) {
@@ -387,7 +387,7 @@
status_t res = TClientBase::startCameraStreamingOps();
if (res != OK) {
ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__,
- TClientBase::mCameraIdStr.string(), res);
+ TClientBase::mCameraIdStr.c_str(), res);
return res;
}
mCameraServiceProxyWrapper->logActive(TClientBase::mCameraIdStr, maxPreviewFps);
@@ -407,7 +407,7 @@
status_t res = TClientBase::finishCameraStreamingOps();
if (res != OK) {
ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__,
- TClientBase::mCameraIdStr.string(), res);
+ TClientBase::mCameraIdStr.c_str(), res);
}
mCameraServiceProxyWrapper->logIdle(TClientBase::mCameraIdStr,
requestCount, resultErrorCount, deviceError, userTag, videoStabilizationMode,
@@ -522,7 +522,7 @@
}
template <typename TClientBase>
-status_t Camera2ClientBase<TClientBase>::injectCamera(const String8& injectedCamId,
+status_t Camera2ClientBase<TClientBase>::injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) {
return mDevice->injectCamera(injectedCamId, manager);
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 5cf3033..30c763d 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -50,10 +50,10 @@
Camera2ClientBase(const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
- const String16& clientPackageName,
+ const std::string& clientPackageName,
bool systemNativeClient,
- const std::optional<String16>& clientFeatureId,
- const String8& cameraId,
+ const std::optional<std::string>& clientFeatureId,
+ const std::string& cameraId,
int api1CameraId,
int cameraFacing,
int sensorOrientation,
@@ -65,11 +65,12 @@
bool legacyClient = false);
virtual ~Camera2ClientBase();
- virtual status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags);
- virtual status_t dumpClient(int fd, const Vector<String16>& args);
- virtual status_t startWatchingTags(const String8 &tags, int out);
- virtual status_t stopWatchingTags(int out);
- virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out);
+ virtual status_t initialize(sp<CameraProviderManager> manager,
+ const std::string& monitorTags) override;
+ virtual status_t dumpClient(int fd, const Vector<String16>& args) override;
+ virtual status_t startWatchingTags(const std::string &tags, int out) override;
+ virtual status_t stopWatchingTags(int out) override;
+ virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
/**
* NotificationListener implementation
@@ -130,7 +131,7 @@
mutable Mutex mRemoteCallbackLock;
} mSharedCameraCallbacks;
- status_t injectCamera(const String8& injectedCamId,
+ status_t injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) override;
status_t stopInjection() override;
@@ -181,7 +182,7 @@
private:
template<typename TProviderPtr>
- status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
+ status_t initializeImpl(TProviderPtr providerPtr, const std::string& monitorTags);
binder::Status disconnectImpl();
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 919108d..017da0f 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -20,7 +20,6 @@
#include <list>
#include <utils/RefBase.h>
-#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
@@ -99,11 +98,12 @@
*/
virtual metadata_vendor_id_t getVendorTagId() const = 0;
- virtual status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) = 0;
+ virtual status_t initialize(sp<CameraProviderManager> manager,
+ const std::string& monitorTags) = 0;
virtual status_t disconnect() = 0;
virtual status_t dump(int fd, const Vector<String16> &args) = 0;
- virtual status_t startWatchingTags(const String8 &tags) = 0;
+ virtual status_t startWatchingTags(const std::string &tags) = 0;
virtual status_t stopWatchingTags() = 0;
virtual status_t dumpWatchedEventsToVector(std::vector<std::string> &out) = 0;
@@ -111,7 +111,7 @@
* The physical camera device's static characteristics metadata buffer, or
* the logical camera's static characteristics if physical id is empty.
*/
- virtual const CameraMetadata& infoPhysical(const String8& physicalId) const = 0;
+ virtual const CameraMetadata& infoPhysical(const std::string& physicalId) const = 0;
virtual bool isCompositeJpegRDisabled() const { return false; };
@@ -188,7 +188,7 @@
virtual status_t createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -212,7 +212,7 @@
virtual status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -510,7 +510,7 @@
* The injection camera session to replace the internal camera
* session.
*/
- virtual status_t injectCamera(const String8& injectedCamId,
+ virtual status_t injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) = 0;
/**
diff --git a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
index 63abcf0..976c47c 100644
--- a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
+++ b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
@@ -20,7 +20,6 @@
#include <vector>
#include <utils/RefBase.h>
-#include <utils/String8.h>
#include <utils/Timers.h>
#include "camera/CaptureResult.h"
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 1a6e341..23051ef 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -43,6 +43,7 @@
#include <hwbinder/IPCThreadState.h>
#include <utils/Trace.h>
#include <ui/PublicFormat.h>
+#include <camera/StringUtils.h>
#include "api2/HeicCompositeStream.h"
#include "device3/ZoomRatioMapper.h"
@@ -143,7 +144,7 @@
String16(aidlHalServiceDescriptor));
for (const auto &aidlInstance : aidlProviders) {
std::string aidlServiceName =
- getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
+ getFullAidlProviderName(toStdString(aidlInstance));
auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
if (res != OK) {
ALOGE("%s Unable to register for notifications with AIDL service manager",
@@ -774,14 +775,14 @@
primaryMap = &mCameraProviderByCameraId;
alternateMap = &mTorchProviderByCameraId;
}
- auto id = cameraId.c_str();
- (*primaryMap)[id] = provider;
- auto search = alternateMap->find(id);
+
+ (*primaryMap)[cameraId] = provider;
+ auto search = alternateMap->find(cameraId);
if (search != alternateMap->end()) {
ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
- "That should not be possible", __FUNCTION__, id);
+ "That should not be possible", __FUNCTION__, cameraId.c_str());
}
- ALOGV("%s: Camera device %s connected", __FUNCTION__, id);
+ ALOGV("%s: Camera device %s connected", __FUNCTION__, cameraId.c_str());
}
void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
@@ -796,7 +797,7 @@
providerMap = &mCameraProviderByCameraId;
}
std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
- auto search = providerMap->find(cameraId.c_str());
+ auto search = providerMap->find(cameraId);
if (search != providerMap->end()) {
// Drop the reference to this ICameraProvider. This is safe to do immediately (without an
// added delay) because hwservicemanager guarantees to hold the reference for at least five
@@ -805,7 +806,7 @@
// restart it. An example when this could happen is switching from a front-facing to a
// rear-facing camera. If the HAL were to exit during the camera switch, the camera could
// appear janky to the user.
- providerMap->erase(cameraId.c_str());
+ providerMap->erase(cameraId);
IPCThreadState::self()->flushCommands();
} else {
ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
@@ -823,7 +824,7 @@
{
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- res = addAidlProviderLocked(String8(name).c_str());
+ res = addAidlProviderLocked(toStdString(name));
}
sp<StatusListener> listener = getStatusListener();
@@ -2035,14 +2036,14 @@
status_t CameraProviderManager::removeProvider(const std::string& provider) {
std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
std::unique_lock<std::mutex> lock(mInterfaceMutex);
- std::vector<String8> removedDeviceIds;
+ std::vector<std::string> removedDeviceIds;
status_t res = NAME_NOT_FOUND;
std::string removedProviderName;
for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
if ((*it)->mProviderInstance == provider) {
removedDeviceIds.reserve((*it)->mDevices.size());
for (auto& deviceInfo : (*it)->mDevices) {
- removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
+ removedDeviceIds.push_back(deviceInfo->mId);
}
removedProviderName = (*it)->mProviderName;
mProviders.erase(it);
@@ -2182,7 +2183,7 @@
return OK;
}
-void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
+void CameraProviderManager::ProviderInfo::removeDevice(const std::string &id) {
for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
if ((*it)->mId == id) {
mUniqueCameraIds.erase(id);
@@ -2222,8 +2223,7 @@
ALOGV("%s: notify device not_present: %s",
__FUNCTION__,
deviceName.c_str());
- listener->onDeviceStatusChanged(String8(id.c_str()),
- CameraDeviceStatus::NOT_PRESENT);
+ listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
mLock.lock();
}
}
@@ -2324,8 +2324,7 @@
CameraDeviceStatus internalNewStatus = newStatus;
if (!mInitialized) {
mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
- cameraDeviceName.c_str(), std::string().c_str(),
- internalNewStatus);
+ cameraDeviceName, std::string(), internalNewStatus);
return;
}
@@ -2339,7 +2338,7 @@
// Call without lock held to allow reentrancy into provider manager
if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
+ listener->onDeviceStatusChanged(id, internalNewStatus);
}
}
@@ -2415,8 +2414,7 @@
}
// Call without lock held to allow reentrancy into provider manager
if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()),
- String8(physicalId.c_str()), newStatus);
+ listener->onDeviceStatusChanged(id, physicalId, newStatus);
}
return;
}
@@ -2467,7 +2465,7 @@
}
*id = cameraId;
- *physicalId = physicalCameraDeviceName.c_str();
+ *physicalId = physicalCameraDeviceName;
return OK;
}
@@ -2511,7 +2509,7 @@
// findDeviceInfo, which should be holding mLock while iterating through
// each provider's devices).
if (listener != nullptr) {
- listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
+ listener->onTorchStatusChanged(id, newStatus, systemCameraKind);
}
return;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index e6e4619..a2ec576 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -179,15 +179,15 @@
struct StatusListener : virtual public RefBase {
~StatusListener() {}
- virtual void onDeviceStatusChanged(const String8 &cameraId,
+ virtual void onDeviceStatusChanged(const std::string &cameraId,
CameraDeviceStatus newStatus) = 0;
- virtual void onDeviceStatusChanged(const String8 &cameraId,
- const String8 &physicalCameraId,
+ virtual void onDeviceStatusChanged(const std::string &cameraId,
+ const std::string &physicalCameraId,
CameraDeviceStatus newStatus) = 0;
- virtual void onTorchStatusChanged(const String8 &cameraId,
+ virtual void onTorchStatusChanged(const std::string &cameraId,
TorchModeStatus newStatus,
SystemCameraKind kind) = 0;
- virtual void onTorchStatusChanged(const String8 &cameraId,
+ virtual void onTorchStatusChanged(const std::string &cameraId,
TorchModeStatus newStatus) = 0;
virtual void onNewProviderRegistered() = 0;
};
@@ -784,7 +784,7 @@
void torchModeStatusChangeInternal(const std::string& cameraDeviceName,
TorchModeStatus newStatus);
- void removeDevice(std::string id);
+ void removeDevice(const std::string &id);
};
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index e259379..2322def 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -21,6 +21,7 @@
#include <map>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "common/FrameProducer.h"
#include "common/FrameProcessorBase.h"
@@ -86,8 +87,8 @@
}
void FrameProcessorBase::dump(int fd, const Vector<String16>& /*args*/) {
- String8 result(" Latest received frame:\n");
- write(fd, result.string(), result.size());
+ std::string result(" Latest received frame:\n");
+ write(fd, result.c_str(), result.size());
CameraMetadata lastFrame;
std::map<std::string, CameraMetadata> lastPhysicalFrames;
@@ -97,16 +98,16 @@
lastFrame = CameraMetadata(mLastFrame);
for (const auto& physicalFrame : mLastPhysicalFrames) {
- lastPhysicalFrames.emplace(String8(physicalFrame.mPhysicalCameraId),
+ lastPhysicalFrames.emplace(physicalFrame.mPhysicalCameraId,
physicalFrame.mPhysicalCameraMetadata);
}
}
lastFrame.dump(fd, /*verbosity*/2, /*indentation*/6);
for (const auto& physicalFrame : lastPhysicalFrames) {
- result = String8::format(" Latest received frame for physical camera %s:\n",
+ result = fmt::sprintf(" Latest received frame for physical camera %s:\n",
physicalFrame.first.c_str());
- write(fd, result.string(), result.size());
+ write(fd, result.c_str(), result.size());
CameraMetadata lastPhysicalMetadata = CameraMetadata(physicalFrame.second);
lastPhysicalMetadata.sort();
lastPhysicalMetadata.dump(fd, /*verbosity*/2, /*indentation*/6);
@@ -138,7 +139,7 @@
ATRACE_CALL();
CaptureResult result;
- ALOGV("%s: Camera %s: Process new frames", __FUNCTION__, device->getId().string());
+ ALOGV("%s: Camera %s: Process new frames", __FUNCTION__, device->getId().c_str());
while ( (res = device->getNextResult(&result)) == OK) {
@@ -149,7 +150,7 @@
entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
if (entry.count == 0) {
ALOGE("%s: Camera %s: Error reading frame number",
- __FUNCTION__, device->getId().string());
+ __FUNCTION__, device->getId().c_str());
break;
}
ATRACE_INT("cam2_frame", entry.data.i32[0]);
@@ -167,7 +168,7 @@
}
if (res != NOT_ENOUGH_DATA) {
ALOGE("%s: Camera %s: Error getting next frame: %s (%d)",
- __FUNCTION__, device->getId().string(), strerror(-res), res);
+ __FUNCTION__, device->getId().c_str(), strerror(-res), res);
return;
}
@@ -177,7 +178,7 @@
bool FrameProcessorBase::processSingleFrame(CaptureResult &result,
const sp<FrameProducer> &device) {
ALOGV("%s: Camera %s: Process single frame (is empty? %d)",
- __FUNCTION__, device->getId().string(), result.mMetadata.isEmpty());
+ __FUNCTION__, device->getId().c_str(), result.mMetadata.isEmpty());
return processListeners(result, device) == OK;
}
@@ -197,7 +198,7 @@
// include CaptureResultExtras.
entry = result.mMetadata.find(ANDROID_REQUEST_ID);
if (entry.count == 0) {
- ALOGE("%s: Camera %s: Error reading frame id", __FUNCTION__, device->getId().string());
+ ALOGE("%s: Camera %s: Error reading frame id", __FUNCTION__, device->getId().c_str());
return BAD_VALUE;
}
int32_t requestId = entry.data.i32[0];
@@ -223,7 +224,7 @@
}
}
ALOGV("%s: Camera %s: Got %zu range listeners out of %zu", __FUNCTION__,
- device->getId().string(), listeners.size(), mRangeListeners.size());
+ device->getId().c_str(), listeners.size(), mRangeListeners.size());
List<sp<FilteredListener> >::iterator item = listeners.begin();
for (; item != listeners.end(); item++) {
diff --git a/services/camera/libcameraservice/common/FrameProducer.h b/services/camera/libcameraservice/common/FrameProducer.h
index a14b3d6..dd4df7d 100644
--- a/services/camera/libcameraservice/common/FrameProducer.h
+++ b/services/camera/libcameraservice/common/FrameProducer.h
@@ -18,7 +18,6 @@
#define ANDROID_SERVERS_CAMERA_FRAMEPRODUCER_H
#include <utils/RefBase.h>
-#include <utils/String8.h>
#include <utils/Timers.h>
#include "camera/CameraMetadata.h"
@@ -39,7 +38,7 @@
/**
* Retrieve the device camera ID
*/
- virtual const String8& getId() const = 0;
+ virtual const std::string& getId() const = 0;
/**
* Wait for a new frame to be produced, with timeout in nanoseconds.
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index b18cbd4..5e79d6b 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -431,7 +431,7 @@
for (const auto& combination : combs) {
std::unordered_set<std::string> deviceIds;
for (const auto &cameraDeviceId : combination.combination) {
- deviceIds.insert(cameraDeviceId.c_str());
+ deviceIds.insert(cameraDeviceId);
}
mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
}
@@ -735,7 +735,7 @@
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
- String8(mId.c_str()), mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
+ mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
if (!bRes.isOk()) {
@@ -789,9 +789,9 @@
return res;
}
camera3::metadataGetter getMetadata =
- [this](const String8 &id, bool overrideForPerfClass) {
+ [this](const std::string &id, bool overrideForPerfClass) {
CameraMetadata physicalDeviceInfo;
- mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+ mManager->getCameraCharacteristicsLocked(id, overrideForPerfClass,
&physicalDeviceInfo,
/*overrideToPortrait*/false);
return physicalDeviceInfo;
@@ -801,7 +801,7 @@
bStatus =
SessionConfigurationUtils::convertToHALStreamCombination(
cameraIdAndSessionConfig.mSessionConfiguration,
- String8(cameraId.c_str()), deviceInfo,
+ cameraId, deviceInfo,
mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
physicalCameraIds, streamConfiguration,
overrideForPerfClass, &shouldExit);
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index 8ff5c3f..bf7a471 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -533,7 +533,7 @@
for (auto& combination : cameraDeviceIdCombinations) {
std::unordered_set<std::string> deviceIds;
for (auto &cameraDeviceId : combination) {
- deviceIds.insert(cameraDeviceId.c_str());
+ deviceIds.insert(cameraDeviceId);
}
mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
}
@@ -837,7 +837,7 @@
hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
bool earlyExit = false;
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
- String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
+ mId, mCameraCharacteristics, getMetadata, mPhysicalIds,
configuration_3_7, overrideForPerfClass, &earlyExit);
if (!bRes.isOk()) {
@@ -927,9 +927,9 @@
return res;
}
camera3::metadataGetter getMetadata =
- [this](const String8 &id, bool overrideForPerfClass) {
+ [this](const std::string &id, bool overrideForPerfClass) {
CameraMetadata physicalDeviceInfo;
- mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+ mManager->getCameraCharacteristicsLocked(id, overrideForPerfClass,
&physicalDeviceInfo, /*overrideToPortrait*/false);
return physicalDeviceInfo;
};
@@ -938,7 +938,7 @@
bStatus =
SessionConfigurationUtils::convertToHALStreamCombination(
cameraIdAndSessionConfig.mSessionConfiguration,
- String8(cameraId.c_str()), deviceInfo, getMetadata,
+ cameraId, deviceInfo, getMetadata,
physicalCameraIds, streamConfiguration,
overrideForPerfClass, &shouldExit);
if (!bStatus.isOk()) {
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 2ac38d5..c42e51a 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -18,10 +18,13 @@
#define LOG_TAG "Camera3-BufferManager"
#define ATRACE_TAG ATRACE_TAG_CAMERA
+#include <sstream>
+
#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "utils/CameraTraces.h"
#include "Camera3BufferManager.h"
@@ -454,34 +457,36 @@
void Camera3BufferManager::dump(int fd, [[maybe_unused]] const Vector<String16>& args) const {
Mutex::Autolock l(mLock);
- String8 lines;
- lines.appendFormat(" Total stream sets: %zu\n", mStreamSetMap.size());
+ std::ostringstream lines;
+ lines << fmt::sprintf(" Total stream sets: %zu\n", mStreamSetMap.size());
for (size_t i = 0; i < mStreamSetMap.size(); i++) {
- lines.appendFormat(" Stream set %d(%d) has below streams:\n",
+ lines << fmt::sprintf(" Stream set %d(%d) has below streams:\n",
mStreamSetMap.keyAt(i).id, mStreamSetMap.keyAt(i).isMultiRes);
for (size_t j = 0; j < mStreamSetMap[i].streamInfoMap.size(); j++) {
- lines.appendFormat(" Stream %d\n", mStreamSetMap[i].streamInfoMap[j].streamId);
+ lines << fmt::sprintf(" Stream %d\n",
+ mStreamSetMap[i].streamInfoMap[j].streamId);
}
- lines.appendFormat(" Stream set max allowed buffer count: %zu\n",
+ lines << fmt::sprintf(" Stream set max allowed buffer count: %zu\n",
mStreamSetMap[i].maxAllowedBufferCount);
- lines.appendFormat(" Stream set buffer count water mark: %zu\n",
+ lines << fmt::sprintf(" Stream set buffer count water mark: %zu\n",
mStreamSetMap[i].allocatedBufferWaterMark);
- lines.appendFormat(" Handout buffer counts:\n");
+ lines << " Handout buffer counts:\n";
for (size_t m = 0; m < mStreamSetMap[i].handoutBufferCountMap.size(); m++) {
int streamId = mStreamSetMap[i].handoutBufferCountMap.keyAt(m);
size_t bufferCount = mStreamSetMap[i].handoutBufferCountMap.valueAt(m);
- lines.appendFormat(" stream id: %d, buffer count: %zu.\n",
+ lines << fmt::sprintf(" stream id: %d, buffer count: %zu.\n",
streamId, bufferCount);
}
- lines.appendFormat(" Attached buffer counts:\n");
+ lines << " Attached buffer counts:\n";
for (size_t m = 0; m < mStreamSetMap[i].attachedBufferCountMap.size(); m++) {
int streamId = mStreamSetMap[i].attachedBufferCountMap.keyAt(m);
size_t bufferCount = mStreamSetMap[i].attachedBufferCountMap.valueAt(m);
- lines.appendFormat(" stream id: %d, attached buffer count: %zu.\n",
+ lines << fmt::sprintf(" stream id: %d, attached buffer count: %zu.\n",
streamId, bufferCount);
}
}
- write(fd, lines.string(), lines.size());
+ std::string linesStr = std::move(lines.str());
+ write(fd, linesStr.c_str(), linesStr.size());
}
bool Camera3BufferManager::checkIfStreamRegisteredLocked(int streamId,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 61c3298..52ba782 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -26,10 +26,10 @@
#endif
// Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
##__VA_ARGS__)
-#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
##__VA_ARGS__)
// Convenience macros for transitioning to the error state
@@ -44,10 +44,12 @@
#include <utility>
+#include <android-base/stringprintf.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
#include <cutils/properties.h>
+#include <camera/StringUtils.h>
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -60,9 +62,9 @@
#include "device3/Camera3InputStream.h"
#include "device3/Camera3OutputStream.h"
#include "device3/Camera3SharedOutputStream.h"
-#include "mediautils/SchedulingPolicyService.h"
#include "utils/CameraThreadState.h"
#include "utils/CameraTraces.h"
+#include "utils/SchedulingPolicyUtils.h"
#include "utils/SessionConfigurationUtils.h"
#include "utils/TraceHFR.h"
@@ -75,7 +77,8 @@
namespace android {
Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8 &id, bool overrideForPerfClass, bool overrideToPortrait, bool legacyClient):
+ const std::string &id, bool overrideForPerfClass, bool overrideToPortrait,
+ bool legacyClient):
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mId(id),
mLegacyClient(legacyClient),
@@ -107,17 +110,17 @@
mActivePhysicalId("")
{
ATRACE_CALL();
- ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.c_str());
}
Camera3Device::~Camera3Device()
{
ATRACE_CALL();
- ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.c_str());
disconnectImpl();
}
-const String8& Camera3Device::getId() const {
+const std::string& Camera3Device::getId() const {
return mId;
}
@@ -125,7 +128,7 @@
/** Start up status tracker thread */
mStatusTracker = new StatusTracker(this);
- status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
+ status_t res = mStatusTracker->run((std::string("C3Dev-") + mId + "-Status").c_str());
if (res != OK) {
SET_ERR_L("Unable to start status tracking thread: %s (%d)",
strerror(-res), res);
@@ -188,7 +191,7 @@
this, mStatusTracker, mInterface, sessionParamKeys,
mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait,
mSupportZoomOverride);
- res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
+ res = mRequestThread->run((std::string("C3Dev-") + mId + "-ReqQueue").c_str());
if (res != OK) {
SET_ERR_L("Unable to start request queue thread: %s (%d)",
strerror(-res), res);
@@ -225,23 +228,23 @@
bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
if (usePrecorrectArray) {
- res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
+ res = mDistortionMappers[mId].setupStaticInfo(mDeviceInfo);
if (res != OK) {
SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
return res;
}
}
- mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
+ mZoomRatioMappers[mId] = ZoomRatioMapper(&mDeviceInfo,
mSupportNativeZoomRatio, usePrecorrectArray);
if (SessionConfigurationUtils::supportsUltraHighResolutionCapture(mDeviceInfo)) {
- mUHRCropAndMeteringRegionMappers[mId.c_str()] =
+ mUHRCropAndMeteringRegionMappers[mId] =
UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray);
}
if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
- mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
+ mRotateAndCropMappers.emplace(mId, &mDeviceInfo);
}
// Hidl/AidlCamera3DeviceInjectionMethods
@@ -428,7 +431,7 @@
/*isUltraHighResolution*/true);
if (maxDefaultJpegResolution.width == 0) {
ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
- __FUNCTION__, mId.string());
+ __FUNCTION__, mId.c_str());
return BAD_VALUE;
}
bool useMaxSensorPixelModeThreshold = false;
@@ -443,7 +446,7 @@
camera_metadata_ro_entry jpegBufMaxSize = info.find(ANDROID_JPEG_MAX_SIZE);
if (jpegBufMaxSize.count == 0) {
ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
- mId.string());
+ mId.c_str());
return BAD_VALUE;
}
maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
@@ -475,7 +478,7 @@
camera_metadata_ro_entry maxPointCount = info.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
if (maxPointCount.count == 0) {
ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
- __FUNCTION__, mId.string());
+ __FUNCTION__, mId.c_str());
return BAD_VALUE;
}
ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
@@ -497,7 +500,7 @@
size_t count = rawOpaqueSizes.count;
if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
- __FUNCTION__, mId.string(), count);
+ __FUNCTION__, mId.c_str(), count);
return BAD_VALUE;
}
@@ -509,7 +512,7 @@
}
ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
- __FUNCTION__, mId.string(), width, height);
+ __FUNCTION__, mId.c_str(), width, height);
return BAD_VALUE;
}
@@ -523,10 +526,10 @@
ALOGW_IF(!gotInterfaceLock,
"Camera %s: %s: Unable to lock interface lock, proceeding anyway",
- mId.string(), __FUNCTION__);
+ mId.c_str(), __FUNCTION__);
ALOGW_IF(!gotLock,
"Camera %s: %s: Unable to lock main lock, proceeding anyway",
- mId.string(), __FUNCTION__);
+ mId.c_str(), __FUNCTION__);
bool dumpTemplates = false;
@@ -536,9 +539,9 @@
if (args[i] == templatesOption) {
dumpTemplates = true;
}
- if (args[i] == TagMonitor::kMonitorOption) {
+ if (args[i] == toString16(TagMonitor::kMonitorOption)) {
if (i + 1 < n) {
- String8 monitorTags = String8(args[i + 1]);
+ std::string monitorTags = toStdString(args[i + 1]);
if (monitorTags == "off") {
mTagMonitor.disableMonitoring();
} else {
@@ -550,7 +553,7 @@
}
}
- String8 lines;
+ std::string lines;
const char *status =
mStatus == STATUS_ERROR ? "ERROR" :
@@ -560,42 +563,42 @@
mStatus == STATUS_ACTIVE ? "ACTIVE" :
"Unknown";
- lines.appendFormat(" Device status: %s\n", status);
+ lines += fmt::sprintf(" Device status: %s\n", status);
if (mStatus == STATUS_ERROR) {
- lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
+ lines += fmt::sprintf(" Error cause: %s\n", mErrorCause.c_str());
}
- lines.appendFormat(" Stream configuration:\n");
+ lines += " Stream configuration:\n";
const char *mode =
mOperatingMode == CAMERA_STREAM_CONFIGURATION_NORMAL_MODE ? "NORMAL" :
mOperatingMode == CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE ?
"CONSTRAINED_HIGH_SPEED" : "CUSTOM";
- lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
+ lines += fmt::sprintf(" Operation mode: %s (%d) \n", mode, mOperatingMode);
if (mInputStream != NULL) {
- write(fd, lines.string(), lines.size());
+ write(fd, lines.c_str(), lines.size());
mInputStream->dump(fd, args);
} else {
- lines.appendFormat(" No input stream.\n");
- write(fd, lines.string(), lines.size());
+ lines += " No input stream.\n";
+ write(fd, lines.c_str(), lines.size());
}
for (size_t i = 0; i < mOutputStreams.size(); i++) {
mOutputStreams[i]->dump(fd,args);
}
if (mBufferManager != NULL) {
- lines = String8(" Camera3 Buffer Manager:\n");
- write(fd, lines.string(), lines.size());
+ lines = " Camera3 Buffer Manager:\n";
+ write(fd, lines.c_str(), lines.size());
mBufferManager->dump(fd, args);
}
- lines = String8(" In-flight requests:\n");
+ lines = " In-flight requests:\n";
if (mInFlightLock.try_lock()) {
if (mInFlightMap.size() == 0) {
- lines.append(" None\n");
+ lines += " None\n";
} else {
for (size_t i = 0; i < mInFlightMap.size(); i++) {
InFlightRequest r = mInFlightMap.valueAt(i);
- lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
+ lines += fmt::sprintf(" Frame %d | Timestamp: %" PRId64 ", metadata"
" arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
r.numBuffersLeft);
@@ -603,9 +606,9 @@
}
mInFlightLock.unlock();
} else {
- lines.append(" Failed to acquire In-flight lock!\n");
+ lines += " Failed to acquire In-flight lock!\n";
}
- write(fd, lines.string(), lines.size());
+ write(fd, lines.c_str(), lines.size());
if (mRequestThread != NULL) {
mRequestThread->dumpCaptureRequestLatency(fd,
@@ -613,8 +616,8 @@
}
{
- lines = String8(" Last request sent:\n");
- write(fd, lines.string(), lines.size());
+ lines = " Last request sent:\n";
+ write(fd, lines.c_str(), lines.size());
CameraMetadata lastRequest = getLatestRequestLocked();
lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
@@ -634,12 +637,12 @@
camera_metadata_t *templateRequest = nullptr;
mInterface->constructDefaultRequestSettings(
(camera_request_template_t) i, &templateRequest);
- lines = String8::format(" HAL Request %s:\n", templateNames[i-1]);
+ lines = fmt::sprintf(" HAL Request %s:\n", templateNames[i-1]);
if (templateRequest == nullptr) {
- lines.append(" Not supported\n");
- write(fd, lines.string(), lines.size());
+ lines += " Not supported\n";
+ write(fd, lines.c_str(), lines.size());
} else {
- write(fd, lines.string(), lines.size());
+ write(fd, lines.c_str(), lines.size());
dump_indented_camera_metadata(templateRequest,
fd, /*verbosity*/2, /*indentation*/8);
}
@@ -650,8 +653,8 @@
mTagMonitor.dumpMonitoredMetadata(fd);
if (mInterface->valid()) {
- lines = String8(" HAL device dump:\n");
- write(fd, lines.string(), lines.size());
+ lines = " HAL device dump:\n";
+ write(fd, lines.c_str(), lines.size());
mInterface->dump(fd);
}
@@ -661,7 +664,7 @@
return OK;
}
-status_t Camera3Device::startWatchingTags(const String8 &tags) {
+status_t Camera3Device::startWatchingTags(const std::string &tags) {
mTagMonitor.parseTagsToMonitor(tags);
return OK;
}
@@ -676,7 +679,7 @@
return OK;
}
-const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
+const CameraMetadata& Camera3Device::infoPhysical(const std::string& physicalId) const {
ALOGVV("%s: E", __FUNCTION__);
if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
mStatus == STATUS_ERROR)) {
@@ -684,12 +687,11 @@
mStatus == STATUS_ERROR ?
"when in error state" : "before init");
}
- if (physicalId.isEmpty()) {
+ if (physicalId.empty()) {
return mDeviceInfo;
} else {
- std::string id(physicalId.c_str());
- if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
- return mPhysicalDeviceInfoMap.at(id);
+ if (mPhysicalDeviceInfoMap.find(physicalId) != mPhysicalDeviceInfoMap.end()) {
+ return mPhysicalDeviceInfoMap.at(physicalId);
} else {
ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
return mDeviceInfo;
@@ -698,8 +700,7 @@
}
const CameraMetadata& Camera3Device::info() const {
- String8 emptyId;
- return infoPhysical(emptyId);
+ return infoPhysical(/*physicalId*/ std::string());
}
status_t Camera3Device::checkStatusOkToCaptureLocked() {
@@ -793,7 +794,7 @@
std::list<const SurfaceMap>& surfaceMaps,
const CameraMetadata& request) {
PhysicalCameraSettingsList requestList;
- requestList.push_back({std::string(getId().string()), request});
+ requestList.push_back({getId(), request});
requestsList.push_back(requestList);
SurfaceMap surfaceMap;
@@ -845,7 +846,7 @@
SET_ERR_L("Can't transition to active in %f seconds!",
kActiveTimeout/1e9);
}
- ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
+ ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.c_str(),
(*(requestList.begin()))->mResultExtras.requestId);
} else {
CLOGE("Cannot queue request. Impossible.");
@@ -928,7 +929,7 @@
SET_ERR_L("Unexpected status: %d", mStatus);
return INVALID_OPERATION;
}
- ALOGV("Camera %s: Clearing repeating request", mId.string());
+ ALOGV("Camera %s: Clearing repeating request", mId.c_str());
return mRequestThread->clearRepeatingRequests(lastFrameNumber);
}
@@ -947,7 +948,7 @@
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
- mId.string(), mNextStreamId, width, height, format);
+ mId.c_str(), mNextStreamId, width, height, format);
status_t res;
bool wasActive = false;
@@ -1006,14 +1007,14 @@
internalResumeLocked();
}
- ALOGV("Camera %s: Created input stream", mId.string());
+ ALOGV("Camera %s: Created input stream", mId.c_str());
return OK;
}
status_t Camera3Device::createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
@@ -1049,7 +1050,8 @@
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
+ const std::string& physicalCameraId,
+ const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
int timestampBase, int mirrorMode, int32_t colorSpace, bool useReadoutTimestamp) {
@@ -1062,8 +1064,8 @@
" consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d"
" dynamicRangeProfile 0x%" PRIx64 ", streamUseCase %" PRId64 ", timestampBase %d,"
" mirrorMode %d, colorSpace %d, useReadoutTimestamp %d",
- mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
- consumerUsage, isShared, physicalCameraId.string(), isMultiResolution,
+ mId.c_str(), mNextStreamId, width, height, format, dataSpace, rotation,
+ consumerUsage, isShared, physicalCameraId.c_str(), isMultiResolution,
dynamicRangeProfile, streamUseCase, timestampBase, mirrorMode, colorSpace,
useReadoutTimestamp);
@@ -1214,7 +1216,7 @@
}
internalResumeLocked();
}
- ALOGV("Camera %s: Created new stream", mId.string());
+ ALOGV("Camera %s: Created new stream", mId.c_str());
return OK;
}
@@ -1299,18 +1301,18 @@
Mutex::Autolock l(mLock);
status_t res;
- ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
+ ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.c_str(), id);
// CameraDevice semantics require device to already be idle before
// deleteStream is called, unlike for createStream.
if (mStatus == STATUS_ACTIVE) {
- ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
+ ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.c_str());
return -EBUSY;
}
if (mStatus == STATUS_ERROR) {
ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
- __FUNCTION__, mId.string());
+ __FUNCTION__, mId.c_str());
return -EBUSY;
}
@@ -1502,7 +1504,7 @@
mRequestTemplateCache[templateId].acquire(rawRequest);
// Override the template request with zoomRatioMapper
- res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
+ res = mZoomRatioMappers[mId].initZoomRatioInTemplate(
&mRequestTemplateCache[templateId]);
if (res != OK) {
CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
@@ -1555,7 +1557,7 @@
SET_ERR_L("Unexpected status: %d",mStatus);
return INVALID_OPERATION;
}
- ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
+ ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.c_str(),
maxExpectedDuration);
status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
/*requestThreadInvocation*/ false);
@@ -1583,7 +1585,7 @@
return NO_INIT;
}
- ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
+ ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.c_str(),
maxExpectedDuration);
status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
requestThreadInvocation);
@@ -1602,7 +1604,7 @@
mRequestThread->setPaused(false);
- ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
+ ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.c_str(),
kActiveTimeout);
// internalResumeLocked is always called from a binder thread.
res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout,
@@ -1819,7 +1821,7 @@
status_t Camera3Device::flush(int64_t *frameNumber) {
ATRACE_CALL();
- ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
+ ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.c_str());
Mutex::Autolock il(mInterfaceLock);
{
@@ -1851,7 +1853,7 @@
status_t Camera3Device::prepare(int maxCount, int streamId) {
ATRACE_CALL();
- ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
+ ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.c_str(), streamId);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -1876,7 +1878,7 @@
status_t Camera3Device::tearDown(int streamId) {
ATRACE_CALL();
- ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
+ ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.c_str(), streamId);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -1897,7 +1899,8 @@
status_t Camera3Device::addBufferListenerForStream(int streamId,
wp<Camera3StreamBufferListener> listener) {
ATRACE_CALL();
- ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
+ ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.c_str(),
+ streamId);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -1945,7 +1948,7 @@
if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
return;
}
- ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
+ ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.c_str(),
idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
@@ -2026,7 +2029,7 @@
const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
ATRACE_CALL();
ALOGV("%s: Camera %s: set consumer surface for stream %d",
- __FUNCTION__, mId.string(), streamId);
+ __FUNCTION__, mId.c_str(), streamId);
if (surfaceIds == nullptr) {
return BAD_VALUE;
@@ -2306,7 +2309,7 @@
res = mPreparerThread->resume();
if (res != OK) {
- ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
+ ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.c_str());
}
}
@@ -2466,7 +2469,7 @@
overrideStreamUseCaseLocked();
// Start configuring the streams
- ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
+ ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.c_str());
mPreparerThread->pause();
@@ -2522,7 +2525,7 @@
static_cast<android_dataspace_t>(
aidl::android::hardware::graphics::common::Dataspace::JPEG_R))) {
bufferSizes[k] = static_cast<uint32_t>(
- getJpegBufferSize(infoPhysical(String8(outputStream->physical_camera_id)),
+ getJpegBufferSize(infoPhysical(outputStream->physical_camera_id),
outputStream->width, outputStream->height));
} else if (outputStream->data_space ==
static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
@@ -2535,7 +2538,7 @@
if (mOutputStreams[i]->isMultiResolution()) {
int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
- const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
+ const std::string &physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
}
@@ -2625,8 +2628,8 @@
if (disableFifo != 1) {
// Boost priority of request thread to SCHED_FIFO.
pid_t requestThreadTid = mRequestThread->getTid();
- res = requestPriority(getpid(), requestThreadTid,
- kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
+ res = SchedulingPolicyUtils::requestPriorityDirect(getpid(), requestThreadTid,
+ kRequestThreadPriority);
if (res != OK) {
ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
strerror(-res), res);
@@ -2650,14 +2653,14 @@
internalUpdateStatusLocked((mFakeStreamId == NO_STREAM) ?
STATUS_CONFIGURED : STATUS_UNCONFIGURED);
- ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
+ ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.c_str());
// tear down the deleted streams after configure streams.
mDeletedStreams.clear();
auto rc = mPreparerThread->resume();
if (rc != OK) {
- SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
+ SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.c_str());
return rc;
}
@@ -2671,7 +2674,7 @@
// configure the injection streams.
if (mInjectionMethods->isInjecting()) {
ALOGD("%s: Injection camera %s: Start to configure streams.",
- __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
+ __FUNCTION__, mInjectionMethods->getInjectedCamId().c_str());
res = mInjectionMethods->injectCamera(config, bufferSizes);
if (res != OK) {
ALOGE("Can't finish inject camera process!");
@@ -2700,11 +2703,11 @@
// Should never be adding a second fake stream when one is already
// active
SET_ERR_L("%s: Camera %s: A fake stream already exists!",
- __FUNCTION__, mId.string());
+ __FUNCTION__, mId.c_str());
return INVALID_OPERATION;
}
- ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.string());
+ ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.c_str());
sp<Camera3OutputStreamInterface> fakeStream =
new Camera3FakeStream(mNextStreamId);
@@ -2728,7 +2731,7 @@
if (mFakeStreamId == NO_STREAM) return OK;
if (mOutputStreams.size() == 1) return OK;
- ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.string());
+ ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.c_str());
// Ok, have a fake stream and there's at least one other output stream,
// so remove the fake
@@ -2780,8 +2783,9 @@
void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
// Print out all error messages to log
- String8 errorCause = String8::formatV(fmt, args);
- ALOGE("Camera %s: %s", mId.string(), errorCause.string());
+ std::string errorCause;
+ base::StringAppendV(&errorCause, fmt, args);
+ ALOGE("Camera %s: %s", mId.c_str(), errorCause.c_str());
// But only do error state transition steps for the first error
if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
@@ -2813,7 +2817,7 @@
status_t Camera3Device::registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool hasAppCallback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
- bool isFixedFps, const std::set<std::set<String8>>& physicalCameraIds,
+ bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
const std::set<std::string>& cameraIdsWithZoom,
const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
@@ -3064,7 +3068,7 @@
void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
const CameraMetadata& sessionParams,
- const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
+ const std::map<int32_t, std::set<std::string>>& groupIdPhysicalCameraMap) {
ATRACE_CALL();
Mutex::Autolock l(mRequestLock);
mReconfigured = true;
@@ -3117,8 +3121,8 @@
return OK;
}
-const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
- static String8 deadId("<DeadDevice>");
+const std::string& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
+ static std::string deadId("<DeadDevice>");
sp<Camera3Device> d = device.promote();
if (d != nullptr) return d->mId;
return deadId;
@@ -3928,7 +3932,7 @@
outputBuffers->insertAt(camera_stream_buffer_t(), 0,
captureRequest->mOutputStreams.size());
halRequest->output_buffers = outputBuffers->array();
- std::set<std::set<String8>> requestedPhysicalCameras;
+ std::set<std::set<std::string>> requestedPhysicalCameras;
sp<Camera3Device> parent = mParent.promote();
if (parent == NULL) {
@@ -4009,11 +4013,11 @@
{
sp<Camera3Device> parent = mParent.promote();
if (parent != nullptr) {
- const String8& streamCameraId = outputStream->getPhysicalCameraId();
+ const std::string& streamCameraId = outputStream->getPhysicalCameraId();
for (const auto& settings : captureRequest->mSettingsList) {
- if ((streamCameraId.isEmpty() &&
- parent->getId() == settings.cameraId.c_str()) ||
- streamCameraId == settings.cameraId.c_str()) {
+ if ((streamCameraId.empty() &&
+ parent->getId() == settings.cameraId) ||
+ streamCameraId == settings.cameraId) {
outputStream->fireBufferRequestForFrameNumber(
captureRequest->mResultExtras.frameNumber,
settings.metadata);
@@ -4022,12 +4026,12 @@
}
}
- String8 physicalCameraId = outputStream->getPhysicalCameraId();
+ const std::string &physicalCameraId = outputStream->getPhysicalCameraId();
int32_t streamGroupId = outputStream->getHalStreamGroupId();
if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
- } else if (!physicalCameraId.isEmpty()) {
- requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
+ } else if (!physicalCameraId.empty()) {
+ requestedPhysicalCameras.insert(std::set<std::string>({physicalCameraId}));
}
halRequest->num_output_buffers++;
}
@@ -5456,9 +5460,9 @@
return mRequestThread->setZoomOverride(zoomOverride);
}
-status_t Camera3Device::injectCamera(const String8& injectedCamId,
+status_t Camera3Device::injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager) {
- ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
+ ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.c_str());
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
// When the camera device is active, injectCamera() and stopInjection() will call
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index b1dd135..0c1bbcb 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -85,7 +85,7 @@
public:
explicit Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+ const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
bool legacyClient = false);
virtual ~Camera3Device();
@@ -101,7 +101,7 @@
* CameraDeviceBase interface
*/
- const String8& getId() const override;
+ const std::string& getId() const override;
metadata_vendor_id_t getVendorTagId() const override { return mVendorTagId; }
@@ -110,15 +110,15 @@
// Transitions to idle state on success.
virtual status_t initialize(sp<CameraProviderManager> /*manager*/,
- const String8& /*monitorTags*/) = 0;
+ const std::string& /*monitorTags*/) = 0;
status_t disconnect() override;
status_t dump(int fd, const Vector<String16> &args) override;
- status_t startWatchingTags(const String8 &tags) override;
+ status_t startWatchingTags(const std::string &tags) override;
status_t stopWatchingTags() override;
status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
const CameraMetadata& info() const override;
- const CameraMetadata& infoPhysical(const String8& physicalId) const override;
+ const CameraMetadata& infoPhysical(const std::string& physicalId) const override;
bool isCompositeJpegRDisabled() const override { return mIsCompositeJpegRDisabled; };
// Capture and setStreamingRequest will configure streams if currently in
@@ -144,7 +144,7 @@
status_t createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -162,7 +162,7 @@
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -330,7 +330,7 @@
* The injection camera session to replace the internal camera
* session.
*/
- status_t injectCamera(const String8& injectedCamId,
+ status_t injectCamera(const std::string& injectedCamId,
sp<CameraProviderManager> manager);
/**
@@ -376,7 +376,7 @@
Mutex mLock;
// Camera device ID
- const String8 mId;
+ const std::string mId;
// Legacy camera client flag
bool mLegacyClient;
@@ -586,14 +586,14 @@
Condition mStatusChanged;
// Tracking cause of fatal errors when in STATUS_ERROR
- String8 mErrorCause;
+ std::string mErrorCause;
camera3::StreamSet mOutputStreams;
sp<camera3::Camera3Stream> mInputStream;
bool mIsInputStreamMultiResolution;
SessionStatsBuilder mSessionStatsBuilder;
// Map from stream group ID to physical cameras backing the stream group
- std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;
+ std::map<int32_t, std::set<std::string>> mGroupIdPhysicalCameraMap;
int mNextStreamId;
bool mNeedConfig;
@@ -709,7 +709,7 @@
*/
virtual CameraMetadata getLatestRequestLocked();
- virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+ virtual status_t injectionCameraInitialize(const std::string &injectCamId,
sp<CameraProviderManager> manager) = 0;
/**
@@ -891,7 +891,7 @@
*/
void configurationComplete(bool isConstrainedHighSpeed,
const CameraMetadata& sessionParams,
- const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap);
+ const std::map<int32_t, std::set<std::string>>& groupIdPhysicalCameraMap);
/**
* Set or clear the list of repeating requests. Does not block
@@ -996,7 +996,7 @@
virtual bool threadLoop();
- static const String8& getId(const wp<Camera3Device> &device);
+ static const std::string& getId(const wp<Camera3Device> &device);
status_t queueTriggerLocked(RequestTrigger trigger);
// Mix-in queued triggers into this request
@@ -1102,7 +1102,7 @@
wp<NotificationListener> mListener;
- const String8 mId; // The camera ID
+ const std::string mId; // The camera ID
int mStatusId; // The RequestThread's component ID for
// status tracking
@@ -1173,7 +1173,7 @@
Vector<int32_t> mSessionParamKeys;
CameraMetadata mLatestSessionParams;
- std::map<int32_t, std::set<String8>> mGroupIdPhysicalCameraMap;
+ std::map<int32_t, std::set<std::string>> mGroupIdPhysicalCameraMap;
const bool mUseHalBufManager;
const bool mSupportCameraMute;
@@ -1209,7 +1209,7 @@
status_t registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool callback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
- bool isFixedFps, const std::set<std::set<String8>>& physicalCameraIds,
+ bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
nsecs_t requestTimeNs);
@@ -1503,7 +1503,7 @@
bool isStreamConfigCompleteButNotInjected();
- const String8& getInjectedCamId() const;
+ const std::string& getInjectedCamId() const;
void getInjectionConfig(/*out*/ camera3::camera_stream_configuration* injectionConfig,
/*out*/ std::vector<uint32_t>* injectionBufferSizes);
@@ -1557,7 +1557,7 @@
Mutex mInjectionLock;
// The injection camera ID.
- String8 mInjectedCamId;
+ std::string mInjectedCamId;
};
virtual sp<Camera3DeviceInjectionMethods>
diff --git a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
index ab772d4..b0e4ca3 100644
--- a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
@@ -157,7 +157,7 @@
return mIsStreamConfigCompleteButNotInjected;
}
-const String8& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
+const std::string& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
const {
return mInjectedCamId;
}
@@ -206,7 +206,7 @@
// Start configuring the streams
ALOGV("%s: Injection camera %s: Starting stream configuration", __FUNCTION__,
- mInjectedCamId.string());
+ mInjectedCamId.c_str());
parent->mPreparerThread->pause();
@@ -249,12 +249,12 @@
parent->internalUpdateStatusLocked(STATUS_CONFIGURED);
ALOGV("%s: Injection camera %s: Stream configuration complete", __FUNCTION__,
- mInjectedCamId.string());
+ mInjectedCamId.c_str());
auto rc = parent->mPreparerThread->resume();
if (rc != OK) {
ALOGE("%s: Injection camera %s: Preparer thread failed to resume!",
- __FUNCTION__, mInjectedCamId.string());
+ __FUNCTION__, mInjectedCamId.c_str());
return rc;
}
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
index 8c0ac71..75162bf 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
@@ -20,13 +20,14 @@
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "Camera3FakeStream.h"
namespace android {
namespace camera3 {
-const String8 Camera3FakeStream::FAKE_ID;
+const std::string Camera3FakeStream::FAKE_ID;
Camera3FakeStream::Camera3FakeStream(int id) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, FAKE_WIDTH, FAKE_HEIGHT,
@@ -68,9 +69,9 @@
}
void Camera3FakeStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
- String8 lines;
- lines.appendFormat(" Stream[%d]: Fake\n", mId);
- write(fd, lines.string(), lines.size());
+ std::string lines;
+ lines += fmt::sprintf(" Stream[%d]: Fake\n", mId);
+ write(fd, lines.c_str(), lines.size());
Camera3IOStreamBase::dump(fd, args);
}
@@ -115,7 +116,7 @@
return OK;
}
-const String8& Camera3FakeStream::getPhysicalCameraId() const {
+const std::string& Camera3FakeStream::getPhysicalCameraId() const {
return FAKE_ID;
}
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.h b/services/camera/libcameraservice/device3/Camera3FakeStream.h
index 1e9f478..1d82190 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.h
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.h
@@ -65,7 +65,7 @@
/**
* Query the physical camera id for the output stream.
*/
- virtual const String8& getPhysicalCameraId() const override;
+ virtual const std::string& getPhysicalCameraId() const override;
/**
* Return if this output stream is for video encoding.
@@ -130,7 +130,7 @@
static const android_dataspace FAKE_DATASPACE = HAL_DATASPACE_UNKNOWN;
static const camera_stream_rotation_t FAKE_ROTATION = CAMERA_STREAM_ROTATION_0;
static const uint64_t FAKE_USAGE = GRALLOC_USAGE_HW_COMPOSER;
- static const String8 FAKE_ID;
+ static const std::string FAKE_ID;
/**
* Internal Camera3Stream interface
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index fbaaf7b..c59138c 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -18,10 +18,13 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <sstream>
+
#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "device3/Camera3IOStreamBase.h"
#include "device3/StatusTracker.h"
@@ -32,7 +35,7 @@
Camera3IOStreamBase::Camera3IOStreamBase(int id, camera_stream_type_t type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile, int64_t streamUseCase,
bool deviceTimeBaseIsRealtime, int timestampBase, int32_t colorSpace) :
@@ -75,32 +78,34 @@
}
void Camera3IOStreamBase::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
- String8 lines;
+ std::ostringstream lines;
uint64_t consumerUsage = 0;
status_t res = getEndpointUsage(&consumerUsage);
if (res != OK) consumerUsage = 0;
- lines.appendFormat(" State: %d\n", mState);
- lines.appendFormat(" Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
+ lines << fmt::sprintf(" State: %d\n", mState);
+ lines << fmt::sprintf(" Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
camera_stream::width, camera_stream::height,
camera_stream::format, camera_stream::data_space);
- lines.appendFormat(" Max size: %zu\n", mMaxSize);
- lines.appendFormat(" Combined usage: 0x%" PRIx64 ", max HAL buffers: %d\n",
+ lines << fmt::sprintf(" Max size: %zu\n", mMaxSize);
+ lines << fmt::sprintf(" Combined usage: 0x%" PRIx64 ", max HAL buffers: %d\n",
mUsage | consumerUsage, camera_stream::max_buffers);
- if (strlen(camera_stream::physical_camera_id) > 0) {
- lines.appendFormat(" Physical camera id: %s\n", camera_stream::physical_camera_id);
+ if (!camera_stream::physical_camera_id.empty()) {
+ lines << " Physical camera id: " << camera_stream::physical_camera_id << "\n";
}
- lines.appendFormat(" Dynamic Range Profile: 0x%" PRIx64 "\n",
+ lines << fmt::sprintf(" Dynamic Range Profile: 0x%" PRIx64 "\n",
camera_stream::dynamic_range_profile);
- lines.appendFormat(" Color Space: %d\n", camera_stream::color_space);
- lines.appendFormat(" Stream use case: %" PRId64 "\n", camera_stream::use_case);
- lines.appendFormat(" Timestamp base: %d\n", getTimestampBase());
- lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
+ lines << fmt::sprintf(" Color Space: %d\n", camera_stream::color_space);
+ lines << fmt::sprintf(" Stream use case: %" PRId64 "\n", camera_stream::use_case);
+ lines << fmt::sprintf(" Timestamp base: %d\n", getTimestampBase());
+ lines << fmt::sprintf(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
mFrameCount, mLastTimestamp);
- lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu, currently cached: %zu\n",
- mTotalBufferCount, mHandoutTotalBufferCount, mCachedOutputBufferCount);
- write(fd, lines.string(), lines.size());
+ lines << fmt::sprintf(" Total buffers: %zu, currently dequeued: %zu, "
+ "currently cached: %zu\n", mTotalBufferCount, mHandoutTotalBufferCount,
+ mCachedOutputBufferCount);
+ std::string linesStr = std::move(lines.str());
+ write(fd, linesStr.c_str(), linesStr.size());
Camera3Stream::dump(fd, args);
}
@@ -268,7 +273,7 @@
// carry on
if (releaseFence != 0) {
- mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
+ mCombinedFence = Fence::merge(toString8(mName), mCombinedFence, releaseFence);
}
if (output) {
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 6af0875..239fc71 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -35,7 +35,7 @@
Camera3IOStreamBase(int id, camera_stream_type_t type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index 631bb43..54ffbd7 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -21,13 +21,14 @@
#include <gui/BufferItem.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "Camera3InputStream.h"
namespace android {
namespace camera3 {
-const String8 Camera3InputStream::FAKE_ID;
+const std::string Camera3InputStream::FAKE_ID;
Camera3InputStream::Camera3InputStream(int id,
uint32_t width, uint32_t height, int format) :
@@ -216,9 +217,9 @@
}
void Camera3InputStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
- String8 lines;
- lines.appendFormat(" Stream[%d]: Input\n", mId);
- write(fd, lines.string(), lines.size());
+ std::string lines;
+ lines += fmt::sprintf(" Stream[%d]: Input\n", mId);
+ write(fd, lines.c_str(), lines.size());
Camera3IOStreamBase::dump(fd, args);
}
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 5e0587b..d4f4b15 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -53,7 +53,7 @@
sp<IGraphicBufferProducer> mProducer;
Vector<BufferItem> mBuffersInFlight;
- static const String8 FAKE_ID;
+ static const std::string FAKE_ID;
/**
* Camera3IOStreamBase
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 1e7bd57..172b62a 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -27,7 +27,9 @@
#include <inttypes.h>
+#include <android-base/stringprintf.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
@@ -42,7 +44,7 @@
namespace android {
-Camera3OfflineSession::Camera3OfflineSession(const String8 &id,
+Camera3OfflineSession::Camera3OfflineSession(const std::string &id,
const sp<camera3::Camera3Stream>& inputStream,
const camera3::StreamSet& offlineStreamSet,
camera3::BufferRecords&& bufferRecords,
@@ -75,15 +77,15 @@
mRotateAndCropMappers(offlineStates.mRotateAndCropMappers),
mStatus(STATUS_UNINITIALIZED) {
ATRACE_CALL();
- ALOGV("%s: Created offline session for camera %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Created offline session for camera %s", __FUNCTION__, mId.c_str());
}
Camera3OfflineSession::~Camera3OfflineSession() {
ATRACE_CALL();
- ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.c_str());
}
-const String8& Camera3OfflineSession::getId() const {
+const std::string& Camera3OfflineSession::getId() const {
return mId;
}
@@ -109,7 +111,7 @@
return OK; // don't close twice
} else if (mStatus == STATUS_ERROR) {
ALOGE("%s: offline session %s shutting down in error state",
- __FUNCTION__, mId.string());
+ __FUNCTION__, mId.c_str());
}
listener = mListener.promote();
}
@@ -217,8 +219,9 @@
void Camera3OfflineSession::setErrorStateLockedV(const char *fmt, va_list args) {
// Print out all error messages to log
- String8 errorCause = String8::formatV(fmt, args);
- ALOGE("Camera %s: %s", mId.string(), errorCause.string());
+ std::string errorCause;
+ base::StringAppendV(&errorCause, fmt, args);
+ ALOGE("Camera %s: %s", mId.c_str(), errorCause.c_str());
// But only do error state transition steps for the first error
if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index e780043..b5fd486 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -20,9 +20,6 @@
#include <memory>
#include <mutex>
-#include <utils/String8.h>
-#include <utils/String16.h>
-
#include <android/hardware/camera/device/3.6/ICameraOfflineSession.h>
#include <fmq/MessageQueue.h>
@@ -138,7 +135,7 @@
public:
// initialize by Camera3Device.
- explicit Camera3OfflineSession(const String8& id,
+ explicit Camera3OfflineSession(const std::string& id,
const sp<camera3::Camera3Stream>& inputStream,
const camera3::StreamSet& offlineStreamSet,
camera3::BufferRecords&& bufferRecords,
@@ -158,7 +155,7 @@
/**
* FrameProducer interface
*/
- const String8& getId() const override;
+ const std::string& getId() const override;
const CameraMetadata& info() const override;
status_t waitForNextFrame(nsecs_t timeout) override;
status_t getNextResult(CaptureResult *frame) override;
@@ -171,7 +168,7 @@
protected:
// Camera device ID
- const String8 mId;
+ const std::string mId;
sp<camera3::Camera3Stream> mInputStream;
camera3::StreamSet mOutputStreams;
camera3::BufferRecords mBufferRecords;
@@ -236,7 +233,7 @@
std::mutex mProcessCaptureResultLock;
// Tracking cause of fatal errors when in STATUS_ERROR
- String8 mErrorCause;
+ std::string mErrorCause;
// Lock to ensure requestStreamBuffers() callbacks are serialized
std::mutex mRequestBufferInterfaceLock;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index aaf5d8d..f98636b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -31,6 +31,7 @@
#include <ui/GraphicBuffer.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include <common/CameraDeviceBase.h>
#include "api1/client2/JpegProcessor.h"
@@ -53,7 +54,7 @@
sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId,
+ nsecs_t timestampOffset, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -88,7 +89,7 @@
sp<Surface> consumer,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId,
+ nsecs_t timestampOffset, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -128,7 +129,7 @@
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -164,7 +165,7 @@
mState = STATE_ERROR;
}
- mConsumerName = String8("Deferred");
+ mConsumerName = "Deferred";
bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
}
@@ -174,7 +175,7 @@
int format,
android_dataspace dataSpace,
camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
IPCTransport transport,
uint64_t consumerUsage, nsecs_t timestampOffset,
@@ -523,10 +524,10 @@
}
void Camera3OutputStream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const {
- String8 lines;
- lines.appendFormat(" Stream[%d]: Output\n", mId);
- lines.appendFormat(" Consumer name: %s\n", mConsumerName.string());
- write(fd, lines.string(), lines.size());
+ std::string lines;
+ lines += fmt::sprintf(" Stream[%d]: Output\n", mId);
+ lines += fmt::sprintf(" Consumer name: %s\n", mConsumerName);
+ write(fd, lines.c_str(), lines.size());
Camera3IOStreamBase::dump(fd, args);
@@ -710,7 +711,8 @@
// service. So update mMaxCachedBufferCount.
mMaxCachedBufferCount = 1;
mTotalBufferCount += mMaxCachedBufferCount;
- res = mPreviewFrameSpacer->run(String8::format("PreviewSpacer-%d", mId).string());
+ res = mPreviewFrameSpacer->run((std::string("PreviewSpacer-")
+ + std::to_string(mId)).c_str());
if (res != OK) {
ALOGE("%s: Unable to start preview spacer: %s (%d)", __FUNCTION__,
strerror(-res), res);
@@ -1234,7 +1236,7 @@
return OK;
}
-const String8& Camera3OutputStream::getPhysicalCameraId() const {
+const std::string& Camera3OutputStream::getPhysicalCameraId() const {
Mutex::Autolock l(mLock);
return physicalCameraId();
}
@@ -1338,7 +1340,7 @@
// Output image data to file
std::string filePath = "/data/misc/cameraserver/";
filePath += imageFileName;
- std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
+ std::ofstream imageFile(filePath, std::ofstream::binary);
if (!imageFile.is_open()) {
ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
graphicBuffer->unlock();
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index ebd5797..65791a9 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -89,7 +89,7 @@
Camera3OutputStream(int id, sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId,
+ nsecs_t timestampOffset, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -108,7 +108,7 @@
Camera3OutputStream(int id, sp<Surface> consumer,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId,
+ nsecs_t timestampOffset, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -126,7 +126,7 @@
Camera3OutputStream(int id, uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
@@ -214,7 +214,7 @@
/**
* Query the physical camera id for the output stream.
*/
- virtual const String8& getPhysicalCameraId() const override;
+ virtual const std::string& getPhysicalCameraId() const override;
/**
* Set the graphic buffer manager to get/return the stream buffers.
@@ -276,7 +276,7 @@
Camera3OutputStream(int id, camera_stream_type_t type,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
@@ -327,7 +327,7 @@
bool mTraceFirstBuffer;
// Name of Surface consumer
- String8 mConsumerName;
+ std::string mConsumerName;
/**
* GraphicBuffer manager this stream is registered to. Used to replace the buffer
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 4baa7e8..1ab8162 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -94,7 +94,7 @@
/**
* Query the physical camera id for the output stream.
*/
- virtual const String8& getPhysicalCameraId() const = 0;
+ virtual const std::string& getPhysicalCameraId() const = 0;
/**
* Set the batch size for buffer operations. The output stream will request
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f742a6d..88a7d69 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -43,6 +43,7 @@
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <camera/CameraUtils.h>
+#include <camera/StringUtils.h>
#include <camera_metadata_hidden.h>
#include "device3/Camera3OutputUtils.h"
@@ -249,18 +250,18 @@
// and RotationAndCrop mappers.
std::set<uint32_t> keysToRemove;
- auto iter = states.distortionMappers.find(states.cameraId.c_str());
+ auto iter = states.distortionMappers.find(states.cameraId);
if (iter != states.distortionMappers.end()) {
const auto& remappedKeys = iter->second.getRemappedKeys();
keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
}
- const auto& remappedKeys = states.zoomRatioMappers[states.cameraId.c_str()].getRemappedKeys();
+ const auto& remappedKeys = states.zoomRatioMappers[states.cameraId].getRemappedKeys();
keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
- auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
+ auto mapper = states.rotateAndCropMappers.find(states.cameraId);
if (mapper != states.rotateAndCropMappers.end()) {
- const auto& remappedKeys = iter->second.getRemappedKeys();
+ const auto& remappedKeys = mapper->second.getRemappedKeys();
keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
}
@@ -342,14 +343,14 @@
physicalMetadata.mPhysicalCameraMetadata.find(ANDROID_SENSOR_TIMESTAMP);
if (timestamp.count == 0) {
SET_ERR("No timestamp provided by HAL for physical camera %s frame %d!",
- String8(physicalMetadata.mPhysicalCameraId).c_str(), frameNumber);
+ physicalMetadata.mPhysicalCameraId.c_str(), frameNumber);
return;
}
}
// Fix up some result metadata to account for HAL-level distortion correction
status_t res = OK;
- auto iter = states.distortionMappers.find(states.cameraId.c_str());
+ auto iter = states.distortionMappers.find(states.cameraId);
if (iter != states.distortionMappers.end()) {
res = iter->second.correctCaptureResult(&captureResult.mMetadata);
if (res != OK) {
@@ -361,8 +362,8 @@
// Fix up result metadata to account for zoom ratio availabilities between
// HAL and app.
- bool zoomRatioIs1 = cameraIdsWithZoom.find(states.cameraId.c_str()) == cameraIdsWithZoom.end();
- res = states.zoomRatioMappers[states.cameraId.c_str()].updateCaptureResult(
+ bool zoomRatioIs1 = cameraIdsWithZoom.find(states.cameraId) == cameraIdsWithZoom.end();
+ res = states.zoomRatioMappers[states.cameraId].updateCaptureResult(
&captureResult.mMetadata, zoomRatioIs1);
if (res != OK) {
SET_ERR("Failed to update capture result zoom ratio metadata for frame %d: %s (%d)",
@@ -372,7 +373,7 @@
// Fix up result metadata to account for rotateAndCrop in AUTO mode
if (rotateAndCropAuto) {
- auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
+ auto mapper = states.rotateAndCropMappers.find(states.cameraId);
if (mapper != states.rotateAndCropMappers.end()) {
res = mapper->second.updateCaptureResult(
&captureResult.mMetadata);
@@ -401,8 +402,8 @@
}
for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
- String8 cameraId8(physicalMetadata.mPhysicalCameraId);
- auto mapper = states.distortionMappers.find(cameraId8.c_str());
+ const std::string cameraId = physicalMetadata.mPhysicalCameraId;
+ auto mapper = states.distortionMappers.find(cameraId);
if (mapper != states.distortionMappers.end()) {
res = mapper->second.correctCaptureResult(
&physicalMetadata.mPhysicalCameraMetadata);
@@ -413,12 +414,12 @@
}
}
- zoomRatioIs1 = cameraIdsWithZoom.find(cameraId8.c_str()) == cameraIdsWithZoom.end();
- res = states.zoomRatioMappers[cameraId8.c_str()].updateCaptureResult(
+ zoomRatioIs1 = cameraIdsWithZoom.find(cameraId) == cameraIdsWithZoom.end();
+ res = states.zoomRatioMappers[cameraId].updateCaptureResult(
&physicalMetadata.mPhysicalCameraMetadata, zoomRatioIs1);
if (res != OK) {
SET_ERR("Failed to update camera %s's physical zoom ratio metadata for "
- "frame %d: %s(%d)", cameraId8.c_str(), frameNumber, strerror(-res), res);
+ "frame %d: %s(%d)", cameraId.c_str(), frameNumber, strerror(-res), res);
return;
}
}
@@ -430,9 +431,9 @@
return;
}
for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
- String8 cameraId8(physicalMetadata.mPhysicalCameraId);
+ const std::string &cameraId = physicalMetadata.mPhysicalCameraId;
res = fixupMonochromeTags(states,
- states.physicalDeviceInfoMap.at(cameraId8.c_str()),
+ states.physicalDeviceInfoMap.at(cameraId),
physicalMetadata.mPhysicalCameraMetadata);
if (res != OK) {
SET_ERR("Failed to override result metadata: %s (%d)", strerror(-res), res);
@@ -442,7 +443,7 @@
std::unordered_map<std::string, CameraMetadata> monitoredPhysicalMetadata;
for (auto& m : physicalMetadatas) {
- monitoredPhysicalMetadata.emplace(String8(m.mPhysicalCameraId).string(),
+ monitoredPhysicalMetadata.emplace(m.mPhysicalCameraId,
CameraMetadata(m.mPhysicalCameraMetadata));
}
states.tagMonitor.monitorMetadata(TagMonitor::RESULT,
@@ -528,7 +529,7 @@
// Erase the subset of physicalCameraIds that contains id
bool erasePhysicalCameraIdSet(
- std::set<std::set<String8>>& physicalCameraIds, const String8& id) {
+ std::set<std::set<std::string>>& physicalCameraIds, const std::string& id) {
bool found = false;
for (auto iter = physicalCameraIds.begin(); iter != physicalCameraIds.end(); iter++) {
if (iter->count(id) == 1) {
@@ -712,7 +713,7 @@
return;
}
for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
- String8 physicalId(result->physcam_ids[i]);
+ const std::string physicalId = result->physcam_ids[i];
bool validPhysicalCameraMetadata =
erasePhysicalCameraIdSet(request.physicalCameraIds, physicalId);
if (!validPhysicalCameraMetadata) {
@@ -768,7 +769,7 @@
for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
CameraMetadata physicalMetadata;
physicalMetadata.append(result->physcam_metadata[i]);
- request.physicalMetadatas.push_back({String16(result->physcam_ids[i]),
+ request.physicalMetadatas.push_back({result->physcam_ids[i],
physicalMetadata});
}
if (shutterTimestamp == 0) {
@@ -996,7 +997,7 @@
}
if (r.hasCallback) {
ALOGVV("Camera %s: %s: Shutter fired for frame %d (id %d) at %" PRId64,
- states.cameraId.string(), __FUNCTION__,
+ states.cameraId.c_str(), __FUNCTION__,
msg.frame_number, r.resultExtras.requestId, msg.timestamp);
// Call listener, if any
if (states.listener != nullptr) {
@@ -1053,15 +1054,15 @@
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
int streamId = 0;
- String16 physicalCameraId;
+ std::string physicalCameraId;
if (msg.error_stream != nullptr) {
Camera3Stream *stream =
Camera3Stream::cast(msg.error_stream);
streamId = stream->getId();
- physicalCameraId = String16(stream->physicalCameraId());
+ physicalCameraId = stream->physicalCameraId();
}
ALOGV("Camera %s: %s: HAL error, frame %d, stream %d: %d",
- states.cameraId.string(), __FUNCTION__, msg.frame_number,
+ states.cameraId.c_str(), __FUNCTION__, msg.frame_number,
streamId, msg.error_code);
CaptureResultExtras resultExtras;
@@ -1083,13 +1084,12 @@
if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
errorCode) {
if (physicalCameraId.size() > 0) {
- String8 cameraId(physicalCameraId);
bool validPhysicalCameraId =
- erasePhysicalCameraIdSet(r.physicalCameraIds, cameraId);
+ erasePhysicalCameraIdSet(r.physicalCameraIds, physicalCameraId);
if (!validPhysicalCameraId) {
ALOGE("%s: Reported result failure for physical camera device: %s "
" which is not part of the respective request!",
- __FUNCTION__, cameraId.string());
+ __FUNCTION__, physicalCameraId.c_str());
break;
}
resultExtras.errorPhysicalCameraId = physicalCameraId;
@@ -1114,7 +1114,7 @@
} else {
resultExtras.frameNumber = msg.frame_number;
ALOGE("Camera %s: %s: cannot find in-flight request on "
- "frame %" PRId64 " error", states.cameraId.string(), __FUNCTION__,
+ "frame %" PRId64 " error", states.cameraId.c_str(), __FUNCTION__,
resultExtras.frameNumber);
}
}
@@ -1123,7 +1123,7 @@
states.listener->notifyError(errorCode, resultExtras);
} else {
ALOGE("Camera %s: %s: no listener available",
- states.cameraId.string(), __FUNCTION__);
+ states.cameraId.c_str(), __FUNCTION__);
}
break;
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index d5328c5..134c037 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -71,7 +71,7 @@
// Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
// callbacks
struct CaptureOutputStates {
- const String8& cameraId;
+ const std::string& cameraId;
std::mutex& inflightLock;
int64_t& lastCompletedRegularFrameNumber;
int64_t& lastCompletedReprocessFrameNumber;
@@ -115,7 +115,7 @@
void notify(CaptureOutputStates& states, const camera_notify_msg *msg);
struct RequestBufferStates {
- const String8& cameraId;
+ const std::string& cameraId;
std::mutex& reqBufferLock; // lock to serialize request buffer calls
const bool useHalBufManager;
StreamSet& outputStreams;
@@ -126,7 +126,7 @@
};
struct ReturnBufferStates {
- const String8& cameraId;
+ const std::string& cameraId;
const bool useHalBufManager;
StreamSet& outputStreams;
SessionStatsBuilder& sessionStatsBuilder;
@@ -134,7 +134,7 @@
};
struct FlushInflightReqStates {
- const String8& cameraId;
+ const std::string& cameraId;
std::mutex& inflightLock;
InFlightRequestMap& inflightMap; // end of inflightLock scope
const bool useHalBufManager;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
index 2e05dda..3ac666b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
@@ -296,7 +296,7 @@
const VecStreamBufferType& buffers) {
if (!states.useHalBufManager) {
ALOGE("%s: Camera %s does not support HAL buffer managerment",
- __FUNCTION__, states.cameraId.string());
+ __FUNCTION__, states.cameraId.c_str());
return;
}
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index f3a7359..1191f05 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -31,7 +31,7 @@
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId,
+ nsecs_t timestampOffset, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool useHalBufManager, int64_t dynamicProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 1102ecb..c2ff20e 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -37,7 +37,7 @@
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId = CAMERA3_STREAM_SET_ID_INVALID,
bool useHalBufManager = false,
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 4395455..23afa6e 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -22,6 +22,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <camera/StringUtils.h>
#include "device3/Camera3Stream.h"
#include "device3/StatusTracker.h"
#include "utils/TraceHFR.h"
@@ -52,7 +53,7 @@
camera_stream_type type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -60,7 +61,7 @@
camera_stream(),
mId(id),
mSetId(setId),
- mName(String8::format("Camera3Stream[%d]", id)),
+ mName(fmt::sprintf("Camera3Stream[%d]", id)),
mMaxSize(maxSize),
mState(STATE_CONSTRUCTED),
mStatusId(StatusTracker::NO_STATUS_ID),
@@ -92,7 +93,7 @@
camera_stream::data_space = dataSpace;
camera_stream::rotation = rotation;
camera_stream::max_buffers = 0;
- camera_stream::physical_camera_id = mPhysicalCameraId.string();
+ camera_stream::physical_camera_id = mPhysicalCameraId;
camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
camera_stream::dynamic_range_profile = dynamicRangeProfile;
camera_stream::use_case = streamUseCase;
@@ -177,7 +178,7 @@
return mOriginalDataSpace;
}
-const String8& Camera3Stream::physicalCameraId() const {
+const std::string& Camera3Stream::physicalCameraId() const {
return mPhysicalCameraId;
}
@@ -376,7 +377,7 @@
sp<StatusTracker> statusTracker = mStatusTracker.promote();
if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
std::string name = std::string("Stream ") + std::to_string(mId);
- mStatusId = statusTracker->addComponent(name.c_str());
+ mStatusId = statusTracker->addComponent(name);
}
// Check if the stream configuration is unchanged, and skip reallocation if
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index f32053b..2bfaaab 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -19,7 +19,6 @@
#include <gui/Surface.h>
#include <utils/RefBase.h>
-#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/List.h>
@@ -163,25 +162,25 @@
/**
* Get the stream's dimensions and format
*/
- uint32_t getWidth() const;
- uint32_t getHeight() const;
- int getFormat() const;
- android_dataspace getDataSpace() const;
- int32_t getColorSpace() const;
- uint64_t getUsage() const;
- void setUsage(uint64_t usage);
- void setFormatOverride(bool formatOverriden);
- bool isFormatOverridden() const;
- int getOriginalFormat() const;
- int64_t getDynamicRangeProfile() const;
- void setDataSpaceOverride(bool dataSpaceOverriden);
- bool isDataSpaceOverridden() const;
- android_dataspace getOriginalDataSpace() const;
- int getMaxHalBuffers() const;
- const String8& physicalCameraId() const;
- int64_t getStreamUseCase() const;
- int getTimestampBase() const;
- bool isDeviceTimeBaseRealtime() const;
+ uint32_t getWidth() const;
+ uint32_t getHeight() const;
+ int getFormat() const;
+ android_dataspace getDataSpace() const;
+ int32_t getColorSpace() const;
+ uint64_t getUsage() const;
+ void setUsage(uint64_t usage);
+ void setFormatOverride(bool formatOverridden);
+ bool isFormatOverridden() const;
+ int getOriginalFormat() const;
+ int64_t getDynamicRangeProfile() const;
+ void setDataSpaceOverride(bool dataSpaceOverridden);
+ bool isDataSpaceOverridden() const;
+ android_dataspace getOriginalDataSpace() const;
+ int getMaxHalBuffers() const;
+ const std::string& physicalCameraId() const;
+ int64_t getStreamUseCase() const;
+ int getTimestampBase() const;
+ bool isDeviceTimeBaseRealtime() const;
void setOfflineProcessingSupport(bool) override;
bool getOfflineProcessingSupport() const override;
@@ -487,7 +486,7 @@
*/
const int mSetId;
- const String8 mName;
+ const std::string mName;
// Zero for formats with fixed buffer size for given dimensions.
const size_t mMaxSize;
@@ -507,7 +506,7 @@
Camera3Stream(int id, camera_stream_type type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId,
+ const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
@@ -634,7 +633,7 @@
bool mDataSpaceOverridden;
const android_dataspace mOriginalDataSpace;
- String8 mPhysicalCameraId;
+ std::string mPhysicalCameraId;
nsecs_t mLastTimestamp;
bool mIsMultiResolution = false;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 823be2e..7fa6273 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -62,7 +62,7 @@
uint32_t max_buffers;
android_dataspace_t data_space;
camera_stream_rotation_t rotation;
- const char* physical_camera_id;
+ std::string physical_camera_id;
std::unordered_set<int32_t> sensor_pixel_modes_used;
int64_t dynamic_range_profile;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index fd23958..8175eb5 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -25,6 +25,7 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/BufferQueue.h>
#include <gui/Surface.h>
+#include <camera/StringUtils.h>
#include <ui/GraphicBuffer.h>
@@ -92,7 +93,7 @@
if (mBufferItemConsumer == nullptr) {
return NO_MEMORY;
}
- mConsumer->setConsumerName(mConsumerName);
+ mConsumer->setConsumerName(toString8(mConsumerName));
*consumer = new Surface(mProducer);
if (*consumer == nullptr) {
@@ -408,9 +409,9 @@
return res;
}
-String8 Camera3StreamSplitter::getUniqueConsumerName() {
+std::string Camera3StreamSplitter::getUniqueConsumerName() {
static volatile int32_t counter = 0;
- return String8::format("Camera3StreamSplitter-%d", android_atomic_inc(&counter));
+ return fmt::sprintf("Camera3StreamSplitter-%d", android_atomic_inc(&counter));
}
status_t Camera3StreamSplitter::notifyBufferReleased(const sp<GraphicBuffer>& buffer) {
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 0f728a0..639353c 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -30,10 +30,10 @@
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
-#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
-#define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
+#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
+#define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
namespace android {
@@ -222,7 +222,7 @@
const BufferItem& bufferItem, size_t surfaceId);
// Get unique name for the buffer queue consumer
- String8 getUniqueConsumerName();
+ std::string getUniqueConsumerName();
// Helper function to get the BufferQueue slot where a particular buffer is attached to.
int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
@@ -289,7 +289,7 @@
// Currently acquired input buffers
size_t mAcquiredInputBuffers;
- String8 mConsumerName;
+ std::string mConsumerName;
const bool mUseHalBufManager;
};
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index 870825a..665ac73 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -21,7 +21,6 @@
#include <camera/CaptureResult.h>
#include <camera/CameraMetadata.h>
-#include <utils/String8.h>
#include <utils/Timers.h>
#include "common/CameraDeviceBase.h"
@@ -168,7 +167,7 @@
// For request on a physical camera stream, the inside set contains one Id
// For request on a stream group containing physical camera streams, the
// inside set contains all stream Ids in the group.
- std::set<std::set<String8>> physicalCameraIds;
+ std::set<std::set<std::string>> physicalCameraIds;
// Map of physicalCameraId <-> Metadata
std::vector<PhysicalCaptureResultInfo> physicalMetadatas;
@@ -224,7 +223,7 @@
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
bool hasAppCallback, nsecs_t minDuration, nsecs_t maxDuration, bool fixedFps,
- const std::set<std::set<String8>>& physicalCameraIdSet, bool isStillCapture,
+ const std::set<std::set<std::string>>& physicalCameraIdSet, bool isStillCapture,
bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
const std::set<std::string>& idsWithZoom, nsecs_t requestNs,
const SurfaceMap& outSurfaces = SurfaceMap{}) :
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index aa941b0..af48dd6 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -26,10 +26,10 @@
#endif
// Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
##__VA_ARGS__)
-#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
##__VA_ARGS__)
// Convenience macros for transitioning to the error state
@@ -53,6 +53,7 @@
#include <aidlcommonsupport/NativeHandle.h>
#include <android/binder_ibinder_platform.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
+#include <camera/StringUtils.h>
#include "utils/CameraTraces.h"
#include "mediautils/SchedulingPolicyService.h"
@@ -164,7 +165,7 @@
AidlCamera3Device::AidlCamera3Device(
std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+ const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
bool legacyClient) :
Camera3Device(cameraServiceProxyWrapper, id, overrideForPerfClass, overrideToPortrait,
legacyClient) {
@@ -172,12 +173,12 @@
}
status_t AidlCamera3Device::initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) {
+ const std::string& monitorTags) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.c_str());
if (mStatus != STATUS_UNINITIALIZED) {
CLOGE("Already initialized!");
return INVALID_OPERATION;
@@ -186,7 +187,7 @@
std::shared_ptr<camera::device::ICameraDeviceSession> session;
ATRACE_BEGIN("CameraHal::openSession");
- status_t res = manager->openAidlSession(mId.string(), mCallbacks,
+ status_t res = manager->openAidlSession(mId, mCallbacks,
/*out*/ &session);
ATRACE_END();
if (res != OK) {
@@ -197,18 +198,18 @@
SET_ERR("Session iface returned is null");
return INVALID_OPERATION;
}
- res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo,
+ res = manager->getCameraCharacteristics(mId, mOverrideForPerfClass, &mDeviceInfo,
mOverrideToPortrait);
if (res != OK) {
SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
session->close();
return res;
}
- mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
- mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId.string());
+ mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId);
+ mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId);
std::vector<std::string> physicalCameraIds;
- bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+ bool isLogical = manager->isLogicalCamera(mId, &physicalCameraIds);
if (isLogical) {
for (auto& physicalId : physicalCameraIds) {
// Do not override characteristics for physical cameras
@@ -299,10 +300,10 @@
mInterface = new AidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
std::string providerType;
- mVendorTagId = manager->getProviderTagIdLocked(mId.string());
+ mVendorTagId = manager->getProviderTagIdLocked(mId);
mTagMonitor.initialize(mVendorTagId);
- if (!monitorTags.isEmpty()) {
- mTagMonitor.parseTagsToMonitor(String8(monitorTags));
+ if (!monitorTags.empty()) {
+ mTagMonitor.parseTagsToMonitor(monitorTags);
}
for (size_t i = 0; i < capabilities.count; i++) {
@@ -922,7 +923,7 @@
dst.colorSpace = src->color_space;
dst.bufferSize = bufferSizes[i];
- if (src->physical_camera_id != nullptr) {
+ if (!src->physical_camera_id.empty()) {
dst.physicalCameraId = src->physical_camera_id;
}
dst.groupId = cam3stream->getHalStreamGroupId();
@@ -1100,7 +1101,7 @@
mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
cam3stream->getOriginalDataSpace() : src->data_space);
dst.bufferSize = bufferSizes[i];
- if (src->physical_camera_id != nullptr) {
+ if (!src->physical_camera_id.empty()) {
dst.physicalCameraId = src->physical_camera_id;
}
dst.groupId = cam3stream->getHalStreamGroupId();
@@ -1456,7 +1457,7 @@
}
status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::injectionInitialize(
- const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::string& injectedCamId, sp<CameraProviderManager> manager,
const std::shared_ptr<camera::device::ICameraDeviceCallback>&callback) {
ATRACE_CALL();
Mutex::Autolock lock(mInjectionLock);
@@ -1480,7 +1481,7 @@
mInjectedCamId = injectedCamId;
std::shared_ptr<camera::device::ICameraInjectionSession> injectionSession;
ATRACE_BEGIN("Injection CameraHal::openSession");
- status_t res = manager->openAidlInjectionSession(injectedCamId.string(), callback,
+ status_t res = manager->openAidlInjectionSession(injectedCamId, callback,
/*out*/ &injectionSession);
ATRACE_END();
if (res != OK) {
@@ -1579,7 +1580,7 @@
return OK;
}
-status_t AidlCamera3Device::injectionCameraInitialize(const String8 &injectedCamId,
+status_t AidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
sp<CameraProviderManager> manager) {
return (static_cast<AidlCamera3DeviceInjectionMethods *>
(mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
index 99a308b..e0be367 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
@@ -41,7 +41,7 @@
friend class AidlCameraDeviceCallbacks;
explicit AidlCamera3Device(
std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+ const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
bool legacyClient = false);
virtual ~AidlCamera3Device() { }
@@ -71,7 +71,7 @@
virtual status_t switchToOffline(const std::vector<int32_t>& /*streamsToKeep*/,
/*out*/ sp<CameraOfflineSessionBase>* /*session*/) override;
- status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
+ status_t initialize(sp<CameraProviderManager> manager, const std::string& monitorTags) override;
class AidlHalInterface : public Camera3Device::HalInterface {
public:
AidlHalInterface(std::shared_ptr<
@@ -196,7 +196,7 @@
public:
// Initialize the injection camera and generate an hal interface.
status_t injectionInitialize(
- const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::string& injectedCamId, sp<CameraProviderManager> manager,
const std::shared_ptr<
aidl::android::hardware::camera::device::ICameraDeviceCallback>&
callback);
@@ -257,7 +257,7 @@
};
private:
- virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+ virtual status_t injectionCameraInitialize(const std::string &injectCamId,
sp<CameraProviderManager> manager) override;
virtual sp<RequestThread> createNewRequestThread(wp<Camera3Device> parent,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
index 3c3db97..01c4e88 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
@@ -31,6 +31,7 @@
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
#include <android/binder_ibinder_platform.h>
+#include <camera/StringUtils.h>
#include "device3/aidl/AidlCamera3OfflineSession.h"
#include "device3/Camera3OutputStream.h"
@@ -47,7 +48,7 @@
AidlCamera3OfflineSession::~AidlCamera3OfflineSession() {
ATRACE_CALL();
- ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.c_str());
Camera3OfflineSession::disconnectImpl();
}
@@ -113,7 +114,7 @@
std::string activePhysicalId(""); // Unused
AidlCaptureOutputStates states {
- {mId,
+ { mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -160,7 +161,7 @@
std::string activePhysicalId(""); // Unused
AidlCaptureOutputStates states {
- {mId,
+ { mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
index b31ffb7..33b638c 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
@@ -20,7 +20,6 @@
#include <memory>
#include <mutex>
-#include <utils/String8.h>
#include <utils/String16.h>
#include "AidlCamera3OutputUtils.h"
@@ -106,7 +105,7 @@
};
// initialize by Camera3Device.
- explicit AidlCamera3OfflineSession(const String8& id,
+ explicit AidlCamera3OfflineSession(const std::string& id,
const sp<camera3::Camera3Stream>& inputStream,
const camera3::StreamSet& offlineStreamSet,
camera3::BufferRecords&& bufferRecords,
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
index b2accc1..74d4230 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
@@ -145,7 +145,7 @@
outBuffers->clear();
if (!states.useHalBufManager) {
ALOGE("%s: Camera %s does not support HAL buffer management",
- __FUNCTION__, states.cameraId.string());
+ __FUNCTION__, states.cameraId.c_str());
*status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
return;
}
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 0d44dd5..06af5ff 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -26,7 +26,7 @@
#endif
// Convenience macro for transient errors
-#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.c_str(), __FUNCTION__, \
##__VA_ARGS__)
// Convenience macros for transitioning to the error state
@@ -46,6 +46,7 @@
#include <utils/Trace.h>
#include <utils/Timers.h>
#include <cutils/properties.h>
+#include <camera/StringUtils.h>
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -140,12 +141,12 @@
}
status_t HidlCamera3Device::initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) {
+ const std::string& monitorTags) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.c_str());
if (mStatus != STATUS_UNINITIALIZED) {
CLOGE("Already initialized!");
return INVALID_OPERATION;
@@ -154,7 +155,7 @@
sp<ICameraDeviceSession> session;
ATRACE_BEGIN("CameraHal::openSession");
- status_t res = manager->openHidlSession(mId.string(), this,
+ status_t res = manager->openHidlSession(mId, this,
/*out*/ &session);
ATRACE_END();
if (res != OK) {
@@ -162,17 +163,17 @@
return res;
}
- res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo,
+ res = manager->getCameraCharacteristics(mId, mOverrideForPerfClass, &mDeviceInfo,
/*overrideToPortrait*/false);
if (res != OK) {
SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
session->close();
return res;
}
- mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
+ mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId);
std::vector<std::string> physicalCameraIds;
- bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+ bool isLogical = manager->isLogicalCamera(mId, &physicalCameraIds);
if (isLogical) {
for (auto& physicalId : physicalCameraIds) {
// Do not override characteristics for physical cameras
@@ -271,17 +272,17 @@
mInterface = new HidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
std::string providerType;
- mVendorTagId = manager->getProviderTagIdLocked(mId.string());
+ mVendorTagId = manager->getProviderTagIdLocked(mId);
mTagMonitor.initialize(mVendorTagId);
- if (!monitorTags.isEmpty()) {
- mTagMonitor.parseTagsToMonitor(String8(monitorTags));
+ if (!monitorTags.empty()) {
+ mTagMonitor.parseTagsToMonitor(monitorTags);
}
// Metadata tags needs fixup for monochrome camera device version less
// than 3.5.
hardware::hidl_version maxVersion{0,0};
IPCTransport transport = IPCTransport::HIDL;
- res = manager->getHighestSupportedVersion(mId.string(), &maxVersion, &transport);
+ res = manager->getHighestSupportedVersion(mId, &maxVersion, &transport);
if (res != OK) {
ALOGE("%s: Error in getting camera device version id: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -416,7 +417,7 @@
}
HidlCaptureOutputStates states {
- {mId,
+ { mId,
mInFlightLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
@@ -464,7 +465,7 @@
}
HidlCaptureOutputStates states {
- {mId,
+ { mId,
mInFlightLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
@@ -715,7 +716,7 @@
return new HidlCamera3DeviceInjectionMethods(parent);
}
-status_t HidlCamera3Device::injectionCameraInitialize(const String8 &injectedCamId,
+status_t HidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
sp<CameraProviderManager> manager) {
return (static_cast<HidlCamera3DeviceInjectionMethods *>(
mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager, this);
@@ -941,7 +942,7 @@
}
dst3_4.v3_2 = dst3_2;
dst3_4.bufferSize = bufferSizes[i];
- if (src->physical_camera_id != nullptr) {
+ if (!src->physical_camera_id.empty()) {
dst3_4.physicalCameraId = src->physical_camera_id;
}
dst3_7.v3_4 = dst3_4;
@@ -1259,7 +1260,7 @@
}
dst3_4.v3_2 = dst3_2;
dst3_4.bufferSize = bufferSizes[i];
- if (src->physical_camera_id != nullptr) {
+ if (!src->physical_camera_id.empty()) {
dst3_4.physicalCameraId = src->physical_camera_id;
}
dst3_7.v3_4 = dst3_4;
@@ -1739,7 +1740,7 @@
}
status_t HidlCamera3Device::HidlCamera3DeviceInjectionMethods::injectionInitialize(
- const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::string& injectedCamId, sp<CameraProviderManager> manager,
const sp<android::hardware::camera::device::V3_2::ICameraDeviceCallback>&
callback) {
ATRACE_CALL();
@@ -1759,7 +1760,7 @@
mInjectedCamId = injectedCamId;
sp<ICameraDeviceSession> session;
ATRACE_BEGIN("Injection CameraHal::openSession");
- status_t res = manager->openHidlSession(injectedCamId.string(), callback,
+ status_t res = manager->openHidlSession(injectedCamId, callback,
/*out*/ &session);
ATRACE_END();
if (res != OK) {
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
index 1e50844..2cfdf9d 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
@@ -31,8 +31,9 @@
public Camera3Device {
public:
- explicit HidlCamera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8& id, bool overrideForPerfClass, bool overrideToPortrait,
+ explicit HidlCamera3Device(
+ std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
+ const std::string& id, bool overrideForPerfClass, bool overrideToPortrait,
bool legacyClient = false) :
Camera3Device(cameraServiceProxyWrapper, id, overrideForPerfClass, overrideToPortrait,
legacyClient) { }
@@ -59,7 +60,7 @@
static uint64_t mapProducerToFrameworkUsage(
hardware::camera::device::V3_2::BufferUsageFlags usage);
- status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
+ status_t initialize(sp<CameraProviderManager> manager, const std::string& monitorTags) override;
/**
* Implementation of android::hardware::camera::device::V3_5::ICameraDeviceCallback
@@ -191,7 +192,7 @@
public:
// Initialize the injection camera and generate an hal interface.
status_t injectionInitialize(
- const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::string& injectedCamId, sp<CameraProviderManager> manager,
const sp<
android::hardware::camera::device::V3_2 ::ICameraDeviceCallback>&
callback);
@@ -217,7 +218,7 @@
hardware::Return<void> notifyHelper(
const hardware::hidl_vec<NotifyMsgType>& msgs);
- virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+ virtual status_t injectionCameraInitialize(const std::string &injectCamId,
sp<CameraProviderManager> manager) override;
virtual sp<RequestThread> createNewRequestThread(wp<Camera3Device> parent,
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
index 28b2b47..e328ef6 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
@@ -23,6 +23,7 @@
#include <utils/Trace.h>
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <camera/StringUtils.h>
#include "device3/hidl/HidlCamera3OfflineSession.h"
#include "device3/Camera3OutputStream.h"
@@ -38,7 +39,7 @@
HidlCamera3OfflineSession::~HidlCamera3OfflineSession() {
ATRACE_CALL();
- ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.string());
+ ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.c_str());
Camera3OfflineSession::disconnectImpl();
}
@@ -94,7 +95,7 @@
std::string activePhysicalId("");
HidlCaptureOutputStates states {
- {mId,
+ { mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -136,7 +137,7 @@
std::string activePhysicalId("");
HidlCaptureOutputStates states {
- {mId,
+ { mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
@@ -173,7 +174,7 @@
std::string activePhysicalId("");
HidlCaptureOutputStates states {
- {mId,
+ { mId,
mOfflineReqsLock, mLastCompletedRegularFrameNumber,
mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
index d22a447..df306b2 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
@@ -20,7 +20,6 @@
#include <memory>
#include <mutex>
-#include <utils/String8.h>
#include <utils/String16.h>
#include <android/hardware/camera/device/3.6/ICameraOfflineSession.h>
@@ -53,7 +52,7 @@
public:
// initialize by Camera3Device.
- explicit HidlCamera3OfflineSession(const String8& id,
+ explicit HidlCamera3OfflineSession(const std::string& id,
const sp<camera3::Camera3Stream>& inputStream,
const camera3::StreamSet& offlineStreamSet,
camera3::BufferRecords&& bufferRecords,
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index ee018c3..cd4a92c 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -23,6 +23,7 @@
#include <utils/Log.h>
#include <gui/RingBufferConsumer.h>
+#include <camera/StringUtils.h>
#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -53,10 +54,10 @@
RingBufferConsumer::~RingBufferConsumer() {
}
-void RingBufferConsumer::setName(const String8& name) {
+void RingBufferConsumer::setName(const std::string& name) {
Mutex::Autolock _l(mMutex);
- mName = name;
- mConsumer->setConsumerName(name);
+ mName = toString8(name);
+ mConsumer->setConsumerName(mName);
}
sp<PinnedBufferItem> RingBufferConsumer::pinSelectedBuffer(
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h
index b737469..2e523d1 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.h
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h
@@ -27,8 +27,6 @@
namespace android {
-class String8;
-
/**
* The RingBufferConsumer maintains a ring buffer of BufferItem objects,
* (which are 'acquired' as long as they are part of the ring buffer, and
@@ -67,7 +65,7 @@
// set the name of the RingBufferConsumer that will be used to identify it in
// log messages.
- void setName(const String8& name);
+ void setName(const std::string& name);
// setDefaultBufferSize is used to set the size of buffers returned by
// requestBuffers when a with and height of zero is requested.
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
index add9121..2b81224 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -16,6 +16,7 @@
#include <hidl/AidlCameraServiceListener.h>
#include <hidl/Utils.h>
+#include <camera/StringUtils.h>
namespace android {
namespace frameworks {
@@ -28,11 +29,11 @@
typedef frameworks::cameraservice::service::V2_1::ICameraServiceListener HCameraServiceListener2_1;
binder::Status H2BCameraServiceListener::onStatusChanged(
- int32_t status, const ::android::String16& cameraId) {
+ int32_t status, const std::string& cameraId) {
HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
CameraStatusAndId cameraStatusAndId;
cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
- cameraStatusAndId.cameraId = String8(cameraId).string();
+ cameraStatusAndId.cameraId = cameraId;
auto ret = mBase->onStatusChanged(cameraStatusAndId);
if (!ret.isOk()) {
ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
@@ -42,8 +43,8 @@
}
binder::Status H2BCameraServiceListener::onPhysicalCameraStatusChanged(
- int32_t status, const ::android::String16& cameraId,
- const ::android::String16& physicalCameraId) {
+ int32_t status, const std::string& cameraId,
+ const std::string& physicalCameraId) {
auto cast2_1 = HCameraServiceListener2_1::castFrom(mBase);
sp<HCameraServiceListener2_1> interface2_1 = nullptr;
if (cast2_1.isOk()) {
@@ -52,8 +53,8 @@
HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
V2_1::PhysicalCameraStatusAndId cameraStatusAndId;
cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
- cameraStatusAndId.cameraId = String8(cameraId).string();
- cameraStatusAndId.physicalCameraId = String8(physicalCameraId).string();
+ cameraStatusAndId.cameraId = cameraId;
+ cameraStatusAndId.physicalCameraId = physicalCameraId;
auto ret = interface2_1->onPhysicalCameraStatusChanged(cameraStatusAndId);
if (!ret.isOk()) {
ALOGE("%s OnPhysicalCameraStatusChanged callback failed due to %s",__FUNCTION__,
@@ -65,13 +66,13 @@
}
::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
- int32_t, const ::android::String16&) {
+ int32_t, const std::string&) {
// We don't implement onTorchStatusChanged
return binder::Status::ok();
}
::android::binder::Status H2BCameraServiceListener::onTorchStrengthLevelChanged(
- const ::android::String16&, int32_t) {
+ const std::string&, int32_t) {
return binder::Status::ok();
}
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 7ef413f..91a4c16 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -47,25 +47,25 @@
~H2BCameraServiceListener() { }
virtual ::android::binder::Status onStatusChanged(int32_t status,
- const ::android::String16& cameraId) override;
+ const std::string& cameraId) override;
virtual ::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
- const ::android::String16& cameraId,
- const ::android::String16& physicalCameraId) override;
+ const std::string& cameraId,
+ const std::string& physicalCameraId) override;
virtual ::android::binder::Status onTorchStatusChanged(
- int32_t status, const ::android::String16& cameraId) override;
+ int32_t status, const std::string& cameraId) override;
virtual ::android::binder::Status onTorchStrengthLevelChanged(
- const ::android::String16& cameraId, int32_t newStrengthLevel) override;
+ const std::string& cameraId, int32_t newStrengthLevel) override;
virtual binder::Status onCameraAccessPrioritiesChanged() {
// TODO: no implementation yet.
return binder::Status::ok();
}
- virtual binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
- const ::android::String16& /*clientPackageId*/) {
+ virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageId*/) {
// empty implementation
return binder::Status::ok();
}
- virtual binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) {
+ virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
// empty implementation
return binder::Status::ok();
}
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
index 0f7f127..59fc1cd 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -112,7 +112,7 @@
physicalCameraSettings->emplace_back();
CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
physicalCameraSettings->back();
- physicalCameraSetting.id = e.id.c_str();
+ physicalCameraSetting.id = e.id;
// Read the settings either from the fmq or straightaway from the
// request. We don't need any synchronization, since submitRequestList
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index d6910fe..4f12933 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -65,7 +65,7 @@
android::CameraMetadata cameraMetadata;
HStatus status = HStatus::NO_ERROR;
binder::Status serviceRet =
- mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
+ mAidlICameraService->getCameraCharacteristics(cameraId,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
&cameraMetadata);
HCameraMetadata hidlMetadata;
@@ -116,7 +116,7 @@
}
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
binder::Status serviceRet = mAidlICameraService->connectDevice(
- callbacks, String16(cameraId.c_str()), String16(""), {},
+ callbacks, cameraId, std::string(), {},
hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
/*out*/&deviceRemote);
@@ -242,7 +242,7 @@
[this](const hardware::CameraStatus& s) {
bool supportsHAL3 = false;
binder::Status sRet =
- mAidlICameraService->supportsCameraApi(String16(s.cameraId),
+ mAidlICameraService->supportsCameraApi(s.cameraId,
hardware::ICameraService::API_VERSION_2, &supportsHAL3);
return !sRet.isOk() || !supportsHAL3;
}), cameraStatusAndIds->end());
diff --git a/services/camera/libcameraservice/hidl/Utils.cpp b/services/camera/libcameraservice/hidl/Utils.cpp
index 2a24a23..b5dddf7 100644
--- a/services/camera/libcameraservice/hidl/Utils.cpp
+++ b/services/camera/libcameraservice/hidl/Utils.cpp
@@ -18,6 +18,7 @@
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <cutils/native_handle.h>
#include <mediautils/AImageReaderUtils.h>
+#include <camera/StringUtils.h>
namespace android {
namespace hardware {
@@ -89,9 +90,9 @@
for (auto &handle : windowHandles) {
iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(handle)));
}
- String16 physicalCameraId16(hOutputConfiguration.physicalCameraId.c_str());
hardware::camera2::params::OutputConfiguration outputConfiguration(
- iGBPs, convertFromHidl(hOutputConfiguration.rotation), physicalCameraId16,
+ iGBPs, convertFromHidl(hOutputConfiguration.rotation),
+ hOutputConfiguration.physicalCameraId,
hOutputConfiguration.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
(windowHandles.size() > 1));
return outputConfiguration;
@@ -157,8 +158,8 @@
hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber;
hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount;
hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId;
- hCaptureResultExtras.errorPhysicalCameraId = hidl_string(String8(
- captureResultExtras.errorPhysicalCameraId).string());
+ hCaptureResultExtras.errorPhysicalCameraId = hidl_string(
+ captureResultExtras.errorPhysicalCameraId.c_str());
return hCaptureResultExtras;
}
@@ -191,7 +192,7 @@
size_t i = 0;
for (auto &statusAndId : src) {
auto &a = (*dst)[i++];
- a.cameraId = statusAndId.cameraId.c_str();
+ a.cameraId = statusAndId.cameraId;
a.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
}
return;
@@ -203,12 +204,12 @@
size_t i = 0;
for (const auto &statusAndId : src) {
auto &a = (*dst)[i++];
- a.v2_0.cameraId = statusAndId.cameraId.c_str();
+ a.v2_0.cameraId = statusAndId.cameraId;
a.v2_0.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
- a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
+ a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
}
}
return;
@@ -265,7 +266,7 @@
std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
HPhysicalCaptureResultInfo hPhysicalCaptureResultInfo;
hPhysicalCaptureResultInfo.physicalCameraId =
- String8(physicalCaptureResultInfo.mPhysicalCameraId).string();
+ toString8(physicalCaptureResultInfo.mPhysicalCameraId);
const camera_metadata_t *rawMetadata =
physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
// Try using fmq at first.
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index b397573..854c342 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -219,13 +219,13 @@
}
void CameraFuzzer::getCameraInformation(int32_t cameraId) {
- String16 cameraIdStr = String16(String8::format("%d", cameraId));
+ std::string cameraIdStr = std::to_string(cameraId);
bool isSupported = false;
mCameraService->supportsCameraApi(
cameraIdStr, kCameraApiVersion[mFuzzedDataProvider->ConsumeBool()], &isSupported);
mCameraService->isHiddenPhysicalCamera(cameraIdStr, &isSupported);
- String16 parameters;
+ std::string parameters;
mCameraService->getLegacyParameters(cameraId, ¶meters);
std::vector<hardware::camera2::utils::ConcurrentCameraIdCombination> concurrentCameraIds;
@@ -318,7 +318,7 @@
}
void CameraFuzzer::invokeTorchAPIs(int32_t cameraId) {
- String16 cameraIdStr = String16(String8::format("%d", cameraId));
+ std::string cameraIdStr = std::to_string(cameraId);
sp<IBinder> binder = new BBinder;
mCameraService->setTorchMode(cameraIdStr, true, binder);
@@ -342,7 +342,7 @@
::android::binder::Status rc;
sp<ICamera> cameraDevice;
- rc = mCameraService->connect(this, cameraId, String16(),
+ rc = mCameraService->connect(this, cameraId, std::string(),
android::CameraService::USE_CALLING_UID,
android::CameraService::USE_CALLING_PID,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__,
@@ -484,17 +484,18 @@
public:
virtual ~TestCameraServiceListener() {};
- virtual binder::Status onStatusChanged(int32_t , const String16&) {
+ virtual binder::Status onStatusChanged(int32_t, const std::string&) {
return binder::Status::ok();
};
virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
- const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+ const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
// No op
return binder::Status::ok();
};
- virtual binder::Status onTorchStatusChanged(int32_t /*status*/, const String16& /*cameraId*/) {
+ virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
+ const std::string& /*cameraId*/) {
return binder::Status::ok();
};
@@ -503,18 +504,18 @@
return binder::Status::ok();
}
- virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
- const String16& /*clientPackageName*/) {
+ virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageName*/) {
// No op
return binder::Status::ok();
}
- virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+ virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
// No op
return binder::Status::ok();
}
- virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+ virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
int32_t /*torchStrength*/) {
// No op
return binder::Status::ok();
@@ -579,7 +580,7 @@
for (auto s : statuses) {
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
- mCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ mCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/true,
&device);
@@ -600,7 +601,7 @@
sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
- String16 noPhysicalId;
+ std::string noPhysicalId;
size_t rotations = sizeof(kRotations) / sizeof(int32_t) - 1;
OutputConfiguration output(gbProducer,
kRotations[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, rotations)],
@@ -626,9 +627,9 @@
kSensorPixelModes[mFuzzedDataProvider->ConsumeBool() ? 1 : 0];
requestTemplate.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1);
request.mPhysicalCameraSettings.clear();
- request.mPhysicalCameraSettings.push_back({s.cameraId.string(), requestTemplate});
+ request.mPhysicalCameraSettings.push_back({s.cameraId, requestTemplate});
device->submitRequest(request, /*streaming*/false, /*out*/&info);
- ALOGV("%s : camera id %s submit request id %d",__FUNCTION__, s.cameraId.string(),
+ ALOGV("%s : camera id %s submit request id %d",__FUNCTION__, s.cameraId.c_str(),
info.mRequestId);
}
device->disconnect();
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 5e2a3fb..b035edd 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -31,11 +31,14 @@
"libmedia_headers",
],
+ defaults: [
+ "libcameraservice_deps",
+ ],
+
shared_libs: [
"libbase",
"libbinder",
"libcutils",
- "libcameraservice",
"libhidlbase",
"liblog",
"libcamera_client",
@@ -45,11 +48,6 @@
"libjpeg",
"libexif",
"android.hardware.camera.common@1.0",
- "android.hardware.camera.provider@2.4",
- "android.hardware.camera.provider@2.5",
- "android.hardware.camera.provider@2.6",
- "android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
@@ -58,6 +56,12 @@
],
static_libs: [
+ "android.hardware.camera.provider@2.4",
+ "android.hardware.camera.provider@2.5",
+ "android.hardware.camera.provider@2.6",
+ "android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V2-ndk",
+ "libcameraservice",
"libgmock",
],
diff --git a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
index 731eebf..db43a02 100644
--- a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
@@ -37,17 +37,18 @@
public:
virtual ~TestCameraServiceListener() {};
- virtual binder::Status onStatusChanged(int32_t , const String16&) {
+ virtual binder::Status onStatusChanged(int32_t , const std::string&) {
return binder::Status::ok();
};
virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
- const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
+ const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
// No op
return binder::Status::ok();
};
- virtual binder::Status onTorchStatusChanged(int32_t /*status*/, const String16& /*cameraId*/) {
+ virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
+ const std::string& /*cameraId*/) {
return binder::Status::ok();
};
@@ -56,18 +57,18 @@
return binder::Status::ok();
}
- virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
- const String16& /*clientPackageName*/) {
+ virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageName*/) {
// No op
return binder::Status::ok();
}
- virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+ virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
// No op
return binder::Status::ok();
}
- virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+ virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
int32_t /*torchStrength*/) {
// No op
return binder::Status::ok();
@@ -123,13 +124,13 @@
mCameraDisabled(false), mOverrideCameraDisabled(false)
{ }
- virtual binder::Status getRotateAndCropOverride(const String16& packageName, int lensFacing,
+ virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
int userId, int *ret) override {
return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
userId, ret);
}
- virtual binder::Status getAutoframingOverride(const String16& packageName, int *ret) override {
+ virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
}
@@ -224,7 +225,7 @@
sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
sp<hardware::camera2::ICameraDeviceUser> device;
binder::Status status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
AutoDisconnectDevice autoDisconnect(device);
@@ -238,7 +239,7 @@
sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
sp<hardware::camera2::ICameraDeviceUser> device;
binder::Status status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
AutoDisconnectDevice autoDisconnect(device);
@@ -257,14 +258,14 @@
sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
binder::Status status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
AutoDisconnectDevice autoDisconnectA(deviceA);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
AutoDisconnectDevice autoDisconnectB(deviceB);
@@ -285,14 +286,14 @@
sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
binder::Status status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
AutoDisconnectDevice autoDisconnectA(deviceA);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
status =
- sCameraService->connectDevice(callbacks, String16(s.cameraId), String16(), {},
+ sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
AutoDisconnectDevice autoDisconnectB(deviceB);
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index 1a6b2e0..c0cd1a9 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -302,15 +302,15 @@
~TestStatusListener() {}
- void onDeviceStatusChanged(const String8 &,
+ void onDeviceStatusChanged(const std::string &,
CameraDeviceStatus) override {}
- void onDeviceStatusChanged(const String8 &, const String8 &,
+ void onDeviceStatusChanged(const std::string &, const std::string &,
CameraDeviceStatus) override {
mPhysicalCameraStatusChangeCount++;
}
- void onTorchStatusChanged(const String8 &,
+ void onTorchStatusChanged(const std::string &,
TorchModeStatus) override {}
- void onTorchStatusChanged(const String8 &,
+ void onTorchStatusChanged(const std::string &,
TorchModeStatus, SystemCameraKind) override {}
void onNewProviderRegistered() override {}
};
diff --git a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
index b367571..33cc61a 100644
--- a/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
+++ b/services/camera/libcameraservice/tests/DistortionMapperTest.cpp
@@ -19,8 +19,8 @@
#include <random>
+#include <fmt/printf.h>
#include <gtest/gtest.h>
-#include <android-base/stringprintf.h>
#include <android-base/chrono_utils.h>
#include "../device3/DistortionMapper.h"
@@ -260,9 +260,9 @@
rawToCorrectedDurationMs) / (randCoords.size() / 2) ).count();
test->RecordProperty("CorrectedToRawDurationPerCoordUs",
- base::StringPrintf("%f", correctedToRawDurationPerCoordUs));
+ fmt::sprintf("%f", correctedToRawDurationPerCoordUs));
test->RecordProperty("RawToCorrectedDurationPerCoordUs",
- base::StringPrintf("%f", rawToCorrectedDurationPerCoordUs));
+ fmt::sprintf("%f", rawToCorrectedDurationPerCoordUs));
// Calculate mapping errors after round trip
float totalErrorSq = 0;
@@ -296,9 +296,9 @@
}
float rmsError = std::sqrt(totalErrorSq / randCoords.size());
- test->RecordProperty("RmsError", base::StringPrintf("%f", rmsError));
+ test->RecordProperty("RmsError", fmt::sprintf("%f", rmsError));
for (size_t i = 0; i < histogram.size(); i++) {
- std::string label = base::StringPrintf("HistogramBin[%f,%f)",
+ std::string label = fmt::sprintf("HistogramBin[%f,%f)",
(float)i/bucketsPerPixel, (float)(i + 1)/bucketsPerPixel);
test->RecordProperty(label, histogram[i]);
}
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index b58975f..d07bf6d 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -20,6 +20,8 @@
#include <inttypes.h>
#include <utils/Log.h>
+#include <utils/String16.h>
+#include <camera/StringUtils.h>
#include <binder/IServiceManager.h>
#include "CameraServiceProxyWrapper.h"
@@ -32,7 +34,7 @@
namespace {
// Sentinel value to be returned when extension session with a stale or invalid key is reported.
-const String16 POISON_EXT_STATS_KEY("poisoned_stats");
+const std::string POISON_EXT_STATS_KEY("poisoned_stats");
} // anonymous namespace
/**
@@ -100,7 +102,7 @@
mSessionStats.mRequestCount = requestCount;
mSessionStats.mResultErrorCount = resultErrorCount;
mSessionStats.mDeviceError = deviceError;
- mSessionStats.mUserTag = String16(userTag.c_str());
+ mSessionStats.mUserTag = userTag;
mSessionStats.mVideoStabilizationMode = videoStabilizationMode;
mSessionStats.mStreamStats = streamStats;
@@ -116,14 +118,14 @@
return mSessionStats.mLogId;
}
-String16 CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateExtensionSessionStats(
+std::string CameraServiceProxyWrapper::CameraSessionStatsWrapper::updateExtensionSessionStats(
const hardware::CameraExtensionSessionStats& extStats) {
Mutex::Autolock l(mLock);
CameraExtensionSessionStats& currStats = mSessionStats.mCameraExtensionSessionStats;
if (currStats.key != extStats.key) {
// Mismatched keys. Extensions stats likely reported for a closed session
ALOGW("%s: mismatched extensions stats key: current='%s' reported='%s'. Dropping stats.",
- __FUNCTION__, String8(currStats.key).c_str(), String8(extStats.key).c_str());
+ __FUNCTION__, toStdString(currStats.key).c_str(), toStdString(extStats.key).c_str());
return POISON_EXT_STATS_KEY; // return poisoned key to so future calls are
// definitely dropped.
}
@@ -134,15 +136,15 @@
ALOGV("%s: Overwriting extension session stats: %s", __FUNCTION__,
extStats.toString().c_str());
currStats = extStats;
- return currStats.key;
+ return toStdString(currStats.key);
}
// Matching empty keys...
- if (mSessionStats.mClientName != extStats.clientName) {
+ if (mSessionStats.mClientName != toStdString(extStats.clientName)) {
ALOGW("%s: extension stats reported for unexpected package: current='%s' reported='%s'. "
"Dropping stats.", __FUNCTION__,
- String8(mSessionStats.mClientName).c_str(),
- String8(extStats.clientName).c_str());
+ mSessionStats.mClientName.c_str(),
+ toStdString(extStats.clientName).c_str());
return POISON_EXT_STATS_KEY;
}
@@ -166,12 +168,12 @@
key << mSessionStats.mSessionIndex << '/' << mSessionStats.mLogId;
currStats.key = String16(key.str().c_str());
ALOGV("%s: New extension session stats: %s", __FUNCTION__, currStats.toString().c_str());
- return currStats.key;
+ return toStdString(currStats.key);
}
// Camera is closed. Probably a stale call.
ALOGW("%s: extension stats reported for closed camera id '%s'. Dropping stats.",
- __FUNCTION__, String8(mSessionStats.mCameraId).c_str());
+ __FUNCTION__, mSessionStats.mCameraId.c_str());
return {};
}
@@ -209,12 +211,13 @@
proxyBinder->pingForUserUpdate();
}
-int CameraServiceProxyWrapper::getRotateAndCropOverride(String16 packageName, int lensFacing,
- int userId) {
+int CameraServiceProxyWrapper::getRotateAndCropOverride(const std::string &packageName,
+ int lensFacing, int userId) {
sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
if (proxyBinder == nullptr) return true;
int ret = 0;
- auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing, userId, &ret);
+ auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing,
+ userId, &ret);
if (!status.isOk()) {
ALOGE("%s: Failed during top activity orientation query: %s", __FUNCTION__,
status.exceptionMessage().c_str());
@@ -223,7 +226,7 @@
return ret;
}
-int CameraServiceProxyWrapper::getAutoframingOverride(const String16& packageName) {
+int CameraServiceProxyWrapper::getAutoframingOverride(const std::string& packageName) {
sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
if (proxyBinder == nullptr) {
return ANDROID_CONTROL_AUTOFRAMING_OFF;
@@ -238,7 +241,7 @@
return ret;
}
-void CameraServiceProxyWrapper::logStreamConfigured(const String8& id,
+void CameraServiceProxyWrapper::logStreamConfigured(const std::string& id,
int operatingMode, bool internalConfig, int32_t latencyMs) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
@@ -256,7 +259,7 @@
sessionStats->onStreamConfigured(operatingMode, internalConfig, latencyMs);
}
-void CameraServiceProxyWrapper::logActive(const String8& id, float maxPreviewFps) {
+void CameraServiceProxyWrapper::logActive(const std::string& id, float maxPreviewFps) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
Mutex::Autolock l(mLock);
@@ -273,7 +276,7 @@
sessionStats->onActive(proxyBinder, maxPreviewFps);
}
-void CameraServiceProxyWrapper::logIdle(const String8& id,
+void CameraServiceProxyWrapper::logIdle(const std::string& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode,
const std::vector<hardware::CameraStreamStats>& streamStats) {
@@ -304,8 +307,8 @@
videoStabilizationMode, streamStats);
}
-void CameraServiceProxyWrapper::logOpen(const String8& id, int facing,
- const String16& clientPackageName, int effectiveApiLevel, bool isNdk,
+void CameraServiceProxyWrapper::logOpen(const std::string& id, int facing,
+ const std::string& clientPackageName, int effectiveApiLevel, bool isNdk,
int32_t latencyMs) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
@@ -325,7 +328,7 @@
int64_t logId = generateLogId(mRandomDevice);
sessionStats = std::make_shared<CameraSessionStatsWrapper>(
- String16(id), facing, CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
+ id, facing, CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
apiLevel, isNdk, latencyMs, logId);
mSessionStatsMap.emplace(id, sessionStats);
ALOGV("%s: Adding id %s", __FUNCTION__, id.c_str());
@@ -337,7 +340,8 @@
sessionStats->onOpen(proxyBinder);
}
-void CameraServiceProxyWrapper::logClose(const String8& id, int32_t latencyMs, bool deviceError) {
+void CameraServiceProxyWrapper::logClose(const std::string& id, int32_t latencyMs,
+ bool deviceError) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
Mutex::Autolock l(mLock);
@@ -376,7 +380,7 @@
return ret;
}
-int64_t CameraServiceProxyWrapper::getCurrentLogIdForCamera(const String8& cameraId) {
+int64_t CameraServiceProxyWrapper::getCurrentLogIdForCamera(const std::string& cameraId) {
std::shared_ptr<CameraSessionStatsWrapper> stats;
{
Mutex::Autolock _l(mLock);
@@ -403,10 +407,10 @@
return ret;
}
-String16 CameraServiceProxyWrapper::updateExtensionStats(
+std::string CameraServiceProxyWrapper::updateExtensionStats(
const hardware::CameraExtensionSessionStats& extStats) {
std::shared_ptr<CameraSessionStatsWrapper> stats;
- String8 cameraId = String8(extStats.cameraId);
+ std::string cameraId = toStdString(extStats.cameraId);
{
Mutex::Autolock _l(mLock);
if (mSessionStatsMap.count(cameraId) == 0) {
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index e32580c..1afe5b3 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -20,11 +20,10 @@
#include <android/hardware/ICameraServiceProxy.h>
#include <utils/Mutex.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
#include <random>
+#include <string>
#include <camera/CameraSessionStats.h>
@@ -49,8 +48,8 @@
void updateProxyDeviceState(sp<hardware::ICameraServiceProxy>& proxyBinder);
public:
- CameraSessionStatsWrapper(const String16& cameraId, int facing, int newCameraState,
- const String16& clientName, int apiLevel, bool isNdk,
+ CameraSessionStatsWrapper(const std::string& cameraId, int facing, int newCameraState,
+ const std::string& clientName, int apiLevel, bool isNdk,
int32_t latencyMs, int64_t logId)
: mSessionStats(cameraId, facing, newCameraState, clientName, apiLevel, isNdk,
latencyMs, logId) {}
@@ -65,7 +64,8 @@
const std::string& userTag, int32_t videoStabilizationMode,
const std::vector<hardware::CameraStreamStats>& streamStats);
- String16 updateExtensionSessionStats(const hardware::CameraExtensionSessionStats& extStats);
+ std::string updateExtensionSessionStats(
+ const hardware::CameraExtensionSessionStats& extStats);
// Returns the logId associated with this event.
int64_t getLogId();
@@ -74,7 +74,7 @@
// Lock for camera session stats map
Mutex mLock;
// Map from camera id to the camera's session statistics
- std::map<String8, std::shared_ptr<CameraSessionStatsWrapper>> mSessionStatsMap;
+ std::map<std::string, std::shared_ptr<CameraSessionStatsWrapper>> mSessionStatsMap;
std::random_device mRandomDevice; // pulls 32-bit random numbers from /dev/urandom
@@ -93,22 +93,22 @@
static sp<hardware::ICameraServiceProxy> getDefaultCameraServiceProxy();
// Open
- void logOpen(const String8& id, int facing,
- const String16& clientPackageName, int apiLevel, bool isNdk,
+ void logOpen(const std::string& id, int facing,
+ const std::string& clientPackageName, int apiLevel, bool isNdk,
int32_t latencyMs);
// Close
- void logClose(const String8& id, int32_t latencyMs, bool deviceError);
+ void logClose(const std::string& id, int32_t latencyMs, bool deviceError);
// Stream configuration
- void logStreamConfigured(const String8& id, int operatingMode, bool internalReconfig,
+ void logStreamConfigured(const std::string& id, int operatingMode, bool internalReconfig,
int32_t latencyMs);
// Session state becomes active
- void logActive(const String8& id, float maxPreviewFps);
+ void logActive(const std::string& id, float maxPreviewFps);
// Session state becomes idle
- void logIdle(const String8& id,
+ void logIdle(const std::string& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode,
const std::vector<hardware::CameraStreamStats>& streamStats);
@@ -117,10 +117,10 @@
void pingCameraServiceProxy();
// Return the current top activity rotate and crop override.
- int getRotateAndCropOverride(String16 packageName, int lensFacing, int userId);
+ int getRotateAndCropOverride(const std::string &packageName, int lensFacing, int userId);
// Return the current top activity autoframing.
- int getAutoframingOverride(const String16& packageName);
+ int getAutoframingOverride(const std::string& packageName);
// Detect if the camera is disabled by device policy.
bool isCameraDisabled(int userId);
@@ -128,10 +128,10 @@
// Returns the logId currently associated with the given cameraId. See 'mLogId' in
// frameworks/av/camera/include/camera/CameraSessionStats.h for more details about this
// identifier. Returns a non-0 value on success.
- int64_t getCurrentLogIdForCamera(const String8& cameraId);
+ int64_t getCurrentLogIdForCamera(const std::string& cameraId);
// Update the stored extension stats to the latest values
- String16 updateExtensionStats(const hardware::CameraExtensionSessionStats& extStats);
+ std::string updateExtensionStats(const hardware::CameraExtensionSessionStats& extStats);
};
} // android
diff --git a/services/camera/libcameraservice/utils/CameraTraces.h b/services/camera/libcameraservice/utils/CameraTraces.h
index 71fa334..be8d393 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.h
+++ b/services/camera/libcameraservice/utils/CameraTraces.h
@@ -18,7 +18,6 @@
#define ANDROID_SERVERS_CAMERA_TRACES_H_
#include <utils/Errors.h>
-#include <utils/String16.h>
#include <utils/Vector.h>
namespace android {
diff --git a/services/camera/libcameraservice/utils/LatencyHistogram.cpp b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
index e2bdc43..a167068 100644
--- a/services/camera/libcameraservice/utils/LatencyHistogram.cpp
+++ b/services/camera/libcameraservice/utils/LatencyHistogram.cpp
@@ -16,8 +16,9 @@
#define LOG_TAG "CameraLatencyHistogram"
#include <inttypes.h>
+#include <android-base/stringprintf.h>
#include <utils/Log.h>
-#include <utils/String8.h>
+#include <camera/StringUtils.h>
#include "LatencyHistogram.h"
@@ -55,18 +56,18 @@
return;
}
- String8 lines;
- lines.appendFormat("%s (%" PRId64 ") samples\n", name, mTotalCount);
+ std::string lines;
+ lines += fmt::sprintf("%s (%" PRId64 ") samples\n", name, mTotalCount);
- String8 lineBins, lineBinCounts;
+ std::string lineBins, lineBinCounts;
formatHistogramText(lineBins, lineBinCounts);
- lineBins.append("\n");
- lineBinCounts.append("\n");
- lines.append(lineBins);
- lines.append(lineBinCounts);
+ lineBins += ("\n");
+ lineBinCounts += ("\n");
+ lines += lineBins;
+ lines += lineBinCounts;
- write(fd, lines.string(), lines.size());
+ write(fd, lines.c_str(), lines.size());
}
void CameraLatencyHistogram::log(const char* fmt, ...) {
@@ -76,11 +77,12 @@
va_list args;
va_start(args, fmt);
- String8 histogramName = String8::formatV(fmt, args);
- ALOGI("%s (%" PRId64 ") samples:", histogramName.string(), mTotalCount);
+ std::string histogramName;
+ base::StringAppendV(&histogramName, fmt, args);
+ ALOGI("%s (%" PRId64 ") samples:", histogramName.c_str(), mTotalCount);
va_end(args);
- String8 lineBins, lineBinCounts;
+ std::string lineBins, lineBinCounts;
formatHistogramText(lineBins, lineBinCounts);
ALOGI("%s", lineBins.c_str());
@@ -88,19 +90,19 @@
}
void CameraLatencyHistogram::formatHistogramText(
- String8& lineBins, String8& lineBinCounts) const {
+ std::string& lineBins, std::string& lineBinCounts) const {
lineBins = " ";
lineBinCounts = " ";
for (int32_t i = 0; i < mBinCount; i++) {
if (i == mBinCount - 1) {
- lineBins.append(" inf (max ms)");
+ lineBins += " inf (max ms)";
} else {
- lineBins.appendFormat("%7d", mBinSizeMs*(i+1));
+ lineBins += fmt::sprintf("%7d", mBinSizeMs*(i+1));
}
- lineBinCounts.appendFormat(" %02.2f", 100.0*mBins[i]/mTotalCount);
+ lineBinCounts += fmt::sprintf(" %02.2f", 100.0*mBins[i]/mTotalCount);
}
- lineBinCounts.append(" (%)");
+ lineBinCounts += " (%)";
}
}; //namespace android
diff --git a/services/camera/libcameraservice/utils/LatencyHistogram.h b/services/camera/libcameraservice/utils/LatencyHistogram.h
index bfd9b1b..89a9cc1 100644
--- a/services/camera/libcameraservice/utils/LatencyHistogram.h
+++ b/services/camera/libcameraservice/utils/LatencyHistogram.h
@@ -40,7 +40,7 @@
std::vector<int64_t> mBins;
uint64_t mTotalCount;
- void formatHistogramText(String8& lineBins, String8& lineBinCounts) const;
+ void formatHistogramText(std::string& lineBins, std::string& lineBinCounts) const;
}; // class CameraLatencyHistogram
}; // namespace android
diff --git a/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp
new file mode 100644
index 0000000..92a1030
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SchedulingPolicyUtils.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+
+#include "CameraThreadState.h"
+#include <private/android_filesystem_config.h>
+#include <processgroup/processgroup.h>
+#include <processgroup/sched_policy.h>
+#include <procinfo/process.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace camera3 {
+namespace SchedulingPolicyUtils {
+
+int requestPriorityDirect(int pid, int tid, int prio) {
+ android::procinfo::ProcessInfo processInfo;
+ static const int kMinPrio = 1;
+ static const int kMaxPrio = 3;
+
+ if (!android::procinfo::GetProcessInfo(tid, &processInfo)) {
+ ALOGE("%s: Error getting process info", __FUNCTION__);
+ return -EPERM;
+ }
+
+ if (prio < kMinPrio || prio > kMaxPrio || processInfo.pid != pid) {
+ ALOGE("%s: Invalid parameter prio=%d pid=%d procinfo.pid=%d", __FUNCTION__, prio, pid,
+ processInfo.pid);
+ return -EPERM;
+ }
+
+ // Set the thread group as audio system thread group in consistent with the
+ // implementation in SchedulingPolicyService.java when isApp is false in
+ // requestPriority method.
+ if (!SetTaskProfiles(tid, {get_sched_policy_profile_name(SP_AUDIO_SYS)},
+ /*use_fd_cache*/ true)) {
+ ALOGE("%s:Error in SetTaskProfiles", __FUNCTION__);
+ return -EPERM;
+ }
+
+ struct sched_param param;
+ param.sched_priority = prio;
+ return sched_setscheduler(tid, SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m);
+}
+
+} // namespace SchedulingPolicyUtils
+} // namespace camera3
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h
new file mode 100644
index 0000000..f71fddf
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SchedulingPolicyUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVICE_CAMERA_SCHEDULING_POLICY_UTILS_H
+#define ANDROID_SERVICE_CAMERA_SCHEDULING_POLICY_UTILS_H
+
+namespace android {
+namespace camera3 {
+namespace SchedulingPolicyUtils {
+
+/**
+ * Request elevated priority for thread tid, whose thread group leader must be pid.
+ * Instead of using scheduling policy service, this method uses direct system calls.
+ * The priority parameter is currently restricted from 1 to 3 matching
+ * scheduling policy service implementation.
+ */
+int requestPriorityDirect(int pid, int tid, int prio);
+
+} // SchedulingPolicyUtils
+} // camera3
+} // android
+
+#endif
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 89e75b3..f7257e3 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -28,6 +28,7 @@
#include "device3/hidl/HidlCamera3Device.h"
#include "device3/Camera3OutputStream.h"
#include "system/graphics-base-v1.1.h"
+#include <camera/StringUtils.h>
#include <ui/PublicFormat.h>
using android::camera3::OutputStreamInfo;
@@ -427,15 +428,15 @@
binder::Status createSurfaceFromGbp(
OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
- const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
+ const std::string &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int64_t dynamicRangeProfile,
int64_t streamUseCase, int timestampBase, int mirrorMode,
int32_t colorSpace) {
// bufferProducer must be non-null
if (gbp == nullptr) {
- String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Surface is NULL", logicalCameraId.c_str());
+ ALOGW("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
// HACK b/10949105
// Query consumer usage bits to set async operation mode for
@@ -444,14 +445,14 @@
uint64_t consumerUsage = 0;
status_t err;
if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
- logicalCameraId.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Failed to query Surface consumer usage: %s (%d)",
+ logicalCameraId.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
- "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
+ "stream", __FUNCTION__, logicalCameraId.c_str(), consumerUsage);
useAsync = true;
}
@@ -469,38 +470,38 @@
int width, height, format;
android_dataspace dataSpace;
if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
- logicalCameraId.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Failed to query Surface width: %s (%d)",
+ logicalCameraId.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
- logicalCameraId.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Failed to query Surface height: %s (%d)",
+ logicalCameraId.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
- logicalCameraId.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Failed to query Surface format: %s (%d)",
+ logicalCameraId.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
reinterpret_cast<int*>(&dataSpace))) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
- logicalCameraId.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: Failed to query Surface dataspace: %s (%d)",
+ logicalCameraId.c_str(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
}
if (colorSpace != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED &&
format != HAL_PIXEL_FORMAT_BLOB) {
if (!dataSpaceFromColorSpace(&dataSpace, colorSpace)) {
- String8 msg = String8::format("Camera %s: color space %d not supported, failed to "
- "convert to data space", logicalCameraId.string(), colorSpace);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: color space %d not supported, failed to "
+ "convert to data space", logicalCameraId.c_str(), colorSpace);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
}
@@ -510,16 +511,16 @@
((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
- __FUNCTION__, logicalCameraId.string(), format);
+ __FUNCTION__, logicalCameraId.c_str(), format);
format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
}
std::unordered_set<int32_t> overriddenSensorPixelModes;
if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
physicalCameraMetadata, &overriddenSensorPixelModes) != OK) {
- String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
- "format %#x are not valid",logicalCameraId.string(), format);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: sensor pixel modes for stream with "
+ "format %#x are not valid",logicalCameraId.c_str(), format);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
bool foundInMaxRes = false;
if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -532,58 +533,58 @@
!SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
/*out*/&height)) {
- String8 msg = String8::format("Camera %s: No supported stream configurations with "
+ std::string msg = fmt::sprintf("Camera %s: No supported stream configurations with "
"format %#x defined, failed to create output stream",
- logicalCameraId.string(), format);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logicalCameraId.c_str(), format);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
physicalCameraMetadata)) {
- String8 msg = String8::format("Camera %s: Dynamic range profile 0x%" PRIx64
- " not supported,failed to create output stream", logicalCameraId.string(),
+ std::string msg = fmt::sprintf("Camera %s: Dynamic range profile 0x%" PRIx64
+ " not supported,failed to create output stream", logicalCameraId.c_str(),
dynamicRangeProfile);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
!SessionConfigurationUtils::is10bitCompatibleFormat(format, dataSpace)) {
- String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
+ std::string msg = fmt::sprintf("Camera %s: No 10-bit supported stream configurations with "
"format %#x defined and profile %" PRIx64 ", failed to create output stream",
- logicalCameraId.string(), format, dynamicRangeProfile);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logicalCameraId.c_str(), format, dynamicRangeProfile);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (colorSpace != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED &&
SessionConfigurationUtils::deviceReportsColorSpaces(physicalCameraMetadata) &&
!SessionConfigurationUtils::isColorSpaceSupported(colorSpace, format, dataSpace,
dynamicRangeProfile, physicalCameraMetadata)) {
- String8 msg = String8::format("Camera %s: Color space %d not supported, failed to "
+ std::string msg = fmt::sprintf("Camera %s: Color space %d not supported, failed to "
"create output stream (pixel format %d dynamic range profile %" PRId64 ")",
- logicalCameraId.string(), colorSpace, format, dynamicRangeProfile);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logicalCameraId.c_str(), colorSpace, format, dynamicRangeProfile);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
physicalCameraMetadata)) {
- String8 msg = String8::format("Camera %s: stream use case %" PRId64 " not supported,"
- " failed to create output stream", logicalCameraId.string(), streamUseCase);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: stream use case %" PRId64 " not supported,"
+ " failed to create output stream", logicalCameraId.c_str(), streamUseCase);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
timestampBase > OutputConfiguration::TIMESTAMP_BASE_MAX) {
- String8 msg = String8::format("Camera %s: invalid timestamp base %d",
- logicalCameraId.string(), timestampBase);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: invalid timestamp base %d",
+ logicalCameraId.c_str(), timestampBase);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (mirrorMode < OutputConfiguration::MIRROR_MODE_AUTO ||
mirrorMode > OutputConfiguration::MIRROR_MODE_V) {
- String8 msg = String8::format("Camera %s: invalid mirroring mode %d",
- logicalCameraId.string(), mirrorMode);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s: invalid mirroring mode %d",
+ logicalCameraId.c_str(), mirrorMode);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (!isStreamInfoValid) {
@@ -601,45 +602,45 @@
return binder::Status::ok();
}
if (width != streamInfo.width) {
- String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
- logicalCameraId.string(), width, streamInfo.width);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s:Surface width doesn't match: %d vs %d",
+ logicalCameraId.c_str(), width, streamInfo.width);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (height != streamInfo.height) {
- String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
- logicalCameraId.string(), height, streamInfo.height);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s:Surface height doesn't match: %d vs %d",
+ logicalCameraId.c_str(), height, streamInfo.height);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (format != streamInfo.format) {
- String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
- logicalCameraId.string(), format, streamInfo.format);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s:Surface format doesn't match: %d vs %d",
+ logicalCameraId.c_str(), format, streamInfo.format);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
if (dataSpace != streamInfo.dataSpace) {
- String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
- logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg = fmt::sprintf("Camera %s:Surface dataSpace doesn't match: %d vs %d",
+ logicalCameraId.c_str(), dataSpace, streamInfo.dataSpace);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
//At the native side, there isn't a way to check whether 2 surfaces come from the same
//surface class type. Use usage flag to approximate the comparison.
if (consumerUsage != streamInfo.consumerUsage) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
- logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logicalCameraId.c_str(), consumerUsage, streamInfo.consumerUsage);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
}
return binder::Status::ok();
}
void mapStreamInfo(const OutputStreamInfo &streamInfo,
- camera3::camera_stream_rotation_t rotation, String8 physicalId,
+ camera3::camera_stream_rotation_t rotation, const std::string &physicalId,
int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
if (stream == nullptr) {
return;
@@ -656,7 +657,7 @@
stream->colorSpace = streamInfo.colorSpace;
stream->rotation = AidlCamera3Device::mapToAidlStreamRotation(rotation);
stream->id = -1; // Invalid stream id
- stream->physicalCameraId = std::string(physicalId.string());
+ stream->physicalCameraId = physicalId;
stream->bufferSize = 0;
stream->groupId = groupId;
stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
@@ -677,34 +678,35 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
bool isCompositeJpegRDisabled,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
auto operatingMode = sessionConfiguration.getOperatingMode();
- binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
+ binder::Status res = checkOperatingMode(operatingMode, deviceInfo,
+ logicalCameraId);
if (!res.isOk()) {
return res;
}
if (earlyExit == nullptr) {
- String8 msg("earlyExit nullptr");
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ std::string msg("earlyExit nullptr");
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
*earlyExit = false;
auto ret = AidlCamera3Device::mapToAidlStreamConfigurationMode(
static_cast<camera_stream_configuration_mode_t> (operatingMode),
/*out*/ &streamConfiguration.operationMode);
if (ret != OK) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Failed mapping operating mode %d requested: %s (%d)",
- logicalCameraId.string(), operatingMode, strerror(-ret), ret);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ logicalCameraId.c_str(), operatingMode, strerror(-ret), ret);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
+ msg.c_str());
}
bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
@@ -749,7 +751,7 @@
const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
it.getGraphicBufferProducers();
bool deferredConsumer = it.isDeferred();
- String8 physicalCameraId = String8(it.getPhysicalCameraId());
+ const std::string &physicalCameraId = it.getPhysicalCameraId();
int64_t dynamicRangeProfile = it.getDynamicRangeProfile();
int32_t colorSpace = it.getColorSpace();
@@ -841,11 +843,11 @@
}
if (ret != OK) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Failed adding composite streams: %s (%d)",
- logicalCameraId.string(), strerror(-ret), ret);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ logicalCameraId.c_str(), strerror(-ret), ret);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
if (compositeStreams.size() == 0) {
@@ -877,17 +879,17 @@
}
binder::Status checkPhysicalCameraId(
- const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
- const String8 &logicalCameraId) {
+ const std::vector<std::string> &physicalCameraIds, const std::string &physicalCameraId,
+ const std::string &logicalCameraId) {
if (physicalCameraId.size() == 0) {
return binder::Status::ok();
}
if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
- physicalCameraId.string()) == physicalCameraIds.end()) {
- String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
- logicalCameraId.string(), physicalCameraId.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ physicalCameraId) == physicalCameraIds.end()) {
+ std::string msg = fmt::sprintf("Camera %s: Camera doesn't support physicalCameraId %s.",
+ logicalCameraId.c_str(), physicalCameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
return binder::Status::ok();
}
@@ -915,13 +917,13 @@
}
binder::Status checkOperatingMode(int operatingMode,
- const CameraMetadata &staticInfo, const String8 &cameraId) {
+ const CameraMetadata &staticInfo, const std::string &cameraId) {
if (operatingMode < 0) {
- String8 msg = String8::format(
- "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ std::string msg = fmt::sprintf(
+ "Camera %s: Invalid operating mode %d requested", cameraId.c_str(), operatingMode);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
+ msg.c_str());
}
bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
@@ -936,12 +938,12 @@
}
}
if (!isConstrainedHighSpeedSupported) {
- String8 msg = String8::format(
+ std::string msg = fmt::sprintf(
"Camera %s: Try to create a constrained high speed configuration on a device"
- " that doesn't support it.", cameraId.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
+ " that doesn't support it.", cameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
+ msg.c_str());
}
}
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index dc143da..79d80ea 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -21,6 +21,7 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
+#include <camera/StringUtils.h>
#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
@@ -37,17 +38,18 @@
#define STATUS_ERROR(errorCode, errorString) \
binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
+ fmt::sprintf("%s:%d: %s", __FUNCTION__, __LINE__, errorString).c_str())
#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
binder::Status::fromServiceSpecificError(errorCode, \
- String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
- __VA_ARGS__))
+ fmt::sprintf("%s:%d: " errorString, __FUNCTION__, __LINE__, \
+ __VA_ARGS__).c_str())
namespace android {
namespace camera3 {
-typedef std::function<CameraMetadata (const String8 &, bool overrideForPerfClass)> metadataGetter;
+typedef std::function<CameraMetadata (const std::string &, bool overrideForPerfClass)>
+ metadataGetter;
class StreamConfiguration {
public:
@@ -96,7 +98,7 @@
binder::Status createSurfaceFromGbp(
camera3::OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
- const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
+ const std::string &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int64_t dynamicRangeProfile,
int64_t streamUseCase, int timestampBase, int mirrorMode,
int32_t colorSpace);
@@ -120,26 +122,27 @@
bool isStreamUseCaseSupported(int64_t streamUseCase, const CameraMetadata &deviceInfo);
void mapStreamInfo(const OutputStreamInfo &streamInfo,
- camera3::camera_stream_rotation_t rotation, String8 physicalId,
+ camera3::camera_stream_rotation_t rotation, const std::string &physicalId,
int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/);
// Check that the physicalCameraId passed in is spported by the camera
// device.
binder::Status checkPhysicalCameraId(
-const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
-const String8 &logicalCameraId);
+const std::vector<std::string> &physicalCameraIds, const std::string &physicalCameraId,
+const std::string &logicalCameraId);
binder::Status checkSurfaceType(size_t numBufferProducers,
bool deferredConsumer, int surfaceType);
binder::Status checkOperatingMode(int operatingMode,
-const CameraMetadata &staticInfo, const String8 &cameraId);
+const CameraMetadata &staticInfo, const std::string &cameraId);
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool isCompositeJpegRDisabled,
- metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+ const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
+ bool isCompositeJpegRDisabled, metadataGetter getMetadata,
+ const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index 111c1bf..cf93d3b 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -105,7 +105,7 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
index c47abe0..eae2e30 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
@@ -34,7 +34,7 @@
// isn't valid.
binder::Status
convertToHALStreamCombination(const SessionConfiguration& sessionConfiguration,
- const String8 &cameraId, const CameraMetadata &deviceInfo,
+ const std::string &cameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp
index d1e54ab..38de93a 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.cpp
+++ b/services/camera/libcameraservice/utils/TagMonitor.cpp
@@ -18,11 +18,15 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <iostream>
+#include <sstream>
+
#include "TagMonitor.h"
#include <inttypes.h>
#include <utils/Log.h>
#include <camera/VendorTagDescriptor.h>
+#include <camera/StringUtils.h>
#include <camera_metadata_hidden.h>
#include <device3/Camera3Stream.h>
@@ -44,7 +48,7 @@
mMonitoringEvents(other.mMonitoringEvents),
mVendorTagId(other.mVendorTagId) {}
-const String16 TagMonitor::kMonitorOption = String16("-m");
+const std::string TagMonitor::kMonitorOption("-m");
const char* TagMonitor::k3aTags =
"android.control.aeMode, android.control.afMode, android.control.awbMode,"
@@ -56,17 +60,17 @@
"android.control.effectMode, android.control.mode, android.control.sceneMode,"
"android.control.videoStabilizationMode";
-void TagMonitor::parseTagsToMonitor(String8 tagNames) {
+void TagMonitor::parseTagsToMonitor(std::string tagNames) {
std::lock_guard<std::mutex> lock(mMonitorMutex);
// Expand shorthands
ssize_t idx = tagNames.find("3a");
if (idx != -1) {
ssize_t end = tagNames.find(",", idx);
- char* start = tagNames.lockBuffer(tagNames.size());
- start[idx] = '\0';
- char* rest = (end != -1) ? (start + end) : (start + tagNames.size());
- tagNames = String8::format("%s%s%s", start, k3aTags, rest);
+ tagNames = tagNames.substr(0, idx) + k3aTags;
+ if (end != -1) {
+ tagNames += tagNames.substr(end);
+ }
}
sp<VendorTagDescriptor> vTags =
@@ -81,14 +85,13 @@
bool gotTag = false;
- char *tokenized = tagNames.lockBuffer(tagNames.size());
- char *savePtr;
- char *nextTagName = strtok_r(tokenized, ", ", &savePtr);
- while (nextTagName != nullptr) {
+ std::istringstream iss(tagNames);
+ std::string nextTagName;
+ while (std::getline(iss, nextTagName, ',')) {
uint32_t tag;
- status_t res = CameraMetadata::getTagFromName(nextTagName, vTags.get(), &tag);
+ status_t res = CameraMetadata::getTagFromName(nextTagName.c_str(), vTags.get(), &tag);
if (res != OK) {
- ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName);
+ ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName.c_str());
} else {
if (!gotTag) {
mMonitoredTagList.clear();
@@ -96,11 +99,9 @@
}
mMonitoredTagList.push_back(tag);
}
- nextTagName = strtok_r(nullptr, ", ", &savePtr);
+ iss >> std::ws;
}
- tagNames.unlockBuffer();
-
if (gotTag) {
// Got at least one new tag
mMonitoringEnabled = true;
@@ -269,7 +270,7 @@
for (const auto& event : mMonitoringEvents) {
int indentation = (event.source == REQUEST) ? 15 : 30;
- String8 eventString = String8::format("f%d:%" PRId64 "ns:%*s%*s",
+ std::string eventString = fmt::sprintf("f%d:%" PRId64 "ns:%*s%*s",
event.frameNumber, event.timestamp,
2, event.cameraId.c_str(),
indentation,
@@ -278,20 +279,20 @@
if (!event.outputStreamIds.empty()) {
eventString += " output stream ids:";
for (const auto& id : event.outputStreamIds) {
- eventString.appendFormat(" %d", id);
+ eventString += fmt::sprintf(" %d", id);
}
eventString += "\n";
- vec.emplace_back(eventString.string());
+ vec.emplace_back(eventString);
continue;
}
if (event.inputStreamId != -1) {
- eventString.appendFormat(" input stream id: %d\n", event.inputStreamId);
- vec.emplace_back(eventString.string());
+ eventString += fmt::sprintf(" input stream id: %d\n", event.inputStreamId);
+ vec.emplace_back(eventString);
continue;
}
- eventString += String8::format(
+ eventString += fmt::sprintf(
"%s.%s: ",
get_local_camera_metadata_section_name_vendor_id(event.tag, mVendorTagId),
get_local_camera_metadata_tag_name_vendor_id(event.tag, mVendorTagId));
@@ -303,14 +304,14 @@
event.newData.data(), event.tag, event.type,
event.newData.size() / camera_metadata_type_size[event.type], indentation + 18);
}
- vec.emplace_back(eventString.string());
+ vec.emplace_back(eventString);
}
}
#define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29
-String8 TagMonitor::getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type, int count,
- int indentation) {
+std::string TagMonitor::getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type,
+ int count, int indentation) {
static int values_per_line[NUM_TYPES] = {
[TYPE_BYTE] = 16,
[TYPE_INT32] = 8,
@@ -327,11 +328,11 @@
int lines = count / values_per_line[type];
if (count % values_per_line[type] != 0) lines++;
- String8 returnStr = String8();
+ std::ostringstream returnStr;
int index = 0;
int j, k;
for (j = 0; j < lines; j++) {
- returnStr.appendFormat("%*s[", (j != 0) ? indentation + 4 : 0, "");
+ returnStr << fmt::sprintf("%*s[", (j != 0) ? indentation + 4 : 0, "");
for (k = 0;
k < values_per_line[type] && count > 0;
k++, count--, index += type_size) {
@@ -344,9 +345,9 @@
value_string_tmp,
sizeof(value_string_tmp))
== OK) {
- returnStr += value_string_tmp;
+ returnStr << value_string_tmp;
} else {
- returnStr.appendFormat("%hhu ", *(data_ptr + index));
+ returnStr << fmt::sprintf("%hhu ", *(data_ptr + index));
}
break;
case TYPE_INT32:
@@ -357,33 +358,33 @@
value_string_tmp,
sizeof(value_string_tmp))
== OK) {
- returnStr += value_string_tmp;
+ returnStr << value_string_tmp;
} else {
- returnStr.appendFormat("%" PRId32 " ", *(int32_t*)(data_ptr + index));
+ returnStr << fmt::sprintf("%" PRId32 " ", *(int32_t*)(data_ptr + index));
}
break;
case TYPE_FLOAT:
- returnStr.appendFormat("%0.8f ", *(float*)(data_ptr + index));
+ returnStr << fmt::sprintf("%0.8f ", *(float*)(data_ptr + index));
break;
case TYPE_INT64:
- returnStr.appendFormat("%" PRId64 " ", *(int64_t*)(data_ptr + index));
+ returnStr << fmt::sprintf("%" PRId64 " ", *(int64_t*)(data_ptr + index));
break;
case TYPE_DOUBLE:
- returnStr.appendFormat("%0.8f ", *(double*)(data_ptr + index));
+ returnStr << fmt::sprintf("%0.8f ", *(double*)(data_ptr + index));
break;
case TYPE_RATIONAL: {
int32_t numerator = *(int32_t*)(data_ptr + index);
int32_t denominator = *(int32_t*)(data_ptr + index + 4);
- returnStr.appendFormat("(%d / %d) ", numerator, denominator);
+ returnStr << fmt::sprintf("(%d / %d) ", numerator, denominator);
break;
}
default:
- returnStr += "??? ";
+ returnStr << "??? ";
}
}
- returnStr += "]\n";
+ returnStr << "]\n";
}
- return returnStr;
+ return std::move(returnStr.str());
}
template<typename T>
diff --git a/services/camera/libcameraservice/utils/TagMonitor.h b/services/camera/libcameraservice/utils/TagMonitor.h
index 9ded15d..bff4de0 100644
--- a/services/camera/libcameraservice/utils/TagMonitor.h
+++ b/services/camera/libcameraservice/utils/TagMonitor.h
@@ -21,9 +21,9 @@
#include <atomic>
#include <mutex>
#include <unordered_map>
+#include <string>
#include <utils/RefBase.h>
-#include <utils/String8.h>
#include <utils/Timers.h>
#include <media/RingBuffer.h>
@@ -42,7 +42,7 @@
public:
// Monitor argument
- static const String16 kMonitorOption;
+ static const std::string kMonitorOption;
enum eventSource {
REQUEST,
@@ -59,7 +59,7 @@
// If invalid, do nothing.
// Recognizes "3a" as a shortcut for enabling tracking 3A state, mode, and
// triggers
- void parseTagsToMonitor(String8 tagNames);
+ void parseTagsToMonitor(std::string tagNames);
// Disable monitoring; does not clear the event log
void disableMonitoring();
@@ -85,8 +85,8 @@
// function.
void dumpMonitoredTagEventsToVectorLocked(std::vector<std::string> &out);
- static String8 getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type, int count,
- int indentation);
+ static std::string getEventDataString(const uint8_t* data_ptr, uint32_t tag, int type,
+ int count, int indentation);
void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber,
nsecs_t timestamp, const std::string& cameraId, uint32_t tag,
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 59d1ae4..bd4ac38 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -242,6 +242,7 @@
"channel_count_hardware",
"sample_rate_hardware",
"uid",
+ "sample_rate_client",
};
static constexpr const char * HeadTrackerDeviceEnabledFields[] {
@@ -1379,6 +1380,10 @@
const auto uid = item->getUid();
+ int32_t sampleRateClient = 0;
+ mAudioAnalytics.mAnalyticsState->timeMachine().get(
+ key, AMEDIAMETRICS_PROP_SAMPLERATECLIENT, &sampleRateClient);
+
LOG(LOG_LEVEL) << "key:" << key
<< " path:" << path
<< " direction:" << direction << "(" << directionStr << ")"
@@ -1402,7 +1407,8 @@
<< " format_hardware:" << formatHardware << "(" << formatHardwareStr << ")"
<< " channel_count_hardware:" << channelCountHardware
<< " sample_rate_hardware: " << sampleRateHardware
- << " uid: " << uid;
+ << " uid: " << uid
+ << " sample_rate_client: " << sampleRateClient;
if (mAudioAnalytics.mDeliverStatistics) {
const stats::media_metrics::BytesField bf_serialized(
@@ -1431,6 +1437,7 @@
, channelCountHardware
, sampleRateHardware
, uid
+ , sampleRateClient
);
std::stringstream ss;
ss << "result:" << result;
@@ -1458,6 +1465,7 @@
, channelCountHardware
, sampleRateHardware
, uid
+ , sampleRateClient
);
ss << " " << fieldsStr;
std::string str = ss.str();
diff --git a/services/mediaresourcemanager/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index d98974f..f38a085 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -27,21 +27,18 @@
default_applicable_licenses: ["frameworks_av_license"],
}
-cc_fuzz {
- name: "mediaresourcemanager_fuzzer",
- srcs: [
- "mediaresourcemanager_fuzzer.cpp",
+cc_defaults {
+ name: "mediaresourcemanager_fuzzer_defaults",
+ defaults: [
+ "service_fuzzer_defaults",
],
static_libs: [
"liblog",
"libresourcemanagerservice",
],
shared_libs: [
- "libbinder",
- "libbinder_ndk",
"libmedia",
"libmediautils",
- "libutils",
"libstats_media_metrics",
"libstatspull",
"libstatssocket",
@@ -54,3 +51,39 @@
componentid: 155276,
},
}
+
+cc_fuzz {
+ name: "mediaresourcemanager_fuzzer",
+ defaults: [
+ "mediaresourcemanager_fuzzer_defaults",
+ ],
+ srcs: [
+ "mediaresourcemanager_fuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "resourcemanager_service_fuzzer",
+ defaults: [
+ "mediaresourcemanager_fuzzer_defaults",
+ ],
+ srcs: [
+ "resourcemanager_service_fuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "resourceobserver_service_fuzzer",
+ defaults: [
+ "mediaresourcemanager_fuzzer_defaults",
+ ],
+ static_libs: [
+ "resourceobserver_aidl_interface-V1-ndk",
+ ],
+ srcs: [
+ "resourceobserver_service_fuzzer.cpp",
+ ],
+ fuzz_config: {
+ triage_assignee: "waghpawan@google.com",
+ },
+}
diff --git a/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
new file mode 100644
index 0000000..ca10d20
--- /dev/null
+++ b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "ResourceManagerService.h"
+
+using android::fuzzService;
+using android::ResourceManagerService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto service = SharedRefBase::make<ResourceManagerService>();
+ fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+ return 0;
+}
diff --git a/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp
new file mode 100644
index 0000000..e69368d
--- /dev/null
+++ b/services/mediaresourcemanager/fuzzer/resourceobserver_service_fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "ResourceObserverService.h"
+
+using android::fuzzService;
+using android::ResourceObserverService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto service = SharedRefBase::make<ResourceObserverService>();
+ fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+ return 0;
+}
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 7f228c7..2ef6fe5 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -45,6 +45,8 @@
#define OUTPUT_ESTIMATED_HARDWARE_OFFSET_NANOS (3 * AAUDIO_NANOS_PER_MILLISECOND)
#define INPUT_ESTIMATED_HARDWARE_OFFSET_NANOS (-1 * AAUDIO_NANOS_PER_MILLISECOND)
+#define AAUDIO_MAX_OPEN_ATTEMPTS 10
+
using namespace android; // TODO just import names needed
using namespace aaudio; // TODO just import names needed
@@ -77,14 +79,23 @@
{AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_16_BIT}
};
-audio_format_t getNextFormatToTry(audio_format_t curFormat, audio_format_t returnedFromAPM) {
- if (returnedFromAPM != AUDIO_FORMAT_DEFAULT) {
- return returnedFromAPM;
- }
+audio_format_t getNextFormatToTry(audio_format_t curFormat) {
const auto it = NEXT_FORMAT_TO_TRY.find(curFormat);
- return it != NEXT_FORMAT_TO_TRY.end() ? it->second : AUDIO_FORMAT_DEFAULT;
+ return it != NEXT_FORMAT_TO_TRY.end() ? it->second : curFormat;
}
+struct configComp {
+ bool operator() (const audio_config_base_t& lhs, const audio_config_base_t& rhs) const {
+ if (lhs.sample_rate != rhs.sample_rate) {
+ return lhs.sample_rate < rhs.sample_rate;
+ } else if (lhs.channel_mask != rhs.channel_mask) {
+ return lhs.channel_mask < rhs.channel_mask;
+ } else {
+ return lhs.format < rhs.format;
+ }
+ }
+};
+
} // namespace
aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
@@ -101,60 +112,66 @@
legacy2aidl_pid_t_int32_t(IPCThreadState::self()->getCallingPid()));
audio_format_t audioFormat = getFormat();
- std::set<audio_format_t> formatsTried;
- while (true) {
- if (formatsTried.find(audioFormat) != formatsTried.end()) {
+ int32_t sampleRate = getSampleRate();
+ if (sampleRate == AAUDIO_UNSPECIFIED) {
+ sampleRate = AAUDIO_SAMPLE_RATE_DEFAULT;
+ }
+
+ const aaudio_direction_t direction = getDirection();
+ audio_config_base_t config;
+ config.format = audioFormat;
+ config.sample_rate = sampleRate;
+ config.channel_mask = AAudio_getChannelMaskForOpen(
+ getChannelMask(), getSamplesPerFrame(), direction == AAUDIO_DIRECTION_INPUT);
+
+ std::set<audio_config_base_t, configComp> configsTried;
+ int32_t numberOfAttempts = 0;
+ while (numberOfAttempts < AAUDIO_MAX_OPEN_ATTEMPTS) {
+ if (configsTried.find(config) != configsTried.end()) {
// APM returning something that has already tried.
- ALOGW("Have already tried to open with format=%#x, but failed before", audioFormat);
+ ALOGW("Have already tried to open with format=%#x and sr=%d, but failed before",
+ config.format, config.sample_rate);
break;
}
- formatsTried.insert(audioFormat);
+ configsTried.insert(config);
- audio_format_t nextFormatToTry = AUDIO_FORMAT_DEFAULT;
- result = openWithFormat(audioFormat, &nextFormatToTry);
+ audio_config_base_t previousConfig = config;
+ result = openWithConfig(&config);
if (result != AAUDIO_ERROR_UNAVAILABLE) {
// Return if it is successful or there is an error that is not
// AAUDIO_ERROR_UNAVAILABLE happens.
- ALOGI("Opened format=%#x with result=%d", audioFormat, result);
+ ALOGI("Opened format=%#x sr=%d, with result=%d", previousConfig.format,
+ previousConfig.sample_rate, result);
break;
}
- nextFormatToTry = getNextFormatToTry(audioFormat, nextFormatToTry);
- ALOGD("%s() %#x failed, perhaps due to format. Try again with %#x",
- __func__, audioFormat, nextFormatToTry);
- audioFormat = nextFormatToTry;
- if (audioFormat == AUDIO_FORMAT_DEFAULT) {
- // Nothing else to try
- break;
+ // Try other formats if the config from APM is the same as our current config.
+ // Some HALs may report its format support incorrectly.
+ if ((previousConfig.format == config.format) &&
+ (previousConfig.sample_rate == config.sample_rate)) {
+ config.format = getNextFormatToTry(config.format);
}
+
+ ALOGD("%s() %#x %d failed, perhaps due to format or sample rate. Try again with %#x %d",
+ __func__, previousConfig.format, previousConfig.sample_rate, config.format,
+ config.sample_rate);
+ numberOfAttempts++;
}
return result;
}
-aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(
- audio_format_t audioFormat, audio_format_t* nextFormatToTry) {
+aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig(
+ audio_config_base_t* config) {
aaudio_result_t result = AAUDIO_OK;
- audio_config_base_t config;
+ audio_config_base_t currentConfig = *config;
audio_port_handle_t deviceId;
const audio_attributes_t attributes = getAudioAttributesFrom(this);
deviceId = mRequestedDeviceId;
- // Fill in config
- config.format = audioFormat;
-
- int32_t aaudioSampleRate = getSampleRate();
- if (aaudioSampleRate == AAUDIO_UNSPECIFIED) {
- aaudioSampleRate = AAUDIO_SAMPLE_RATE_DEFAULT;
- }
- config.sample_rate = aaudioSampleRate;
-
const aaudio_direction_t direction = getDirection();
- config.channel_mask = AAudio_getChannelMaskForOpen(
- getChannelMask(), getSamplesPerFrame(), direction == AAUDIO_DIRECTION_INPUT);
-
if (direction == AAUDIO_DIRECTION_OUTPUT) {
mHardwareTimeOffsetNanos = OUTPUT_ESTIMATED_HARDWARE_OFFSET_NANOS; // frames at DAC later
@@ -177,11 +194,11 @@
// Open HAL stream. Set mMmapStream
ALOGD("%s trying to open MMAP stream with format=%#x, "
"sample_rate=%u, channel_mask=%#x, device=%d",
- __func__, config.format, config.sample_rate,
- config.channel_mask, deviceId);
+ __func__, config->format, config->sample_rate,
+ config->channel_mask, deviceId);
const status_t status = MmapStreamInterface::openMmapStream(streamDirection,
&attributes,
- &config,
+ config,
mMmapClient,
&deviceId,
&sessionId,
@@ -195,9 +212,9 @@
// not match the hardware.
ALOGD("%s() - openMmapStream() returned status=%d, suggested format=%#x, sample_rate=%u, "
"channel_mask=%#x",
- __func__, status, config.format, config.sample_rate, config.channel_mask);
- *nextFormatToTry = config.format != audioFormat ? config.format
- : *nextFormatToTry;
+ __func__, status, config->format, config->sample_rate, config->channel_mask);
+ // Keep the channel mask of the current config
+ config->channel_mask = currentConfig.channel_mask;
return AAUDIO_ERROR_UNAVAILABLE;
}
@@ -217,7 +234,7 @@
setSessionId(actualSessionId);
ALOGD("%s(format = 0x%X) deviceId = %d, sessionId = %d",
- __func__, audioFormat, getDeviceId(), getSessionId());
+ __func__, config->format, getDeviceId(), getSessionId());
// Create MMAP/NOIRQ buffer.
result = createMmapBuffer();
@@ -227,11 +244,11 @@
// Get information about the stream and pass it back to the caller.
setChannelMask(AAudioConvert_androidToAAudioChannelMask(
- config.channel_mask, getDirection() == AAUDIO_DIRECTION_INPUT,
- AAudio_isChannelIndexMask(config.channel_mask)));
+ config->channel_mask, getDirection() == AAUDIO_DIRECTION_INPUT,
+ AAudio_isChannelIndexMask(config->channel_mask)));
- setFormat(config.format);
- setSampleRate(config.sample_rate);
+ setFormat(config->format);
+ setSampleRate(config->sample_rate);
setHardwareSampleRate(getSampleRate());
setHardwareFormat(getFormat());
setHardwareSamplesPerFrame(AAudioConvert_channelMaskToCount(getChannelMask()));
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 38cf0ba..f19005c 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -97,7 +97,7 @@
private:
- aaudio_result_t openWithFormat(audio_format_t audioFormat, audio_format_t* nextFormatToTry);
+ aaudio_result_t openWithConfig(audio_config_base_t* config);
aaudio_result_t createMmapBuffer();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index bc7ccde..8f51ce4 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -220,18 +220,6 @@
return mSuspended;
}
- bool isCloseNeeded() const {
- return mCloseNeeded.load();
- }
-
- /**
- * Mark this stream as needing to be closed.
- * Once marked for closing, it cannot be unmarked.
- */
- void markCloseNeeded() {
- mCloseNeeded.store(true);
- }
-
virtual const char *getTypeText() const { return "Base"; }
protected:
@@ -419,12 +407,8 @@
aaudio_handle_t mHandle = -1;
bool mFlowing = false;
- // This indicates that a stream that is being referenced by a binder call
- // and needs to closed.
- std::atomic<bool> mCloseNeeded{false}; // TODO remove
-
// This indicate that a running stream should not be processed because of an error,
- // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
+ // for example a full message queue.
std::atomic<bool> mSuspended{false};
bool mDisconnected GUARDED_BY(mLock) {false};
diff --git a/services/oboeservice/AAudioThread.cpp b/services/oboeservice/AAudioThread.cpp
index 549fa59..502d773 100644
--- a/services/oboeservice/AAudioThread.cpp
+++ b/services/oboeservice/AAudioThread.cpp
@@ -75,7 +75,9 @@
aaudio_result_t AAudioThread::stop() {
if (!mHasThread) {
- ALOGE("stop() but no thread running");
+ // There can be cases that the thread is just created but not started.
+ // Logging as warning to attract attention but not too serious.
+ ALOGW("stop() but no thread running");
return AAUDIO_ERROR_INVALID_STATE;
}
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index c5080a4..3521979 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -78,12 +78,38 @@
]
+cc_defaults {
+ name: "libaaudioservice_dependencies",
-cc_library {
+ shared_libs: [
+ "libaaudio_internal",
+ "libaudioclient",
+ "libaudioutils",
+ "libmedia_helper",
+ "libmediametrics",
+ "libmediautils",
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "aaudio-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ "libaudioclient_aidl_conversion",
+ "packagemanager_aidl-cpp",
+ ],
+
+ static_libs: [
+ "libaudioflinger",
+ ]
+}
+
+cc_library_static {
name: "libaaudioservice",
defaults: [
+ "libaaudioservice_dependencies",
"latest_android_media_audio_common_types_cpp_shared",
],
@@ -116,25 +142,6 @@
"-Werror",
],
- shared_libs: [
- "libaaudio_internal",
- "libaudioclient",
- "libaudioflinger",
- "libaudioutils",
- "libmedia_helper",
- "libmediametrics",
- "libmediautils",
- "libbase",
- "libbinder",
- "libcutils",
- "liblog",
- "libutils",
- "aaudio-aidl-cpp",
- "framework-permission-aidl-cpp",
- "libaudioclient_aidl_conversion",
- "packagemanager_aidl-cpp",
- ],
-
export_shared_lib_headers: [
"libaaudio_internal",
"framework-permission-aidl-cpp",
diff --git a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
index f047065..f5c2e6c 100644
--- a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
+++ b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
@@ -403,13 +403,6 @@
request.getConfiguration().setBufferCapacity(fdp.ConsumeIntegral<int32_t>());
- request.getConfiguration().setHardwareSampleRate(fdp.ConsumeIntegral<int32_t>());
- request.getConfiguration().setHardwareSamplesPerFrame(fdp.ConsumeIntegral<int32_t>());
- request.getConfiguration().setHardwareFormat((audio_format_t)(
- fdp.ConsumeBool()
- ? fdp.ConsumeIntegral<int32_t>()
- : kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
-
auto streamHandleInfo = mClient->openStream(request, configurationOutput);
if (streamHandleInfo.getHandle() < 0) {
// invalid request, stream not opened.
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index ea5139d..e29d520 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -86,6 +86,7 @@
"android.hardware.tv.tuner@1.1",
"android.hardware.tv.tuner-V2-ndk",
"libbase",
+ "libcutils",
"libbinder",
"libfmq",
"libhidlbase",
diff --git a/services/tuner/main_tunerservice.cpp b/services/tuner/main_tunerservice.cpp
index 90f1731..acfaf8a 100644
--- a/services/tuner/main_tunerservice.cpp
+++ b/services/tuner/main_tunerservice.cpp
@@ -17,6 +17,7 @@
#include <android-base/logging.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <hidl/HidlTransportSupport.h>
@@ -31,6 +32,11 @@
int main() {
ALOGD("Tuner service starting");
+ if (!property_get_bool("tuner.server.enable", false)) {
+ ALOGD("tuner is not enabled, terminating");
+ return 0;
+ }
+
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
hardware::configureRpcThreadpool(16, true);