CameraProvider.cpp revision 1903059507815cc89e9cf268f73d86b2bb3feef7
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 "CamProvider@2.4-impl"
18//#define LOG_NDEBUG 0
19#include <android/log.h>
20
21#include "CameraProvider.h"
22#include "ExternalCameraProvider.h"
23#include "CameraDevice_1_0.h"
24#include "CameraDevice_3_3.h"
25#include "CameraDevice_3_4.h"
26#include <cutils/properties.h>
27#include <string.h>
28#include <utils/Trace.h>
29
30
31namespace android {
32namespace hardware {
33namespace camera {
34namespace provider {
35namespace V2_4 {
36namespace implementation {
37
38namespace {
39const char *kLegacyProviderName = "legacy/0";
40const char *kExternalProviderName = "external/0";
41// "device@<version>/legacy/<id>"
42const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
43const char *kHAL3_2 = "3.2";
44const char *kHAL3_3 = "3.3";
45const char *kHAL3_4 = "3.4";
46const char *kHAL1_0 = "1.0";
47const int kMaxCameraDeviceNameLen = 128;
48const int kMaxCameraIdLen = 16;
49
50bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
51                     std::string* cameraId) {
52    std::string deviceNameStd(deviceName.c_str());
53    std::smatch sm;
54    if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
55        if (deviceVersion != nullptr) {
56            *deviceVersion = sm[1];
57        }
58        if (cameraId != nullptr) {
59            *cameraId = sm[2];
60        }
61        return true;
62    }
63    return false;
64}
65
66} // anonymous namespace
67
68using ::android::hardware::camera::common::V1_0::CameraMetadataType;
69using ::android::hardware::camera::common::V1_0::Status;
70
71void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
72{
73    char cameraId[kMaxCameraIdLen];
74    snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
75    std::string cameraIdStr(cameraId);
76
77    mCameraIds.add(cameraIdStr);
78
79    // initialize mCameraDeviceNames and mOpenLegacySupported
80    mOpenLegacySupported[cameraIdStr] = false;
81    int deviceVersion = mModule->getDeviceVersion(camera_id);
82    auto deviceNamePair = std::make_pair(cameraIdStr,
83                                         getHidlDeviceName(cameraIdStr, deviceVersion));
84    mCameraDeviceNames.add(deviceNamePair);
85    if (cam_new) {
86        mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
87    }
88    if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
89            mModule->isOpenLegacyDefined()) {
90        // try open_legacy to see if it actually works
91        struct hw_device_t* halDev = nullptr;
92        int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
93        if (ret == 0) {
94            mOpenLegacySupported[cameraIdStr] = true;
95            halDev->close(halDev);
96            deviceNamePair = std::make_pair(cameraIdStr,
97                            getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
98            mCameraDeviceNames.add(deviceNamePair);
99            if (cam_new) {
100                mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
101            }
102        } else if (ret == -EBUSY || ret == -EUSERS) {
103            // Looks like this provider instance is not initialized during
104            // system startup and there are other camera users already.
105            // Not a good sign but not fatal.
106            ALOGW("%s: open_legacy try failed!", __FUNCTION__);
107        }
108    }
109}
110
111/**
112 * static callback forwarding methods from HAL to instance
113 */
114void CameraProvider::sCameraDeviceStatusChange(
115        const struct camera_module_callbacks* callbacks,
116        int camera_id,
117        int new_status) {
118    CameraProvider* cp = const_cast<CameraProvider*>(
119            static_cast<const CameraProvider*>(callbacks));
120    bool found = false;
121
122    if (cp == nullptr) {
123        ALOGE("%s: callback ops is null", __FUNCTION__);
124        return;
125    }
126
127    Mutex::Autolock _l(cp->mCbLock);
128    char cameraId[kMaxCameraIdLen];
129    snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
130    std::string cameraIdStr(cameraId);
131    cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
132    if (cp->mCallbacks != nullptr) {
133        CameraDeviceStatus status = (CameraDeviceStatus) new_status;
134        for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
135            if (cameraIdStr.compare(deviceNamePair.first) == 0) {
136                cp->mCallbacks->cameraDeviceStatusChange(
137                        deviceNamePair.second, status);
138                found = true;
139            }
140        }
141
142        if (!found) {
143            cp->addDeviceNames(camera_id, status, true);
144        }
145    }
146}
147
148void CameraProvider::sTorchModeStatusChange(
149        const struct camera_module_callbacks* callbacks,
150        const char* camera_id,
151        int new_status) {
152    CameraProvider* cp = const_cast<CameraProvider*>(
153            static_cast<const CameraProvider*>(callbacks));
154
155    if (cp == nullptr) {
156        ALOGE("%s: callback ops is null", __FUNCTION__);
157        return;
158    }
159
160    Mutex::Autolock _l(cp->mCbLock);
161    if (cp->mCallbacks != nullptr) {
162        std::string cameraIdStr(camera_id);
163        TorchModeStatus status = (TorchModeStatus) new_status;
164        for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
165            if (cameraIdStr.compare(deviceNamePair.first) == 0) {
166                cp->mCallbacks->torchModeStatusChange(
167                        deviceNamePair.second, status);
168            }
169        }
170    }
171}
172
173Status CameraProvider::getHidlStatus(int status) {
174    switch (status) {
175        case 0: return Status::OK;
176        case -ENODEV: return Status::INTERNAL_ERROR;
177        case -EINVAL: return Status::ILLEGAL_ARGUMENT;
178        default:
179            ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
180            return Status::INTERNAL_ERROR;
181    }
182}
183
184std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
185    std::string cameraId;
186    matchDeviceName(deviceName, nullptr, &cameraId);
187    return cameraId;
188}
189
190int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
191    std::string deviceVersion;
192    bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
193    if (!match) {
194        return -1;
195    }
196    if (deviceVersion == kHAL3_3) {
197        return CAMERA_DEVICE_API_VERSION_3_3;
198    } else if (deviceVersion == kHAL3_2) {
199        return CAMERA_DEVICE_API_VERSION_3_2;
200    } else if (deviceVersion == kHAL1_0) {
201        return CAMERA_DEVICE_API_VERSION_1_0;
202    }
203    return 0;
204}
205
206std::string CameraProvider::getHidlDeviceName(
207        std::string cameraId, int deviceVersion) {
208    // Maybe consider create a version check method and SortedVec to speed up?
209    if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
210            deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
211            deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
212            deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 &&
213            deviceVersion != CAMERA_DEVICE_API_VERSION_3_5) {
214        return hidl_string("");
215    }
216    bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
217    int versionMajor = isV1 ? 1 : 3;
218    int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
219    if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
220        versionMinor = 4;
221    }
222    char deviceName[kMaxCameraDeviceNameLen];
223    snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
224            versionMajor, versionMinor, cameraId.c_str());
225    return deviceName;
226}
227
228CameraProvider::CameraProvider() :
229        camera_module_callbacks_t({sCameraDeviceStatusChange,
230                                   sTorchModeStatusChange}) {
231    mInitFailed = initialize();
232}
233
234CameraProvider::~CameraProvider() {}
235
236bool CameraProvider::initialize() {
237    camera_module_t *rawModule;
238    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
239            (const hw_module_t **)&rawModule);
240    if (err < 0) {
241        ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
242        return true;
243    }
244
245    mModule = new CameraModule(rawModule);
246    err = mModule->init();
247    if (err != OK) {
248        ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
249        mModule.clear();
250        return true;
251    }
252    ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
253
254    // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
255    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
256    if (!setUpVendorTags()) {
257        ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
258    }
259
260    // Setup callback now because we are going to try openLegacy next
261    err = mModule->setCallbacks(this);
262    if (err != OK) {
263        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
264        mModule.clear();
265        return true;
266    }
267
268    mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
269    ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
270    switch(mPreferredHal3MinorVersion) {
271        case 2:
272        case 3:
273            // OK
274            break;
275        default:
276            ALOGW("Unknown minor camera device HAL version %d in property "
277                    "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
278                    mPreferredHal3MinorVersion);
279            mPreferredHal3MinorVersion = 3;
280    }
281
282    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
283    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
284        struct camera_info info;
285        auto rc = mModule->getCameraInfo(i, &info);
286        if (rc != NO_ERROR) {
287            ALOGE("%s: Camera info query failed!", __func__);
288            mModule.clear();
289            return true;
290        }
291
292        if (checkCameraVersion(i, info) != OK) {
293            ALOGE("%s: Camera version check failed!", __func__);
294            mModule.clear();
295            return true;
296        }
297
298        char cameraId[kMaxCameraIdLen];
299        snprintf(cameraId, sizeof(cameraId), "%d", i);
300        std::string cameraIdStr(cameraId);
301        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
302
303        addDeviceNames(i);
304    }
305
306    return false; // mInitFailed
307}
308
309/**
310 * Check that the device HAL version is still in supported.
311 */
312int CameraProvider::checkCameraVersion(int id, camera_info info) {
313    if (mModule == nullptr) {
314        return NO_INIT;
315    }
316
317    // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
318    // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
319    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
320        // Verify the device version is in the supported range
321        switch (info.device_version) {
322            case CAMERA_DEVICE_API_VERSION_1_0:
323            case CAMERA_DEVICE_API_VERSION_3_2:
324            case CAMERA_DEVICE_API_VERSION_3_3:
325            case CAMERA_DEVICE_API_VERSION_3_4:
326            case CAMERA_DEVICE_API_VERSION_3_5:
327                // in support
328                break;
329            case CAMERA_DEVICE_API_VERSION_2_0:
330            case CAMERA_DEVICE_API_VERSION_2_1:
331            case CAMERA_DEVICE_API_VERSION_3_0:
332            case CAMERA_DEVICE_API_VERSION_3_1:
333                // no longer supported
334            default:
335                ALOGE("%s: Device %d has HAL version %x, which is not supported",
336                        __FUNCTION__, id, info.device_version);
337                return NO_INIT;
338        }
339    }
340
341    return OK;
342}
343
344bool CameraProvider::setUpVendorTags() {
345    ATRACE_CALL();
346    vendor_tag_ops_t vOps = vendor_tag_ops_t();
347
348    // Check if vendor operations have been implemented
349    if (!mModule->isVendorTagDefined()) {
350        ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
351        return true;
352    }
353
354    mModule->getVendorTagOps(&vOps);
355
356    // Ensure all vendor operations are present
357    if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
358            vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
359            vOps.get_tag_type == nullptr) {
360        ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
361               , __FUNCTION__);
362        return false;
363    }
364
365    // Read all vendor tag definitions into a descriptor
366    sp<VendorTagDescriptor> desc;
367    status_t res;
368    if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
369            != OK) {
370        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
371              "received error %s (%d). Camera clients will not be able to use"
372              "vendor tags", __FUNCTION__, strerror(res), res);
373        return false;
374    }
375
376    // Set the global descriptor to use with camera metadata
377    VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
378    const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
379    size_t numSections = sectionNames->size();
380    std::vector<std::vector<VendorTag>> tagsBySection(numSections);
381    int tagCount = desc->getTagCount();
382    std::vector<uint32_t> tags(tagCount);
383    desc->getTagArray(tags.data());
384    for (int i = 0; i < tagCount; i++) {
385        VendorTag vt;
386        vt.tagId = tags[i];
387        vt.tagName = desc->getTagName(tags[i]);
388        vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
389        ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
390        tagsBySection[sectionIdx].push_back(vt);
391    }
392    mVendorTagSections.resize(numSections);
393    for (size_t s = 0; s < numSections; s++) {
394        mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
395        mVendorTagSections[s].tags = tagsBySection[s];
396    }
397    return true;
398}
399
400// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
401Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback)  {
402    Mutex::Autolock _l(mCbLock);
403    mCallbacks = callback;
404    return Status::OK;
405}
406
407Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb)  {
408    _hidl_cb(Status::OK, mVendorTagSections);
409    return Void();
410}
411
412Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb)  {
413    std::vector<hidl_string> deviceNameList;
414    for (auto const& deviceNamePair : mCameraDeviceNames) {
415        if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
416            deviceNameList.push_back(deviceNamePair.second);
417        }
418    }
419    hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
420    _hidl_cb(Status::OK, hidlDeviceNameList);
421    return Void();
422}
423
424Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
425    bool support = mModule->isSetTorchModeSupported();
426    _hidl_cb (Status::OK, support);
427    return Void();
428}
429
430Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
431        const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
432    std::string cameraId, deviceVersion;
433    bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
434    if (!match) {
435        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
436        return Void();
437    }
438
439    std::string deviceName(cameraDeviceName.c_str());
440    ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
441    if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
442        Status status = Status::OK;
443        ssize_t idx = mCameraIds.indexOf(cameraId);
444        if (idx == NAME_NOT_FOUND) {
445            ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
446            status = Status::ILLEGAL_ARGUMENT;
447        } else { // invalid version
448            ALOGE("%s: camera device %s does not support version %s!",
449                    __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
450            status = Status::OPERATION_NOT_SUPPORTED;
451        }
452        _hidl_cb(status, nullptr);
453        return Void();
454    }
455
456    if (mCameraStatusMap.count(cameraId) == 0 ||
457            mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
458        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
459        return Void();
460    }
461
462    sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
463            new android::hardware::camera::device::V1_0::implementation::CameraDevice(
464                    mModule, cameraId, mCameraDeviceNames);
465
466    if (device == nullptr) {
467        ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
468        _hidl_cb(Status::INTERNAL_ERROR, nullptr);
469        return Void();
470    }
471
472    if (device->isInitFailed()) {
473        ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
474        device = nullptr;
475        _hidl_cb(Status::INTERNAL_ERROR, nullptr);
476        return Void();
477    }
478
479    _hidl_cb (Status::OK, device);
480    return Void();
481}
482
483Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
484        const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
485    std::string cameraId, deviceVersion;
486    bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
487    if (!match) {
488        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
489        return Void();
490    }
491
492    std::string deviceName(cameraDeviceName.c_str());
493    ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
494    if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
495        Status status = Status::OK;
496        ssize_t idx = mCameraIds.indexOf(cameraId);
497        if (idx == NAME_NOT_FOUND) {
498            ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
499            status = Status::ILLEGAL_ARGUMENT;
500        } else { // invalid version
501            ALOGE("%s: camera device %s does not support version %s!",
502                    __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
503            status = Status::OPERATION_NOT_SUPPORTED;
504        }
505        _hidl_cb(status, nullptr);
506        return Void();
507    }
508
509    if (mCameraStatusMap.count(cameraId) == 0 ||
510            mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
511        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
512        return Void();
513    }
514
515    sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
516    if (deviceVersion == kHAL3_4) {
517        ALOGV("Constructing v3.4 camera device");
518        sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
519            new android::hardware::camera::device::V3_4::implementation::CameraDevice(
520                    mModule, cameraId, mCameraDeviceNames);
521        if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
522            ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
523            device = nullptr;
524            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
525            return Void();
526        }
527
528        device = deviceImpl;
529        _hidl_cb (Status::OK, device);
530        return Void();
531    }
532
533    // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
534    // to the newest possible Treble HAL revision, but allow for override if needed via
535    // system property.
536    switch (mPreferredHal3MinorVersion) {
537        case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
538            ALOGV("Constructing v3.2 camera device");
539            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
540                    new android::hardware::camera::device::V3_2::implementation::CameraDevice(
541                    mModule, cameraId, mCameraDeviceNames);
542            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
543                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
544                device = nullptr;
545                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
546                return Void();
547            }
548            device = deviceImpl;
549            break;
550        }
551        case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
552            ALOGV("Constructing v3.3 camera device");
553            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
554                    new android::hardware::camera::device::V3_3::implementation::CameraDevice(
555                    mModule, cameraId, mCameraDeviceNames);
556            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
557                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
558                device = nullptr;
559                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
560                return Void();
561            }
562            device = deviceImpl;
563            break;
564        }
565        default:
566            ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
567            device = nullptr;
568            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
569            return Void();
570    }
571    _hidl_cb (Status::OK, device);
572    return Void();
573}
574
575ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
576    if (strcmp(name, kLegacyProviderName) == 0) {
577        CameraProvider* provider = new CameraProvider();
578        if (provider == nullptr) {
579            ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
580            return nullptr;
581        }
582        if (provider->isInitFailed()) {
583            ALOGE("%s: camera provider init failed!", __FUNCTION__);
584            delete provider;
585            return nullptr;
586        }
587        return provider;
588    } else if (strcmp(name, kExternalProviderName) == 0) {
589        ExternalCameraProvider* provider = new ExternalCameraProvider();
590        return provider;
591    }
592    ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
593    return nullptr;
594}
595
596} // namespace implementation
597}  // namespace V2_4
598}  // namespace provider
599}  // namespace camera
600}  // namespace hardware
601}  // namespace android
602