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/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index bf7e597..d93b9e5 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2189,31 +2189,40 @@
         std::lock_guard<std::mutex> l(mOutputLock);
         listener = mListener.promote();
     }
-    if (idle && listener != NULL) {
-        // Get session stats from the builder, and notify the listener.
-        int64_t requestCount, resultErrorCount;
-        bool deviceError;
-        std::map<int, StreamStats> streamStatsMap;
-        mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
-                &deviceError, &streamStatsMap);
-        for (size_t i = 0; i < streamIds.size(); i++) {
-            int streamId = streamIds[i];
-            auto stats = streamStatsMap.find(streamId);
-            if (stats != streamStatsMap.end()) {
-                streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
-                streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
-                streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
-                streamStats[i].mHistogramType =
-                        hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
-                streamStats[i].mHistogramBins.assign(
-                        stats->second.mCaptureLatencyBins.begin(),
-                        stats->second.mCaptureLatencyBins.end());
-                streamStats[i].mHistogramCounts.assign(
-                        stats->second.mCaptureLatencyHistogram.begin(),
-                        stats->second.mCaptureLatencyHistogram.end());
+    status_t res = OK;
+    if (listener != nullptr) {
+        if (idle) {
+            // Get session stats from the builder, and notify the listener.
+            int64_t requestCount, resultErrorCount;
+            bool deviceError;
+            std::map<int, StreamStats> streamStatsMap;
+            mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
+                    &deviceError, &streamStatsMap);
+            for (size_t i = 0; i < streamIds.size(); i++) {
+                int streamId = streamIds[i];
+                auto stats = streamStatsMap.find(streamId);
+                if (stats != streamStatsMap.end()) {
+                    streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
+                    streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
+                    streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
+                    streamStats[i].mHistogramType =
+                            hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
+                    streamStats[i].mHistogramBins.assign(
+                            stats->second.mCaptureLatencyBins.begin(),
+                            stats->second.mCaptureLatencyBins.end());
+                    streamStats[i].mHistogramCounts.assign(
+                           stats->second.mCaptureLatencyHistogram.begin(),
+                           stats->second.mCaptureLatencyHistogram.end());
+                }
             }
+            listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
+        } else {
+            res = listener->notifyActive();
         }
-        listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
+    }
+    if (res != OK) {
+        SET_ERR("Camera access permission lost mid-operation: %s (%d)",
+                strerror(-res), res);
     }
 }