Home | History | Annotate | Download | only in default
      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 "DeviceHAL"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <algorithm>
     21 #include <memory.h>
     22 #include <string.h>
     23 
     24 #include <android/log.h>
     25 
     26 #include "Conversions.h"
     27 #include "Device.h"
     28 #include "HidlUtils.h"
     29 #include "StreamIn.h"
     30 #include "StreamOut.h"
     31 #include "Util.h"
     32 
     33 namespace android {
     34 namespace hardware {
     35 namespace audio {
     36 namespace V2_0 {
     37 namespace implementation {
     38 
     39 Device::Device(audio_hw_device_t* device)
     40         : mDevice(device) {
     41 }
     42 
     43 Device::~Device() {
     44     int status = audio_hw_device_close(mDevice);
     45     ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice,
     46              strerror(-status));
     47     mDevice = nullptr;
     48 }
     49 
     50 Result Device::analyzeStatus(const char* funcName, int status) {
     51     if (status != 0) {
     52         ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status));
     53     }
     54     switch (status) {
     55         case 0:
     56             return Result::OK;
     57         case -EINVAL:
     58             return Result::INVALID_ARGUMENTS;
     59         case -ENODATA:
     60             return Result::INVALID_STATE;
     61         case -ENODEV:
     62             return Result::NOT_INITIALIZED;
     63         case -ENOSYS:
     64             return Result::NOT_SUPPORTED;
     65         default:
     66             return Result::INVALID_STATE;
     67     }
     68 }
     69 
     70 void Device::closeInputStream(audio_stream_in_t* stream) {
     71     mDevice->close_input_stream(mDevice, stream);
     72 }
     73 
     74 void Device::closeOutputStream(audio_stream_out_t* stream) {
     75     mDevice->close_output_stream(mDevice, stream);
     76 }
     77 
     78 char* Device::halGetParameters(const char* keys) {
     79     return mDevice->get_parameters(mDevice, keys);
     80 }
     81 
     82 int Device::halSetParameters(const char* keysAndValues) {
     83     return mDevice->set_parameters(mDevice, keysAndValues);
     84 }
     85 
     86 // Methods from ::android::hardware::audio::V2_0::IDevice follow.
     87 Return<Result> Device::initCheck() {
     88     return analyzeStatus("init_check", mDevice->init_check(mDevice));
     89 }
     90 
     91 Return<Result> Device::setMasterVolume(float volume) {
     92     if (mDevice->set_master_volume == NULL) {
     93         return Result::NOT_SUPPORTED;
     94     }
     95     if (!isGainNormalized(volume)) {
     96         ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
     97         return Result::INVALID_ARGUMENTS;
     98     }
     99     return analyzeStatus("set_master_volume",
    100                          mDevice->set_master_volume(mDevice, volume));
    101 }
    102 
    103 Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
    104     Result retval(Result::NOT_SUPPORTED);
    105     float volume = 0;
    106     if (mDevice->get_master_volume != NULL) {
    107         retval = analyzeStatus("get_master_volume",
    108                                mDevice->get_master_volume(mDevice, &volume));
    109     }
    110     _hidl_cb(retval, volume);
    111     return Void();
    112 }
    113 
    114 Return<Result> Device::setMicMute(bool mute) {
    115     return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
    116 }
    117 
    118 Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
    119     bool mute = false;
    120     Result retval =
    121         analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
    122     _hidl_cb(retval, mute);
    123     return Void();
    124 }
    125 
    126 Return<Result> Device::setMasterMute(bool mute) {
    127     Result retval(Result::NOT_SUPPORTED);
    128     if (mDevice->set_master_mute != NULL) {
    129         retval = analyzeStatus("set_master_mute",
    130                                mDevice->set_master_mute(mDevice, mute));
    131     }
    132     return retval;
    133 }
    134 
    135 Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
    136     Result retval(Result::NOT_SUPPORTED);
    137     bool mute = false;
    138     if (mDevice->get_master_mute != NULL) {
    139         retval = analyzeStatus("get_master_mute",
    140                                mDevice->get_master_mute(mDevice, &mute));
    141     }
    142     _hidl_cb(retval, mute);
    143     return Void();
    144 }
    145 
    146 Return<void> Device::getInputBufferSize(const AudioConfig& config,
    147                                         getInputBufferSize_cb _hidl_cb) {
    148     audio_config_t halConfig;
    149     HidlUtils::audioConfigToHal(config, &halConfig);
    150     size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
    151     Result retval(Result::INVALID_ARGUMENTS);
    152     uint64_t bufferSize = 0;
    153     if (halBufferSize != 0) {
    154         retval = Result::OK;
    155         bufferSize = halBufferSize;
    156     }
    157     _hidl_cb(retval, bufferSize);
    158     return Void();
    159 }
    160 
    161 Return<void> Device::openOutputStream(int32_t ioHandle,
    162                                       const DeviceAddress& device,
    163                                       const AudioConfig& config,
    164                                       AudioOutputFlag flags,
    165                                       openOutputStream_cb _hidl_cb) {
    166     audio_config_t halConfig;
    167     HidlUtils::audioConfigToHal(config, &halConfig);
    168     audio_stream_out_t* halStream;
    169     ALOGV(
    170         "open_output_stream handle: %d devices: %x flags: %#x "
    171         "srate: %d format %#x channels %x address %s",
    172         ioHandle, static_cast<audio_devices_t>(device.device),
    173         static_cast<audio_output_flags_t>(flags), halConfig.sample_rate,
    174         halConfig.format, halConfig.channel_mask,
    175         deviceAddressToHal(device).c_str());
    176     int status = mDevice->open_output_stream(
    177         mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
    178         static_cast<audio_output_flags_t>(flags), &halConfig, &halStream,
    179         deviceAddressToHal(device).c_str());
    180     ALOGV("open_output_stream status %d stream %p", status, halStream);
    181     sp<IStreamOut> streamOut;
    182     if (status == OK) {
    183         streamOut = new StreamOut(this, halStream);
    184     }
    185     AudioConfig suggestedConfig;
    186     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
    187     _hidl_cb(analyzeStatus("open_output_stream", status), streamOut,
    188              suggestedConfig);
    189     return Void();
    190 }
    191 
    192 Return<void> Device::openInputStream(int32_t ioHandle,
    193                                      const DeviceAddress& device,
    194                                      const AudioConfig& config,
    195                                      AudioInputFlag flags, AudioSource source,
    196                                      openInputStream_cb _hidl_cb) {
    197     audio_config_t halConfig;
    198     HidlUtils::audioConfigToHal(config, &halConfig);
    199     audio_stream_in_t* halStream;
    200     ALOGV(
    201         "open_input_stream handle: %d devices: %x flags: %#x "
    202         "srate: %d format %#x channels %x address %s source %d",
    203         ioHandle, static_cast<audio_devices_t>(device.device),
    204         static_cast<audio_input_flags_t>(flags), halConfig.sample_rate,
    205         halConfig.format, halConfig.channel_mask,
    206         deviceAddressToHal(device).c_str(),
    207         static_cast<audio_source_t>(source));
    208     int status = mDevice->open_input_stream(
    209         mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
    210         &halConfig, &halStream, static_cast<audio_input_flags_t>(flags),
    211         deviceAddressToHal(device).c_str(),
    212         static_cast<audio_source_t>(source));
    213     ALOGV("open_input_stream status %d stream %p", status, halStream);
    214     sp<IStreamIn> streamIn;
    215     if (status == OK) {
    216         streamIn = new StreamIn(this, halStream);
    217     }
    218     AudioConfig suggestedConfig;
    219     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
    220     _hidl_cb(analyzeStatus("open_input_stream", status), streamIn,
    221              suggestedConfig);
    222     return Void();
    223 }
    224 
    225 Return<bool> Device::supportsAudioPatches() {
    226     return version() >= AUDIO_DEVICE_API_VERSION_3_0;
    227 }
    228 
    229 Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
    230                                       const hidl_vec<AudioPortConfig>& sinks,
    231                                       createAudioPatch_cb _hidl_cb) {
    232     Result retval(Result::NOT_SUPPORTED);
    233     AudioPatchHandle patch = 0;
    234     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
    235         std::unique_ptr<audio_port_config[]> halSources(
    236             HidlUtils::audioPortConfigsToHal(sources));
    237         std::unique_ptr<audio_port_config[]> halSinks(
    238             HidlUtils::audioPortConfigsToHal(sinks));
    239         audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
    240         retval = analyzeStatus(
    241             "create_audio_patch",
    242             mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0],
    243                                         sinks.size(), &halSinks[0], &halPatch));
    244         if (retval == Result::OK) {
    245             patch = static_cast<AudioPatchHandle>(halPatch);
    246         }
    247     }
    248     _hidl_cb(retval, patch);
    249     return Void();
    250 }
    251 
    252 Return<Result> Device::releaseAudioPatch(int32_t patch) {
    253     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
    254         return analyzeStatus(
    255             "release_audio_patch",
    256             mDevice->release_audio_patch(
    257                 mDevice, static_cast<audio_patch_handle_t>(patch)));
    258     }
    259     return Result::NOT_SUPPORTED;
    260 }
    261 
    262 Return<void> Device::getAudioPort(const AudioPort& port,
    263                                   getAudioPort_cb _hidl_cb) {
    264     audio_port halPort;
    265     HidlUtils::audioPortToHal(port, &halPort);
    266     Result retval = analyzeStatus("get_audio_port",
    267                                   mDevice->get_audio_port(mDevice, &halPort));
    268     AudioPort resultPort = port;
    269     if (retval == Result::OK) {
    270         HidlUtils::audioPortFromHal(halPort, &resultPort);
    271     }
    272     _hidl_cb(retval, resultPort);
    273     return Void();
    274 }
    275 
    276 Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
    277     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
    278         struct audio_port_config halPortConfig;
    279         HidlUtils::audioPortConfigToHal(config, &halPortConfig);
    280         return analyzeStatus(
    281             "set_audio_port_config",
    282             mDevice->set_audio_port_config(mDevice, &halPortConfig));
    283     }
    284     return Result::NOT_SUPPORTED;
    285 }
    286 
    287 Return<AudioHwSync> Device::getHwAvSync() {
    288     int halHwAvSync;
    289     Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
    290     return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
    291 }
    292 
    293 Return<Result> Device::setScreenState(bool turnedOn) {
    294     return setParam(AudioParameter::keyScreenState, turnedOn);
    295 }
    296 
    297 Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys,
    298                                    getParameters_cb _hidl_cb) {
    299     getParametersImpl(keys, _hidl_cb);
    300     return Void();
    301 }
    302 
    303 Return<Result> Device::setParameters(
    304     const hidl_vec<ParameterValue>& parameters) {
    305     return setParametersImpl(parameters);
    306 }
    307 
    308 Return<void> Device::debugDump(const hidl_handle& fd) {
    309     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
    310         analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
    311     }
    312     return Void();
    313 }
    314 
    315 }  // namespace implementation
    316 }  // namespace V2_0
    317 }  // namespace audio
    318 }  // namespace hardware
    319 }  // namespace android
    320