Camera: Move app ops to start/stop of streaming
A camera can be open but not streaming data. While most applications
immediately start streaming data, it can be useful to simply open the
camera early to hide some of the startup latency.
Historically, the camera service has reported camera app ops as
starting when the device is open, and stopping when the device closes.
With camera app op state becoming more directly visible to end users
via camera muting and camera usage notifications, it's useful to
narrow the scope of appops reporting to when the camera is actually
streaming frames, which is the time that's privacy-sensitive.
Here, the device-level status tracker is used to report idle and
active state to the client class, which then reports to appops
accordingly. The same source is used for both idle and active to
ensure that there's no race condition possible that might cause
desynchronization of client state.
Bug: 185798362
Test: Manual testing with TestingCamera1 and 2, Camera CTS continues to pass
Change-Id: Ie2537e66603acfead20d69cf0fc5299462c0e9e4
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 1f79354..ce479a1 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -250,10 +250,32 @@
}
template <typename TClientBase>
+status_t Camera2ClientBase<TClientBase>::notifyActive() {
+ if (!mDeviceActive) {
+ status_t res = TClientBase::startCameraStreamingOps();
+ if (res != OK) {
+ ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__,
+ TClientBase::mCameraIdStr.string(), res);
+ return res;
+ }
+ CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr);
+ }
+ mDeviceActive = true;
+
+ ALOGV("Camera device is now active");
+ return OK;
+}
+
+template <typename TClientBase>
void Camera2ClientBase<TClientBase>::notifyIdle(
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::vector<hardware::CameraStreamStats>& streamStats) {
if (mDeviceActive) {
+ status_t res = TClientBase::finishCameraStreamingOps();
+ if (res != OK) {
+ ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__,
+ TClientBase::mCameraIdStr.string(), res);
+ }
CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr,
requestCount, resultErrorCount, deviceError, streamStats);
}
@@ -268,11 +290,6 @@
(void)resultExtras;
(void)timestamp;
- if (!mDeviceActive) {
- CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr);
- }
- mDeviceActive = true;
-
ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
__FUNCTION__, resultExtras.requestId, timestamp);
}