1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CameraProviderManager"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include "CameraProviderManager.h"
22
23#include <chrono>
24#include <inttypes.h>
25#include <hidl/ServiceManagement.h>
26#include <functional>
27#include <camera_metadata_hidden.h>
28
29namespace android {
30
31using namespace ::android::hardware::camera;
32using namespace ::android::hardware::camera::common::V1_0;
33
34namespace {
35// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
36// service manager
37const std::string kLegacyProviderName("legacy/0");
38
39// Slash-separated list of provider types to consider for use via the old camera API
40const std::string kStandardProviderTypes("internal/legacy");
41
42} // anonymous namespace
43
44CameraProviderManager::HardwareServiceInteractionProxy
45CameraProviderManager::sHardwareServiceInteractionProxy{};
46
47CameraProviderManager::~CameraProviderManager() {
48}
49
50status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
51        ServiceInteractionProxy* proxy) {
52    std::lock_guard<std::mutex> lock(mInterfaceMutex);
53    if (proxy == nullptr) {
54        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
55        return BAD_VALUE;
56    }
57    mListener = listener;
58    mServiceProxy = proxy;
59
60    // Registering will trigger notifications for all already-known providers
61    bool success = mServiceProxy->registerForNotifications(
62        /* instance name, empty means no filter */ "",
63        this);
64    if (!success) {
65        ALOGE("%s: Unable to register with hardware service manager for notifications "
66                "about camera providers", __FUNCTION__);
67        return INVALID_OPERATION;
68    }
69
70    // See if there's a passthrough HAL, but let's not complain if there's not
71    addProviderLocked(kLegacyProviderName, /*expected*/ false);
72
73    return OK;
74}
75
76int CameraProviderManager::getCameraCount() const {
77    std::lock_guard<std::mutex> lock(mInterfaceMutex);
78    int count = 0;
79    for (auto& provider : mProviders) {
80        count += provider->mUniqueDeviceCount;
81    }
82    return count;
83}
84
85int CameraProviderManager::getAPI1CompatibleCameraCount() const {
86    std::lock_guard<std::mutex> lock(mInterfaceMutex);
87    int count = 0;
88    for (auto& provider : mProviders) {
89        if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
90            count += provider->mUniqueAPI1CompatibleCameraIds.size();
91        }
92    }
93    return count;
94}
95
96std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
97    std::lock_guard<std::mutex> lock(mInterfaceMutex);
98    std::vector<std::string> deviceIds;
99    for (auto& provider : mProviders) {
100        for (auto& id : provider->mUniqueCameraIds) {
101            deviceIds.push_back(id);
102        }
103    }
104    return deviceIds;
105}
106
107std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
108    std::lock_guard<std::mutex> lock(mInterfaceMutex);
109    std::vector<std::string> deviceIds;
110    for (auto& provider : mProviders) {
111        if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
112            for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
113                deviceIds.push_back(id);
114            }
115        }
116    }
117    return deviceIds;
118}
119
120bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
121    std::lock_guard<std::mutex> lock(mInterfaceMutex);
122    return isValidDeviceLocked(id, majorVersion);
123}
124
125bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
126    for (auto& provider : mProviders) {
127        for (auto& deviceInfo : provider->mDevices) {
128            if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
129                return true;
130            }
131        }
132    }
133    return false;
134}
135
136bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
137    std::lock_guard<std::mutex> lock(mInterfaceMutex);
138
139    auto deviceInfo = findDeviceInfoLocked(id);
140    if (deviceInfo == nullptr) return false;
141
142    return deviceInfo->hasFlashUnit();
143}
144
145status_t CameraProviderManager::getResourceCost(const std::string &id,
146        CameraResourceCost* cost) const {
147    std::lock_guard<std::mutex> lock(mInterfaceMutex);
148
149    auto deviceInfo = findDeviceInfoLocked(id);
150    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
151
152    *cost = deviceInfo->mResourceCost;
153    return OK;
154}
155
156status_t CameraProviderManager::getCameraInfo(const std::string &id,
157        hardware::CameraInfo* info) const {
158    std::lock_guard<std::mutex> lock(mInterfaceMutex);
159
160    auto deviceInfo = findDeviceInfoLocked(id);
161    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
162
163    return deviceInfo->getCameraInfo(info);
164}
165
166status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
167        CameraMetadata* characteristics) const {
168    std::lock_guard<std::mutex> lock(mInterfaceMutex);
169
170    auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
171    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
172
173    return deviceInfo->getCameraCharacteristics(characteristics);
174}
175
176status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
177        hardware::hidl_version *v) {
178    std::lock_guard<std::mutex> lock(mInterfaceMutex);
179
180    hardware::hidl_version maxVersion{0,0};
181    bool found = false;
182    for (auto& provider : mProviders) {
183        for (auto& deviceInfo : provider->mDevices) {
184            if (deviceInfo->mId == id) {
185                if (deviceInfo->mVersion > maxVersion) {
186                    maxVersion = deviceInfo->mVersion;
187                    found = true;
188                }
189            }
190        }
191    }
192    if (!found) {
193        return NAME_NOT_FOUND;
194    }
195    *v = maxVersion;
196    return OK;
197}
198
199bool CameraProviderManager::supportSetTorchMode(const std::string &id) {
200    std::lock_guard<std::mutex> lock(mInterfaceMutex);
201    bool support = false;
202    for (auto& provider : mProviders) {
203        auto deviceInfo = findDeviceInfoLocked(id);
204        if (deviceInfo != nullptr) {
205            provider->mInterface->isSetTorchModeSupported(
206                [&support](auto status, bool supported) {
207                    if (status == Status::OK) {
208                        support = supported;
209                    }
210                });
211        }
212    }
213    return support;
214}
215
216status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
217    std::lock_guard<std::mutex> lock(mInterfaceMutex);
218
219    auto deviceInfo = findDeviceInfoLocked(id);
220    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
221
222    return deviceInfo->setTorchMode(enabled);
223}
224
225status_t CameraProviderManager::setUpVendorTags() {
226    sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
227
228    for (auto& provider : mProviders) {
229        hardware::hidl_vec<VendorTagSection> vts;
230        Status status;
231        hardware::Return<void> ret;
232        ret = provider->mInterface->getVendorTags(
233            [&](auto s, const auto& vendorTagSecs) {
234                status = s;
235                if (s == Status::OK) {
236                    vts = vendorTagSecs;
237                }
238        });
239        if (!ret.isOk()) {
240            ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
241                    __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
242            return DEAD_OBJECT;
243        }
244        if (status != Status::OK) {
245            return mapToStatusT(status);
246        }
247
248        // Read all vendor tag definitions into a descriptor
249        sp<VendorTagDescriptor> desc;
250        status_t res;
251        if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
252                != OK) {
253            ALOGE("%s: Could not generate descriptor from vendor tag operations,"
254                  "received error %s (%d). Camera clients will not be able to use"
255                  "vendor tags", __FUNCTION__, strerror(res), res);
256            return res;
257        }
258
259        tagCache->addVendorDescriptor(provider->mProviderTagid, desc);
260    }
261
262    VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
263
264    return OK;
265}
266
267status_t CameraProviderManager::openSession(const std::string &id,
268        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
269        /*out*/
270        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
271
272    std::lock_guard<std::mutex> lock(mInterfaceMutex);
273
274    auto deviceInfo = findDeviceInfoLocked(id,
275            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
276    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
277
278    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
279
280    Status status;
281    hardware::Return<void> ret;
282    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
283            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
284                status = s;
285                if (status == Status::OK) {
286                    *session = cameraSession;
287                }
288            });
289    if (!ret.isOk()) {
290        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
291                __FUNCTION__, id.c_str(), ret.description().c_str());
292        return DEAD_OBJECT;
293    }
294    return mapToStatusT(status);
295}
296
297status_t CameraProviderManager::openSession(const std::string &id,
298        const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
299        /*out*/
300        sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
301
302    std::lock_guard<std::mutex> lock(mInterfaceMutex);
303
304    auto deviceInfo = findDeviceInfoLocked(id,
305            /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
306    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
307
308    auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
309
310    hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
311    if (!status.isOk()) {
312        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
313                __FUNCTION__, id.c_str(), status.description().c_str());
314        return DEAD_OBJECT;
315    }
316    if (status == Status::OK) {
317        *session = deviceInfo1->mInterface;
318    }
319    return mapToStatusT(status);
320}
321
322
323hardware::Return<void> CameraProviderManager::onRegistration(
324        const hardware::hidl_string& /*fqName*/,
325        const hardware::hidl_string& name,
326        bool /*preexisting*/) {
327    {
328        std::lock_guard<std::mutex> lock(mInterfaceMutex);
329
330        addProviderLocked(name);
331    }
332
333    sp<StatusListener> listener = getStatusListener();
334    if (nullptr != listener.get()) {
335        listener->onNewProviderRegistered();
336    }
337
338    return hardware::Return<void>();
339}
340
341status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
342    std::lock_guard<std::mutex> lock(mInterfaceMutex);
343
344    for (auto& provider : mProviders) {
345        provider->dump(fd, args);
346    }
347    return OK;
348}
349
350CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
351        const std::string& id,
352        hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
353    for (auto& provider : mProviders) {
354        for (auto& deviceInfo : provider->mDevices) {
355            if (deviceInfo->mId == id &&
356                    minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
357                return deviceInfo.get();
358            }
359        }
360    }
361    return nullptr;
362}
363
364metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
365        const std::string& id, hardware::hidl_version minVersion,
366        hardware::hidl_version maxVersion) const {
367    metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
368
369    std::lock_guard<std::mutex> lock(mInterfaceMutex);
370    for (auto& provider : mProviders) {
371        for (auto& deviceInfo : provider->mDevices) {
372            if (deviceInfo->mId == id &&
373                    minVersion <= deviceInfo->mVersion &&
374                    maxVersion >= deviceInfo->mVersion) {
375                return provider->mProviderTagid;
376            }
377        }
378    }
379
380    return ret;
381}
382
383status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
384    for (const auto& providerInfo : mProviders) {
385        if (providerInfo->mProviderName == newProvider) {
386            ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
387                    newProvider.c_str());
388            return ALREADY_EXISTS;
389        }
390    }
391
392    sp<provider::V2_4::ICameraProvider> interface;
393    interface = mServiceProxy->getService(newProvider);
394
395    if (interface == nullptr) {
396        if (expected) {
397            ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
398                    newProvider.c_str());
399            return BAD_VALUE;
400        } else {
401            return OK;
402        }
403    }
404
405    sp<ProviderInfo> providerInfo =
406            new ProviderInfo(newProvider, interface, this);
407    status_t res = providerInfo->initialize();
408    if (res != OK) {
409        return res;
410    }
411
412    mProviders.push_back(providerInfo);
413
414    return OK;
415}
416
417status_t CameraProviderManager::removeProvider(const std::string& provider) {
418    std::unique_lock<std::mutex> lock(mInterfaceMutex);
419    std::vector<String8> removedDeviceIds;
420    status_t res = NAME_NOT_FOUND;
421    for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
422        if ((*it)->mProviderName == provider) {
423            removedDeviceIds.reserve((*it)->mDevices.size());
424            for (auto& deviceInfo : (*it)->mDevices) {
425                removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
426            }
427            mProviders.erase(it);
428            res = OK;
429            break;
430        }
431    }
432    if (res != OK) {
433        ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
434                provider.c_str());
435    } else {
436        // Inform camera service of loss of presence for all the devices from this provider,
437        // without lock held for reentrancy
438        sp<StatusListener> listener = getStatusListener();
439        if (listener != nullptr) {
440            lock.unlock();
441            for (auto& id : removedDeviceIds) {
442                listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
443            }
444        }
445    }
446    return res;
447}
448
449sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
450    return mListener.promote();
451}
452
453/**** Methods for ProviderInfo ****/
454
455
456CameraProviderManager::ProviderInfo::ProviderInfo(
457        const std::string &providerName,
458        sp<provider::V2_4::ICameraProvider>& interface,
459        CameraProviderManager *manager) :
460        mProviderName(providerName),
461        mInterface(interface),
462        mProviderTagid(generateVendorTagId(providerName)),
463        mUniqueDeviceCount(0),
464        mManager(manager) {
465    (void) mManager;
466}
467
468status_t CameraProviderManager::ProviderInfo::initialize() {
469    status_t res = parseProviderName(mProviderName, &mType, &mId);
470    if (res != OK) {
471        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
472        return BAD_VALUE;
473    }
474    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
475            mProviderName.c_str(), mInterface->isRemote());
476    hardware::Return<Status> status = mInterface->setCallback(this);
477    if (!status.isOk()) {
478        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
479                __FUNCTION__, mProviderName.c_str(), status.description().c_str());
480        return DEAD_OBJECT;
481    }
482    if (status != Status::OK) {
483        ALOGE("%s: Unable to register callbacks with camera provider '%s'",
484                __FUNCTION__, mProviderName.c_str());
485        return mapToStatusT(status);
486    }
487
488    hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
489    if (!linked.isOk()) {
490        ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
491                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
492        return DEAD_OBJECT;
493    } else if (!linked) {
494        ALOGW("%s: Unable to link to provider '%s' death notifications",
495                __FUNCTION__, mProviderName.c_str());
496    }
497
498    // Get initial list of camera devices, if any
499    std::vector<std::string> devices;
500    hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
501            Status idStatus,
502            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
503        status = idStatus;
504        if (status == Status::OK) {
505            for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
506                devices.push_back(cameraDeviceNames[i]);
507            }
508        } });
509    if (!ret.isOk()) {
510        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
511                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
512        return DEAD_OBJECT;
513    }
514    if (status != Status::OK) {
515        ALOGE("%s: Unable to query for camera devices from provider '%s'",
516                __FUNCTION__, mProviderName.c_str());
517        return mapToStatusT(status);
518    }
519
520    sp<StatusListener> listener = mManager->getStatusListener();
521    for (auto& device : devices) {
522        std::string id;
523        status_t res = addDevice(device,
524                hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
525        if (res != OK) {
526            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
527                    __FUNCTION__, device.c_str(), strerror(-res), res);
528            continue;
529        }
530    }
531
532    for (auto& device : mDevices) {
533        mUniqueCameraIds.insert(device->mId);
534        if (device->isAPI1Compatible()) {
535            mUniqueAPI1CompatibleCameraIds.insert(device->mId);
536        }
537    }
538    mUniqueDeviceCount = mUniqueCameraIds.size();
539
540    ALOGI("Camera provider %s ready with %zu camera devices",
541            mProviderName.c_str(), mDevices.size());
542
543    return OK;
544}
545
546const std::string& CameraProviderManager::ProviderInfo::getType() const {
547    return mType;
548}
549
550status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
551        CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
552
553    ALOGI("Enumerating new camera device: %s", name.c_str());
554
555    uint16_t major, minor;
556    std::string type, id;
557
558    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
559    if (res != OK) {
560        return res;
561    }
562    if (type != mType) {
563        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
564                type.c_str(), mType.c_str());
565        return BAD_VALUE;
566    }
567    if (mManager->isValidDeviceLocked(id, major)) {
568        ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
569                name.c_str(), id.c_str(), major);
570        return BAD_VALUE;
571    }
572
573    std::unique_ptr<DeviceInfo> deviceInfo;
574    switch (major) {
575        case 1:
576            deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
577                    id, minor);
578            break;
579        case 3:
580            deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
581                    id, minor);
582            break;
583        default:
584            ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
585                    name.c_str(), major);
586            return BAD_VALUE;
587    }
588    if (deviceInfo == nullptr) return BAD_VALUE;
589    deviceInfo->mStatus = initialStatus;
590
591    mDevices.push_back(std::move(deviceInfo));
592
593    if (parsedId != nullptr) {
594        *parsedId = id;
595    }
596    return OK;
597}
598
599status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
600    dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
601            mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
602            mDevices.size());
603
604    for (auto& device : mDevices) {
605        dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
606                device->mVersion.get_major(), device->mVersion.get_minor());
607        dprintf(fd, "  Resource cost: %d\n", device->mResourceCost.resourceCost);
608        if (device->mResourceCost.conflictingDevices.size() == 0) {
609            dprintf(fd, "  Conflicting devices: None\n");
610        } else {
611            dprintf(fd, "  Conflicting devices:\n");
612            for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
613                dprintf(fd, "    %s\n",
614                        device->mResourceCost.conflictingDevices[i].c_str());
615            }
616        }
617        dprintf(fd, "  API1 info:\n");
618        dprintf(fd, "    Has a flash unit: %s\n",
619                device->hasFlashUnit() ? "true" : "false");
620        hardware::CameraInfo info;
621        status_t res = device->getCameraInfo(&info);
622        if (res != OK) {
623            dprintf(fd, "   <Error reading camera info: %s (%d)>\n",
624                    strerror(-res), res);
625        } else {
626            dprintf(fd, "    Facing: %s\n",
627                    info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
628            dprintf(fd, "    Orientation: %d\n", info.orientation);
629        }
630        CameraMetadata info2;
631        res = device->getCameraCharacteristics(&info2);
632        if (res == INVALID_OPERATION) {
633            dprintf(fd, "  API2 not directly supported\n");
634        } else if (res != OK) {
635            dprintf(fd, "  <Error reading camera characteristics: %s (%d)>\n",
636                    strerror(-res), res);
637        } else {
638            dprintf(fd, "  API2 camera characteristics:\n");
639            info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
640        }
641    }
642    return OK;
643}
644
645hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
646        const hardware::hidl_string& cameraDeviceName,
647        CameraDeviceStatus newStatus) {
648    sp<StatusListener> listener;
649    std::string id;
650    {
651        std::lock_guard<std::mutex> lock(mLock);
652        bool known = false;
653        for (auto& deviceInfo : mDevices) {
654            if (deviceInfo->mName == cameraDeviceName) {
655                ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
656                        deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
657                deviceInfo->mStatus = newStatus;
658                // TODO: Handle device removal (NOT_PRESENT)
659                id = deviceInfo->mId;
660                known = true;
661                break;
662            }
663        }
664        // Previously unseen device; status must not be NOT_PRESENT
665        if (!known) {
666            if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
667                ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
668                    mProviderName.c_str(), cameraDeviceName.c_str());
669                return hardware::Void();
670            }
671            addDevice(cameraDeviceName, newStatus, &id);
672        }
673        listener = mManager->getStatusListener();
674    }
675    // Call without lock held to allow reentrancy into provider manager
676    if (listener != nullptr) {
677        listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
678    }
679    return hardware::Void();
680}
681
682hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
683        const hardware::hidl_string& cameraDeviceName,
684        TorchModeStatus newStatus) {
685    sp<StatusListener> listener;
686    std::string id;
687    {
688        std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
689        bool known = false;
690        for (auto& deviceInfo : mDevices) {
691            if (deviceInfo->mName == cameraDeviceName) {
692                ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
693                        torchStatusToString(newStatus));
694                id = deviceInfo->mId;
695                known = true;
696                break;
697            }
698        }
699        if (!known) {
700            ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
701                    mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
702            return hardware::Void();
703        }
704        listener = mManager->getStatusListener();
705    }
706    // Call without lock held to allow reentrancy into provider manager
707    if (listener != nullptr) {
708        listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
709    }
710    return hardware::Void();
711}
712
713void CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
714        const wp<hidl::base::V1_0::IBase>& who) {
715    (void) who;
716    ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
717    if (cookie != mId) {
718        ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
719                __FUNCTION__, cookie, mId);
720    }
721    mManager->removeProvider(mProviderName);
722}
723
724template<class DeviceInfoT>
725std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
726    CameraProviderManager::ProviderInfo::initializeDeviceInfo(
727        const std::string &name, const metadata_vendor_id_t tagId,
728        const std::string &id, uint16_t minorVersion) const {
729    Status status;
730
731    auto cameraInterface =
732            getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
733    if (cameraInterface == nullptr) return nullptr;
734
735    CameraResourceCost resourceCost;
736    cameraInterface->getResourceCost([&status, &resourceCost](
737        Status s, CameraResourceCost cost) {
738                status = s;
739                resourceCost = cost;
740            });
741    if (status != Status::OK) {
742        ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
743                name.c_str(), statusToString(status));
744        return nullptr;
745    }
746    return std::unique_ptr<DeviceInfo>(
747        new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
748                cameraInterface));
749}
750
751template<class InterfaceT>
752sp<InterfaceT>
753CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
754    ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
755            name.c_str(), InterfaceT::version.get_major());
756    return nullptr;
757}
758
759template<>
760sp<device::V1_0::ICameraDevice>
761CameraProviderManager::ProviderInfo::getDeviceInterface
762        <device::V1_0::ICameraDevice>(const std::string &name) const {
763    Status status;
764    sp<device::V1_0::ICameraDevice> cameraInterface;
765    hardware::Return<void> ret;
766    ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
767        Status s, sp<device::V1_0::ICameraDevice> interface) {
768                status = s;
769                cameraInterface = interface;
770            });
771    if (!ret.isOk()) {
772        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
773                __FUNCTION__, name.c_str(), ret.description().c_str());
774        return nullptr;
775    }
776    if (status != Status::OK) {
777        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
778                name.c_str(), statusToString(status));
779        return nullptr;
780    }
781    return cameraInterface;
782}
783
784template<>
785sp<device::V3_2::ICameraDevice>
786CameraProviderManager::ProviderInfo::getDeviceInterface
787        <device::V3_2::ICameraDevice>(const std::string &name) const {
788    Status status;
789    sp<device::V3_2::ICameraDevice> cameraInterface;
790    hardware::Return<void> ret;
791    ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
792        Status s, sp<device::V3_2::ICameraDevice> interface) {
793                status = s;
794                cameraInterface = interface;
795            });
796    if (!ret.isOk()) {
797        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
798                __FUNCTION__, name.c_str(), ret.description().c_str());
799        return nullptr;
800    }
801    if (status != Status::OK) {
802        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
803                name.c_str(), statusToString(status));
804        return nullptr;
805    }
806    return cameraInterface;
807}
808
809CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
810
811template<class InterfaceT>
812status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
813        bool enabled) {
814    Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
815    return mapToStatusT(s);
816}
817
818CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
819        const metadata_vendor_id_t tagId, const std::string &id,
820        uint16_t minorVersion,
821        const CameraResourceCost& resourceCost,
822        sp<InterfaceT> interface) :
823        DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
824                   resourceCost),
825        mInterface(interface) {
826    // Get default parameters and initialize flash unit availability
827    // Requires powering on the camera device
828    hardware::Return<Status> status = mInterface->open(nullptr);
829    if (!status.isOk()) {
830        ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
831                __FUNCTION__, mId.c_str(), status.description().c_str());
832        return;
833    }
834    if (status != Status::OK) {
835        ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
836                mId.c_str(), CameraProviderManager::statusToString(status));
837        return;
838    }
839    hardware::Return<void> ret;
840    ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
841                mDefaultParameters.unflatten(String8(parms.c_str()));
842            });
843    if (!ret.isOk()) {
844        ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
845                __FUNCTION__, mId.c_str(), status.description().c_str());
846        return;
847    }
848    const char *flashMode =
849            mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
850    if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
851        mHasFlashUnit = true;
852    }
853
854    ret = mInterface->close();
855    if (!ret.isOk()) {
856        ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
857                __FUNCTION__, mId.c_str(), status.description().c_str());
858    }
859}
860
861CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
862
863status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
864    return DeviceInfo::setTorchMode(mInterface, enabled);
865}
866
867status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
868        hardware::CameraInfo *info) const {
869    if (info == nullptr) return BAD_VALUE;
870
871    Status status;
872    device::V1_0::CameraInfo cInfo;
873    hardware::Return<void> ret;
874    ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
875                status = s;
876                cInfo = camInfo;
877            });
878    if (!ret.isOk()) {
879        ALOGE("%s: Transaction error reading camera info from device %s: %s",
880                __FUNCTION__, mId.c_str(), ret.description().c_str());
881        return DEAD_OBJECT;
882    }
883    if (status != Status::OK) {
884        return mapToStatusT(status);
885    }
886
887    switch(cInfo.facing) {
888        case device::V1_0::CameraFacing::BACK:
889            info->facing = hardware::CAMERA_FACING_BACK;
890            break;
891        case device::V1_0::CameraFacing::EXTERNAL:
892            // Map external to front for legacy API
893        case device::V1_0::CameraFacing::FRONT:
894            info->facing = hardware::CAMERA_FACING_FRONT;
895            break;
896        default:
897            ALOGW("%s: Device %s: Unknown camera facing: %d",
898                    __FUNCTION__, mId.c_str(), cInfo.facing);
899            info->facing = hardware::CAMERA_FACING_BACK;
900    }
901    info->orientation = cInfo.orientation;
902
903    return OK;
904}
905
906CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
907        const metadata_vendor_id_t tagId, const std::string &id,
908        uint16_t minorVersion,
909        const CameraResourceCost& resourceCost,
910        sp<InterfaceT> interface) :
911        DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
912                   resourceCost),
913        mInterface(interface) {
914    // Get camera characteristics and initialize flash unit availability
915    Status status;
916    hardware::Return<void> ret;
917    ret = mInterface->getCameraCharacteristics([&status, this](Status s,
918                    device::V3_2::CameraMetadata metadata) {
919                status = s;
920                if (s == Status::OK) {
921                    camera_metadata_t *buffer =
922                            reinterpret_cast<camera_metadata_t*>(metadata.data());
923                    size_t expectedSize = metadata.size();
924                    int res = validate_camera_metadata_structure(buffer, &expectedSize);
925                    if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
926                        set_camera_metadata_vendor_id(buffer, mProviderTagid);
927                        mCameraCharacteristics = buffer;
928                    } else {
929                        ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
930                        status = Status::INTERNAL_ERROR;
931                    }
932                }
933            });
934    if (!ret.isOk()) {
935        ALOGE("%s: Transaction error getting camera characteristics for device %s"
936                " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
937                ret.description().c_str());
938        return;
939    }
940    if (status != Status::OK) {
941        ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
942                __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
943        return;
944    }
945    camera_metadata_entry flashAvailable =
946            mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
947    if (flashAvailable.count == 1 &&
948            flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
949        mHasFlashUnit = true;
950    } else {
951        mHasFlashUnit = false;
952    }
953}
954
955CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
956
957status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
958    return DeviceInfo::setTorchMode(mInterface, enabled);
959}
960
961status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
962        hardware::CameraInfo *info) const {
963    if (info == nullptr) return BAD_VALUE;
964
965    camera_metadata_ro_entry facing =
966            mCameraCharacteristics.find(ANDROID_LENS_FACING);
967    if (facing.count == 1) {
968        switch (facing.data.u8[0]) {
969            case ANDROID_LENS_FACING_BACK:
970                info->facing = hardware::CAMERA_FACING_BACK;
971                break;
972            case ANDROID_LENS_FACING_EXTERNAL:
973                // Map external to front for legacy API
974            case ANDROID_LENS_FACING_FRONT:
975                info->facing = hardware::CAMERA_FACING_FRONT;
976                break;
977        }
978    } else {
979        ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
980        return NAME_NOT_FOUND;
981    }
982
983    camera_metadata_ro_entry orientation =
984            mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
985    if (orientation.count == 1) {
986        info->orientation = orientation.data.i32[0];
987    } else {
988        ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
989        return NAME_NOT_FOUND;
990    }
991
992    return OK;
993}
994bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
995    bool isBackwardCompatible = false;
996    camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
997            ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
998    for (size_t i = 0; i < caps.count; i++) {
999        if (caps.data.u8[i] ==
1000                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1001            isBackwardCompatible = true;
1002            break;
1003        }
1004    }
1005
1006    return isBackwardCompatible;
1007}
1008
1009status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
1010        CameraMetadata *characteristics) const {
1011    if (characteristics == nullptr) return BAD_VALUE;
1012
1013    *characteristics = mCameraCharacteristics;
1014    return OK;
1015}
1016
1017status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
1018        std::string *type, uint32_t *id) {
1019    // Format must be "<type>/<id>"
1020#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. "       \
1021    "Should match '<type>/<id>' - "
1022
1023    if (!type || !id) return INVALID_OPERATION;
1024
1025    std::string::size_type slashIdx = name.find('/');
1026    if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
1027        ALOGE(ERROR_MSG_PREFIX
1028                "does not have / separator between type and id",
1029                __FUNCTION__, name.c_str());
1030        return BAD_VALUE;
1031    }
1032
1033    std::string typeVal = name.substr(0, slashIdx);
1034
1035    char *endPtr;
1036    errno = 0;
1037    long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
1038    if (errno != 0) {
1039        ALOGE(ERROR_MSG_PREFIX
1040                "cannot parse provider id as an integer: %s (%d)",
1041                __FUNCTION__, name.c_str(), strerror(errno), errno);
1042        return BAD_VALUE;
1043    }
1044    if (endPtr != name.c_str() + name.size()) {
1045        ALOGE(ERROR_MSG_PREFIX
1046                "provider id has unexpected length",
1047                __FUNCTION__, name.c_str());
1048        return BAD_VALUE;
1049    }
1050    if (idVal < 0) {
1051        ALOGE(ERROR_MSG_PREFIX
1052                "id is negative: %ld",
1053                __FUNCTION__, name.c_str(), idVal);
1054        return BAD_VALUE;
1055    }
1056
1057#undef ERROR_MSG_PREFIX
1058
1059    *type = typeVal;
1060    *id = static_cast<uint32_t>(idVal);
1061
1062    return OK;
1063}
1064
1065metadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
1066        const std::string &name) {
1067    metadata_vendor_id_t ret = std::hash<std::string> {} (name);
1068    // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
1069    if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
1070        ret = 0;
1071    }
1072
1073    return ret;
1074}
1075
1076status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
1077        uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
1078
1079    // Format must be "device@<major>.<minor>/<type>/<id>"
1080
1081#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
1082    "Should match 'device@<major>.<minor>/<type>/<id>' - "
1083
1084    if (!major || !minor || !type || !id) return INVALID_OPERATION;
1085
1086    // Verify starting prefix
1087    const char expectedPrefix[] = "device@";
1088
1089    if (name.find(expectedPrefix) != 0) {
1090        ALOGE(ERROR_MSG_PREFIX
1091                "does not start with '%s'",
1092                __FUNCTION__, name.c_str(), expectedPrefix);
1093        return BAD_VALUE;
1094    }
1095
1096    // Extract major/minor versions
1097    constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
1098    std::string::size_type dotIdx = name.find('.', atIdx);
1099    if (dotIdx == std::string::npos) {
1100        ALOGE(ERROR_MSG_PREFIX
1101                "does not have @<major>. version section",
1102                __FUNCTION__, name.c_str());
1103        return BAD_VALUE;
1104    }
1105    std::string::size_type typeSlashIdx = name.find('/', dotIdx);
1106    if (typeSlashIdx == std::string::npos) {
1107        ALOGE(ERROR_MSG_PREFIX
1108                "does not have .<minor>/ version section",
1109                __FUNCTION__, name.c_str());
1110        return BAD_VALUE;
1111    }
1112
1113    char *endPtr;
1114    errno = 0;
1115    long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
1116    if (errno != 0) {
1117        ALOGE(ERROR_MSG_PREFIX
1118                "cannot parse major version: %s (%d)",
1119                __FUNCTION__, name.c_str(), strerror(errno), errno);
1120        return BAD_VALUE;
1121    }
1122    if (endPtr != name.c_str() + dotIdx) {
1123        ALOGE(ERROR_MSG_PREFIX
1124                "major version has unexpected length",
1125                __FUNCTION__, name.c_str());
1126        return BAD_VALUE;
1127    }
1128    long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
1129    if (errno != 0) {
1130        ALOGE(ERROR_MSG_PREFIX
1131                "cannot parse minor version: %s (%d)",
1132                __FUNCTION__, name.c_str(), strerror(errno), errno);
1133        return BAD_VALUE;
1134    }
1135    if (endPtr != name.c_str() + typeSlashIdx) {
1136        ALOGE(ERROR_MSG_PREFIX
1137                "minor version has unexpected length",
1138                __FUNCTION__, name.c_str());
1139        return BAD_VALUE;
1140    }
1141    if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
1142        ALOGE(ERROR_MSG_PREFIX
1143                "major/minor version is out of range of uint16_t: %ld.%ld",
1144                __FUNCTION__, name.c_str(), majorVal, minorVal);
1145        return BAD_VALUE;
1146    }
1147
1148    // Extract type and id
1149
1150    std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
1151    if (instanceSlashIdx == std::string::npos) {
1152        ALOGE(ERROR_MSG_PREFIX
1153                "does not have /<type>/ component",
1154                __FUNCTION__, name.c_str());
1155        return BAD_VALUE;
1156    }
1157    std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
1158
1159    if (instanceSlashIdx == name.size() - 1) {
1160        ALOGE(ERROR_MSG_PREFIX
1161                "does not have an /<id> component",
1162                __FUNCTION__, name.c_str());
1163        return BAD_VALUE;
1164    }
1165    std::string idVal = name.substr(instanceSlashIdx + 1);
1166
1167#undef ERROR_MSG_PREFIX
1168
1169    *major = static_cast<uint16_t>(majorVal);
1170    *minor = static_cast<uint16_t>(minorVal);
1171    *type = typeVal;
1172    *id = idVal;
1173
1174    return OK;
1175}
1176
1177
1178
1179CameraProviderManager::ProviderInfo::~ProviderInfo() {
1180    // Destruction of ProviderInfo is only supposed to happen when the respective
1181    // CameraProvider interface dies, so do not unregister callbacks.
1182
1183}
1184
1185status_t CameraProviderManager::mapToStatusT(const Status& s)  {
1186    switch(s) {
1187        case Status::OK:
1188            return OK;
1189        case Status::ILLEGAL_ARGUMENT:
1190            return BAD_VALUE;
1191        case Status::CAMERA_IN_USE:
1192            return -EBUSY;
1193        case Status::MAX_CAMERAS_IN_USE:
1194            return -EUSERS;
1195        case Status::METHOD_NOT_SUPPORTED:
1196            return UNKNOWN_TRANSACTION;
1197        case Status::OPERATION_NOT_SUPPORTED:
1198            return INVALID_OPERATION;
1199        case Status::CAMERA_DISCONNECTED:
1200            return DEAD_OBJECT;
1201        case Status::INTERNAL_ERROR:
1202            return INVALID_OPERATION;
1203    }
1204    ALOGW("Unexpected HAL status code %d", s);
1205    return INVALID_OPERATION;
1206}
1207
1208const char* CameraProviderManager::statusToString(const Status& s) {
1209    switch(s) {
1210        case Status::OK:
1211            return "OK";
1212        case Status::ILLEGAL_ARGUMENT:
1213            return "ILLEGAL_ARGUMENT";
1214        case Status::CAMERA_IN_USE:
1215            return "CAMERA_IN_USE";
1216        case Status::MAX_CAMERAS_IN_USE:
1217            return "MAX_CAMERAS_IN_USE";
1218        case Status::METHOD_NOT_SUPPORTED:
1219            return "METHOD_NOT_SUPPORTED";
1220        case Status::OPERATION_NOT_SUPPORTED:
1221            return "OPERATION_NOT_SUPPORTED";
1222        case Status::CAMERA_DISCONNECTED:
1223            return "CAMERA_DISCONNECTED";
1224        case Status::INTERNAL_ERROR:
1225            return "INTERNAL_ERROR";
1226    }
1227    ALOGW("Unexpected HAL status code %d", s);
1228    return "UNKNOWN_ERROR";
1229}
1230
1231const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
1232    switch(s) {
1233        case CameraDeviceStatus::NOT_PRESENT:
1234            return "NOT_PRESENT";
1235        case CameraDeviceStatus::PRESENT:
1236            return "PRESENT";
1237        case CameraDeviceStatus::ENUMERATING:
1238            return "ENUMERATING";
1239    }
1240    ALOGW("Unexpected HAL device status code %d", s);
1241    return "UNKNOWN_STATUS";
1242}
1243
1244const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
1245    switch(s) {
1246        case TorchModeStatus::NOT_AVAILABLE:
1247            return "NOT_AVAILABLE";
1248        case TorchModeStatus::AVAILABLE_OFF:
1249            return "AVAILABLE_OFF";
1250        case TorchModeStatus::AVAILABLE_ON:
1251            return "AVAILABLE_ON";
1252    }
1253    ALOGW("Unexpected HAL torch mode status code %d", s);
1254    return "UNKNOWN_STATUS";
1255}
1256
1257
1258status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
1259        const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
1260        /*out*/
1261        sp<VendorTagDescriptor>& descriptor) {
1262
1263    int tagCount = 0;
1264
1265    for (size_t s = 0; s < vts.size(); s++) {
1266        tagCount += vts[s].tags.size();
1267    }
1268
1269    if (tagCount < 0 || tagCount > INT32_MAX) {
1270        ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
1271        return BAD_VALUE;
1272    }
1273
1274    Vector<uint32_t> tagArray;
1275    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
1276            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
1277
1278
1279    sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
1280    desc->mTagCount = tagCount;
1281
1282    SortedVector<String8> sections;
1283    KeyedVector<uint32_t, String8> tagToSectionMap;
1284
1285    int idx = 0;
1286    for (size_t s = 0; s < vts.size(); s++) {
1287        const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
1288        const char *sectionName = section.sectionName.c_str();
1289        if (sectionName == NULL) {
1290            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
1291            return BAD_VALUE;
1292        }
1293        String8 sectionString(sectionName);
1294        sections.add(sectionString);
1295
1296        for (size_t j = 0; j < section.tags.size(); j++) {
1297            uint32_t tag = section.tags[j].tagId;
1298            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
1299                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
1300                return BAD_VALUE;
1301            }
1302
1303            tagArray.editItemAt(idx++) = section.tags[j].tagId;
1304
1305            const char *tagName = section.tags[j].tagName.c_str();
1306            if (tagName == NULL) {
1307                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
1308                return BAD_VALUE;
1309            }
1310            desc->mTagToNameMap.add(tag, String8(tagName));
1311            tagToSectionMap.add(tag, sectionString);
1312
1313            int tagType = (int) section.tags[j].tagType;
1314            if (tagType < 0 || tagType >= NUM_TYPES) {
1315                ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
1316                return BAD_VALUE;
1317            }
1318            desc->mTagToTypeMap.add(tag, tagType);
1319        }
1320    }
1321
1322    desc->mSections = sections;
1323
1324    for (size_t i = 0; i < tagArray.size(); ++i) {
1325        uint32_t tag = tagArray[i];
1326        String8 sectionString = tagToSectionMap.valueFor(tag);
1327
1328        // Set up tag to section index map
1329        ssize_t index = sections.indexOf(sectionString);
1330        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
1331        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
1332
1333        // Set up reverse mapping
1334        ssize_t reverseIndex = -1;
1335        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
1336            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
1337            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
1338        }
1339        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
1340    }
1341
1342    descriptor = desc;
1343    return OK;
1344}
1345
1346
1347} // namespace android
1348