12f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala/*
22f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * Copyright (C) 2016 The Android Open Source Project
32f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala *
42f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
52f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * you may not use this file except in compliance with the License.
62f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * You may obtain a copy of the License at
72f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala *
82f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
92f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala *
102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * See the License for the specific language governing permissions and
142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala * limitations under the License.
152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala */
162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#define LOG_TAG "CameraProviderManager"
182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala//#define LOG_NDEBUG 0
202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#include "CameraProviderManager.h"
222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
23c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#include <algorithm>
246540509f9180bbaf9b0a76bc061ea3c0d7f8dbb8Yin-Chia Yeh#include <chrono>
258d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala#include <inttypes.h>
262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#include <hidl/ServiceManagement.h>
2771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev#include <functional>
2871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev#include <camera_metadata_hidden.h>
29c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#include <android-base/parseint.h>
302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalanamespace android {
322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalausing namespace ::android::hardware::camera;
342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalausing namespace ::android::hardware::camera::common::V1_0;
352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalanamespace {
372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala// service manager
392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaconst std::string kLegacyProviderName("legacy/0");
40d78041a9e7ae0da849328e898785e35cd1f66fbeYin-Chia Yehconst std::string kExternalProviderName("external/0");
412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala} // anonymous namespace
432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::HardwareServiceInteractionProxy
452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::sHardwareServiceInteractionProxy{};
462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::~CameraProviderManager() {
482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ServiceInteractionProxy* proxy) {
524c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    std::lock_guard<std::mutex> lock(mInterfaceMutex);
534c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    if (proxy == nullptr) {
544c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
554c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        return BAD_VALUE;
562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
574c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    mListener = listener;
584c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    mServiceProxy = proxy;
594c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh
604c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    // Registering will trigger notifications for all already-known providers
614c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    bool success = mServiceProxy->registerForNotifications(
624c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        /* instance name, empty means no filter */ "",
634c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        this);
644c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh    if (!success) {
654c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        ALOGE("%s: Unable to register with hardware service manager for notifications "
664c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh                "about camera providers", __FUNCTION__);
674c5b1c777680df26af1d28624b99f8388fb9df4cYin-Chia Yeh        return INVALID_OPERATION;
686540509f9180bbaf9b0a76bc061ea3c0d7f8dbb8Yin-Chia Yeh    }
695d7e5151e2572413fa7e30a8f65beadd89f45416Emilian Peev
706566536c89a9e8646404bd2e671e3e081c181b4aEino-Ville Talvala    // See if there's a passthrough HAL, but let's not complain if there's not
718d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    addProviderLocked(kLegacyProviderName, /*expected*/ false);
72d78041a9e7ae0da849328e898785e35cd1f66fbeYin-Chia Yeh    addProviderLocked(kExternalProviderName, /*expected*/ false);
736566536c89a9e8646404bd2e671e3e081c181b4aEino-Ville Talvala
742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaint CameraProviderManager::getCameraCount() const {
782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    int count = 0;
802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
81c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        count += provider->mUniqueCameraIds.size();
822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return count;
842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastd::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::vector<std::string> deviceIds;
892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
90dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh        for (auto& id : provider->mUniqueCameraIds) {
91dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh            deviceIds.push_back(id);
92dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh        }
93dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    }
94dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    return deviceIds;
95dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh}
96dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh
97f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peevstd::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
98dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    std::lock_guard<std::mutex> lock(mInterfaceMutex);
99dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    std::vector<std::string> deviceIds;
100dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    for (auto& provider : mProviders) {
101e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
102e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
103e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        // API1 app doesn't handle logical and physical camera devices well. So
104e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        // for each [logical, physical1, physical2, ...] id combo, only take the
105e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        // first id advertised by HAL, and filter out the rest.
106e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        filterLogicalCameraIdsLocked(providerDeviceIds);
107e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
108e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
1092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
110c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
111c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    std::sort(deviceIds.begin(), deviceIds.end(),
112c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            [](const std::string& a, const std::string& b) -> bool {
113c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                uint32_t aUint = 0, bUint = 0;
114c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                bool aIsUint = base::ParseUint(a, &aUint);
115c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                bool bIsUint = base::ParseUint(b, &bUint);
116c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
117c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                // Uint device IDs first
118c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                if (aIsUint && bIsUint) {
119c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    return aUint < bUint;
120c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                } else if (aIsUint) {
121c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    return true;
122c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                } else if (bIsUint) {
123c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    return false;
124c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                }
125c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                // Simple string compare if both id are not uint
126c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                return a < b;
127c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            });
1282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return deviceIds;
1292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalabool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
1322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
1332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return isValidDeviceLocked(id, majorVersion);
1342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalabool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
1372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
1382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (auto& deviceInfo : provider->mDevices) {
1392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
1402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                return true;
1412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
1422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
1432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return false;
1452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalabool CameraProviderManager::hasFlashUnit(const std::string &id) const {
1482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
1492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id);
1512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (deviceInfo == nullptr) return false;
1522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return deviceInfo->hasFlashUnit();
1542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::getResourceCost(const std::string &id,
1572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraResourceCost* cost) const {
1582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
1592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id);
1612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
1622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *cost = deviceInfo->mResourceCost;
1642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
1652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::getCameraInfo(const std::string &id,
1682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        hardware::CameraInfo* info) const {
1692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
1702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id);
1722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
1732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return deviceInfo->getCameraInfo(info);
1752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
1782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraMetadata* characteristics) const {
1792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
180e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    return getCameraCharacteristicsLocked(id, characteristics);
1812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
1842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        hardware::hidl_version *v) {
1852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
1862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    hardware::hidl_version maxVersion{0,0};
1882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    bool found = false;
1892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
1902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (auto& deviceInfo : provider->mDevices) {
1912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            if (deviceInfo->mId == id) {
1922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                if (deviceInfo->mVersion > maxVersion) {
1932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    maxVersion = deviceInfo->mVersion;
1942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    found = true;
1952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                }
1962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
1972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
1982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!found) {
2002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return NAME_NOT_FOUND;
2012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
2022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *v = maxVersion;
2032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
2042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
2052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
206dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yehbool CameraProviderManager::supportSetTorchMode(const std::string &id) {
207dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    std::lock_guard<std::mutex> lock(mInterfaceMutex);
208dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    bool support = false;
209dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    for (auto& provider : mProviders) {
210dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh        auto deviceInfo = findDeviceInfoLocked(id);
211dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh        if (deviceInfo != nullptr) {
21273d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh            auto ret = provider->mInterface->isSetTorchModeSupported(
213dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh                [&support](auto status, bool supported) {
214dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh                    if (status == Status::OK) {
215dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh                        support = supported;
216dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh                    }
217dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh                });
21873d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh            if (!ret.isOk()) {
21973d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh                ALOGE("%s: Transaction error checking torch mode support '%s': %s",
22073d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh                        __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
22173d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh            }
22273d0374fcb522fc5106c2c8f75d482cbc8a5e1c0Yin-Chia Yeh            break;
223dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh        }
224dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    }
225dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh    return support;
226dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh}
227dc3134e3f612050ae2c8a0d847bf091c53ed2f4cYin-Chia Yeh
2282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
2292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
2302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id);
2322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
2332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
2342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return deviceInfo->setTorchMode(enabled);
2352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
2362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
237067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yehstatus_t CameraProviderManager::setUpVendorTags() {
23871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
23971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
240067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    for (auto& provider : mProviders) {
241067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        hardware::hidl_vec<VendorTagSection> vts;
242067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        Status status;
2438d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        hardware::Return<void> ret;
2448d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ret = provider->mInterface->getVendorTags(
245067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            [&](auto s, const auto& vendorTagSecs) {
246067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                status = s;
247067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                if (s == Status::OK) {
248067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                    vts = vendorTagSecs;
249067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                }
250067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        });
2518d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (!ret.isOk()) {
2528d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
2538d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
2548d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            return DEAD_OBJECT;
2558d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
256067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        if (status != Status::OK) {
257067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            return mapToStatusT(status);
258067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        }
259067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
260067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        // Read all vendor tag definitions into a descriptor
261067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        sp<VendorTagDescriptor> desc;
262067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        status_t res;
263067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
264067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                != OK) {
265067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            ALOGE("%s: Could not generate descriptor from vendor tag operations,"
266067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                  "received error %s (%d). Camera clients will not be able to use"
267067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                  "vendor tags", __FUNCTION__, strerror(res), res);
268067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            return res;
269067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        }
270067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
27171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        tagCache->addVendorDescriptor(provider->mProviderTagid, desc);
272067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    }
27371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
27471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
27571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
276067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    return OK;
277067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh}
278067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
2790b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvalastatus_t CameraProviderManager::openSession(const std::string &id,
2800b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
2810b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        /*out*/
2820b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
2830b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
2840b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
2850b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
2860b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id,
2870b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
2880b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
2890b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
2900b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
2910b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
2920b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    Status status;
2938d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
2948d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
2950b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
2960b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala                status = s;
2970b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala                if (status == Status::OK) {
2980b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala                    *session = cameraSession;
2990b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala                }
3000b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala            });
3018d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
3028d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
3038d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, id.c_str(), ret.description().c_str());
3048d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
3058d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
3060b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    return mapToStatusT(status);
3070b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala}
3080b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3090b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvalastatus_t CameraProviderManager::openSession(const std::string &id,
3100b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
3110b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        /*out*/
3120b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
3130b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3140b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
3150b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3160b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    auto deviceInfo = findDeviceInfoLocked(id,
3170b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala            /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
3180b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
3190b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3200b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
3210b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3228d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
3238d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!status.isOk()) {
3248d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
3258d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, id.c_str(), status.description().c_str());
3268d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
3278d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
3280b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    if (status == Status::OK) {
3290b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        *session = deviceInfo1->mInterface;
3300b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    }
3310b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala    return mapToStatusT(status);
3320b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala}
3330b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3340b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala
3352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalahardware::Return<void> CameraProviderManager::onRegistration(
3362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const hardware::hidl_string& /*fqName*/,
3372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const hardware::hidl_string& name,
3382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        bool /*preexisting*/) {
339aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    {
340aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        std::lock_guard<std::mutex> lock(mInterfaceMutex);
341aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
342aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        addProviderLocked(name);
343aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    }
344aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev
345aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    sp<StatusListener> listener = getStatusListener();
346aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    if (nullptr != listener.get()) {
347aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        listener->onNewProviderRegistered();
348aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    }
3492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
3502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return hardware::Return<void>();
3512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
3522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
3532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
3542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::lock_guard<std::mutex> lock(mInterfaceMutex);
3552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
3562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
3572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        provider->dump(fd, args);
3582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
3592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
3602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
3612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
3622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
3630b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        const std::string& id,
3640b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala        hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
3652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& provider : mProviders) {
3662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (auto& deviceInfo : provider->mDevices) {
3670b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala            if (deviceInfo->mId == id &&
3680b1cb14c804d7d4343fe91c78578da8db9a678d5Eino-Ville Talvala                    minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
3692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                return deviceInfo.get();
3702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
3712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
3722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
3732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return nullptr;
3742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
3752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
37671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peevmetadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
37771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const std::string& id, hardware::hidl_version minVersion,
37871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        hardware::hidl_version maxVersion) const {
37971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
38071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
38171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    std::lock_guard<std::mutex> lock(mInterfaceMutex);
38271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    for (auto& provider : mProviders) {
38371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        for (auto& deviceInfo : provider->mDevices) {
38471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            if (deviceInfo->mId == id &&
38571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    minVersion <= deviceInfo->mVersion &&
38671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    maxVersion >= deviceInfo->mVersion) {
38771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                return provider->mProviderTagid;
38871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            }
38971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        }
39071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
39171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
39271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return ret;
39371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
3942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
395e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wangbool CameraProviderManager::isLogicalCamera(const CameraMetadata& staticInfo,
396e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        std::vector<std::string>* physicalCameraIds) {
397e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    bool isLogicalCam = false;
398e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    camera_metadata_ro_entry_t entryCap;
399e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
400e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
401e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    for (size_t i = 0; i < entryCap.count; ++i) {
402e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        uint8_t capability = entryCap.data.u8[i];
403e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
404e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            isLogicalCam = true;
405e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            break;
406e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        }
407e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    }
408e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    if (!isLogicalCam) {
409e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        return false;
410e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    }
411e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
412e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    camera_metadata_ro_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
413e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    const uint8_t* ids = entryIds.data.u8;
414e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    size_t start = 0;
415e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    for (size_t i = 0; i < entryIds.count; ++i) {
416e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        if (ids[i] == '\0') {
417e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            if (start != i) {
418e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                physicalCameraIds->push_back((const char*)ids+start);
419e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            }
420e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            start = i+1;
421e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        }
422e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    }
423e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    return true;
424e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang}
425e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
4268d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvalastatus_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
4272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (const auto& providerInfo : mProviders) {
4282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (providerInfo->mProviderName == newProvider) {
4292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
4302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    newProvider.c_str());
4312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return ALREADY_EXISTS;
4322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
4332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
4348d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala
4358d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    sp<provider::V2_4::ICameraProvider> interface;
4368d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    interface = mServiceProxy->getService(newProvider);
4372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (interface == nullptr) {
4392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (expected) {
4408d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
4418d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    newProvider.c_str());
4422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return BAD_VALUE;
4432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        } else {
4442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return OK;
4452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
4462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
4472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sp<ProviderInfo> providerInfo =
4492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            new ProviderInfo(newProvider, interface, this);
4502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = providerInfo->initialize();
4512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res != OK) {
4522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return res;
4532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
4542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    mProviders.push_back(providerInfo);
4562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
4582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
4592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::removeProvider(const std::string& provider) {
4618d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    std::unique_lock<std::mutex> lock(mInterfaceMutex);
4628d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    std::vector<String8> removedDeviceIds;
4638d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    status_t res = NAME_NOT_FOUND;
4642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
4652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if ((*it)->mProviderName == provider) {
4668d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            removedDeviceIds.reserve((*it)->mDevices.size());
4678d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            for (auto& deviceInfo : (*it)->mDevices) {
4688d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
4698d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            }
4702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mProviders.erase(it);
4718d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            res = OK;
4728d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            break;
4732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
4742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
4758d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (res != OK) {
4768d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
4778d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                provider.c_str());
4788d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    } else {
4798d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // Inform camera service of loss of presence for all the devices from this provider,
4808d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        // without lock held for reentrancy
4818d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        sp<StatusListener> listener = getStatusListener();
4828d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        if (listener != nullptr) {
4838d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            lock.unlock();
4848d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            for (auto& id : removedDeviceIds) {
4858d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
4868d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            }
4878d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
4888d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
4898d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    return res;
4908d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala}
4918d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala
4928d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvalasp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
4938d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    return mListener.promote();
4942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
4952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala/**** Methods for ProviderInfo ****/
4972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
4992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::ProviderInfo(
5002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const std::string &providerName,
5012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sp<provider::V2_4::ICameraProvider>& interface,
5022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraProviderManager *manager) :
5032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mProviderName(providerName),
5042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInterface(interface),
50571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        mProviderTagid(generateVendorTagId(providerName)),
506cdb74a6840fc4ae594afadf5eedc1d27106989eaEmilian Peev        mUniqueDeviceCount(0),
5072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mManager(manager) {
5082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    (void) mManager;
5092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
5102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::initialize() {
5122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = parseProviderName(mProviderName, &mType, &mId);
5132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res != OK) {
5142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
5152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
5162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
5176540509f9180bbaf9b0a76bc061ea3c0d7f8dbb8Yin-Chia Yeh    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
5186540509f9180bbaf9b0a76bc061ea3c0d7f8dbb8Yin-Chia Yeh            mProviderName.c_str(), mInterface->isRemote());
519c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
520c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // before setCallback returns
5218d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<Status> status = mInterface->setCallback(this);
5228d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!status.isOk()) {
5238d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
5248d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str(), status.description().c_str());
5258d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
5268d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
5272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
5282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to register callbacks with camera provider '%s'",
5292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str());
5302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return mapToStatusT(status);
5312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
5328d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala
5338d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
5348d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!linked.isOk()) {
5358d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
5368d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
5378d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
5388d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    } else if (!linked) {
5398d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGW("%s: Unable to link to provider '%s' death notifications",
5408d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str());
5418d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
5422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Get initial list of camera devices, if any
5442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::vector<std::string> devices;
5458d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
5462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            Status idStatus,
5472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
5482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        status = idStatus;
5492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (status == Status::OK) {
5502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
5512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                devices.push_back(cameraDeviceNames[i]);
5522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
5532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        } });
5548d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
5558d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
5568d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
5578d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
5588d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
5592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
5602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to query for camera devices from provider '%s'",
5612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, mProviderName.c_str());
5622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return mapToStatusT(status);
5632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
5642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5658d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    sp<StatusListener> listener = mManager->getStatusListener();
5662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& device : devices) {
5678d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        std::string id;
5688d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        status_t res = addDevice(device,
5698d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
5702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (res != OK) {
5712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
5722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    __FUNCTION__, device.c_str(), strerror(-res), res);
5738d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            continue;
5748d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        }
5752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
5762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGI("Camera provider %s ready with %zu camera devices",
5782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mProviderName.c_str(), mDevices.size());
5792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
580c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mInitialized = true;
5812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
5822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
5832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaconst std::string& CameraProviderManager::ProviderInfo::getType() const {
5852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return mType;
5862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
5872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
5892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
5902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGI("Enumerating new camera device: %s", name.c_str());
5922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    uint16_t major, minor;
5942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string type, id;
5952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
5962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
5972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (res != OK) {
5982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return res;
5992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
6002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (type != mType) {
6012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
6022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                type.c_str(), mType.c_str());
6032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
6042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
6052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (mManager->isValidDeviceLocked(id, major)) {
6062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
6072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                name.c_str(), id.c_str(), major);
6082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
6092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
6102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
6112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::unique_ptr<DeviceInfo> deviceInfo;
6122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch (major) {
6132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case 1:
61471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
61571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    id, minor);
6162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            break;
6172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case 3:
61871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
61971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    id, minor);
6202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            break;
6212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        default:
6222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
6232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    name.c_str(), major);
6242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return BAD_VALUE;
6252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
6262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (deviceInfo == nullptr) return BAD_VALUE;
6272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    deviceInfo->mStatus = initialStatus;
628c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
6292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
6302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    mDevices.push_back(std::move(deviceInfo));
6312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
632c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mUniqueCameraIds.insert(id);
633c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    if (isAPI1Compatible) {
634e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        mUniqueAPI1CompatibleCameraIds.push_back(id);
635c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
636c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
6372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (parsedId != nullptr) {
6382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        *parsedId = id;
6392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
6402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
6412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
6422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
6436034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetskivoid CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
6446034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
6456034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        if ((*it)->mId == id) {
646c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mUniqueCameraIds.erase(id);
647c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            if ((*it)->isAPI1Compatible()) {
648e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                mUniqueAPI1CompatibleCameraIds.erase(std::remove(
649e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                        mUniqueAPI1CompatibleCameraIds.begin(),
650e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                        mUniqueAPI1CompatibleCameraIds.end(), id));
651c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            }
6526034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski            mDevices.erase(it);
6536034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski            break;
6546034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        }
6556034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    }
6566034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski}
6576034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
6582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
6598d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
6608d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
6618d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            mDevices.size());
6622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
6632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (auto& device : mDevices) {
664d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
665d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                device->mVersion.get_major(), device->mVersion.get_minor());
666d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  Resource cost: %d\n", device->mResourceCost.resourceCost);
667d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (device->mResourceCost.conflictingDevices.size() == 0) {
668d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  Conflicting devices: None\n");
669d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        } else {
670d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  Conflicting devices:\n");
6712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
672d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                dprintf(fd, "    %s\n",
6732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        device->mResourceCost.conflictingDevices[i].c_str());
6742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
6752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
676d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "  API1 info:\n");
677d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        dprintf(fd, "    Has a flash unit: %s\n",
678d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                device->hasFlashUnit() ? "true" : "false");
679d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        hardware::CameraInfo info;
680d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        status_t res = device->getCameraInfo(&info);
681d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (res != OK) {
682d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "   <Error reading camera info: %s (%d)>\n",
683d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    strerror(-res), res);
684d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        } else {
685d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "    Facing: %s\n",
686d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
687d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "    Orientation: %d\n", info.orientation);
688d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        }
689d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        CameraMetadata info2;
690d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        res = device->getCameraCharacteristics(&info2);
691d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        if (res == INVALID_OPERATION) {
692d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  API2 not directly supported\n");
693d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        } else if (res != OK) {
694d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  <Error reading camera characteristics: %s (%d)>\n",
695d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala                    strerror(-res), res);
696d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        } else {
697d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            dprintf(fd, "  API2 camera characteristics:\n");
698d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala            info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
699d00111e3b0c2ee59736fda992dd9ea24b23ef46aEino-Ville Talvala        }
700487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh
701487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        dprintf(fd, "== Camera HAL device %s (v%d.%d) dumpState: ==\n", device->mName.c_str(),
702487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh                device->mVersion.get_major(), device->mVersion.get_minor());
703487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        res = device->dumpState(fd);
704487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        if (res != OK) {
705487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh            dprintf(fd, "   <Error dumping device %s state: %s (%d)>\n",
706487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh                    device->mName.c_str(), strerror(-res), res);
707487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        }
7082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
7092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
7102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
7112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
7122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalahardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
7132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const hardware::hidl_string& cameraDeviceName,
7142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraDeviceStatus newStatus) {
7152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sp<StatusListener> listener;
7162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string id;
717c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    bool initialized = false;
7182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    {
7198d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        std::lock_guard<std::mutex> lock(mLock);
7202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        bool known = false;
7212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (auto& deviceInfo : mDevices) {
7222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            if (deviceInfo->mName == cameraDeviceName) {
7232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
7242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
7252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                deviceInfo->mStatus = newStatus;
7262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                // TODO: Handle device removal (NOT_PRESENT)
7272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                id = deviceInfo->mId;
7282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                known = true;
7292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                break;
7302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
7312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
7322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        // Previously unseen device; status must not be NOT_PRESENT
7332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (!known) {
7342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
7352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
7362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    mProviderName.c_str(), cameraDeviceName.c_str());
7372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                return hardware::Void();
7382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
7392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            addDevice(cameraDeviceName, newStatus, &id);
7406034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski        } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
7416034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski            removeDevice(id);
7422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
7438d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        listener = mManager->getStatusListener();
744c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        initialized = mInitialized;
7452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
7462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Call without lock held to allow reentrancy into provider manager
747c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // Don't send the callback if providerInfo hasn't been initialized.
748c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // CameraService will initialize device status after provider is
749c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // initialized
750c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    if (listener != nullptr && initialized) {
7512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
7522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
7532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return hardware::Void();
7542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
7552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
7562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalahardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
7572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const hardware::hidl_string& cameraDeviceName,
7582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        TorchModeStatus newStatus) {
7592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sp<StatusListener> listener;
7602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string id;
7612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    {
76252778d448123c185fd30cd77e84659fab966d740Yin-Chia Yeh        std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
7632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        bool known = false;
7642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        for (auto& deviceInfo : mDevices) {
7652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            if (deviceInfo->mName == cameraDeviceName) {
7662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
7672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                        torchStatusToString(newStatus));
7682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                id = deviceInfo->mId;
7692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                known = true;
7702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                break;
7712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            }
7722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
7732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        if (!known) {
7742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
7752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
7762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return hardware::Void();
7772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
7788d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        listener = mManager->getStatusListener();
7792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
7802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Call without lock held to allow reentrancy into provider manager
7812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (listener != nullptr) {
7822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
7832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
7842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return hardware::Void();
7852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
7862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
7878d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvalavoid CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
7888d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        const wp<hidl::base::V1_0::IBase>& who) {
7898d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    (void) who;
7908d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
7918d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (cookie != mId) {
7928d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
7938d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, cookie, mId);
7948d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
7958d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    mManager->removeProvider(mProviderName);
7968d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala}
7972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
7982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalatemplate<class DeviceInfoT>
7992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastd::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
8002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraProviderManager::ProviderInfo::initializeDeviceInfo(
80171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const std::string &name, const metadata_vendor_id_t tagId,
8022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const std::string &id, uint16_t minorVersion) const {
8032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status status;
8042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    auto cameraInterface =
8062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
8072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (cameraInterface == nullptr) return nullptr;
8082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    CameraResourceCost resourceCost;
8102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    cameraInterface->getResourceCost([&status, &resourceCost](
8112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        Status s, CameraResourceCost cost) {
8122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                status = s;
8132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                resourceCost = cost;
8142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
8152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
8162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
8172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                name.c_str(), statusToString(status));
8182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return nullptr;
8192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
820472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang
821472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang    for (auto& conflictName : resourceCost.conflictingDevices) {
822472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        uint16_t major, minor;
823472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        std::string type, id;
824472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
825472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        if (res != OK) {
826472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang            ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
827472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang            return nullptr;
828472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        }
829472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang        conflictName = id;
830472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang    }
831472836998ef2f7499050ae107eecfa0ee47c230aShuzhen Wang
8322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return std::unique_ptr<DeviceInfo>(
83371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
83471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                cameraInterface));
8352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
8362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalatemplate<class InterfaceT>
8382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<InterfaceT>
8392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
8402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
8412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            name.c_str(), InterfaceT::version.get_major());
8422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return nullptr;
8432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
8442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalatemplate<>
8462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<device::V1_0::ICameraDevice>
8472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::getDeviceInterface
8482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        <device::V1_0::ICameraDevice>(const std::string &name) const {
8492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status status;
8502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sp<device::V1_0::ICameraDevice> cameraInterface;
8518d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
8528d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
8532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        Status s, sp<device::V1_0::ICameraDevice> interface) {
8542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                status = s;
8552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cameraInterface = interface;
8562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
8578d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
8588d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
8598d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, name.c_str(), ret.description().c_str());
8608d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return nullptr;
8618d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
8622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
8632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
8642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                name.c_str(), statusToString(status));
8652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return nullptr;
8662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
8672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return cameraInterface;
8682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
8692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalatemplate<>
8712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalasp<device::V3_2::ICameraDevice>
8722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::getDeviceInterface
8732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        <device::V3_2::ICameraDevice>(const std::string &name) const {
8742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status status;
8752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    sp<device::V3_2::ICameraDevice> cameraInterface;
8768d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
8778d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
8782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        Status s, sp<device::V3_2::ICameraDevice> interface) {
8792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                status = s;
8802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cameraInterface = interface;
8812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
8828d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
8838d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
8848d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, name.c_str(), ret.description().c_str());
8858d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return nullptr;
8868d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
8872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
8882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
8892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                name.c_str(), statusToString(status));
8902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return nullptr;
8912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
8922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return cameraInterface;
8932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
8942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
8962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
8972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalatemplate<class InterfaceT>
8982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
8992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        bool enabled) {
9002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
9012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return mapToStatusT(s);
9022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
9032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
90571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const metadata_vendor_id_t tagId, const std::string &id,
9062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        uint16_t minorVersion,
9072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const CameraResourceCost& resourceCost,
9082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sp<InterfaceT> interface) :
90971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
91071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                   resourceCost),
9112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInterface(interface) {
9122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Get default parameters and initialize flash unit availability
9132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Requires powering on the camera device
9148d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<Status> status = mInterface->open(nullptr);
9158d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!status.isOk()) {
9168d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
9178d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mId.c_str(), status.description().c_str());
9188d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return;
9198d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
9202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
9218d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
9228d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                mId.c_str(), CameraProviderManager::statusToString(status));
9232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return;
9242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
9258d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
9268d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
9272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                mDefaultParameters.unflatten(String8(parms.c_str()));
9282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
9298d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
9308d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
9318d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mId.c_str(), status.description().c_str());
9328d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return;
9338d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
9342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    const char *flashMode =
9352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
9362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
9372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mHasFlashUnit = true;
9382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
9392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9408d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->close();
9418d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
9428d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
9438d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mId.c_str(), status.description().c_str());
9448d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
9452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
9462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
9482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
9502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return DeviceInfo::setTorchMode(mInterface, enabled);
9512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
9522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
9542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        hardware::CameraInfo *info) const {
9552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (info == nullptr) return BAD_VALUE;
9562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status status;
9582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    device::V1_0::CameraInfo cInfo;
9598d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
9608d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
9612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                status = s;
9622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                cInfo = camInfo;
9632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
9648d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
9658d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error reading camera info from device %s: %s",
9668d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                __FUNCTION__, mId.c_str(), ret.description().c_str());
9678d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return DEAD_OBJECT;
9688d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
9692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
9702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return mapToStatusT(status);
9712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
9722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch(cInfo.facing) {
9742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case device::V1_0::CameraFacing::BACK:
9752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            info->facing = hardware::CAMERA_FACING_BACK;
9762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            break;
9772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case device::V1_0::CameraFacing::EXTERNAL:
9782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            // Map external to front for legacy API
9792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case device::V1_0::CameraFacing::FRONT:
9802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            info->facing = hardware::CAMERA_FACING_FRONT;
9812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            break;
9822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        default:
9838d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala            ALOGW("%s: Device %s: Unknown camera facing: %d",
9848d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    __FUNCTION__, mId.c_str(), cInfo.facing);
9852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            info->facing = hardware::CAMERA_FACING_BACK;
9862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
9872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    info->orientation = cInfo.orientation;
9882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
9892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
9902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
9912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
992487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yehstatus_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) const {
993487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    native_handle_t* handle = native_handle_create(1,0);
994487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    handle->data[0] = fd;
995487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    hardware::Return<Status> s = mInterface->dumpState(handle);
996487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    native_handle_delete(handle);
997487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    if (!s.isOk()) {
998487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        return INVALID_OPERATION;
999487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    }
1000487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    return mapToStatusT(s);
1001487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh}
1002487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh
10032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
100471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const metadata_vendor_id_t tagId, const std::string &id,
10052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        uint16_t minorVersion,
10062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        const CameraResourceCost& resourceCost,
10072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        sp<InterfaceT> interface) :
100871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
100971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                   resourceCost),
10102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInterface(interface) {
10112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Get camera characteristics and initialize flash unit availability
10122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    Status status;
10138d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    hardware::Return<void> ret;
10148d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    ret = mInterface->getCameraCharacteristics([&status, this](Status s,
10152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    device::V3_2::CameraMetadata metadata) {
10162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                status = s;
10172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                if (s == Status::OK) {
10182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                    camera_metadata_t *buffer =
10192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                            reinterpret_cast<camera_metadata_t*>(metadata.data());
1020238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                    size_t expectedSize = metadata.size();
1021238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                    int res = validate_camera_metadata_structure(buffer, &expectedSize);
1022238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                    if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
1023238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                        set_camera_metadata_vendor_id(buffer, mProviderTagid);
1024238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                        mCameraCharacteristics = buffer;
1025238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                    } else {
1026238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                        ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
1027238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                        status = Status::INTERNAL_ERROR;
1028238ef5f352a59e97a90e2f9af88a27ad705442e5Yin-Chia Yeh                    }
10292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                }
10302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            });
10318d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    if (!ret.isOk()) {
10328d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        ALOGE("%s: Transaction error getting camera characteristics for device %s"
10338d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
10348d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                ret.description().c_str());
10358d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala        return;
10368d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala    }
10372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (status != Status::OK) {
10382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
10392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
10402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return;
10412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
10422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    camera_metadata_entry flashAvailable =
10432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
10442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (flashAvailable.count == 1 &&
10452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
10462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mHasFlashUnit = true;
10472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    } else {
10482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mHasFlashUnit = false;
10492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
10502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
10512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
10532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
10552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return DeviceInfo::setTorchMode(mInterface, enabled);
10562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
10572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
10592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        hardware::CameraInfo *info) const {
10602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (info == nullptr) return BAD_VALUE;
10612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    camera_metadata_ro_entry facing =
10632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mCameraCharacteristics.find(ANDROID_LENS_FACING);
10642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (facing.count == 1) {
10652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        switch (facing.data.u8[0]) {
10662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            case ANDROID_LENS_FACING_BACK:
10672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                info->facing = hardware::CAMERA_FACING_BACK;
10682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                break;
10692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            case ANDROID_LENS_FACING_EXTERNAL:
10702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                // Map external to front for legacy API
10712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            case ANDROID_LENS_FACING_FRONT:
10722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                info->facing = hardware::CAMERA_FACING_FRONT;
10732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                break;
10742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
10752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    } else {
10762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
10772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return NAME_NOT_FOUND;
10782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
10792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    camera_metadata_ro_entry orientation =
10812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
10822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (orientation.count == 1) {
10832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        info->orientation = orientation.data.i32[0];
10842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    } else {
10852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
10862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return NAME_NOT_FOUND;
10872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
10882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
10892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
10902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
1091f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peevbool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
1092f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    bool isBackwardCompatible = false;
1093f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
1094f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1095f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    for (size_t i = 0; i < caps.count; i++) {
1096f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        if (caps.data.u8[i] ==
1097f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1098f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            isBackwardCompatible = true;
1099f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev            break;
1100f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        }
1101f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    }
1102f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
1103f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    return isBackwardCompatible;
1104f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev}
11052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1106487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yehstatus_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) const {
1107487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    native_handle_t* handle = native_handle_create(1,0);
1108487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    handle->data[0] = fd;
1109487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    auto ret = mInterface->dumpState(handle);
1110487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    native_handle_delete(handle);
1111487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    if (!ret.isOk()) {
1112487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh        return INVALID_OPERATION;
1113487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    }
1114487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh    return OK;
1115487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh}
1116487785ade74d55f8bb9391250571dad06768d937Yin-Chia Yeh
11172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
11182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        CameraMetadata *characteristics) const {
11192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (characteristics == nullptr) return BAD_VALUE;
11202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *characteristics = mCameraCharacteristics;
11222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
11232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
11242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
11262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        std::string *type, uint32_t *id) {
11272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Format must be "<type>/<id>"
11282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. "       \
11292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    "Should match '<type>/<id>' - "
11302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!type || !id) return INVALID_OPERATION;
11322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string::size_type slashIdx = name.find('/');
11342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
11352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
11362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not have / separator between type and id",
11372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
11382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
11392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
11402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string typeVal = name.substr(0, slashIdx);
11422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    char *endPtr;
11442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    errno = 0;
11452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
11462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (errno != 0) {
11472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
11482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "cannot parse provider id as an integer: %s (%d)",
11492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), strerror(errno), errno);
11502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
11512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
11522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (endPtr != name.c_str() + name.size()) {
11532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
11542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "provider id has unexpected length",
11552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
11562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
11572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
11582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (idVal < 0) {
11592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
11602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "id is negative: %ld",
11612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), idVal);
11622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
11632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
11642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#undef ERROR_MSG_PREFIX
11662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *type = typeVal;
11682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *id = static_cast<uint32_t>(idVal);
11692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
11712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
11722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
117371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peevmetadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
117471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        const std::string &name) {
117571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    metadata_vendor_id_t ret = std::hash<std::string> {} (name);
117671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
117771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
117871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        ret = 0;
117971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
118071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
118171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return ret;
118271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
118371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
11842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
11852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
11862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Format must be "device@<major>.<minor>/<type>/<id>"
11882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
11902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    "Should match 'device@<major>.<minor>/<type>/<id>' - "
11912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (!major || !minor || !type || !id) return INVALID_OPERATION;
11932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Verify starting prefix
11952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    const char expectedPrefix[] = "device@";
11962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
11972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (name.find(expectedPrefix) != 0) {
11982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
11992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not start with '%s'",
12002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), expectedPrefix);
12012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Extract major/minor versions
12052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
12062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string::size_type dotIdx = name.find('.', atIdx);
12072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (dotIdx == std::string::npos) {
12082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not have @<major>. version section",
12102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string::size_type typeSlashIdx = name.find('/', dotIdx);
12142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (typeSlashIdx == std::string::npos) {
12152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not have .<minor>/ version section",
12172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    char *endPtr;
12222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    errno = 0;
12232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
12242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (errno != 0) {
12252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "cannot parse major version: %s (%d)",
12272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), strerror(errno), errno);
12282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (endPtr != name.c_str() + dotIdx) {
12312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "major version has unexpected length",
12332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
12372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (errno != 0) {
12382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "cannot parse minor version: %s (%d)",
12402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), strerror(errno), errno);
12412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (endPtr != name.c_str() + typeSlashIdx) {
12442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "minor version has unexpected length",
12462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
12502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "major/minor version is out of range of uint16_t: %ld.%ld",
12522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str(), majorVal, minorVal);
12532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Extract type and id
12572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
12592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (instanceSlashIdx == std::string::npos) {
12602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not have /<type>/ component",
12622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12652f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
12662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12672f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (instanceSlashIdx == name.size() - 1) {
12682f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        ALOGE(ERROR_MSG_PREFIX
12692f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                "does not have an /<id> component",
12702f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                __FUNCTION__, name.c_str());
12712f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        return BAD_VALUE;
12722f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
12732f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    std::string idVal = name.substr(instanceSlashIdx + 1);
12742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#undef ERROR_MSG_PREFIX
12762f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12772f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *major = static_cast<uint16_t>(majorVal);
12782f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *minor = static_cast<uint16_t>(minorVal);
12792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *type = typeVal;
12802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    *id = idVal;
12812f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12822f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return OK;
12832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
12842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12862f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12872f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaCameraProviderManager::ProviderInfo::~ProviderInfo() {
12882f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // Destruction of ProviderInfo is only supposed to happen when the respective
12892f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // CameraProvider interface dies, so do not unregister callbacks.
12902f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12912f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
12922f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
12932f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalastatus_t CameraProviderManager::mapToStatusT(const Status& s)  {
12942f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch(s) {
12952f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::OK:
12962f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return OK;
12972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::ILLEGAL_ARGUMENT:
12982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return BAD_VALUE;
12992f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::CAMERA_IN_USE:
13002f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return -EBUSY;
13012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::MAX_CAMERAS_IN_USE:
13022f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return -EUSERS;
13032f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::METHOD_NOT_SUPPORTED:
13042f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return UNKNOWN_TRANSACTION;
13052f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::OPERATION_NOT_SUPPORTED:
13062f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return INVALID_OPERATION;
13072f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::CAMERA_DISCONNECTED:
13082f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return DEAD_OBJECT;
13092f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::INTERNAL_ERROR:
13102f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return INVALID_OPERATION;
13112f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
13122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGW("Unexpected HAL status code %d", s);
13132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return INVALID_OPERATION;
13142f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
13152f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
13162f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaconst char* CameraProviderManager::statusToString(const Status& s) {
13172f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch(s) {
13182f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::OK:
13192f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "OK";
13202f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::ILLEGAL_ARGUMENT:
13212f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "ILLEGAL_ARGUMENT";
13222f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::CAMERA_IN_USE:
13232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "CAMERA_IN_USE";
13242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::MAX_CAMERAS_IN_USE:
13252f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "MAX_CAMERAS_IN_USE";
13262f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::METHOD_NOT_SUPPORTED:
13272f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "METHOD_NOT_SUPPORTED";
13282f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::OPERATION_NOT_SUPPORTED:
13292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "OPERATION_NOT_SUPPORTED";
13302f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::CAMERA_DISCONNECTED:
13312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "CAMERA_DISCONNECTED";
13322f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case Status::INTERNAL_ERROR:
13332f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "INTERNAL_ERROR";
13342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
13352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGW("Unexpected HAL status code %d", s);
13362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return "UNKNOWN_ERROR";
13372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
13382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
13392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaconst char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
13402f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch(s) {
13412f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case CameraDeviceStatus::NOT_PRESENT:
13422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "NOT_PRESENT";
13432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case CameraDeviceStatus::PRESENT:
13442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "PRESENT";
13452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case CameraDeviceStatus::ENUMERATING:
13462f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "ENUMERATING";
13472f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
13482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGW("Unexpected HAL device status code %d", s);
13492f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return "UNKNOWN_STATUS";
13502f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
13512f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
13522f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvalaconst char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
13532f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    switch(s) {
13542f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case TorchModeStatus::NOT_AVAILABLE:
13552f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "NOT_AVAILABLE";
13562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_OFF:
13572f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "AVAILABLE_OFF";
13582f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case TorchModeStatus::AVAILABLE_ON:
13592f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            return "AVAILABLE_ON";
13602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
13612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGW("Unexpected HAL torch mode status code %d", s);
13622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return "UNKNOWN_STATUS";
13632f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala}
13642f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
1365067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1366067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yehstatus_t HidlVendorTagDescriptor::createDescriptorFromHidl(
1367067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
1368067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        /*out*/
1369067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        sp<VendorTagDescriptor>& descriptor) {
1370067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1371067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    int tagCount = 0;
1372067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1373067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    for (size_t s = 0; s < vts.size(); s++) {
1374067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        tagCount += vts[s].tags.size();
1375067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    }
1376067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1377067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    if (tagCount < 0 || tagCount > INT32_MAX) {
1378067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
1379067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        return BAD_VALUE;
1380067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    }
1381067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1382067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    Vector<uint32_t> tagArray;
1383067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
1384067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
1385067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1386067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1387067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
1388067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    desc->mTagCount = tagCount;
1389067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1390067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    SortedVector<String8> sections;
1391067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    KeyedVector<uint32_t, String8> tagToSectionMap;
1392067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1393067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    int idx = 0;
1394067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    for (size_t s = 0; s < vts.size(); s++) {
1395067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
1396067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        const char *sectionName = section.sectionName.c_str();
1397067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        if (sectionName == NULL) {
1398067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
1399067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            return BAD_VALUE;
1400067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        }
1401067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        String8 sectionString(sectionName);
1402067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        sections.add(sectionString);
1403067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1404067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        for (size_t j = 0; j < section.tags.size(); j++) {
1405067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            uint32_t tag = section.tags[j].tagId;
1406067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
1407067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
1408067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                return BAD_VALUE;
1409067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            }
1410067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1411067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            tagArray.editItemAt(idx++) = section.tags[j].tagId;
1412067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1413067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            const char *tagName = section.tags[j].tagName.c_str();
1414067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            if (tagName == NULL) {
1415067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
1416067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                return BAD_VALUE;
1417067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            }
1418067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            desc->mTagToNameMap.add(tag, String8(tagName));
1419067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            tagToSectionMap.add(tag, sectionString);
1420067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1421067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            int tagType = (int) section.tags[j].tagType;
1422067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            if (tagType < 0 || tagType >= NUM_TYPES) {
1423067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
1424067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh                return BAD_VALUE;
1425067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            }
1426067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            desc->mTagToTypeMap.add(tag, tagType);
1427067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        }
1428067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    }
1429067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1430067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    desc->mSections = sections;
1431067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1432067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    for (size_t i = 0; i < tagArray.size(); ++i) {
1433067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        uint32_t tag = tagArray[i];
1434067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        String8 sectionString = tagToSectionMap.valueFor(tag);
1435067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1436067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        // Set up tag to section index map
1437067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        ssize_t index = sections.indexOf(sectionString);
1438067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
1439067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
1440067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1441067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        // Set up reverse mapping
1442067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        ssize_t reverseIndex = -1;
1443067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
1444067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
1445067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
1446067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        }
1447067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
1448067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    }
1449067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1450a0b8496016dcd98dc9b8086f0d22b14efb7e48f2George Burgess IV    descriptor = std::move(desc);
1451067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh    return OK;
1452067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh}
1453067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
1454e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wangstatus_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
1455e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        CameraMetadata* characteristics) const {
1456e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
1457e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
1458e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1459e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    return deviceInfo->getCameraCharacteristics(characteristics);
1460e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang}
1461e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1462e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wangvoid CameraProviderManager::filterLogicalCameraIdsLocked(
1463e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        std::vector<std::string>& deviceIds) const
1464e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang{
1465e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    std::unordered_set<std::string> removedIds;
1466e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1467e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    for (auto& deviceId : deviceIds) {
1468e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        CameraMetadata info;
1469e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        status_t res = getCameraCharacteristicsLocked(deviceId, &info);
1470e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        if (res != OK) {
1471e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
1472e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                    deviceId.c_str());
1473e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            return;
1474e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        }
1475e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1476e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        // idCombo contains the ids of a logical camera and its physical cameras
1477e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        std::vector<std::string> idCombo;
1478e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        bool logicalCamera = CameraProviderManager::isLogicalCamera(info, &idCombo);
1479e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        if (!logicalCamera) {
1480e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            continue;
1481e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        }
1482e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        idCombo.push_back(deviceId);
1483e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1484e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        for (auto& id : deviceIds) {
1485e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
1486e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            if (foundId == idCombo.end()) {
1487e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang                continue;
1488e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            }
1489e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1490e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            idCombo.erase(foundId);
1491e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            removedIds.insert(idCombo.begin(), idCombo.end());
1492e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            break;
1493e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang        }
1494e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    }
1495e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang
1496e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang    deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
1497e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
1498e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang            deviceIds.end());
1499e8aceb53e9ea4f3e03c0be3be21170a0a43faab4Shuzhen Wang}
1500067428c5a8429d711f94bf008debde29ac118849Yin-Chia Yeh
15012f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala} // namespace android
1502