Merge "Set PAUSING state when start pausing a stream." into main
diff --git a/Android.bp b/Android.bp
index 72b8721..fa043b2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -34,6 +34,24 @@
],
}
+aidl_interface_defaults {
+ name: "audio-aidl-defaults",
+ unstable: true,
+ host_supported: true,
+ backend: {
+ cpp: {
+ enabled: true,
+ },
+ java: {
+ enabled: true,
+ },
+ rust: {
+ enabled: true,
+ },
+ },
+
+}
+
aidl_interface {
name: "av-types-aidl",
unstable: true,
@@ -71,6 +89,18 @@
},
}
+aidl_interface {
+ name: "audio-permission-aidl",
+ // TODO remove
+ vendor_available: true,
+ double_loadable: true,
+ defaults: ["audio-aidl-defaults"],
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/com/android/media/permission/*",
+ ],
+}
+
cc_library_headers {
name: "av-headers",
export_include_dirs: ["include"],
diff --git a/aidl/com/android/media/permission/INativePermissionController.aidl b/aidl/com/android/media/permission/INativePermissionController.aidl
new file mode 100644
index 0000000..5766e33
--- /dev/null
+++ b/aidl/com/android/media/permission/INativePermissionController.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media.permission;
+
+import com.android.media.permission.UidPackageState;
+
+/**
+ * This interface is used by system_server to communicate permission information
+ * downwards towards native services.
+ * {@hide}
+ */
+interface INativePermissionController {
+ /**
+ * Initialize app-ids and their corresponding packages, to be used for package validation.
+ */
+ void populatePackagesForUids(in List<UidPackageState> initialPackageStates);
+ /**
+ * Replace or populate the list of packages associated with a given uid.
+ * If the list is empty, the package no longer exists.
+ */
+ void updatePackagesForUid(in UidPackageState newPackageState);
+}
diff --git a/aidl/com/android/media/permission/UidPackageState.aidl b/aidl/com/android/media/permission/UidPackageState.aidl
new file mode 100644
index 0000000..41b8c65
--- /dev/null
+++ b/aidl/com/android/media/permission/UidPackageState.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media.permission;
+
+/**
+ * Entity representing the package names associated with a particular uid/app-id
+ * {@hide}
+ */
+parcelable UidPackageState {
+ int uid;
+ @utf8InCpp List<String> packageNames;
+}
diff --git a/camera/Android.bp b/camera/Android.bp
index d0f8e7e..75c2999 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -169,7 +169,6 @@
srcs: [
"aidl/android/hardware/CameraExtensionSessionStats.aidl",
"aidl/android/hardware/ICameraService.aidl",
- "aidl/android/hardware/CameraIdRemapping.aidl",
"aidl/android/hardware/ICameraServiceListener.aidl",
"aidl/android/hardware/ICameraServiceProxy.aidl",
"aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl",
diff --git a/camera/aidl/android/hardware/CameraExtensionSessionStats.aidl b/camera/aidl/android/hardware/CameraExtensionSessionStats.aidl
index 1c81831..a3c0e69 100644
--- a/camera/aidl/android/hardware/CameraExtensionSessionStats.aidl
+++ b/camera/aidl/android/hardware/CameraExtensionSessionStats.aidl
@@ -66,4 +66,9 @@
* true if advanced extensions are being used, false otherwise
*/
boolean isAdvanced = false;
+
+ /**
+ * Format of image capture request
+ */
+ int captureFormat;
}
\ No newline at end of file
diff --git a/camera/aidl/android/hardware/CameraIdRemapping.aidl b/camera/aidl/android/hardware/CameraIdRemapping.aidl
deleted file mode 100644
index 453f696..0000000
--- a/camera/aidl/android/hardware/CameraIdRemapping.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware;
-
-/**
- * Specifies a remapping of Camera Ids.
- *
- * Example: For a given package, a remapping of camera id0 to id1 specifies
- * that any operation to perform on id0 should instead be performed on id1.
- *
- * @hide
- */
-parcelable CameraIdRemapping {
- /**
- * Specifies remapping of Camera Ids per package.
- */
- parcelable PackageIdRemapping {
- /** Package Name (e.g. com.android.xyz). */
- @utf8InCpp String packageName;
- /**
- * Ordered list of Camera Ids to replace. Only Camera Ids present in this list will be
- * affected.
- */
- @utf8InCpp List<String> cameraIdsToReplace;
- /**
- * Ordered list of updated Camera Ids, where updatedCameraIds[i] corresponds to
- * the updated camera id for cameraIdsToReplace[i].
- */
- @utf8InCpp List<String> updatedCameraIds;
- }
-
- /**
- * List of Camera Id remappings to perform.
- */
- List<PackageIdRemapping> packageIdRemappings;
-}
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 9569e2f..d9a0934 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -30,7 +30,6 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.ICameraServiceListener;
import android.hardware.CameraInfo;
-import android.hardware.CameraIdRemapping;
import android.hardware.CameraStatus;
import android.hardware.CameraExtensionSessionStats;
@@ -210,22 +209,6 @@
int targetSdkVersion, int deviceId, int devicePolicy);
/**
- * Remap Camera Ids in the CameraService.
- *
- * Once this is in effect, all binder calls in the ICameraService that
- * use logicalCameraId should consult remapping state to arrive at the
- * correct cameraId to perform the operation on.
- *
- * Note: Before the new cameraIdRemapping state is applied, the previous
- * state is cleared.
- *
- * @param cameraIdRemapping the camera ids to remap. Sending an unpopulated
- * cameraIdRemapping object will result in clearing of any previous
- * cameraIdRemapping state in the camera service.
- */
- void remapCameraIds(in CameraIdRemapping cameraIdRemapping);
-
- /**
* Inject Session Params into an existing camera session.
*
* @param cameraId the camera id session to inject session params into. Note that
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 421469a..5577775 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -77,6 +77,8 @@
"impl/ACameraCaptureSession.cpp",
],
shared_libs: [
+ "android.companion.virtual.virtualdevice_aidl-cpp",
+ "android.companion.virtualdevice.flags-aconfig-cc",
"libbinder",
"liblog",
"libgui",
diff --git a/camera/ndk/NdkCameraManager.cpp b/camera/ndk/NdkCameraManager.cpp
index 2de4a50..1b3343e 100644
--- a/camera/ndk/NdkCameraManager.cpp
+++ b/camera/ndk/NdkCameraManager.cpp
@@ -68,7 +68,7 @@
EXPORT
camera_status_t ACameraManager_registerAvailabilityCallback(
- ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) {
+ ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) {
ATRACE_CALL();
if (callback == nullptr) {
ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
@@ -81,13 +81,13 @@
callback->onCameraAvailable, callback->onCameraUnavailable);
return ACAMERA_ERROR_INVALID_PARAMETER;
}
- CameraManagerGlobal::getInstance()->registerAvailabilityCallback(callback);
+ manager->registerAvailabilityCallback(callback);
return ACAMERA_OK;
}
EXPORT
camera_status_t ACameraManager_unregisterAvailabilityCallback(
- ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) {
+ ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) {
ATRACE_CALL();
if (callback == nullptr) {
ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
@@ -100,13 +100,13 @@
callback->onCameraAvailable, callback->onCameraUnavailable);
return ACAMERA_ERROR_INVALID_PARAMETER;
}
- CameraManagerGlobal::getInstance()->unregisterAvailabilityCallback(callback);
+ manager->unregisterAvailabilityCallback(callback);
return ACAMERA_OK;
}
EXPORT
camera_status_t ACameraManager_registerExtendedAvailabilityCallback(
- ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
ATRACE_CALL();
if (callback == nullptr) {
ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
@@ -131,13 +131,13 @@
return ACAMERA_ERROR_INVALID_PARAMETER;
}
}
- CameraManagerGlobal::getInstance()->registerExtendedAvailabilityCallback(callback);
+ manager->registerExtendedAvailabilityCallback(callback);
return ACAMERA_OK;
}
EXPORT
camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback(
- ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
ATRACE_CALL();
if (callback == nullptr) {
ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
@@ -154,7 +154,7 @@
callback->onCameraAccessPrioritiesChanged);
return ACAMERA_ERROR_INVALID_PARAMETER;
}
- CameraManagerGlobal::getInstance()->unregisterExtendedAvailabilityCallback(callback);
+ manager->unregisterExtendedAvailabilityCallback(callback);
return ACAMERA_OK;
}
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index d8e5f3c..f36a743 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -17,23 +17,108 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "ACameraManager"
-#include <memory>
#include "ACameraManager.h"
-#include "ACameraMetadata.h"
-#include "ACameraDevice.h"
-#include <utils/Vector.h>
-#include <cutils/properties.h>
-#include <stdlib.h>
+#include <android_companion_virtualdevice_flags.h>
#include <camera/CameraUtils.h>
#include <camera/StringUtils.h>
#include <camera/VendorTagDescriptor.h>
+#include <cutils/properties.h>
+#include <stdlib.h>
+#include <utils/Vector.h>
+#include <memory>
+#include "ACameraDevice.h"
+#include "ACameraMetadata.h"
using namespace android::acam;
+namespace vd_flags = android::companion::virtualdevice::flags;
namespace android {
namespace acam {
+namespace {
-// TODO(b/291736219): Add device-awareness to ACameraManager.
+using ::android::binder::Status;
+using ::android::companion::virtualnative::IVirtualDeviceManagerNative;
+
+// Return binder connection to VirtualDeviceManager.
+//
+// Subsequent calls return the same cached instance.
+sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() {
+ auto connectToVirtualDeviceManagerNative = []() {
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16("virtualdevice_native"));
+ if (binder == nullptr) {
+ ALOGW("%s: Cannot get virtualdevice_native service", __func__);
+ return interface_cast<IVirtualDeviceManagerNative>(nullptr);
+ }
+ return interface_cast<IVirtualDeviceManagerNative>(binder);
+ };
+
+ static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative();
+ return vdm;
+}
+
+// Returns device id calling process is running on.
+// If the process cannot be attributed to single virtual device id, returns default device id.
+int getCurrentDeviceId() {
+ if (!vd_flags::camera_device_awareness()) {
+ return kDefaultDeviceId;
+ }
+
+ auto vdm = getVirtualDeviceManager();
+ if (vdm == nullptr) {
+ return kDefaultDeviceId;
+ }
+
+ const uid_t myUid = getuid();
+ std::vector<int> deviceIds;
+ Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds);
+ if (!status.isOk() || deviceIds.empty()) {
+ ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s",
+ __func__, myUid, status.toString8().c_str());
+ return kDefaultDeviceId;
+ }
+
+ // If the UID is associated with multiple virtual devices, use the default device's
+ // camera as we cannot disambiguate here. This effectively means that the app has
+ // activities on different devices at the same time.
+ if (deviceIds.size() != 1) {
+ return kDefaultDeviceId;
+ }
+ return deviceIds[0];
+}
+
+// Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId.
+DevicePolicy getDevicePolicyForDeviceId(const int deviceId) {
+ if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) {
+ return DevicePolicy::DEVICE_POLICY_DEFAULT;
+ }
+
+ auto vdm = getVirtualDeviceManager();
+ if (vdm == nullptr) {
+ return DevicePolicy::DEVICE_POLICY_DEFAULT;
+ }
+
+ int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT;
+ Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA,
+ &policy);
+ if (!status.isOk()) {
+ ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s",
+ __func__, deviceId, status.toString8().c_str());
+ return DevicePolicy::DEVICE_POLICY_DEFAULT;
+ }
+ return static_cast<DevicePolicy>(policy);
+}
+
+// Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext.
+bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) {
+ if (!vd_flags::camera_device_awareness() ||
+ deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) {
+ return cameraDeviceId == kDefaultDeviceId;
+ }
+ return deviceContext.deviceId == cameraDeviceId;
+}
+
+} // namespace
// Static member definitions
const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
@@ -44,6 +129,11 @@
Mutex CameraManagerGlobal::sLock;
wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
+DeviceContext::DeviceContext() {
+ deviceId = getCurrentDeviceId();
+ policy = getDevicePolicyForDeviceId(deviceId);
+}
+
sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
Mutex::Autolock _l(sLock);
sp<CameraManagerGlobal> instance = sInstance.promote();
@@ -128,17 +218,11 @@
std::vector<hardware::CameraStatus> cameraStatuses{};
mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
for (auto& c : cameraStatuses) {
- // Skip callback for cameras not belonging to the default device, as NDK doesn't support
- // device awareness yet.
- if (c.deviceId != kDefaultDeviceId) {
- continue;
- }
-
- onStatusChangedLocked(c.status, c.cameraId);
+ onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
- c.cameraId, unavailablePhysicalId);
+ c.deviceId, c.cameraId, unavailablePhysicalId);
}
}
@@ -198,14 +282,15 @@
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
AutoMutex lock(cm->mLock);
- std::vector<std::string> cameraIdList;
+ std::vector<DeviceStatusMapKey> keysToRemove;
+ keysToRemove.reserve(cm->mDeviceStatusMap.size());
for (auto& pair : cm->mDeviceStatusMap) {
- cameraIdList.push_back(pair.first);
+ keysToRemove.push_back(pair.first);
}
- for (const std::string& cameraId : cameraIdList) {
- cm->onStatusChangedLocked(
- CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
+ for (const DeviceStatusMapKey& key : keysToRemove) {
+ cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
+ key.cameraId);
}
cm->mCameraService.clear();
// TODO: consider adding re-connect call here?
@@ -213,32 +298,35 @@
}
void CameraManagerGlobal::registerExtendedAvailabilityCallback(
- const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
- return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
+ const DeviceContext& deviceContext,
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
+ return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
+ callback);
}
void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
- const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ const DeviceContext& deviceContext,
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
Mutex::Autolock _l(mLock);
drainPendingCallbacksLocked();
- Callback cb(callback);
+ Callback cb(deviceContext, callback);
mCallbacks.erase(cb);
}
void CameraManagerGlobal::registerAvailabilityCallback(
- const ACameraManager_AvailabilityCallbacks *callback) {
- return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
+ const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
+ return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
}
void CameraManagerGlobal::unregisterAvailabilityCallback(
- const ACameraManager_AvailabilityCallbacks *callback) {
+ const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
Mutex::Autolock _l(mLock);
drainPendingCallbacksLocked();
- Callback cb(callback);
+ Callback cb(deviceContext, callback);
mCallbacks.erase(cb);
}
@@ -261,20 +349,24 @@
}
}
-template<class T>
-void CameraManagerGlobal::registerAvailCallback(const T *callback) {
+template <class T>
+void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
+ const T* callback) {
Mutex::Autolock _l(mLock);
getCameraServiceLocked();
- Callback cb(callback);
- auto pair = mCallbacks.insert(cb);
+ Callback cb(deviceContext, callback);
+ const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
// Send initial callbacks if callback is newly registered
- if (pair.second) {
- for (auto& pair : mDeviceStatusMap) {
- const std::string& cameraId = pair.first;
- int32_t status = pair.second.getStatus();
+ if (newlyRegistered) {
+ for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
+ if (!isCameraAccessible(deviceContext, key.deviceId)) {
+ continue;
+ }
+ const std::string& cameraId = key.cameraId;
+ int32_t status = statusAndHAL3Support.getStatus();
// Don't send initial callbacks for camera ids which don't support
// camera2
- if (!pair.second.supportsHAL3) {
+ if (!statusAndHAL3Support.supportsHAL3) {
continue;
}
@@ -290,7 +382,7 @@
// Physical camera unavailable callback
std::set<std::string> unavailablePhysicalCameras =
- pair.second.getUnavailablePhysicalIds();
+ statusAndHAL3Support.getUnavailablePhysicalIds();
for (const auto& physicalCameraId : unavailablePhysicalCameras) {
sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
@@ -320,21 +412,26 @@
return camera2Support;
}
-void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) {
+void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
+ 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
getCameraServiceLocked();
- for(auto& deviceStatus : mDeviceStatusMap) {
- int32_t status = deviceStatus.second.getStatus();
+ for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
+ if (!isCameraAccessible(context, key.deviceId)) {
+ continue;
+ }
+
+ int32_t status = statusAndHAL3Support.getStatus();
if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
continue;
}
- if (!deviceStatus.second.supportsHAL3) {
+ if (!statusAndHAL3Support.supportsHAL3) {
continue;
}
- cameraIds->push_back(deviceStatus.first);
+ cameraIds->push_back(key.cameraId);
}
}
@@ -471,36 +568,24 @@
binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
int32_t status, const std::string& cameraId, int deviceId) {
- // Skip callback for cameras not belonging to the default device, as NDK doesn't support
- // device awareness yet.
- if (deviceId != kDefaultDeviceId) {
- return binder::Status::ok();
- }
-
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
- cm->onStatusChanged(status, cameraId);
- } else {
- ALOGE("Cannot deliver status change. Global camera manager died");
+ cm->onStatusChanged(status, deviceId, cameraId);
}
+ ALOGE_IF(cm == nullptr,
+ "Cannot deliver physical camera status change. Global camera manager died");
return binder::Status::ok();
}
binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
int deviceId) {
- // Skip callback for cameras not belonging to the default device, as NDK doesn't support
- // device awareness yet.
- if (deviceId != kDefaultDeviceId) {
- return binder::Status::ok();
- }
-
sp<CameraManagerGlobal> cm = mCameraManager.promote();
if (cm != nullptr) {
- cm->onStatusChanged(status, cameraId, physicalCameraId);
- } else {
- ALOGE("Cannot deliver physical camera status change. Global camera manager died");
+ cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
}
+ ALOGE_IF(cm == nullptr,
+ "Cannot deliver physical camera status change. Global camera manager died");
return binder::Status::ok();
}
@@ -518,23 +603,24 @@
}
}
-void CameraManagerGlobal::onStatusChanged(
- int32_t status, const std::string& cameraId) {
+void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
+ const std::string& cameraId) {
Mutex::Autolock _l(mLock);
- onStatusChangedLocked(status, cameraId);
+ onStatusChangedLocked(status, deviceId, cameraId);
}
-void CameraManagerGlobal::onStatusChangedLocked(
- int32_t status, const std::string& cameraId) {
+void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
+ const std::string& cameraId) {
if (!validStatus(status)) {
ALOGE("%s: Invalid status %d", __FUNCTION__, status);
return;
}
- bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
- int32_t oldStatus = firstStatus ?
- status : // first status
- mDeviceStatusMap[cameraId].getStatus();
+ DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
+
+ bool firstStatus = (mDeviceStatusMap.count(key) == 0);
+ int32_t oldStatus = firstStatus ? status : // first status
+ mDeviceStatusMap[key].getStatus();
if (!firstStatus &&
isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
@@ -544,15 +630,17 @@
bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
if (firstStatus) {
- mDeviceStatusMap.emplace(std::piecewise_construct,
- std::forward_as_tuple(cameraId),
- std::forward_as_tuple(status, supportsHAL3));
+ mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(status, supportsHAL3));
} else {
- mDeviceStatusMap[cameraId].updateStatus(status);
+ mDeviceStatusMap[key].updateStatus(status);
}
// Iterate through all registered callbacks
if (supportsHAL3) {
for (auto cb : mCallbacks) {
+ if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
+ continue;
+ }
sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
cb.mAvailable : cb.mUnavailable;
@@ -564,30 +652,31 @@
}
}
if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
- mDeviceStatusMap.erase(cameraId);
+ mDeviceStatusMap.erase(key);
}
}
-void CameraManagerGlobal::onStatusChanged(
- int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
+void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
+ const std::string& cameraId, const std::string& physicalCameraId) {
Mutex::Autolock _l(mLock);
- onStatusChangedLocked(status, cameraId, physicalCameraId);
+ onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
}
-void CameraManagerGlobal::onStatusChangedLocked(
- int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
+void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
+ const std::string& cameraId, const std::string& physicalCameraId) {
if (!validStatus(status)) {
ALOGE("%s: Invalid status %d", __FUNCTION__, status);
return;
}
- auto logicalStatus = mDeviceStatusMap.find(cameraId);
+ DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
+ auto logicalStatus = mDeviceStatusMap.find(key);
if (logicalStatus == mDeviceStatusMap.end()) {
ALOGE("%s: Physical camera id %s status change on a non-present id %s",
__FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
return;
}
- int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
+ int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
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",
@@ -599,14 +688,17 @@
bool updated = false;
if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
- updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
+ updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
} else {
- updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
+ updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
}
// Iterate through all registered callbacks
if (supportsHAL3 && updated) {
for (auto cb : mCallbacks) {
+ if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
+ continue;
+ }
sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
@@ -660,7 +752,7 @@
Mutex::Autolock _l(mLock);
std::vector<std::string> idList;
- CameraManagerGlobal::getInstance()->getCameraIdList(&idList);
+ mGlobalManager->getCameraIdList(mDeviceContext, &idList);
int numCameras = idList.size();
ACameraIdList *out = new ACameraIdList;
@@ -710,7 +802,7 @@
const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Mutex::Autolock _l(mLock);
- sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
+ sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
if (cs == nullptr) {
ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
return ACAMERA_ERROR_CAMERA_DISCONNECTED;
@@ -720,7 +812,7 @@
int targetSdkVersion = android_get_application_target_sdk_version();
binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0,
+ mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy),
&rawMetadata);
if (!serviceRet.isOk()) {
switch(serviceRet.serviceSpecificErrorCode()) {
@@ -758,7 +850,7 @@
ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
- sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
+ sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
if (cs == nullptr) {
ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
delete device;
@@ -774,7 +866,7 @@
callbacks, cameraId, "", {},
hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0,
+ mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy),
/*out*/&deviceRemote);
if (!serviceRet.isOk()) {
@@ -822,6 +914,22 @@
return ACAMERA_OK;
}
-ACameraManager::~ACameraManager() {
+void ACameraManager::registerAvailabilityCallback(
+ const ACameraManager_AvailabilityCallbacks* callback) {
+ mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
+}
+void ACameraManager::unregisterAvailabilityCallback(
+ const ACameraManager_AvailabilityCallbacks* callback) {
+ mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
+}
+
+void ACameraManager::registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
+ mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
+}
+
+void ACameraManager::unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
+ mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
}
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index c6e2bf9..d8bf6b1 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -20,6 +20,7 @@
#include <camera/NdkCameraManager.h>
#include <android-base/parseint.h>
+#include <android/companion/virtualnative/IVirtualDeviceManagerNative.h>
#include <android/hardware/ICameraService.h>
#include <android/hardware/BnCameraServiceListener.h>
#include <camera/CameraMetadata.h>
@@ -37,6 +38,36 @@
namespace android {
namespace acam {
+enum class DevicePolicy {
+ DEVICE_POLICY_DEFAULT =
+ ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT,
+ DEVICE_POLICY_CUSTOM =
+ ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM
+};
+
+/**
+ * Device context within which are cameras accessed.
+ *
+ * When constructed, the device id is set to id of virtual device corresponding to
+ * caller's UID (or default device id if current app process is not running on virtual device).
+ *
+ * See getDeviceId() in Context.java for more context (no pun intented).
+ */
+struct DeviceContext {
+ DeviceContext();
+
+ // Id of virtual device asociated with this context (or DEFAULT_DEVICE_ID = 0 in case
+ // caller UID is not running on virtual device).
+ int deviceId;
+ // Device policy corresponding to VirtualDeviceParams.POLICY_TYPE_CAMERA:
+ //
+ // Can be either:
+ // * (0) DEVICE_POLICY_DEFAULT - virtual devices have access to default device cameras.
+ // * (1) DEVICE_POLICY_CUSTOM - virtual devices do not have access to default device cameras
+ // and can only access virtual cameras owned by the same device.
+ DevicePolicy policy;
+};
+
/**
* Per-process singleton instance of CameraManger. Shared by all ACameraManager
* instances. Created when first ACameraManager is created and destroyed when
@@ -49,20 +80,22 @@
static sp<CameraManagerGlobal> getInstance();
sp<hardware::ICameraService> getCameraService();
- void registerAvailabilityCallback(
- const ACameraManager_AvailabilityCallbacks *callback);
- void unregisterAvailabilityCallback(
- const ACameraManager_AvailabilityCallbacks *callback);
+ void registerAvailabilityCallback(const DeviceContext& context,
+ const ACameraManager_AvailabilityCallbacks* callback);
+ void unregisterAvailabilityCallback(const DeviceContext& context,
+ const ACameraManager_AvailabilityCallbacks* callback);
void registerExtendedAvailabilityCallback(
+ const DeviceContext& context,
const ACameraManager_ExtendedAvailabilityCallbacks* callback);
void unregisterExtendedAvailabilityCallback(
+ const DeviceContext& context,
const ACameraManager_ExtendedAvailabilityCallbacks* callback);
/**
* Return camera IDs that support camera2
*/
- void getCameraIdList(std::vector<std::string> *cameraIds);
+ void getCameraIdList(const DeviceContext& deviceContext, std::vector<std::string>* cameraIds);
private:
sp<hardware::ICameraService> mCameraService;
@@ -70,8 +103,8 @@
const char* kCameraServiceName = "media.camera";
Mutex mLock;
- template<class T>
- void registerAvailCallback(const T *callback);
+ template <class T>
+ void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
class DeathNotifier : public IBinder::DeathRecipient {
public:
@@ -115,29 +148,34 @@
// Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
struct Callback {
- explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
- mAvailable(callback->onCameraAvailable),
- mUnavailable(callback->onCameraUnavailable),
- mAccessPriorityChanged(nullptr),
- mPhysicalCamAvailable(nullptr),
- mPhysicalCamUnavailable(nullptr),
- mContext(callback->context) {}
+ explicit Callback(const DeviceContext& deviceContext,
+ const ACameraManager_AvailabilityCallbacks* callback)
+ : mDeviceContext(deviceContext),
+ mAvailable(callback->onCameraAvailable),
+ mUnavailable(callback->onCameraUnavailable),
+ mAccessPriorityChanged(nullptr),
+ mPhysicalCamAvailable(nullptr),
+ mPhysicalCamUnavailable(nullptr),
+ mContext(callback->context) {}
- explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
- mAvailable(callback->availabilityCallbacks.onCameraAvailable),
- mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
- mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
- mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
- mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
- mContext(callback->availabilityCallbacks.context) {}
+ explicit Callback(const DeviceContext& deviceContext,
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback)
+ : mDeviceContext(deviceContext),
+ mAvailable(callback->availabilityCallbacks.onCameraAvailable),
+ mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
+ mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
+ mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
+ mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
+ mContext(callback->availabilityCallbacks.context) {}
bool operator == (const Callback& other) const {
- return (mAvailable == other.mAvailable &&
- mUnavailable == other.mUnavailable &&
+ return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
mAccessPriorityChanged == other.mAccessPriorityChanged &&
mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
- mContext == other.mContext);
+ mContext == other.mContext &&
+ mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
+ mDeviceContext.policy == other.mDeviceContext.policy);
}
bool operator != (const Callback& other) const {
return !(*this == other);
@@ -146,6 +184,9 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
if (*this == other) return false;
+ if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
+ return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
+ }
if (mContext != other.mContext) return mContext < other.mContext;
if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
@@ -163,6 +204,7 @@
bool operator > (const Callback& other) const {
return (*this != other && !(*this < other));
}
+ DeviceContext mDeviceContext;
ACameraManager_AvailabilityCallback mAvailable;
ACameraManager_AvailabilityCallback mUnavailable;
ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
@@ -204,37 +246,17 @@
sp<hardware::ICameraService> getCameraServiceLocked();
void onCameraAccessPrioritiesChanged();
- 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);
+ void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId);
+ void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId);
+ void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId,
+ const std::string& physicalCameraId);
+ void onStatusChangedLocked(int32_t status, int deviceId, 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 std::string &cameraId);
- // The sort logic must match the logic in
- // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
- struct CameraIdComparator {
- 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);
-
- // Uint device IDs first
- if (aIsUint && bIsUint) {
- return aUint < bUint;
- } else if (aIsUint) {
- return true;
- } else if (bIsUint) {
- return false;
- }
- // Simple string compare if both id are not uint
- return a < b;
- }
- };
-
struct StatusAndHAL3Support {
private:
int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
@@ -253,13 +275,40 @@
std::set<std::string> getUnavailablePhysicalIds();
};
- // Map camera_id -> status
- std::map<std::string, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
+ struct DeviceStatusMapKey {
+ int deviceId;
+ std::string cameraId;
+
+ bool operator<(const DeviceStatusMapKey& other) const {
+ if (deviceId != other.deviceId) {
+ return deviceId < other.deviceId;
+ }
+
+ // The sort logic must match the logic in
+ // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
+ uint32_t cameraIdUint = 0, otherCameraIdUint = 0;
+ bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint);
+ bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint);
+
+ // Uint device IDs first
+ if (cameraIdIsUint && otherCameraIdIsUint) {
+ return cameraIdUint < otherCameraIdUint;
+ } else if (cameraIdIsUint) {
+ return true;
+ } else if (otherCameraIdIsUint) {
+ return false;
+ }
+ // Simple string compare if both id are not uint
+ return cameraIdIsUint < otherCameraIdIsUint;
+ }
+ };
+
+ std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap;
// For the singleton instance
static Mutex sLock;
static wp<CameraManagerGlobal> sInstance;
- CameraManagerGlobal() {};
+ CameraManagerGlobal() {}
~CameraManagerGlobal();
};
@@ -271,9 +320,7 @@
* Leave outside of android namespace because it's NDK struct
*/
struct ACameraManager {
- ACameraManager() :
- mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
- ~ACameraManager();
+ ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
static void deleteCameraIdList(ACameraIdList* cameraIdList);
@@ -282,6 +329,12 @@
camera_status_t openCamera(const char* cameraId,
ACameraDevice_StateCallbacks* callback,
/*out*/ACameraDevice** device);
+ void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
+ void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
+ void registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+ void unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
private:
enum {
@@ -289,6 +342,7 @@
};
android::Mutex mLock;
android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
+ const android::acam::DeviceContext mDeviceContext;
};
#endif //_ACAMERA_MANAGER_H
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index 099786b..db27143 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -866,6 +866,25 @@
return status == OK ? ACAMERA_OK : ACAMERA_ERROR_METADATA_NOT_FOUND;
}
-ACameraManager::~ACameraManager() {
+void ACameraManager::registerAvailabilityCallback(
+ const ACameraManager_AvailabilityCallbacks* callback) {
+ mGlobalManager->registerAvailabilityCallback(callback);
+}
+void ACameraManager::unregisterAvailabilityCallback(
+ const ACameraManager_AvailabilityCallbacks* callback) {
+ mGlobalManager->unregisterAvailabilityCallback(callback);
+}
+
+void ACameraManager::registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
+ mGlobalManager->registerExtendedAvailabilityCallback(callback);
+}
+
+void ACameraManager::unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
+ mGlobalManager->unregisterExtendedAvailabilityCallback(callback);
+}
+
+ACameraManager::~ACameraManager() {
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 85acee7..2d8eefa 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -265,6 +265,12 @@
ACameraDevice_StateCallbacks* callback,
/*out*/ACameraDevice** device);
camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);
+ void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
+ void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
+ void registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+ void unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
private:
enum {
diff --git a/media/audio/aconfig/audio.aconfig b/media/audio/aconfig/audio.aconfig
index fc15554..c642a94 100644
--- a/media/audio/aconfig/audio.aconfig
+++ b/media/audio/aconfig/audio.aconfig
@@ -6,6 +6,14 @@
container: "system"
flag {
+ name: "abs_volume_index_fix"
+ namespace: "media_audio"
+ description:
+ "Fix double attenuation and index jumps in absolute volume mode"
+ bug: "340693050"
+}
+
+flag {
name: "alarm_min_volume_zero"
namespace: "media_audio"
description: "Support configuring alarm min vol to zero"
diff --git a/media/audio/aconfig/audioserver.aconfig b/media/audio/aconfig/audioserver.aconfig
index 5c6504f..96e2b75 100644
--- a/media/audio/aconfig/audioserver.aconfig
+++ b/media/audio/aconfig/audioserver.aconfig
@@ -22,6 +22,15 @@
}
flag {
+ name: "fix_concurrent_playback_behavior_with_bit_perfect_client"
+ namespace: "media_audio"
+ description:
+ "Treat playback use cases differently when bit-perfect client is active to improve the "
+ "user experience with bit-perfect playback."
+ bug: "339515899"
+}
+
+flag {
name: "mutex_priority_inheritance"
namespace: "media_audio"
description:
diff --git a/media/codec2/hal/client/GraphicsTracker.cpp b/media/codec2/hal/client/GraphicsTracker.cpp
index 1c2a0fb..dbbabfe 100644
--- a/media/codec2/hal/client/GraphicsTracker.cpp
+++ b/media/codec2/hal/client/GraphicsTracker.cpp
@@ -173,7 +173,7 @@
}
GraphicsTracker::GraphicsTracker(int maxDequeueCount)
- : mBufferCache(new BufferCache()), mMaxDequeue{maxDequeueCount},
+ : mBufferCache(new BufferCache()), mNumDequeueing{0}, mMaxDequeue{maxDequeueCount},
mMaxDequeueCommitted{maxDequeueCount},
mDequeueable{maxDequeueCount},
mTotalDequeued{0}, mTotalCancelled{0}, mTotalDropped{0}, mTotalReleased{0},
@@ -235,6 +235,7 @@
const sp<IGraphicBufferProducer>& igbp, uint32_t generation) {
// TODO: wait until operations to previous IGBP is completed.
std::shared_ptr<BufferCache> prevCache;
+ int prevDequeueRequested = 0;
int prevDequeueCommitted;
std::unique_lock<std::mutex> cl(mConfigLock);
@@ -243,6 +244,9 @@
mInConfig = true;
prevCache = mBufferCache;
prevDequeueCommitted = mMaxDequeueCommitted;
+ if (mMaxDequeueRequested.has_value()) {
+ prevDequeueRequested = mMaxDequeueRequested.value();
+ }
}
// NOTE: Switching to the same surface is blocked from MediaCodec.
// Switching to the same surface might not work if tried, since disconnect()
@@ -263,6 +267,11 @@
mInConfig = false;
return C2_BAD_VALUE;
}
+ ALOGD("new surface in configuration: maxDequeueRequested(%d), maxDequeueCommitted(%d)",
+ prevDequeueRequested, prevDequeueCommitted);
+ if (prevDequeueRequested > 0 && prevDequeueRequested > prevDequeueCommitted) {
+ prevDequeueCommitted = prevDequeueRequested;
+ }
if (igbp) {
ret = igbp->setMaxDequeuedBufferCount(prevDequeueCommitted);
if (ret != ::android::OK) {
@@ -280,6 +289,34 @@
std::unique_lock<std::mutex> l(mLock);
mInConfig = false;
mBufferCache = newCache;
+ // {@code dequeued} is the number of currently dequeued buffers.
+ // {@code prevDequeueCommitted} is max dequeued buffer at any moment
+ // from the new surface.
+ // {@code newDequeueable} is hence the current # of dequeueable buffers
+ // if no change occurs.
+ int dequeued = mDequeued.size() + mNumDequeueing;
+ int newDequeueable = prevDequeueCommitted - dequeued;
+ if (newDequeueable < 0) {
+ // This will not happen.
+ // But if this happens, we respect the value and try to continue.
+ ALOGE("calculated new dequeueable is negative: %d max(%d),dequeued(%d)",
+ newDequeueable, prevDequeueCommitted, dequeued);
+ }
+
+ if (mMaxDequeueRequested.has_value() && mMaxDequeueRequested == prevDequeueCommitted) {
+ mMaxDequeueRequested.reset();
+ }
+ mMaxDequeue = mMaxDequeueCommitted = prevDequeueCommitted;
+
+ int delta = newDequeueable - mDequeueable;
+ if (delta > 0) {
+ writeIncDequeueableLocked(delta);
+ } else if (delta < 0) {
+ drainDequeueableLocked(-delta);
+ }
+ ALOGV("new surfcace dequeueable %d(delta %d), maxDequeue %d",
+ newDequeueable, delta, mMaxDequeue);
+ mDequeueable = newDequeueable;
}
return C2_OK;
}
@@ -529,6 +566,7 @@
ALOGE("writing end for the waitable object seems to be closed");
return C2_BAD_STATE;
}
+ mNumDequeueing++;
mDequeueable--;
*cache = mBufferCache;
return C2_OK;
@@ -543,6 +581,7 @@
bool cached, int slot, const sp<Fence> &fence,
std::shared_ptr<BufferItem> *pBuffer, bool *updateDequeue) {
std::unique_lock<std::mutex> l(mLock);
+ mNumDequeueing--;
if (res == C2_OK) {
if (cached) {
auto it = cache->mBuffers.find(slot);
@@ -655,7 +694,8 @@
ALOGE("allocate by dequeueBuffer() successful, but requestBuffer() failed %d",
status);
igbp->cancelBuffer(slotId, fence);
- return C2_CORRUPTED;
+ // This might be due to life-cycle end and/or surface switching.
+ return C2_BLOCKING;
}
*buffer = std::make_shared<BufferItem>(generation, slotId, realloced, fence);
if (!*buffer) {
diff --git a/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
index dd6c869..762030b 100644
--- a/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
+++ b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
@@ -234,6 +234,7 @@
// Maps bufferId to buffer
std::map<uint64_t, std::shared_ptr<BufferItem>> mDequeued;
std::set<uint64_t> mDeallocating;
+ int mNumDequeueing;
// These member variables are read and modified accessed as follows.
// 1. mConfigLock being held
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index f2910b8..5aff5f2 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -202,8 +202,12 @@
StreamDescriptor::Reply reply;
switch (state) {
case StreamDescriptor::State::ACTIVE:
+ case StreamDescriptor::State::DRAINING:
+ case StreamDescriptor::State::TRANSFERRING:
RETURN_STATUS_IF_ERROR(pause(&reply));
- if (reply.state != StreamDescriptor::State::PAUSED) {
+ if (reply.state != StreamDescriptor::State::PAUSED &&
+ reply.state != StreamDescriptor::State::DRAIN_PAUSED &&
+ reply.state != StreamDescriptor::State::TRANSFER_PAUSED) {
ALOGE("%s: unexpected stream state: %s (expected PAUSED)",
__func__, toString(reply.state).c_str());
return INVALID_OPERATION;
@@ -211,6 +215,7 @@
FALLTHROUGH_INTENDED;
case StreamDescriptor::State::PAUSED:
case StreamDescriptor::State::DRAIN_PAUSED:
+ case StreamDescriptor::State::TRANSFER_PAUSED:
if (mIsInput) return flush();
RETURN_STATUS_IF_ERROR(flush(&reply));
if (reply.state != StreamDescriptor::State::IDLE) {
@@ -658,21 +663,16 @@
return transfer(const_cast<void*>(buffer), bytes, written);
}
-status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames) {
+status_t StreamOutHalAidl::getRenderPosition(uint64_t *dspFrames) {
if (dspFrames == nullptr) {
return BAD_VALUE;
}
int64_t aidlFrames = 0, aidlTimestamp = 0;
RETURN_STATUS_IF_ERROR(getObservablePosition(&aidlFrames, &aidlTimestamp));
- *dspFrames = static_cast<uint32_t>(aidlFrames);
+ *dspFrames = aidlFrames;
return OK;
}
-status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
- // Obsolete, use getPresentationPosition.
- return INVALID_OPERATION;
-}
-
status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
ALOGD("%p %s", this, __func__);
TIME_CHECK();
@@ -733,6 +733,11 @@
return OK;
}
+status_t StreamOutHalAidl::presentationComplete() {
+ ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+ return OK;
+}
+
status_t StreamOutHalAidl::updateSourceMetadata(
const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
TIME_CHECK();
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index b20eb00..8a398d8 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -308,10 +308,7 @@
// Return the number of audio frames written by the audio dsp to DAC since
// the output has exited standby.
- status_t getRenderPosition(uint32_t *dspFrames) override;
-
- // Get the local time at which the next write to the audio driver will be presented.
- status_t getNextWriteTimestamp(int64_t *timestamp) override;
+ status_t getRenderPosition(uint64_t *dspFrames) override;
// Set the callback for notifying completion of non-blocking write and drain.
status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
@@ -337,6 +334,9 @@
// Return a recent count of the number of audio frames presented to an external observer.
status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
+ // Notifies the HAL layer that the framework considers the current playback as completed.
+ status_t presentationComplete() override;
+
// Called when the metadata of the stream's source has been changed.
status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 77c75db..9e22700 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -17,6 +17,8 @@
#define LOG_TAG "StreamHalHidl"
//#define LOG_NDEBUG 0
+#include <cinttypes>
+
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioParameter.h>
@@ -589,32 +591,39 @@
return OK;
}
-status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
+status_t StreamOutHalHidl::getRenderPosition(uint64_t *dspFrames) {
// TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
Result retval;
+ uint32_t halPosition = 0;
Return<void> ret = mStream->getRenderPosition(
[&](Result r, uint32_t d) {
retval = r;
if (retval == Result::OK) {
- *dspFrames = d;
+ halPosition = d;
}
});
- return processReturn("getRenderPosition", ret, retval);
-}
+ status_t status = processReturn("getRenderPosition", ret, retval);
+ if (status != OK) {
+ return status;
+ }
+ // Maintain a 64-bit render position using the 32-bit result from the HAL.
+ // This delta calculation relies on the arithmetic overflow behavior
+ // of integers. For example (100 - 0xFFFFFFF0) = 116.
+ std::lock_guard l(mPositionMutex);
+ const auto truncatedPosition = (uint32_t)mRenderPosition;
+ int32_t deltaHalPosition; // initialization not needed, overwitten by __builtin_sub_overflow()
+ (void) __builtin_sub_overflow(halPosition, truncatedPosition, &deltaHalPosition);
-status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
- TIME_CHECK();
- if (mStream == 0) return NO_INIT;
- Result retval;
- Return<void> ret = mStream->getNextWriteTimestamp(
- [&](Result r, int64_t t) {
- retval = r;
- if (retval == Result::OK) {
- *timestamp = t;
- }
- });
- return processReturn("getRenderPosition", ret, retval);
+ if (deltaHalPosition >= 0) {
+ mRenderPosition += deltaHalPosition;
+ } else if (mExpectRetrograde) {
+ mExpectRetrograde = false;
+ mRenderPosition -= static_cast<uint64_t>(-deltaHalPosition);
+ ALOGW("Retrograde motion of %" PRId32 " frames", -deltaHalPosition);
+ }
+ *dspFrames = mRenderPosition;
+ return OK;
}
status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
@@ -667,9 +676,23 @@
status_t StreamOutHalHidl::flush() {
TIME_CHECK();
if (mStream == 0) return NO_INIT;
+ {
+ std::lock_guard l(mPositionMutex);
+ mRenderPosition = 0;
+ mExpectRetrograde = false;
+ }
return processReturn("pause", mStream->flush());
}
+status_t StreamOutHalHidl::standby() {
+ {
+ std::lock_guard l(mPositionMutex);
+ mRenderPosition = 0;
+ mExpectRetrograde = false;
+ }
+ return StreamHalHidl::standby();
+}
+
status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
// TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
@@ -696,6 +719,16 @@
}
}
+status_t StreamOutHalHidl::presentationComplete() {
+ // Avoid suppressing retrograde motion in mRenderPosition for gapless offload/direct when
+ // transitioning between tracks.
+ // The HAL resets the frame position without flush/stop being called, but calls back prior to
+ // this event. So, on the next occurrence of retrograde motion, we permit backwards movement of
+ // mRenderPosition.
+ mExpectRetrograde = true;
+ return OK;
+}
+
#if MAJOR_VERSION == 2
status_t StreamOutHalHidl::updateSourceMetadata(
const StreamOutHalInterface::SourceMetadata& /* sourceMetadata */) {
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 48da633..80379d0 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -18,10 +18,12 @@
#define ANDROID_HARDWARE_STREAM_HAL_HIDL_H
#include <atomic>
+#include <mutex>
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStream.h)
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h)
#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
+#include <android-base/thread_annotations.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <media/audiohal/EffectHalInterface.h>
@@ -119,6 +121,9 @@
class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
public:
+ // Put the audio hardware input/output into standby mode (from StreamHalInterface).
+ status_t standby() override;
+
// Return the frame size (number of bytes per sample) of a stream.
virtual status_t getFrameSize(size_t *size);
@@ -136,10 +141,7 @@
// Return the number of audio frames written by the audio dsp to DAC since
// the output has exited standby.
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
- // Get the local time at which the next write to the audio driver will be presented.
- virtual status_t getNextWriteTimestamp(int64_t *timestamp);
+ virtual status_t getRenderPosition(uint64_t *dspFrames);
// Set the callback for notifying completion of non-blocking write and drain.
virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
@@ -165,6 +167,9 @@
// Return a recent count of the number of audio frames presented to an external observer.
virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
+ // Notifies the HAL layer that the framework considers the current playback as completed.
+ status_t presentationComplete() override;
+
// Called when the metadata of the stream's source has been changed.
status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
@@ -221,6 +226,10 @@
std::unique_ptr<StatusMQ> mStatusMQ;
std::atomic<pid_t> mWriterClient;
EventFlag* mEfGroup;
+ std::mutex mPositionMutex;
+ // Used to expand correctly the 32-bit position from the HAL.
+ uint64_t mRenderPosition GUARDED_BY(mPositionMutex) = 0;
+ bool mExpectRetrograde GUARDED_BY(mPositionMutex) = false; // See 'presentationComplete'.
// Can not be constructed directly by clients.
StreamOutHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& stream);
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index 37615af..eb14f6b 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -151,10 +151,7 @@
// Return the number of audio frames written by the audio dsp to DAC since
// the output has exited standby.
- virtual status_t getRenderPosition(uint32_t *dspFrames) = 0;
-
- // Get the local time at which the next write to the audio driver will be presented.
- virtual status_t getNextWriteTimestamp(int64_t *timestamp) = 0;
+ virtual status_t getRenderPosition(uint64_t *dspFrames) = 0;
// Set the callback for notifying completion of non-blocking write and drain.
// The callback must be owned by someone else. The output stream does not own it
@@ -182,6 +179,9 @@
// Return a recent count of the number of audio frames presented to an external observer.
virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;
+ // Notifies the HAL layer that the framework considers the current playback as completed.
+ virtual status_t presentationComplete() = 0;
+
struct SourceMetadata {
std::vector<playback_track_metadata_v7_t> tracks;
};
diff --git a/media/libmediaplayerservice/DeathNotifier.cpp b/media/libmediaplayerservice/DeathNotifier.cpp
index ab22f67..241c52d 100644
--- a/media/libmediaplayerservice/DeathNotifier.cpp
+++ b/media/libmediaplayerservice/DeathNotifier.cpp
@@ -17,11 +17,18 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaPlayerService-DeathNotifier"
#include <android-base/logging.h>
+#include <map>
#include "DeathNotifier.h"
namespace android {
+// Only dereference the cookie if it's valid (if it's in this set)
+// Only used with ndk
+static uintptr_t sCookieKeyCounter = 0;
+static std::map<uintptr_t, wp<DeathNotifier::DeathRecipient>> sCookies;
+static std::mutex sCookiesMutex;
+
class DeathNotifier::DeathRecipient :
public IBinder::DeathRecipient,
public hardware::hidl_death_recipient {
@@ -44,13 +51,32 @@
}
static void OnBinderDied(void *cookie) {
- DeathRecipient *thiz = (DeathRecipient *)cookie;
- thiz->mNotify();
+ std::unique_lock<std::mutex> guard(sCookiesMutex);
+ if (auto it = sCookies.find(reinterpret_cast<uintptr_t>(cookie)); it != sCookies.end()) {
+ sp<DeathRecipient> recipient = it->second.promote();
+ sCookies.erase(it);
+ guard.unlock();
+
+ if (recipient) {
+ LOG(INFO) << "Notifying DeathRecipient from OnBinderDied.";
+ recipient->mNotify();
+ } else {
+ LOG(INFO) <<
+ "Tried to notify DeathRecipient from OnBinderDied but could not promote.";
+ }
+ }
}
AIBinder_DeathRecipient *getNdkRecipient() {
return mNdkRecipient.get();;
}
+ ~DeathRecipient() {
+ // lock must be taken so object is not used in OnBinderDied"
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ sCookies.erase(mCookieKey);
+ }
+
+ uintptr_t mCookieKey;
private:
Notify mNotify;
@@ -73,8 +99,15 @@
: mService{std::in_place_index<3>, service},
mDeathRecipient{new DeathRecipient(notify)} {
mDeathRecipient->initNdk();
+ {
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ mDeathRecipient->mCookieKey = sCookieKeyCounter++;
+ sCookies[mDeathRecipient->mCookieKey] = mDeathRecipient;
+ }
AIBinder_linkToDeath(
- service.get(), mDeathRecipient->getNdkRecipient(), mDeathRecipient.get());
+ service.get(),
+ mDeathRecipient->getNdkRecipient(),
+ reinterpret_cast<void*>(mDeathRecipient->mCookieKey));
}
DeathNotifier::DeathNotifier(DeathNotifier&& other)
@@ -94,10 +127,11 @@
std::get<2>(mService)->unlinkToDeath(mDeathRecipient);
break;
case 3:
+
AIBinder_unlinkToDeath(
std::get<3>(mService).get(),
mDeathRecipient->getNdkRecipient(),
- mDeathRecipient.get());
+ reinterpret_cast<void*>(mDeathRecipient->mCookieKey));
break;
default:
CHECK(false) << "Corrupted service type during destruction.";
diff --git a/media/libmediaplayerservice/DeathNotifier.h b/media/libmediaplayerservice/DeathNotifier.h
index 24e45a3..0fd7c65 100644
--- a/media/libmediaplayerservice/DeathNotifier.h
+++ b/media/libmediaplayerservice/DeathNotifier.h
@@ -37,10 +37,11 @@
DeathNotifier(DeathNotifier&& other);
~DeathNotifier();
+ class DeathRecipient;
+
private:
std::variant<std::monostate, sp<IBinder>, sp<HBase>, ::ndk::SpAIBinder> mService;
- class DeathRecipient;
sp<DeathRecipient> mDeathRecipient;
};
diff --git a/media/libnblog/Reader.cpp b/media/libnblog/Reader.cpp
index 71ebfd1..d5f16e8 100644
--- a/media/libnblog/Reader.cpp
+++ b/media/libnblog/Reader.cpp
@@ -93,7 +93,7 @@
do {
availToRead = mFifoReader->obtain(iovec, capacity, NULL /*timeout*/, &lostTemp);
lost += lostTemp;
- } while (availToRead < 0 || ++tries <= kMaxObtainTries);
+ } while (availToRead < 0 && ++tries <= kMaxObtainTries);
if (availToRead <= 0) {
ALOGW_IF(availToRead < 0, "NBLog Reader %s failed to catch up with Writer", mName.c_str());
diff --git a/media/libstagefright/rtsp/fuzzer/Android.bp b/media/libstagefright/rtsp/fuzzer/Android.bp
index a2791ba..ff64af5 100644
--- a/media/libstagefright/rtsp/fuzzer/Android.bp
+++ b/media/libstagefright/rtsp/fuzzer/Android.bp
@@ -29,11 +29,19 @@
header_libs: [
"libstagefright_rtsp_headers",
],
- fuzz_config:{
+ fuzz_config: {
cc: [
- "android-media-fuzzing-reports@google.com",
+ "android-media-playback@google.com",
],
componentid: 155276,
+ hotlists: [
+ "4593311",
+ ],
+ description: "This fuzzer targets the APIs of libstagefright_rtsp",
+ vector: "local_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
@@ -44,7 +52,7 @@
],
defaults: [
"libstagefright_rtsp_fuzzer_defaults",
- ]
+ ],
}
cc_fuzz {
@@ -55,7 +63,7 @@
defaults: [
"libstagefright_rtsp_fuzzer_defaults",
],
- shared_libs:[
+ shared_libs: [
"libandroid_net",
"libbase",
"libstagefright",
diff --git a/media/module/bufferpool/2.0/AccessorImpl.cpp b/media/module/bufferpool/2.0/AccessorImpl.cpp
index 1d2562e..202d803 100644
--- a/media/module/bufferpool/2.0/AccessorImpl.cpp
+++ b/media/module/bufferpool/2.0/AccessorImpl.cpp
@@ -609,7 +609,7 @@
}
if (ret == false) {
ALOGW("buffer status message processing failure - message : %d connection : %lld",
- message.newStatus, (long long)message.connectionId);
+ (int)message.newStatus, (long long)message.connectionId);
}
}
messages.clear();
diff --git a/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
index af53f64..43a4628 100644
--- a/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
+++ b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
@@ -21,6 +21,7 @@
#include <aidl/android/media/IResourceObserverService.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <map>
#include <media/TranscodingResourcePolicy.h>
#include <utils/Log.h>
@@ -66,11 +67,31 @@
TranscodingResourcePolicy* mOwner;
};
+// cookie used for death recipients. The TranscodingResourcePolicy
+// that this cookie is associated with must outlive this cookie. It is
+// either deleted by binderDied, or in unregisterSelf which is also called
+// in the destructor of TranscodingResourcePolicy
+class TranscodingResourcePolicyCookie {
+ public:
+ TranscodingResourcePolicyCookie(TranscodingResourcePolicy* policy) : mPolicy(policy) {}
+ TranscodingResourcePolicyCookie() = delete;
+ TranscodingResourcePolicy* mPolicy;
+};
+
+static std::map<uintptr_t, std::unique_ptr<TranscodingResourcePolicyCookie>> sCookies;
+static uintptr_t sCookieKeyCounter;
+static std::mutex sCookiesMutex;
+
// static
void TranscodingResourcePolicy::BinderDiedCallback(void* cookie) {
- TranscodingResourcePolicy* owner = reinterpret_cast<TranscodingResourcePolicy*>(cookie);
- if (owner != nullptr) {
- owner->unregisterSelf();
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ if (auto it = sCookies.find(reinterpret_cast<uintptr_t>(cookie)); it != sCookies.end()) {
+ ALOGI("BinderDiedCallback unregistering TranscodingResourcePolicy");
+ auto policy = reinterpret_cast<TranscodingResourcePolicy*>(it->second->mPolicy);
+ if (policy) {
+ policy->unregisterSelf();
+ }
+ sCookies.erase(it);
}
// TODO(chz): retry to connecting to IResourceObserverService after failure.
// Also need to have back-up logic if IResourceObserverService is offline for
@@ -88,6 +109,23 @@
}
TranscodingResourcePolicy::~TranscodingResourcePolicy() {
+ {
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+
+ // delete all of the cookies associated with this TranscodingResourcePolicy
+ // instance since they are holding pointers to this object that will no
+ // longer be valid.
+ std::erase_if(sCookies, [this](const auto& cookieEntry) {
+ auto const& [key, cookie] = cookieEntry;
+ std::lock_guard guard(mCookieKeysLock);
+ if (const auto& it = mCookieKeys.find(key); it != mCookieKeys.end()) {
+ // No longer need to track this cookie
+ mCookieKeys.erase(key);
+ return true;
+ }
+ return false;
+ });
+ }
unregisterSelf();
}
@@ -123,7 +161,17 @@
return;
}
- AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast<void*>(this));
+ std::unique_ptr<TranscodingResourcePolicyCookie> cookie =
+ std::make_unique<TranscodingResourcePolicyCookie>(this);
+ void* cookiePtr = static_cast<void*>(cookie.get());
+ uintptr_t cookieKey = sCookieKeyCounter++;
+ sCookies.emplace(cookieKey, std::move(cookie));
+ {
+ std::lock_guard guard(mCookieKeysLock);
+ mCookieKeys.insert(cookieKey);
+ }
+
+ AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast<void*>(cookieKey));
ALOGD("@@@ registered observer");
mRegistered = true;
@@ -141,7 +189,6 @@
::ndk::SpAIBinder binder = mService->asBinder();
if (binder.get() != nullptr) {
Status status = mService->unregisterObserver(mObserver);
- AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast<void*>(this));
}
mService = nullptr;
diff --git a/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
index ee232e7..4d762b5 100644
--- a/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
+++ b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
@@ -22,6 +22,7 @@
#include <utils/Condition.h>
#include <mutex>
+#include <set>
namespace aidl {
namespace android {
namespace media {
@@ -48,6 +49,8 @@
bool mRegistered GUARDED_BY(mRegisteredLock);
std::shared_ptr<IResourceObserverService> mService GUARDED_BY(mRegisteredLock);
std::shared_ptr<ResourceObserver> mObserver;
+ mutable std::mutex mCookieKeysLock;
+ std::set<uintptr_t> mCookieKeys;
mutable std::mutex mCallbackLock;
std::weak_ptr<ResourcePolicyCallbackInterface> mResourcePolicyCallback
@@ -59,6 +62,7 @@
static void BinderDiedCallback(void* cookie);
void registerSelf();
+ // must delete the associated TranscodingResourcePolicyCookie any time this is called
void unregisterSelf();
void onResourceAvailable(pid_t pid);
}; // class TranscodingUidPolicy
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 3f0e305..7c248dc 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3401,9 +3401,9 @@
return NO_ERROR;
} else {
status_t status;
- uint32_t frames;
+ uint64_t frames = 0;
status = mOutput->getRenderPosition(&frames);
- *dspFrames = (size_t)frames;
+ *dspFrames = (uint32_t)frames;
return status;
}
}
@@ -5970,7 +5970,7 @@
vaf = v * sendLevel * (1. / MAX_GAIN_INT);
}
- track->setFinalVolume(vrf, vlf);
+ track->setFinalVolume(vlf, vrf);
// Delegate volume control to effect in track effect chain if needed
if (chain != 0 && chain->setVolume(&vl, &vr)) {
diff --git a/services/audioflinger/datapath/AudioStreamIn.cpp b/services/audioflinger/datapath/AudioStreamIn.cpp
index 76618f4..165ac25 100644
--- a/services/audioflinger/datapath/AudioStreamIn.cpp
+++ b/services/audioflinger/datapath/AudioStreamIn.cpp
@@ -58,7 +58,7 @@
if (mHalFormatHasProportionalFrames &&
(flags & AUDIO_INPUT_FLAG_DIRECT) == AUDIO_INPUT_FLAG_DIRECT) {
- // For DirectRecord reset timestamp to 0 on standby.
+ // For DirectRecord reset position to 0 on standby.
const uint64_t adjustedPosition = (halPosition <= mFramesReadAtStandby) ?
0 : (halPosition - mFramesReadAtStandby);
// Scale from HAL sample rate to application rate.
diff --git a/services/audioflinger/datapath/AudioStreamOut.cpp b/services/audioflinger/datapath/AudioStreamOut.cpp
index aad538f..a686ff6 100644
--- a/services/audioflinger/datapath/AudioStreamOut.cpp
+++ b/services/audioflinger/datapath/AudioStreamOut.cpp
@@ -51,42 +51,17 @@
return NO_INIT;
}
- uint32_t halPosition = 0;
+ uint64_t halPosition = 0;
const status_t status = stream->getRenderPosition(&halPosition);
if (status != NO_ERROR) {
return status;
}
-
- // Maintain a 64-bit render position using the 32-bit result from the HAL.
- // This delta calculation relies on the arithmetic overflow behavior
- // of integers. For example (100 - 0xFFFFFFF0) = 116.
- const auto truncatedPosition = (uint32_t)mRenderPosition;
- int32_t deltaHalPosition; // initialization not needed, overwitten by __builtin_sub_overflow()
- (void) __builtin_sub_overflow(halPosition, truncatedPosition, &deltaHalPosition);
-
- if (deltaHalPosition >= 0) {
- mRenderPosition += deltaHalPosition;
- } else if (mExpectRetrograde) {
- mExpectRetrograde = false;
- mRenderPosition -= static_cast<uint64_t>(-deltaHalPosition);
- }
// Scale from HAL sample rate to application rate.
- *frames = mRenderPosition / mRateMultiplier;
+ *frames = halPosition / mRateMultiplier;
return status;
}
-// return bottom 32-bits of the render position
-status_t AudioStreamOut::getRenderPosition(uint32_t *frames)
-{
- uint64_t position64 = 0;
- const status_t status = getRenderPosition(&position64);
- if (status == NO_ERROR) {
- *frames = (uint32_t)position64;
- }
- return status;
-}
-
status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp)
{
if (stream == nullptr) {
@@ -101,7 +76,7 @@
if (mHalFormatHasProportionalFrames &&
(flags & AUDIO_OUTPUT_FLAG_DIRECT) == AUDIO_OUTPUT_FLAG_DIRECT) {
- // For DirectTrack reset timestamp to 0 on standby.
+ // For DirectTrack reset position to 0 on standby.
const uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ?
0 : (halPosition - mFramesWrittenAtStandby);
// Scale from HAL sample rate to application rate.
@@ -179,8 +154,6 @@
int AudioStreamOut::flush()
{
- mRenderPosition = 0;
- mExpectRetrograde = false;
mFramesWritten = 0;
mFramesWrittenAtStandby = 0;
const status_t result = stream->flush();
@@ -189,12 +162,14 @@
int AudioStreamOut::standby()
{
- mRenderPosition = 0;
- mExpectRetrograde = false;
mFramesWrittenAtStandby = mFramesWritten;
return stream->standby();
}
+void AudioStreamOut::presentationComplete() {
+ stream->presentationComplete();
+}
+
ssize_t AudioStreamOut::write(const void *buffer, size_t numBytes)
{
size_t bytesWritten;
diff --git a/services/audioflinger/datapath/AudioStreamOut.h b/services/audioflinger/datapath/AudioStreamOut.h
index ea41bba..2c9fb3e 100644
--- a/services/audioflinger/datapath/AudioStreamOut.h
+++ b/services/audioflinger/datapath/AudioStreamOut.h
@@ -51,9 +51,6 @@
virtual ~AudioStreamOut();
- // Get the bottom 32-bits of the 64-bit render position.
- status_t getRenderPosition(uint32_t *frames);
-
virtual status_t getRenderPosition(uint64_t *frames);
virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
@@ -91,21 +88,14 @@
virtual status_t flush();
virtual status_t standby();
- // Avoid suppressing retrograde motion in mRenderPosition for gapless offload/direct when
- // transitioning between tracks.
- // The HAL resets the frame position without flush/stop being called, but calls back prior to
- // this event. So, on the next occurrence of retrograde motion, we permit backwards movement of
- // mRenderPosition.
- virtual void presentationComplete() { mExpectRetrograde = true; }
+ virtual void presentationComplete();
protected:
uint64_t mFramesWritten = 0; // reset by flush
uint64_t mFramesWrittenAtStandby = 0;
- uint64_t mRenderPosition = 0; // reset by flush, standby, or presentation complete
int mRateMultiplier = 1;
bool mHalFormatHasProportionalFrames = false;
size_t mHalFrameSize = 0;
- bool mExpectRetrograde = false; // see presentationComplete
};
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 3e1245b..f372c71 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -865,6 +865,8 @@
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
// OR the client is the current InputMethodService
// AND a RTT call is active AND the source is VOICE_RECOGNITION
+// OR The client is an active communication owner
+// AND is on TOP or latest started
// OR Any client
// AND The assistant is not on TOP
// AND is on TOP or latest started
@@ -1029,7 +1031,12 @@
bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;
- auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mMutex) {
+ // TODO: b/339112720
+ // Refine this logic when we have the correct phone state owner UID. The current issue is
+ // when a VOIP APP use Telecom API to manage calls, the mPhoneStateOwnerUid is AID_SYSTEM
+ // instead of the actual VOIP APP UID, so isPhoneStateOwnerActive here is not accurate.
+ const bool canCaptureIfInCallOrCommunication = [&](const auto& recordClient) REQUIRES(
+ mMutex) {
uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
recordClient->attributionSource.uid));
bool canCaptureCall = recordClient->canCaptureOutput;
@@ -1038,19 +1045,26 @@
|| recordUid == mPhoneStateOwnerUid;
return !(isInCall && !canCaptureCall)
&& !(isInCommunication && !canCaptureCommunication);
- };
+ }(current);
// By default allow capture if:
// The assistant is not on TOP
- // AND is on TOP or latest started
- // AND there is no active privacy sensitive capture or call
+ // AND is on TOP or latest started
+ // AND there is no active privacy sensitive capture or call
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
- bool allowSensitiveCapture =
+ // The assistant is on TOP
+ // AND is ongoing communication owner
+ // AND is on TOP or latest started
+ const bool allowSensitiveCapture =
!isSensitiveActive || isTopOrLatestSensitive || current->canCaptureOutput;
- bool allowCapture = !isAssistantOnTop
- && (isTopOrLatestActive || isTopOrLatestSensitive)
- && allowSensitiveCapture
- && canCaptureIfInCallOrCommunication(current);
+ bool allowCapture = false;
+ if (!isAssistantOnTop) {
+ allowCapture = (isTopOrLatestActive || isTopOrLatestSensitive) &&
+ allowSensitiveCapture && canCaptureIfInCallOrCommunication;
+ } else {
+ allowCapture = isInCommunication && isTopOrLatestSensitive &&
+ canCaptureIfInCallOrCommunication;
+ }
if (!current->hasOp()) {
// Never allow capture if app op is denied
@@ -1073,7 +1087,7 @@
allowCapture = true;
}
} else if (allowSensitiveCapture
- && canCaptureIfInCallOrCommunication(current)) {
+ && canCaptureIfInCallOrCommunication) {
if (isTopOrLatestAssistant
&& (source == AUDIO_SOURCE_VOICE_RECOGNITION
|| source == AUDIO_SOURCE_HOTWORD)) {
@@ -1094,7 +1108,7 @@
allowCapture = true;
}
} else if (allowSensitiveCapture
- && canCaptureIfInCallOrCommunication(current)) {
+ && canCaptureIfInCallOrCommunication) {
if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
{
allowCapture = true;
@@ -1109,7 +1123,7 @@
// Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
if (!isAssistantOnTop
&& allowSensitiveCapture
- && canCaptureIfInCallOrCommunication(current)) {
+ && canCaptureIfInCallOrCommunication) {
allowCapture = true;
}
if (isA11yOnTop) {
@@ -1123,7 +1137,7 @@
// AND no call is active
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
if (onlyHotwordActive
- && canCaptureIfInCallOrCommunication(current)) {
+ && canCaptureIfInCallOrCommunication) {
allowCapture = true;
}
} else if (mUidPolicy->isCurrentImeUid(currentUid)) {
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 30f16c7..7a2b434 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -342,25 +342,6 @@
mappedCameraId, deviceId);
i->handleBinderStatus(ret, "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d",
__FUNCTION__, i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
-
- // Only cameras of the default device can be remapped to a different camera (using
- // remapCameraIds method), so do the following only if the camera is associated with the
- // default device.
- if (deviceId == kDefaultDeviceId) {
- // For the default device, also trigger the torch callbacks for cameras that were
- // remapped to the current cameraId for the specific package that this listener belongs
- // to.
- std::vector<std::string> remappedCameraIds =
- findOriginalIdsForRemappedCameraId(cameraId, i->getListenerUid());
- for (auto &remappedCameraId: remappedCameraIds) {
- ret = i->getListener()->onTorchStatusChanged(mapToInterface(status),
- remappedCameraId, kDefaultDeviceId);
- i->handleBinderStatus(ret,
- "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d",
- __FUNCTION__, i->getListenerUid(), i->getListenerPid(),
- ret.exceptionCode());
- }
- }
}
}
@@ -839,24 +820,6 @@
return Status::ok();
}
-Status CameraService::remapCameraIds(const hardware::CameraIdRemapping& cameraIdRemapping) {
- if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) {
- const int pid = getCallingPid();
- const int uid = getCallingUid();
- ALOGE("%s: Permission Denial: can't configure camera ID mapping pid=%d, uid=%d",
- __FUNCTION__, pid, uid);
- return STATUS_ERROR(ERROR_PERMISSION_DENIED,
- "Permission Denial: no permission to configure camera id mapping");
- }
- TCameraIdRemapping cameraIdRemappingMap{};
- binder::Status parseStatus = parseCameraIdRemapping(cameraIdRemapping, &cameraIdRemappingMap);
- if (!parseStatus.isOk()) {
- return parseStatus;
- }
- remapCameraIds(cameraIdRemappingMap);
- return Status::ok();
-}
-
Status CameraService::createDefaultRequest(const std::string& unresolvedCameraId, int templateId,
int32_t deviceId, int32_t devicePolicy,
/* out */
@@ -874,7 +837,7 @@
}
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, getCallingUid());
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -937,7 +900,7 @@
}
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, getCallingUid());
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -1032,7 +995,7 @@
}
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, getCallingUid());
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -1171,120 +1134,6 @@
return Status::ok();
}
-Status CameraService::parseCameraIdRemapping(
- const hardware::CameraIdRemapping& cameraIdRemapping,
- /* out */ TCameraIdRemapping* cameraIdRemappingMap) {
- std::string packageName;
- std::string cameraIdToReplace, updatedCameraId;
- for (const auto& packageIdRemapping: cameraIdRemapping.packageIdRemappings) {
- packageName = packageIdRemapping.packageName;
- if (packageName.empty()) {
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: Package name cannot be empty");
- }
- if (packageIdRemapping.cameraIdsToReplace.size()
- != packageIdRemapping.updatedCameraIds.size()) {
- return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: Mismatch in CameraId Remapping lists sizes for package %s",
- packageName.c_str());
- }
- for (size_t i = 0; i < packageIdRemapping.cameraIdsToReplace.size(); i++) {
- cameraIdToReplace = packageIdRemapping.cameraIdsToReplace[i];
- updatedCameraId = packageIdRemapping.updatedCameraIds[i];
- if (cameraIdToReplace.empty() || updatedCameraId.empty()) {
- return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: Camera Id cannot be empty for package %s",
- packageName.c_str());
- }
- if (cameraIdToReplace == updatedCameraId) {
- return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: CameraIdToReplace cannot be the same"
- " as updatedCameraId for %s",
- packageName.c_str());
- }
-
- // Do not allow any camera remapping that involves a virtual camera.
- auto [deviceIdForCameraToReplace, _] =
- mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(
- cameraIdToReplace);
- if (deviceIdForCameraToReplace != kDefaultDeviceId) {
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: CameraIdToReplace cannot be a virtual camera");
- }
- [[maybe_unused]] auto [deviceIdForUpdatedCamera, unusedMappedCameraId] =
- mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(updatedCameraId);
- if (deviceIdForUpdatedCamera != kDefaultDeviceId) {
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
- "CameraIdRemapping: UpdatedCameraId cannot be a virtual camera");
- }
-
- (*cameraIdRemappingMap)[packageName][cameraIdToReplace] = updatedCameraId;
- }
- }
- return Status::ok();
-}
-
-void CameraService::remapCameraIds(const TCameraIdRemapping& cameraIdRemapping) {
- // Acquire mServiceLock and prevent other clients from connecting
- std::unique_ptr<AutoConditionLock> serviceLockWrapper =
- AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
-
- // Collect all existing clients for camera Ids that are being
- // remapped in the new cameraIdRemapping, but only if they were being used by a
- // targeted packageName.
- std::vector<sp<BasicClient>> clientsToDisconnect;
- std::vector<std::string> cameraIdsToUpdate;
- for (const auto& [packageName, injectionMap] : cameraIdRemapping) {
- for (auto& [id0, id1] : injectionMap) {
- ALOGI("%s: UPDATE:= %s: %s: %s", __FUNCTION__, packageName.c_str(),
- id0.c_str(), id1.c_str());
- auto clientDescriptor = mActiveClientManager.get(id0);
- if (clientDescriptor != nullptr) {
- sp<BasicClient> clientSp = clientDescriptor->getValue();
- if (clientSp->getPackageName() == packageName) {
- // This camera is being used by a targeted packageName and
- // being remapped to a new camera Id. We should disconnect it.
- clientsToDisconnect.push_back(clientSp);
- cameraIdsToUpdate.push_back(id0);
- }
- }
- }
- }
-
- for (auto& clientSp : clientsToDisconnect) {
- // Notify the clients about the disconnection.
- clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
- CaptureResultExtras{});
- }
-
- // Do not hold mServiceLock while disconnecting clients, but retain the condition
- // blocking other clients from connecting in mServiceLockWrapper if held.
- mServiceLock.unlock();
-
- // Clear calling identity for disconnect() PID checks.
- int64_t token = clearCallingIdentity();
-
- // Disconnect clients.
- for (auto& clientSp : clientsToDisconnect) {
- // This also triggers a call to updateStatus() which also reads mCameraIdRemapping
- // and requires mCameraIdRemappingLock.
- clientSp->disconnect();
- }
-
- // Invoke destructors (which call disconnect()) now while we don't hold the mServiceLock.
- clientsToDisconnect.clear();
-
- restoreCallingIdentity(token);
- mServiceLock.lock();
-
- {
- Mutex::Autolock lock(mCameraIdRemappingLock);
- // Update mCameraIdRemapping.
- mCameraIdRemapping.clear();
- mCameraIdRemapping.insert(cameraIdRemapping.begin(), cameraIdRemapping.end());
- }
-}
-
Status CameraService::injectSessionParams(
const std::string& cameraId,
const CameraMetadata& sessionParams) {
@@ -1325,56 +1174,10 @@
return Status::ok();
}
-std::vector<std::string> CameraService::findOriginalIdsForRemappedCameraId(
- const std::string& inputCameraId, int clientUid) {
- std::string packageName = getPackageNameFromUid(clientUid);
- std::vector<std::string> cameraIds;
- Mutex::Autolock lock(mCameraIdRemappingLock);
- if (auto packageMapIter = mCameraIdRemapping.find(packageName);
- packageMapIter != mCameraIdRemapping.end()) {
- for (auto& [id0, id1]: packageMapIter->second) {
- if (id1 == inputCameraId) {
- cameraIds.push_back(id0);
- }
- }
- }
- return cameraIds;
-}
-
-std::string CameraService::resolveCameraId(
- const std::string& inputCameraId,
- int clientUid,
- const std::string& packageName) {
- std::string packageNameVal = packageName;
- if (packageName.empty()) {
- packageNameVal = getPackageNameFromUid(clientUid);
- }
- if (clientUid < AID_APP_START || packageNameVal.empty()) {
- // We shouldn't remap cameras for processes with system/vendor UIDs.
- return inputCameraId;
- }
- Mutex::Autolock lock(mCameraIdRemappingLock);
- if (auto packageMapIter = mCameraIdRemapping.find(packageNameVal);
- packageMapIter != mCameraIdRemapping.end()) {
- auto packageMap = packageMapIter->second;
- if (auto replacementIdIter = packageMap.find(inputCameraId);
- replacementIdIter != packageMap.end()) {
- ALOGI("%s: resolveCameraId: remapping cameraId %s for %s to %s",
- __FUNCTION__, inputCameraId.c_str(),
- packageNameVal.c_str(),
- replacementIdIter->second.c_str());
- return replacementIdIter->second;
- }
- }
- return inputCameraId;
-}
-
std::optional<std::string> CameraService::resolveCameraId(
const std::string& inputCameraId,
int32_t deviceId,
- int32_t devicePolicy,
- int clientUid,
- const std::string& packageName) {
+ int32_t devicePolicy) {
if ((deviceId == kDefaultDeviceId)
|| (devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) {
auto [storedDeviceId, _] =
@@ -1386,7 +1189,7 @@
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return std::nullopt;
}
- return resolveCameraId(inputCameraId, clientUid, packageName);
+ return inputCameraId;
}
return mVirtualDeviceCameraIdMapper.getActualCameraId(deviceId, inputCameraId);
@@ -1463,8 +1266,7 @@
return std::string{};
}
- std::string unresolvedCameraId = (*cameraIds)[cameraIdInt];
- return resolveCameraId(unresolvedCameraId, getCallingUid());
+ return (*cameraIds)[cameraIdInt];
}
std::string CameraService::cameraIdIntToStr(int cameraIdInt, int32_t deviceId,
@@ -1491,7 +1293,7 @@
}
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, getCallingUid());
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -1533,7 +1335,7 @@
Mutex::Autolock l(mServiceLock);
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, getCallingUid());
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -1819,9 +1621,7 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
}
- std::string unresolvedCameraId = std::to_string(cameraId);
- std::string cameraIdStr = resolveCameraId(unresolvedCameraId,
- getCallingUid());
+ std::string cameraIdStr = std::to_string(cameraId);
// Check if we already have parameters
{
@@ -2444,7 +2244,7 @@
}
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, callingUid, clientPackageNameAdj);
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -3028,7 +2828,7 @@
int uid = getCallingUid();
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, uid);
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -3165,7 +2965,7 @@
int uid = getCallingUid();
std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy, uid);
+ devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
unresolvedCameraId.c_str(), deviceId);
@@ -3514,8 +3314,7 @@
for (auto cameraIdAndSessionConfiguration : cameraIdsAndSessionConfigurations) {
std::optional<std::string> cameraIdOptional =
- resolveCameraId(cameraIdAndSessionConfiguration.mCameraId, deviceId, devicePolicy,
- getCallingUid());
+ resolveCameraId(cameraIdAndSessionConfiguration.mCameraId, deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
cameraIdAndSessionConfiguration.mCameraId.c_str(), deviceId);
@@ -3631,8 +3430,7 @@
[this, &isVendorListener, &clientPid, &clientUid](const hardware::CameraStatus& s) {
std::string cameraId = s.cameraId;
std::optional<std::string> cameraIdOptional = resolveCameraId(s.cameraId,
- s.deviceId, IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM,
- clientUid);
+ s.deviceId, IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM);
if (!cameraIdOptional.has_value()) {
std::string msg =
fmt::sprintf(
@@ -3738,13 +3536,10 @@
return ret;
}
-Status CameraService::supportsCameraApi(const std::string& unresolvedCameraId, int apiVersion,
+Status CameraService::supportsCameraApi(const std::string& cameraId, int apiVersion,
/*out*/ bool *isSupported) {
ATRACE_CALL();
- const std::string cameraId = resolveCameraId(
- unresolvedCameraId, getCallingUid());
-
ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
switch (apiVersion) {
@@ -3806,13 +3601,10 @@
return Status::ok();
}
-Status CameraService::isHiddenPhysicalCamera(const std::string& unresolvedCameraId,
+Status CameraService::isHiddenPhysicalCamera(const std::string& cameraId,
/*out*/ bool *isSupported) {
ATRACE_CALL();
- const std::string cameraId = resolveCameraId(unresolvedCameraId,
- getCallingUid());
-
ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
*isSupported = mCameraProviderManager->isHiddenPhysicalCamera(cameraId);
@@ -5918,26 +5710,6 @@
"%s: Failed to trigger onStatusChanged callback for %d:%d: %d",
__FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
ret.exceptionCode());
-
- // Only cameras of the default device can be remapped to a different camera
- // (using remapCameraIds method), so do the following only if the camera is
- // associated with the default device.
- if (deviceId == kDefaultDeviceId) {
- // For the default device, also trigger the callbacks for cameras that were
- // remapped to the current cameraId for the specific package that this
- // listener belongs to.
- std::vector<std::string> remappedCameraIds =
- findOriginalIdsForRemappedCameraId(cameraId,
- listener->getListenerUid());
- for (auto &remappedCameraId: remappedCameraIds) {
- ret = listener->getListener()->onStatusChanged(
- mapToInterface(status), remappedCameraId, kDefaultDeviceId);
- listener->handleBinderStatus(ret,
- "%s: Failed to trigger onStatusChanged callback for %d:%d: %d",
- __FUNCTION__, listener->getListenerUid(),
- listener->getListenerPid(), ret.exceptionCode());
- }
- }
}
});
}
@@ -6168,8 +5940,6 @@
return handleWatchCommand(args, in, out);
} else if (args.size() >= 2 && args[0] == toString16("set-watchdog")) {
return handleSetCameraServiceWatchdog(args);
- } else if (args.size() >= 4 && args[0] == toString16("remap-camera-id")) {
- return handleCameraIdRemapping(args, err);
} else if (args.size() == 1 && args[0] == toString16("help")) {
printHelp(out);
return OK;
@@ -6178,23 +5948,6 @@
return BAD_VALUE;
}
-status_t CameraService::handleCameraIdRemapping(const Vector<String16>& args, int err) {
- uid_t uid = IPCThreadState::self()->getCallingUid();
- if (uid != AID_ROOT) {
- dprintf(err, "Must be adb root\n");
- return PERMISSION_DENIED;
- }
- if (args.size() != 4) {
- dprintf(err, "Expected format: remap-camera-id <PACKAGE> <Id0> <Id1>\n");
- return BAD_VALUE;
- }
- std::string packageName = toStdString(args[1]);
- std::string cameraIdToReplace = toStdString(args[2]);
- std::string cameraIdNew = toStdString(args[3]);
- remapCameraIds({{packageName, {{cameraIdToReplace, cameraIdNew}}}});
- return OK;
-}
-
status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
std::string packageName = toStdString(args[1]);
@@ -6811,7 +6564,6 @@
" set-watchdog <VALUE> enables or disables the camera service watchdog\n"
" Valid values 0=disable, 1=enable\n"
" watch <start|stop|dump|print|clear> manages tag monitoring in connected clients\n"
- " remap-camera-id <PACKAGE> <Id0> <Id1> remaps camera ids. Must use adb root\n"
" help print this message\n");
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 7b2fcff..9998fb8 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -21,7 +21,6 @@
#include <android/hardware/BnCameraService.h>
#include <android/hardware/BnSensorPrivacyListener.h>
#include <android/hardware/ICameraServiceListener.h>
-#include <android/hardware/CameraIdRemapping.h>
#include <android/hardware/camera2/BnCameraInjectionSession.h>
#include <android/hardware/camera2/ICameraInjectionCallback.h>
@@ -153,7 +152,7 @@
// ICameraService
// IMPORTANT: All binder calls that deal with logicalCameraId should use
// resolveCameraId(logicalCameraId, deviceId, devicePolicy) to arrive at the correct
- // cameraId to perform the operation on (in case of Id Remapping, or in case of contexts
+ // cameraId to perform the operation on (in case of contexts
// associated with virtual devices).
virtual binder::Status getNumberOfCameras(int32_t type, int32_t deviceId,
int32_t devicePolicy, int32_t* numCameras);
@@ -243,9 +242,6 @@
virtual binder::Status reportExtensionSessionStats(
const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/);
- virtual binder::Status remapCameraIds(const hardware::CameraIdRemapping&
- cameraIdRemapping);
-
virtual binder::Status injectSessionParams(
const std::string& cameraId,
const hardware::camera2::impl::CameraMetadataNative& sessionParams);
@@ -1043,43 +1039,9 @@
mutable Mutex mCameraStatesLock;
/**
- * Mapping from packageName -> {cameraIdToReplace -> newCameraIdtoUse}.
- *
- * This specifies that for packageName, for every binder operation targeting
- * cameraIdToReplace, use newCameraIdToUse instead.
- */
- typedef std::map<std::string, std::map<std::string, std::string>> TCameraIdRemapping;
- TCameraIdRemapping mCameraIdRemapping{};
- /** Mutex guarding mCameraIdRemapping. */
- Mutex mCameraIdRemappingLock;
-
- /** Parses cameraIdRemapping parcelable into the native cameraIdRemappingMap. */
- binder::Status parseCameraIdRemapping(
- const hardware::CameraIdRemapping& cameraIdRemapping,
- /* out */ TCameraIdRemapping* cameraIdRemappingMap);
-
- /**
- * Resolve the (potentially remapped) camera id to use for packageName for the default device
- * context.
- *
- * This returns the Camera id to use in case inputCameraId was remapped to a
- * different id for the given packageName. Otherwise, it returns the inputCameraId.
- *
- * If the packageName is not provided, it will be inferred from the clientUid.
- */
- std::string resolveCameraId(
- const std::string& inputCameraId,
- int clientUid,
- const std::string& packageName = "");
-
- /**
* Resolve the (potentially remapped) camera id for the given input camera id and the given
* device id and device policy (for the device associated with the context of the caller).
*
- * For any context associated with the default device or a virtual device with default camera
- * policy, this will return the actual camera id (in case inputCameraId was remapped using
- * the remapCameraIds method).
- *
* For any context associated with a virtual device with custom camera policy, this will return
* the actual camera id if inputCameraId corresponds to the mapped id of a virtual camera
* (for virtual devices with custom camera policy, the back and front virtual cameras of that
@@ -1088,20 +1050,7 @@
std::optional<std::string> resolveCameraId(
const std::string& inputCameraId,
int32_t deviceId,
- int32_t devicePolicy,
- int clientUid,
- const std::string& packageName = "");
-
- /**
- * Updates the state of mCameraIdRemapping, while disconnecting active clients as necessary.
- */
- void remapCameraIds(const TCameraIdRemapping& cameraIdRemapping);
-
- /**
- * Finds the Camera Ids that were remapped to the inputCameraId for the given client.
- */
- std::vector<std::string> findOriginalIdsForRemappedCameraId(
- const std::string& inputCameraId, int clientUid);
+ int32_t devicePolicy);
// Circular buffer for storing event logging for dumps
RingBuffer<std::string> mEventLog;
diff --git a/services/camera/virtualcamera/util/Util.cc b/services/camera/virtualcamera/util/Util.cc
index 7fdf54b..4aff60f 100644
--- a/services/camera/virtualcamera/util/Util.cc
+++ b/services/camera/virtualcamera/util/Util.cc
@@ -65,7 +65,6 @@
if (gBuffer == nullptr) {
return;
}
- gBuffer->unlock();
status_t status = gBuffer->unlock();
if (status != NO_ERROR) {
ALOGE("Failed to unlock graphic buffer: %s", statusToString(status).c_str());