1 /*
2  * Copyright (C) 2016 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_NDEBUG 0
18 #define LOG_TAG "ACameraCaptureSession"
19 
20 #include "ACameraCaptureSession.h"
21 
22 using namespace android;
23 
~ACameraCaptureSession()24 ACameraCaptureSession::~ACameraCaptureSession() {
25     ALOGV("~ACameraCaptureSession: %p notify device end of life", this);
26 #ifdef __ANDROID_VNDK__
27     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
28 #else
29     sp<acam::CameraDevice> dev = getDeviceSp();
30 #endif
31     if (dev != nullptr && !dev->isClosed()) {
32         dev->lockDeviceForSessionOps();
33         {
34             Mutex::Autolock _l(mSessionLock);
35             dev->notifySessionEndOfLifeLocked(this);
36         }
37         dev->unlockDevice();
38     }
39     // Fire onClosed callback
40     if (mUserSessionCallback.onClosed != nullptr) {
41         (*mUserSessionCallback.onClosed)(mUserSessionCallback.context, this);
42     }
43     ALOGV("~ACameraCaptureSession: %p is deleted", this);
44 }
45 
46 void
closeByApp()47 ACameraCaptureSession::closeByApp() {
48     {
49         Mutex::Autolock _l(mSessionLock);
50         if (mClosedByApp) {
51             // Do not close twice
52             return;
53         }
54         mClosedByApp = true;
55     }
56 
57 #ifdef __ANDROID_VNDK__
58     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
59 #else
60     sp<acam::CameraDevice> dev = getDeviceSp();
61 #endif
62     if (dev != nullptr) {
63         dev->lockDeviceForSessionOps();
64     }
65 
66     {
67         Mutex::Autolock _l(mSessionLock);
68 
69         if (!mIsClosed && dev != nullptr) {
70             camera_status_t ret = dev->stopRepeatingLocked();
71             if (ret != ACAMERA_OK) {
72                 ALOGE("Stop repeating request failed while closing session %p", this);
73             }
74         }
75         mIsClosed = true;
76     }
77 
78     if (dev != nullptr) {
79         dev->unlockDevice();
80     }
81     this->decStrong((void*) ACameraDevice_createCaptureSession);
82 }
83 
84 camera_status_t
stopRepeating()85 ACameraCaptureSession::stopRepeating() {
86 #ifdef __ANDROID_VNDK__
87     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
88 #else
89     sp<acam::CameraDevice> dev = getDeviceSp();
90 #endif
91     if (dev == nullptr) {
92         ALOGE("Error: Device associated with session %p has been closed!", this);
93         return ACAMERA_ERROR_SESSION_CLOSED;
94     }
95 
96     camera_status_t ret;
97     dev->lockDeviceForSessionOps();
98     {
99         Mutex::Autolock _l(mSessionLock);
100         ret = dev->stopRepeatingLocked();
101     }
102     dev->unlockDevice();
103     return ret;
104 }
105 
106 camera_status_t
abortCaptures()107 ACameraCaptureSession::abortCaptures() {
108 #ifdef __ANDROID_VNDK__
109     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
110 #else
111     sp<acam::CameraDevice> dev = getDeviceSp();
112 #endif
113     if (dev == nullptr) {
114         ALOGE("Error: Device associated with session %p has been closed!", this);
115         return ACAMERA_ERROR_SESSION_CLOSED;
116     }
117 
118     camera_status_t ret;
119     dev->lockDeviceForSessionOps();
120     {
121         Mutex::Autolock _l(mSessionLock);
122         ret = dev->flushLocked(this);
123     }
124     dev->unlockDevice();
125     return ret;
126 }
127 
updateOutputConfiguration(ACaptureSessionOutput * output)128 camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSessionOutput *output) {
129 #ifdef __ANDROID_VNDK__
130     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
131 #else
132     sp<acam::CameraDevice> dev = getDeviceSp();
133 #endif
134     if (dev == nullptr) {
135         ALOGE("Error: Device associated with session %p has been closed!", this);
136         return ACAMERA_ERROR_SESSION_CLOSED;
137     }
138 
139     camera_status_t ret;
140     dev->lockDeviceForSessionOps();
141     {
142         Mutex::Autolock _l(mSessionLock);
143         ret = dev->updateOutputConfigurationLocked(output);
144     }
145     dev->unlockDevice();
146     return ret;
147 }
148 
prepare(ANativeWindow * window)149 camera_status_t ACameraCaptureSession::prepare(ANativeWindow* window) {
150 #ifdef __ANDROID_VNDK__
151     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
152 #else
153     sp<acam::CameraDevice> dev = getDeviceSp();
154 #endif
155     if (dev == nullptr) {
156         ALOGE("Error: Device associated with session %p has been closed!", this);
157         return ACAMERA_ERROR_SESSION_CLOSED;
158     }
159 
160     camera_status_t ret;
161     dev->lockDeviceForSessionOps();
162     {
163         Mutex::Autolock _l(mSessionLock);
164         ret = dev->prepareLocked(window);
165     }
166     dev->unlockDevice();
167     return ret;
168 }
169 
170 ACameraDevice*
getDevice()171 ACameraCaptureSession::getDevice() {
172     Mutex::Autolock _l(mSessionLock);
173 #ifdef __ANDROID_VNDK__
174     std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
175 #else
176     sp<acam::CameraDevice> dev = getDeviceSp();
177 #endif
178     if (dev == nullptr) {
179         ALOGE("Error: Device associated with session %p has been closed!", this);
180         return nullptr;
181     }
182     return dev->getWrapper();
183 }
184 
185 void
closeByDevice()186 ACameraCaptureSession::closeByDevice() {
187     Mutex::Autolock _l(mSessionLock);
188     mIsClosed = true;
189 }
190 
191 #ifdef __ANDROID_VNDK__
192 std::shared_ptr<acam::CameraDevice>
getDevicePtr()193 ACameraCaptureSession::getDevicePtr() {
194     std::shared_ptr<acam::CameraDevice> device = mDevice.lock();
195     if (device == nullptr || device->isClosed()) {
196         ALOGW("Device is closed but session %d is not notified", mId);
197         return nullptr;
198     }
199     return device;
200 }
201 #else
202 sp<acam::CameraDevice>
getDeviceSp()203 ACameraCaptureSession::getDeviceSp() {
204     sp<acam::CameraDevice> device = mDevice.promote();
205     if (device == nullptr || device->isClosed()) {
206         ALOGW("Device is closed but session %d is not notified", mId);
207         return nullptr;
208     }
209     return device;
210 }
211 #endif
212