1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "CameraServiceProxyWrapper"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <inttypes.h>
22 #include <utils/Log.h>
23 #include <binder/IServiceManager.h>
24 
25 #include "CameraServiceProxyWrapper.h"
26 
27 namespace android {
28 
29 using hardware::ICameraServiceProxy;
30 using hardware::CameraSessionStats;
31 
32 Mutex CameraServiceProxyWrapper::sProxyMutex;
33 sp<hardware::ICameraServiceProxy> CameraServiceProxyWrapper::sCameraServiceProxy;
34 
35 Mutex CameraServiceProxyWrapper::mLock;
36 std::map<String8, std::shared_ptr<CameraServiceProxyWrapper::CameraSessionStatsWrapper>>
37         CameraServiceProxyWrapper::mSessionStatsMap;
38 
39 /**
40  * CameraSessionStatsWrapper functions
41  */
42 
onOpen()43 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onOpen() {
44     Mutex::Autolock l(mLock);
45 
46     updateProxyDeviceState(mSessionStats);
47 }
48 
onClose(int32_t latencyMs)49 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onClose(int32_t latencyMs) {
50     Mutex::Autolock l(mLock);
51 
52     mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_CLOSED;
53     mSessionStats.mLatencyMs = latencyMs;
54     updateProxyDeviceState(mSessionStats);
55 }
56 
onStreamConfigured(int operatingMode,bool internalReconfig,int32_t latencyMs)57 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onStreamConfigured(
58         int operatingMode, bool internalReconfig, int32_t latencyMs) {
59     Mutex::Autolock l(mLock);
60 
61     if (internalReconfig) {
62         mSessionStats.mInternalReconfigure++;
63     } else {
64         mSessionStats.mLatencyMs = latencyMs;
65         mSessionStats.mSessionType = operatingMode;
66     }
67 }
68 
onActive()69 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onActive() {
70     Mutex::Autolock l(mLock);
71 
72     mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_ACTIVE;
73     updateProxyDeviceState(mSessionStats);
74 
75     // Reset mCreationDuration to -1 to distinguish between 1st session
76     // after configuration, and all other sessions after configuration.
77     mSessionStats.mLatencyMs = -1;
78 }
79 
onIdle(int64_t requestCount,int64_t resultErrorCount,bool deviceError,const std::vector<hardware::CameraStreamStats> & streamStats)80 void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onIdle(
81         int64_t requestCount, int64_t resultErrorCount, bool deviceError,
82         const std::vector<hardware::CameraStreamStats>& streamStats) {
83     Mutex::Autolock l(mLock);
84 
85     mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_IDLE;
86     mSessionStats.mRequestCount = requestCount;
87     mSessionStats.mResultErrorCount = resultErrorCount;
88     mSessionStats.mDeviceError = deviceError;
89     mSessionStats.mStreamStats = streamStats;
90     updateProxyDeviceState(mSessionStats);
91 
92     mSessionStats.mInternalReconfigure = 0;
93     mSessionStats.mStreamStats.clear();
94 }
95 
96 /**
97  * CameraServiceProxyWrapper functions
98  */
99 
getCameraServiceProxy()100 sp<ICameraServiceProxy> CameraServiceProxyWrapper::getCameraServiceProxy() {
101 #ifndef __BRILLO__
102     Mutex::Autolock al(sProxyMutex);
103     if (sCameraServiceProxy == nullptr) {
104         sp<IServiceManager> sm = defaultServiceManager();
105         // Use checkService because cameraserver normally starts before the
106         // system server and the proxy service. So the long timeout that getService
107         // has before giving up is inappropriate.
108         sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
109         if (binder != nullptr) {
110             sCameraServiceProxy = interface_cast<ICameraServiceProxy>(binder);
111         }
112     }
113 #endif
114     return sCameraServiceProxy;
115 }
116 
pingCameraServiceProxy()117 void CameraServiceProxyWrapper::pingCameraServiceProxy() {
118     sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
119     if (proxyBinder == nullptr) return;
120     proxyBinder->pingForUserUpdate();
121 }
122 
getRotateAndCropOverride(String16 packageName,int lensFacing,int userId)123 int CameraServiceProxyWrapper::getRotateAndCropOverride(String16 packageName, int lensFacing,
124         int userId) {
125     sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
126     if (proxyBinder == nullptr) return true;
127     int ret = 0;
128     auto status = proxyBinder->getRotateAndCropOverride(packageName, lensFacing, userId, &ret);
129     if (!status.isOk()) {
130         ALOGE("%s: Failed during top activity orientation query: %s", __FUNCTION__,
131                 status.exceptionMessage().c_str());
132     }
133 
134     return ret;
135 }
136 
updateProxyDeviceState(const CameraSessionStats & sessionStats)137 void CameraServiceProxyWrapper::updateProxyDeviceState(const CameraSessionStats& sessionStats) {
138     sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
139     if (proxyBinder == nullptr) return;
140     proxyBinder->notifyCameraState(sessionStats);
141 }
142 
logStreamConfigured(const String8 & id,int operatingMode,bool internalConfig,int32_t latencyMs)143 void CameraServiceProxyWrapper::logStreamConfigured(const String8& id,
144         int operatingMode, bool internalConfig, int32_t latencyMs) {
145     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
146     {
147         Mutex::Autolock l(mLock);
148         sessionStats = mSessionStatsMap[id];
149         if (sessionStats == nullptr) {
150             ALOGE("%s: SessionStatsMap should contain camera %s",
151                     __FUNCTION__, id.c_str());
152             return;
153         }
154     }
155 
156     ALOGV("%s: id %s, operatingMode %d, internalConfig %d, latencyMs %d",
157             __FUNCTION__, id.c_str(), operatingMode, internalConfig, latencyMs);
158     sessionStats->onStreamConfigured(operatingMode, internalConfig, latencyMs);
159 }
160 
logActive(const String8 & id)161 void CameraServiceProxyWrapper::logActive(const String8& id) {
162     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
163     {
164         Mutex::Autolock l(mLock);
165         sessionStats = mSessionStatsMap[id];
166         if (sessionStats == nullptr) {
167             ALOGE("%s: SessionStatsMap should contain camera %s when logActive is called",
168                     __FUNCTION__, id.c_str());
169             return;
170         }
171     }
172 
173     ALOGV("%s: id %s", __FUNCTION__, id.c_str());
174     sessionStats->onActive();
175 }
176 
logIdle(const String8 & id,int64_t requestCount,int64_t resultErrorCount,bool deviceError,const std::vector<hardware::CameraStreamStats> & streamStats)177 void CameraServiceProxyWrapper::logIdle(const String8& id,
178         int64_t requestCount, int64_t resultErrorCount, bool deviceError,
179         const std::vector<hardware::CameraStreamStats>& streamStats) {
180     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
181     {
182         Mutex::Autolock l(mLock);
183         sessionStats = mSessionStatsMap[id];
184     }
185 
186     if (sessionStats == nullptr) {
187         ALOGE("%s: SessionStatsMap should contain camera %s when logIdle is called",
188                 __FUNCTION__, id.c_str());
189         return;
190     }
191 
192     ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d",
193             __FUNCTION__, id.c_str(), requestCount, resultErrorCount, deviceError);
194     for (size_t i = 0; i < streamStats.size(); i++) {
195         ALOGV("%s: streamStats[%zu]: w %d h %d, requestedCount %" PRId64 ", dropCount %"
196                 PRId64 ", startTimeMs %d" ,
197                 __FUNCTION__, i, streamStats[i].mWidth, streamStats[i].mHeight,
198                 streamStats[i].mRequestCount, streamStats[i].mErrorCount,
199                 streamStats[i].mStartLatencyMs);
200     }
201 
202     sessionStats->onIdle(requestCount, resultErrorCount, deviceError, streamStats);
203 }
204 
logOpen(const String8 & id,int facing,const String16 & clientPackageName,int effectiveApiLevel,bool isNdk,int32_t latencyMs)205 void CameraServiceProxyWrapper::logOpen(const String8& id, int facing,
206             const String16& clientPackageName, int effectiveApiLevel, bool isNdk,
207             int32_t latencyMs) {
208     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
209     {
210         Mutex::Autolock l(mLock);
211         if (mSessionStatsMap.count(id) > 0) {
212             ALOGE("%s: SessionStatsMap shouldn't contain camera %s",
213                     __FUNCTION__, id.c_str());
214             return;
215         }
216 
217         int apiLevel = CameraSessionStats::CAMERA_API_LEVEL_1;
218         if (effectiveApiLevel == 2) {
219             apiLevel = CameraSessionStats::CAMERA_API_LEVEL_2;
220         }
221 
222         sessionStats = std::make_shared<CameraSessionStatsWrapper>(String16(id), facing,
223                 CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
224                 apiLevel, isNdk, latencyMs);
225         mSessionStatsMap.emplace(id, sessionStats);
226         ALOGV("%s: Adding id %s", __FUNCTION__, id.c_str());
227     }
228 
229     ALOGV("%s: id %s, facing %d, effectiveApiLevel %d, isNdk %d, latencyMs %d",
230             __FUNCTION__, id.c_str(), facing, effectiveApiLevel, isNdk, latencyMs);
231     sessionStats->onOpen();
232 }
233 
logClose(const String8 & id,int32_t latencyMs)234 void CameraServiceProxyWrapper::logClose(const String8& id, int32_t latencyMs) {
235     std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
236     {
237         Mutex::Autolock l(mLock);
238         if (mSessionStatsMap.count(id) == 0) {
239             ALOGE("%s: SessionStatsMap should contain camera %s before it's closed",
240                     __FUNCTION__, id.c_str());
241             return;
242         }
243 
244         sessionStats = mSessionStatsMap[id];
245         if (sessionStats == nullptr) {
246             ALOGE("%s: SessionStatsMap should contain camera %s",
247                     __FUNCTION__, id.c_str());
248             return;
249         }
250         mSessionStatsMap.erase(id);
251         ALOGV("%s: Erasing id %s", __FUNCTION__, id.c_str());
252     }
253 
254     ALOGV("%s: id %s, latencyMs %d", __FUNCTION__, id.c_str(), latencyMs);
255     sessionStats->onClose(latencyMs);
256 }
257 
258 }; // namespace android
259