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 #include <common/all-versions/IncludeGuard.h>
18 
19 #include <string.h>
20 
21 #include <android/log.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace audio {
26 namespace AUDIO_HAL_VERSION {
27 namespace implementation {
28 
29 #ifdef AUDIO_HAL_VERSION_2_0
openDevice(IDevicesFactory::Device device,openDevice_cb _hidl_cb)30 Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
31     switch (device) {
32         case IDevicesFactory::Device::PRIMARY:
33             return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
34         case IDevicesFactory::Device::A2DP:
35             return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb);
36         case IDevicesFactory::Device::USB:
37             return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb);
38         case IDevicesFactory::Device::R_SUBMIX:
39             return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb);
40         case IDevicesFactory::Device::STUB:
41             return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb);
42     }
43     _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
44     return Void();
45 }
46 #endif
47 #ifdef AUDIO_HAL_VERSION_4_0
openDevice(const hidl_string & moduleName,openDevice_cb _hidl_cb)48 Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
49     if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
50         return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb);
51     }
52     return openDevice(moduleName.c_str(), _hidl_cb);
53 }
openPrimaryDevice(openPrimaryDevice_cb _hidl_cb)54 Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
55     return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
56 }
57 #endif
58 
openDevice(const char * moduleName,openDevice_cb _hidl_cb)59 Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
60     return openDevice<implementation::Device>(moduleName, _hidl_cb);
61 }
62 
63 template <class DeviceShim, class Callback>
openDevice(const char * moduleName,Callback _hidl_cb)64 Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
65     audio_hw_device_t* halDevice;
66     Result retval(Result::INVALID_ARGUMENTS);
67     sp<DeviceShim> result;
68     int halStatus = loadAudioInterface(moduleName, &halDevice);
69     if (halStatus == OK) {
70         result = new DeviceShim(halDevice);
71         retval = Result::OK;
72     } else if (halStatus == -EINVAL) {
73         retval = Result::NOT_INITIALIZED;
74     }
75     _hidl_cb(retval, result);
76     return Void();
77 }
78 
79 // static
loadAudioInterface(const char * if_name,audio_hw_device_t ** dev)80 int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) {
81     const hw_module_t* mod;
82     int rc;
83 
84     rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
85     if (rc) {
86         ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
87               if_name, strerror(-rc));
88         goto out;
89     }
90     rc = audio_hw_device_open(mod, dev);
91     if (rc) {
92         ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID,
93               if_name, strerror(-rc));
94         goto out;
95     }
96     if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
97         ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
98         rc = -EINVAL;
99         audio_hw_device_close(*dev);
100         goto out;
101     }
102     return OK;
103 
104 out:
105     *dev = NULL;
106     return rc;
107 }
108 
HIDL_FETCH_IDevicesFactory(const char *)109 IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* /* name */) {
110     return new DevicesFactory();
111 }
112 
113 }  // namespace implementation
114 }  // namespace AUDIO_HAL_VERSION
115 }  // namespace audio
116 }  // namespace hardware
117 }  // namespace android
118