blob: e54f699472b2cbc79d9451f63118ad53a815f101 [file] [log] [blame]
Scott Randolph5c99d852016-11-15 17:01:23 -08001/*
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
Scott Randolph83422792017-03-01 20:32:59 -080017#define LOG_TAG "android.hardware.automotive.evs@1.0-service"
Scott Randolph5c99d852016-11-15 17:01:23 -080018
19#include "EvsEnumerator.h"
20#include "EvsCamera.h"
21#include "EvsDisplay.h"
22
23namespace android {
24namespace hardware {
Scott Randolph83422792017-03-01 20:32:59 -080025namespace automotive {
Scott Randolph5c99d852016-11-15 17:01:23 -080026namespace evs {
27namespace V1_0 {
28namespace implementation {
29
30
Scott Randolphdb5a5982017-01-23 12:35:05 -080031// TODO(b/31632518): Need to get notification when our client dies so we can close the camera.
32// As it stands, if the client dies suddenly, the camera will be stuck "open".
33// NOTE: Display should already be safe by virtue of holding only a weak pointer.
34
35
Scott Randolph5c99d852016-11-15 17:01:23 -080036EvsEnumerator::EvsEnumerator() {
37 ALOGD("EvsEnumerator created");
38
39 // Add sample camera data to our list of cameras
40 // NOTE: The id strings trigger special initialization inside the EvsCamera constructor
41 mCameraList.emplace_back( new EvsCamera(EvsCamera::kCameraName_Backup), false );
42 mCameraList.emplace_back( new EvsCamera("LaneView"), false );
43 mCameraList.emplace_back( new EvsCamera(EvsCamera::kCameraName_RightTurn), false );
44}
45
Scott Randolph83422792017-03-01 20:32:59 -080046// Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow.
Scott Randolph5c99d852016-11-15 17:01:23 -080047Return<void> EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb) {
48 ALOGD("getCameraList");
49
50 const unsigned numCameras = mCameraList.size();
51
52 // Build up a packed array of CameraDesc for return
53 // NOTE: Only has to live until the callback returns
54 std::vector<CameraDesc> descriptions;
55 descriptions.reserve(numCameras);
56 for (const auto& cam : mCameraList) {
57 descriptions.push_back( cam.pCamera->getDesc() );
58 }
59
60 // Encapsulate our camera descriptions in the HIDL vec type
61 hidl_vec<CameraDesc> hidlCameras(descriptions);
62
63 // Send back the results
64 ALOGD("reporting %zu cameras available", hidlCameras.size());
65 _hidl_cb(hidlCameras);
66
67 // HIDL convention says we return Void if we sent our result back via callback
68 return Void();
69}
70
Martijn Coenen527924a2017-01-04 12:59:48 +010071Return<sp<IEvsCamera>> EvsEnumerator::openCamera(const hidl_string& cameraId) {
Scott Randolph5c99d852016-11-15 17:01:23 -080072 ALOGD("openCamera");
73
74 // Find the named camera
75 CameraRecord *pRecord = nullptr;
76 for (auto &&cam : mCameraList) {
77 if (cam.pCamera->getDesc().cameraId == cameraId) {
78 // Found a match!
79 pRecord = &cam;
80 break;
81 }
82 }
83
84 if (!pRecord) {
85 ALOGE("Requested camera %s not found", cameraId.c_str());
Martijn Coenen527924a2017-01-04 12:59:48 +010086 return nullptr;
Scott Randolphdb5a5982017-01-23 12:35:05 -080087 } else if (pRecord->inUse) {
Scott Randolph5c99d852016-11-15 17:01:23 -080088 ALOGE("Cannot open camera %s which is already in use", cameraId.c_str());
Martijn Coenen527924a2017-01-04 12:59:48 +010089 return nullptr;
Scott Randolphdb5a5982017-01-23 12:35:05 -080090 } else {
Scott Randolph5c99d852016-11-15 17:01:23 -080091 pRecord->inUse = true;
Martijn Coenen527924a2017-01-04 12:59:48 +010092 return(pRecord->pCamera);
Scott Randolph5c99d852016-11-15 17:01:23 -080093 }
Scott Randolph5c99d852016-11-15 17:01:23 -080094}
95
96Return<void> EvsEnumerator::closeCamera(const ::android::sp<IEvsCamera>& camera) {
97 ALOGD("closeCamera");
98
99 if (camera == nullptr) {
100 ALOGE("Ignoring call to closeCamera with null camera pointer");
Scott Randolphdb5a5982017-01-23 12:35:05 -0800101 } else {
102 // Find this camera in our list
103 auto it = std::find_if(mCameraList.begin(),
104 mCameraList.end(),
105 [camera](const CameraRecord& rec) {
106 return (rec.pCamera == camera);
107 });
108 if (it == mCameraList.end()) {
109 ALOGE("Ignoring close on unrecognized camera");
110 } else {
111 // Make sure the camera has stopped streaming
112 camera->stopVideoStream();
Scott Randolph5c99d852016-11-15 17:01:23 -0800113
Scott Randolphdb5a5982017-01-23 12:35:05 -0800114 it->inUse = false;
115 }
Scott Randolph5c99d852016-11-15 17:01:23 -0800116 }
117
118 return Void();
119}
120
Martijn Coenen527924a2017-01-04 12:59:48 +0100121Return<sp<IEvsDisplay>> EvsEnumerator::openDisplay() {
Scott Randolph5c99d852016-11-15 17:01:23 -0800122 ALOGD("openDisplay");
123
124 // If we already have a display active, then this request must be denied
Scott Randolphdb5a5982017-01-23 12:35:05 -0800125 sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
126 if (pActiveDisplay != nullptr) {
Scott Randolph5c99d852016-11-15 17:01:23 -0800127 ALOGW("Rejecting openDisplay request the display is already in use.");
Martijn Coenen527924a2017-01-04 12:59:48 +0100128 return nullptr;
Scott Randolphdb5a5982017-01-23 12:35:05 -0800129 } else {
Scott Randolph5c99d852016-11-15 17:01:23 -0800130 // Create a new display interface and return it
Scott Randolphdb5a5982017-01-23 12:35:05 -0800131 pActiveDisplay = new EvsDisplay();
132 mActiveDisplay = pActiveDisplay;
133 ALOGD("Returning new EvsDisplay object %p", pActiveDisplay.get());
134 return pActiveDisplay;
Scott Randolph5c99d852016-11-15 17:01:23 -0800135 }
Scott Randolph5c99d852016-11-15 17:01:23 -0800136}
137
138Return<void> EvsEnumerator::closeDisplay(const ::android::sp<IEvsDisplay>& display) {
139 ALOGD("closeDisplay");
140
Scott Randolphdb5a5982017-01-23 12:35:05 -0800141 // Do we still have a display object we think should be active?
142 sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
143
144 if (pActiveDisplay == nullptr) {
145 ALOGE("Ignoring closeDisplay when there is no active display.");
146 } else if (display != pActiveDisplay) {
147 ALOGE("Ignoring closeDisplay on a display we didn't issue");
148 ALOGI("Got %p while active display is %p.", display.get(), pActiveDisplay.get());
149 } else {
Scott Randolph5c99d852016-11-15 17:01:23 -0800150 // Drop the active display
Scott Randolph5c99d852016-11-15 17:01:23 -0800151 mActiveDisplay = nullptr;
152 }
153
154 return Void();
155}
156
Scott Randolphdb5a5982017-01-23 12:35:05 -0800157Return<DisplayState> EvsEnumerator::getDisplayState() {
158 ALOGD("getDisplayState");
Scott Randolph5c99d852016-11-15 17:01:23 -0800159
Scott Randolphdb5a5982017-01-23 12:35:05 -0800160 // Do we still have a display object we think should be active?
161 sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote();
162 if (pActiveDisplay != nullptr) {
163 return pActiveDisplay->getDisplayState();
164 } else {
165 return DisplayState::NOT_OPEN;
166 }
167}
Scott Randolph5c99d852016-11-15 17:01:23 -0800168
169} // namespace implementation
170} // namespace V1_0
171} // namespace evs
Scott Randolph83422792017-03-01 20:32:59 -0800172} // namespace automotive
Scott Randolph5c99d852016-11-15 17:01:23 -0800173} // namespace hardware
174} // namespace android