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
22using namespace android;
23
24ACameraCaptureSession::~ACameraCaptureSession() {
25    ALOGV("~ACameraCaptureSession: %p notify device end of life", this);
26    sp<CameraDevice> dev = getDeviceSp();
27    if (dev != nullptr && !dev->isClosed()) {
28        dev->lockDeviceForSessionOps();
29        {
30            Mutex::Autolock _l(mSessionLock);
31            dev->notifySessionEndOfLifeLocked(this);
32        }
33        dev->unlockDevice();
34    }
35    // Fire onClosed callback
36    (*mUserSessionCallback.onClosed)(mUserSessionCallback.context, this);
37    ALOGV("~ACameraCaptureSession: %p is deleted", this);
38}
39
40void
41ACameraCaptureSession::closeByApp() {
42    {
43        Mutex::Autolock _l(mSessionLock);
44        if (mClosedByApp) {
45            // Do not close twice
46            return;
47        }
48        mClosedByApp = true;
49    }
50
51    sp<CameraDevice> dev = getDeviceSp();
52    if (dev != nullptr) {
53        dev->lockDeviceForSessionOps();
54    }
55
56    {
57        Mutex::Autolock _l(mSessionLock);
58
59        if (!mIsClosed && dev != nullptr) {
60            camera_status_t ret = dev->stopRepeatingLocked();
61            if (ret != ACAMERA_OK) {
62                ALOGE("Stop repeating request failed while closing session %p", this);
63            }
64        }
65        mIsClosed = true;
66    }
67
68    if (dev != nullptr) {
69        dev->unlockDevice();
70    }
71    this->decStrong((void*) ACameraDevice_createCaptureSession);
72}
73
74camera_status_t
75ACameraCaptureSession::stopRepeating() {
76    sp<CameraDevice> dev = getDeviceSp();
77    if (dev == nullptr) {
78        ALOGE("Error: Device associated with session %p has been closed!", this);
79        return ACAMERA_ERROR_SESSION_CLOSED;
80    }
81
82    camera_status_t ret;
83    dev->lockDeviceForSessionOps();
84    {
85        Mutex::Autolock _l(mSessionLock);
86        ret = dev->stopRepeatingLocked();
87    }
88    dev->unlockDevice();
89    return ret;
90}
91
92camera_status_t
93ACameraCaptureSession::abortCaptures() {
94    sp<CameraDevice> dev = getDeviceSp();
95    if (dev == nullptr) {
96        ALOGE("Error: Device associated with session %p has been closed!", this);
97        return ACAMERA_ERROR_SESSION_CLOSED;
98    }
99
100    camera_status_t ret;
101    dev->lockDeviceForSessionOps();
102    {
103        Mutex::Autolock _l(mSessionLock);
104        ret = dev->flushLocked(this);
105    }
106    dev->unlockDevice();
107    return ret;
108}
109
110camera_status_t
111ACameraCaptureSession::setRepeatingRequest(
112        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
113        int numRequests, ACaptureRequest** requests,
114        /*optional*/int* captureSequenceId) {
115    sp<CameraDevice> dev = getDeviceSp();
116    if (dev == nullptr) {
117        ALOGE("Error: Device associated with session %p has been closed!", this);
118        return ACAMERA_ERROR_SESSION_CLOSED;
119    }
120
121    camera_status_t ret;
122    dev->lockDeviceForSessionOps();
123    {
124        Mutex::Autolock _l(mSessionLock);
125        ret = dev->setRepeatingRequestsLocked(
126                this, cbs, numRequests, requests, captureSequenceId);
127    }
128    dev->unlockDevice();
129    return ret;
130}
131
132camera_status_t ACameraCaptureSession::capture(
133        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
134        int numRequests, ACaptureRequest** requests,
135        /*optional*/int* captureSequenceId) {
136    sp<CameraDevice> dev = getDeviceSp();
137    if (dev == nullptr) {
138        ALOGE("Error: Device associated with session %p has been closed!", this);
139        return ACAMERA_ERROR_SESSION_CLOSED;
140    }
141    camera_status_t ret;
142    dev->lockDeviceForSessionOps();
143    {
144        Mutex::Autolock _l(mSessionLock);
145        ret = dev->captureLocked(this, cbs, numRequests, requests, captureSequenceId);
146    }
147    dev->unlockDevice();
148    return ret;
149}
150
151ACameraDevice*
152ACameraCaptureSession::getDevice() {
153    Mutex::Autolock _l(mSessionLock);
154    sp<CameraDevice> dev = getDeviceSp();
155    if (dev == nullptr) {
156        ALOGE("Error: Device associated with session %p has been closed!", this);
157        return nullptr;
158    }
159    return dev->getWrapper();
160}
161
162void
163ACameraCaptureSession::closeByDevice() {
164    Mutex::Autolock _l(mSessionLock);
165    mIsClosed = true;
166}
167
168sp<CameraDevice>
169ACameraCaptureSession::getDeviceSp() {
170    sp<CameraDevice> device = mDevice.promote();
171    if (device == nullptr || device->isClosed()) {
172        ALOGW("Device is closed but session %d is not notified", mId);
173        return nullptr;
174    }
175    return device;
176}
177
178
179