1dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph/* 2dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Copyright (C) 2016 The Android Open Source Project 3dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 4dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Licensed under the Apache License, Version 2.0 (the "License"); 5dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * you may not use this file except in compliance with the License. 6dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * You may obtain a copy of the License at 7dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 8dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * http://www.apache.org/licenses/LICENSE-2.0 9dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * 10dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * Unless required by applicable law or agreed to in writing, software 11dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * distributed under the License is distributed on an "AS IS" BASIS, 12dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * See the License for the specific language governing permissions and 14dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph * limitations under the License. 15dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph */ 16dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 17dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph#include "Enumerator.h" 18dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 19dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace android { 20dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace automotive { 21dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace evs { 22dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace V1_0 { 23dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphnamespace implementation { 24dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 25dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 26dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolphbool Enumerator::init(const char* hardwareServiceName) { 27dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("init"); 28dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 29dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Connect with the underlying hardware enumerator 30dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwEnumerator = IEvsEnumerator::getService(hardwareServiceName); 31dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bool result = (mHwEnumerator.get() != nullptr); 32dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 33dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return result; 34dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 35dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 36dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 37f1b55e7bfee3aeb42436373b4c6ea318c1ee56dfScott Randolph// Methods from ::android::hardware::automotive::evs::V1_0::IEvsEnumerator follow. 38dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<void> Enumerator::getCameraList(getCameraList_cb list_cb) { 39dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("getCameraList"); 40dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 41dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Simply pass through to hardware layer 42dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return mHwEnumerator->getCameraList(list_cb); 43dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 44dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 45dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 46dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<sp<IEvsCamera>> Enumerator::openCamera(const hidl_string& cameraId) { 47dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("openCamera"); 48dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 49dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Is the underlying hardware camera already open? 50dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<HalCamera> hwCamera; 51dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph for (auto &&cam : mCameras) { 52dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph bool match = false; 53da289be96177f528495cc660f83472ade76c5918Scott Randolph cam->getHwCamera()->getCameraInfo([cameraId, &match](CameraDesc desc) { 54da289be96177f528495cc660f83472ade76c5918Scott Randolph if (desc.cameraId == cameraId) { 55dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph match = true; 56dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 57dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 58dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ); 59dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (match) { 60dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph hwCamera = cam; 61dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph break; 62dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 63dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 64dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 65dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Do we need to open a new hardware camera? 66dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (hwCamera == nullptr) { 67dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Is the hardware camera available? 68dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<IEvsCamera> device = mHwEnumerator->openCamera(cameraId); 69dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (device == nullptr) { 70dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Failed to open hardware camera %s", cameraId.c_str()); 71dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 72dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph hwCamera = new HalCamera(device); 73dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (hwCamera == nullptr) { 74dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Failed to allocate camera wrapper object"); 75dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwEnumerator->closeCamera(device); 76dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 77dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 78dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 79dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 80dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Construct a virtual camera wrapper for this hardware camera 81dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<VirtualCamera> clientCamera; 82dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (hwCamera != nullptr) { 83dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph clientCamera = hwCamera->makeVirtualCamera(); 84dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 85dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 8629803803b299652fc219713774181dd9a7dd8decScott Randolph // Add the hardware camera to our list, which will keep it alive via ref count 87dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (clientCamera != nullptr) { 88dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mCameras.push_back(hwCamera); 89dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 90dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Requested camera %s not found or not available", cameraId.c_str()); 91dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 92dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 9329803803b299652fc219713774181dd9a7dd8decScott Randolph // Send the virtual camera object back to the client by strong pointer which will keep it alive 94dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return clientCamera; 95dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 96dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 97dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 98dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<void> Enumerator::closeCamera(const ::android::sp<IEvsCamera>& clientCamera) { 99dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("closeCamera"); 100dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 101dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (clientCamera.get() == nullptr) { 102dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGE("Ignoring call with null camera pointer."); 103dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return Void(); 104dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 105dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 106dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // All our client cameras are actually VirtualCamera objects 107dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<VirtualCamera> virtualCamera = reinterpret_cast<VirtualCamera*>(clientCamera.get()); 108dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 109dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Find the parent camera that backs this virtual camera 110dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph sp<HalCamera> halCamera = virtualCamera->getHalCamera(); 111dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 112dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Tell the virtual camera's parent to clean it up and drop it 113dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // NOTE: The camera objects will only actually destruct when the sp<> ref counts get to 114dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // zero, so it is important to break all cyclic references. 115dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph halCamera->disownVirtualCamera(virtualCamera); 116dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 117dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Did we just remove the last client of this camera? 118dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph if (halCamera->getClientCount() == 0) { 119da289be96177f528495cc660f83472ade76c5918Scott Randolph // Take this now unused camera out of our list 120dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // NOTE: This should drop our last reference to the camera, resulting in its 121dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // destruction. 122dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mCameras.remove(halCamera); 123dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 124dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 125dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return Void(); 126dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 127dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 128dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 129dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<sp<IEvsDisplay>> Enumerator::openDisplay() { 130dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("openDisplay"); 131dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 132da289be96177f528495cc660f83472ade76c5918Scott Randolph // We simply keep track of the most recently opened display instance. 133da289be96177f528495cc660f83472ade76c5918Scott Randolph // In the underlying layers we expect that a new open will cause the previous 134da289be96177f528495cc660f83472ade76c5918Scott Randolph // object to be destroyed. This avoids any race conditions associated with 135da289be96177f528495cc660f83472ade76c5918Scott Randolph // create/destroy order and provides a cleaner restart sequence if the previous owner 136da289be96177f528495cc660f83472ade76c5918Scott Randolph // is non-responsive for some reason. 137da289be96177f528495cc660f83472ade76c5918Scott Randolph // Request exclusive access to the EVS display 138da289be96177f528495cc660f83472ade76c5918Scott Randolph sp<IEvsDisplay> pActiveDisplay = mHwEnumerator->openDisplay(); 139da289be96177f528495cc660f83472ade76c5918Scott Randolph if (pActiveDisplay == nullptr) { 140da289be96177f528495cc660f83472ade76c5918Scott Randolph ALOGE("EVS Display unavailable"); 141dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 142da289be96177f528495cc660f83472ade76c5918Scott Randolph 143da289be96177f528495cc660f83472ade76c5918Scott Randolph // Remember (via weak pointer) who we think the most recently opened display is so that 144da289be96177f528495cc660f83472ade76c5918Scott Randolph // we can proxy state requests from other callers to it. 145da289be96177f528495cc660f83472ade76c5918Scott Randolph mActiveDisplay = pActiveDisplay; 146da289be96177f528495cc660f83472ade76c5918Scott Randolph return pActiveDisplay; 147dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 148dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 149dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 150dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<void> Enumerator::closeDisplay(const ::android::sp<IEvsDisplay>& display) { 151dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("closeDisplay"); 152dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 15329803803b299652fc219713774181dd9a7dd8decScott Randolph // Do we still have a display object we think should be active? 15429803803b299652fc219713774181dd9a7dd8decScott Randolph sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote(); 15529803803b299652fc219713774181dd9a7dd8decScott Randolph 156dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Drop the active display 15729803803b299652fc219713774181dd9a7dd8decScott Randolph if (display.get() != pActiveDisplay.get()) { 15829803803b299652fc219713774181dd9a7dd8decScott Randolph ALOGW("Ignoring call to closeDisplay with unrecognzied display object."); 15929803803b299652fc219713774181dd9a7dd8decScott Randolph ALOGI("Got %p while active display is %p.", display.get(), pActiveDisplay.get()); 160dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 161dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph // Pass this request through to the hardware layer 162dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mHwEnumerator->closeDisplay(display); 163dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph mActiveDisplay = nullptr; 164dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 165dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 166dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph return Void(); 167dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 168dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 169dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 170dcc3534f0f7523e4ee7285522586d6e2827aa407Scott RandolphReturn<DisplayState> Enumerator::getDisplayState() { 171dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph ALOGD("getDisplayState"); 172dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 17329803803b299652fc219713774181dd9a7dd8decScott Randolph // Do we have a display object we think should be active? 17429803803b299652fc219713774181dd9a7dd8decScott Randolph sp<IEvsDisplay> pActiveDisplay = mActiveDisplay.promote(); 17529803803b299652fc219713774181dd9a7dd8decScott Randolph if (pActiveDisplay != nullptr) { 17629803803b299652fc219713774181dd9a7dd8decScott Randolph // Pass this request through to the hardware layer 17729803803b299652fc219713774181dd9a7dd8decScott Randolph return pActiveDisplay->getDisplayState(); 178dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } else { 17929803803b299652fc219713774181dd9a7dd8decScott Randolph // We don't have a live display right now 18029803803b299652fc219713774181dd9a7dd8decScott Randolph mActiveDisplay = nullptr; 18129803803b299652fc219713774181dd9a7dd8decScott Randolph return DisplayState::NOT_OPEN; 182dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph } 183dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} 184dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 185dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph 186dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace implementation 187dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace V1_0 188dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace evs 189dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace automotive 190dcc3534f0f7523e4ee7285522586d6e2827aa407Scott Randolph} // namespace android 191