• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "Camera3DeviceInjectionMethods"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <utils/Log.h>
22 #include <utils/Trace.h>
23 
24 #include "common/CameraProviderManager.h"
25 #include "device3/Camera3Device.h"
26 
27 namespace android {
28 
Camera3DeviceInjectionMethods(wp<Camera3Device> parent)29 Camera3Device::Camera3DeviceInjectionMethods::Camera3DeviceInjectionMethods(
30         wp<Camera3Device> parent)
31         : mParent(parent) {
32     ALOGV("%s: Created injection camera methods", __FUNCTION__);
33 }
34 
~Camera3DeviceInjectionMethods()35 Camera3Device::Camera3DeviceInjectionMethods::~Camera3DeviceInjectionMethods() {
36     ALOGV("%s: Removed injection camera methods", __FUNCTION__);
37     injectionDisconnectImpl();
38 }
39 
injectCamera(camera3::camera_stream_configuration & injectionConfig,const std::vector<uint32_t> & injectionBufferSizes)40 status_t Camera3Device::Camera3DeviceInjectionMethods::injectCamera(
41         camera3::camera_stream_configuration& injectionConfig,
42         const std::vector<uint32_t>& injectionBufferSizes) {
43     status_t res = NO_ERROR;
44 
45     if (mInjectedCamHalInterface == nullptr) {
46         ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
47         return DEAD_OBJECT;
48     }
49 
50     sp<Camera3Device> parent = mParent.promote();
51     if (parent == nullptr) {
52         ALOGE("%s: parent does not exist!", __FUNCTION__);
53         return INVALID_OPERATION;
54     }
55 
56     nsecs_t maxExpectedDuration = parent->getExpectedInFlightDuration();
57     bool wasActive = false;
58     if (parent->mStatus == STATUS_ACTIVE) {
59         ALOGV("%s: Let the device be IDLE and the request thread is paused",
60                 __FUNCTION__);
61         res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
62         if (res != OK) {
63             ALOGE("%s: Can't pause captures to inject camera!", __FUNCTION__);
64             return res;
65         }
66         wasActive = true;
67     }
68 
69     ALOGV("%s: Injection camera: replaceHalInterface", __FUNCTION__);
70     res = replaceHalInterface(mInjectedCamHalInterface, true);
71     if (res != OK) {
72         ALOGE("%s: Failed to replace the new HalInterface!", __FUNCTION__);
73         injectionDisconnectImpl();
74         return res;
75     }
76 
77     res = parent->mRequestThread->setHalInterface(mInjectedCamHalInterface);
78     if (res != OK) {
79         ALOGE("%s: Failed to set new HalInterface in RequestThread!", __FUNCTION__);
80         replaceHalInterface(mBackupHalInterface, false);
81         injectionDisconnectImpl();
82         return res;
83     }
84 
85     parent->mNeedConfig = true;
86     res = injectionConfigureStreams(injectionConfig, injectionBufferSizes);
87     parent->mNeedConfig = false;
88     if (res != OK) {
89         ALOGE("Can't injectionConfigureStreams device for streams:  %d: %s "
90                 "(%d)", parent->mNextStreamId, strerror(-res), res);
91         replaceHalInterface(mBackupHalInterface, false);
92         injectionDisconnectImpl();
93         return res;
94     }
95 
96     if (wasActive) {
97         ALOGV("%s: Restarting activity to inject camera", __FUNCTION__);
98         // Reuse current operating mode and session parameters for new stream
99         // config.
100         parent->internalResumeLocked();
101     }
102 
103     return OK;
104 }
105 
stopInjection()106 status_t Camera3Device::Camera3DeviceInjectionMethods::stopInjection() {
107     status_t res = NO_ERROR;
108 
109     sp<Camera3Device> parent = mParent.promote();
110     if (parent == nullptr) {
111         ALOGE("%s: parent does not exist!", __FUNCTION__);
112         return DEAD_OBJECT;
113     }
114 
115     nsecs_t maxExpectedDuration = parent->getExpectedInFlightDuration();
116     bool wasActive = false;
117     if (parent->mStatus == STATUS_ACTIVE) {
118         ALOGV("%s: Let the device be IDLE and the request thread is paused",
119                 __FUNCTION__);
120         res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
121         if (res != OK) {
122             ALOGE("%s: Can't pause captures to stop injection!", __FUNCTION__);
123             return res;
124         }
125         wasActive = true;
126     }
127 
128     res = replaceHalInterface(mBackupHalInterface, false);
129     if (res != OK) {
130         ALOGE("%s: Failed to restore the backup HalInterface!", __FUNCTION__);
131         injectionDisconnectImpl();
132         return res;
133     }
134     injectionDisconnectImpl();
135 
136     if (wasActive) {
137         ALOGV("%s: Restarting activity to stop injection", __FUNCTION__);
138         // Reuse current operating mode and session parameters for new stream
139         // config.
140         parent->internalResumeLocked();
141     }
142 
143     return OK;
144 }
145 
isInjecting()146 bool Camera3Device::Camera3DeviceInjectionMethods::isInjecting() {
147     if (mInjectedCamHalInterface == nullptr) {
148         return false;
149     } else {
150         return true;
151     }
152 }
153 
isStreamConfigCompleteButNotInjected()154 bool Camera3Device::Camera3DeviceInjectionMethods::isStreamConfigCompleteButNotInjected() {
155     return mIsStreamConfigCompleteButNotInjected;
156 }
157 
getInjectedCamId() const158 const String8& Camera3Device::Camera3DeviceInjectionMethods::getInjectedCamId()
159         const {
160     return mInjectedCamId;
161 }
162 
getInjectionConfig(camera3::camera_stream_configuration * injectionConfig,std::vector<uint32_t> * injectionBufferSizes)163 void Camera3Device::Camera3DeviceInjectionMethods::getInjectionConfig(
164         /*out*/ camera3::camera_stream_configuration* injectionConfig,
165         /*out*/ std::vector<uint32_t>* injectionBufferSizes) {
166     if (injectionConfig == nullptr || injectionBufferSizes == nullptr) {
167         ALOGE("%s: Injection configuration arguments must not be null!", __FUNCTION__);
168         return;
169     }
170 
171     *injectionConfig = mInjectionConfig;
172     *injectionBufferSizes = mInjectionBufferSizes;
173 }
174 
storeInjectionConfig(const camera3::camera_stream_configuration & injectionConfig,const std::vector<uint32_t> & injectionBufferSizes)175 void Camera3Device::Camera3DeviceInjectionMethods::storeInjectionConfig(
176         const camera3::camera_stream_configuration& injectionConfig,
177         const std::vector<uint32_t>& injectionBufferSizes) {
178     mIsStreamConfigCompleteButNotInjected = true;
179     mInjectionConfig = injectionConfig;
180     mInjectionStreams.clear();
181     for (size_t i = 0; i < injectionConfig.num_streams; i++) {
182         mInjectionStreams.push_back(injectionConfig.streams[i]);
183     }
184     mInjectionConfig.streams = mInjectionStreams.editArray();
185     mInjectionBufferSizes = injectionBufferSizes;
186 }
187 
injectionConfigureStreams(camera3::camera_stream_configuration & injectionConfig,const std::vector<uint32_t> & injectionBufferSizes)188 status_t Camera3Device::Camera3DeviceInjectionMethods::injectionConfigureStreams(
189         camera3::camera_stream_configuration& injectionConfig,
190         const std::vector<uint32_t>& injectionBufferSizes) {
191     ATRACE_CALL();
192     status_t res = NO_ERROR;
193 
194     sp<Camera3Device> parent = mParent.promote();
195     if (parent == nullptr) {
196         ALOGE("%s: parent does not exist!", __FUNCTION__);
197         return INVALID_OPERATION;
198     }
199 
200     if (parent->mOperatingMode < 0) {
201         ALOGE("Invalid operating mode: %d", parent->mOperatingMode);
202         return BAD_VALUE;
203     }
204 
205     // Start configuring the streams
206     ALOGV("%s: Injection camera %s: Starting stream configuration", __FUNCTION__,
207             mInjectedCamId.string());
208 
209     parent->mPreparerThread->pause();
210 
211     // Do the HAL configuration; will potentially touch stream
212     // max_buffers, usage, and priv fields, as well as data_space and format
213     // fields for IMPLEMENTATION_DEFINED formats.
214 
215     const camera_metadata_t* sessionBuffer = parent->mSessionParams.getAndLock();
216     res = mInjectedCamHalInterface->configureInjectedStreams(
217             sessionBuffer, &injectionConfig, injectionBufferSizes,
218             parent->mDeviceInfo);
219     parent->mSessionParams.unlock(sessionBuffer);
220 
221     if (res == BAD_VALUE) {
222         // HAL rejected this set of streams as unsupported, clean up config
223         // attempt and return to unconfigured state
224         ALOGE("Set of requested outputs not supported by HAL");
225         parent->cancelStreamsConfigurationLocked();
226         return BAD_VALUE;
227     } else if (res != OK) {
228         // Some other kind of error from configure_streams - this is not
229         // expected
230         ALOGE("Unable to configure streams with HAL: %s (%d)", strerror(-res),
231                   res);
232         return res;
233     }
234 
235     for (size_t i = 0; i < parent->mOutputStreams.size(); i++) {
236         sp<camera3::Camera3OutputStreamInterface> outputStream =
237                 parent->mOutputStreams[i];
238         mInjectedCamHalInterface->onStreamReConfigured(outputStream->getId());
239     }
240 
241     // Request thread needs to know to avoid using repeat-last-settings protocol
242     // across configure_streams() calls
243     parent->mRequestThread->configurationComplete(
244             parent->mIsConstrainedHighSpeedConfiguration, parent->mSessionParams,
245             parent->mGroupIdPhysicalCameraMap);
246 
247     parent->internalUpdateStatusLocked(STATUS_CONFIGURED);
248 
249     ALOGV("%s: Injection camera %s: Stream configuration complete", __FUNCTION__,
250             mInjectedCamId.string());
251 
252     auto rc = parent->mPreparerThread->resume();
253     if (rc != OK) {
254         ALOGE("%s: Injection camera %s: Preparer thread failed to resume!",
255                  __FUNCTION__, mInjectedCamId.string());
256         return rc;
257     }
258 
259     return OK;
260 }
261 
injectionDisconnectImpl()262 void Camera3Device::Camera3DeviceInjectionMethods::injectionDisconnectImpl() {
263     ATRACE_CALL();
264     ALOGI("%s: Injection camera disconnect", __FUNCTION__);
265     mIsStreamConfigCompleteButNotInjected = false;
266     mInjectionStreams.clear();
267     mInjectionConfig.streams = nullptr;
268 
269     mBackupHalInterface = nullptr;
270     HalInterface* interface = nullptr;
271     {
272         Mutex::Autolock lock(mInjectionLock);
273         if (mInjectedCamHalInterface != nullptr) {
274             interface = mInjectedCamHalInterface.get();
275             // Call close without internal mutex held, as the HAL close may need
276             // to wait on assorted callbacks,etc, to complete before it can
277             // return.
278         }
279     }
280 
281     if (interface != nullptr) {
282         interface->close();
283     }
284 
285     {
286         Mutex::Autolock lock(mInjectionLock);
287         if (mInjectedCamHalInterface != nullptr) {
288             mInjectedCamHalInterface->clear();
289             mInjectedCamHalInterface = nullptr;
290         }
291     }
292 }
293 
294 };  // namespace android
295