Home | History | Annotate | Download | only in audio_extn
      1 /*
      2  * Copyright (C) 2014 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 "ext_speaker"
     18 /*#define LOG_NDEBUG 0*/
     19 #include <log/log.h>
     20 
     21 #include <stdlib.h>
     22 #include <audio_hw.h>
     23 #include <dlfcn.h>
     24 
     25 #ifdef __LP64__
     26 #define LIB_SPEAKER_BUNDLE "/vendor/lib64/soundfx/libspeakerbundle.so"
     27 #else
     28 #define LIB_SPEAKER_BUNDLE "/vendor/lib/soundfx/libspeakerbundle.so"
     29 #endif
     30 
     31 typedef void (*set_mode_t)(int);
     32 typedef void (*set_speaker_on_t)(bool);
     33 typedef void (*set_earpiece_on_t)(bool);
     34 typedef void (*set_voice_vol_t)(float);
     35 
     36 struct speaker_data {
     37     struct audio_device *adev;
     38     void *speaker_bundle;
     39     set_mode_t set_mode;
     40     set_speaker_on_t set_speaker_on;
     41     set_earpiece_on_t set_earpiece_on;
     42     set_voice_vol_t set_voice_vol;
     43 };
     44 
     45 static struct speaker_data* open_speaker_bundle()
     46 {
     47     struct speaker_data *sd = calloc(1, sizeof(struct speaker_data));
     48 
     49     sd->speaker_bundle = dlopen(LIB_SPEAKER_BUNDLE, RTLD_NOW);
     50     if (sd->speaker_bundle == NULL) {
     51         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_SPEAKER_BUNDLE);
     52         goto error;
     53     } else {
     54         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_SPEAKER_BUNDLE);
     55 
     56         sd->set_mode = (set_mode_t)dlsym(sd->speaker_bundle,
     57                                              "set_mode");
     58         if (sd->set_mode == NULL) {
     59             ALOGE("%s: dlsym error %s for set_mode", __func__,
     60                   dlerror());
     61             goto error;
     62         }
     63         sd->set_speaker_on = (set_speaker_on_t)dlsym(sd->speaker_bundle,
     64                                              "set_speaker_on");
     65         if (sd->set_speaker_on == NULL) {
     66             ALOGE("%s: dlsym error %s for set_speaker_on", __func__,
     67                   dlerror());
     68             goto error;
     69         }
     70         sd->set_earpiece_on = (set_earpiece_on_t)dlsym(sd->speaker_bundle,
     71                                              "set_earpiece_on");
     72         if (sd->set_earpiece_on == NULL) {
     73             ALOGE("%s: dlsym error %s for set_earpiece_on", __func__,
     74                   dlerror());
     75             goto error;
     76         }
     77         sd->set_voice_vol = (set_voice_vol_t)dlsym(sd->speaker_bundle,
     78                                              "set_voice_volume");
     79         if (sd->set_voice_vol == NULL) {
     80             ALOGE("%s: dlsym error %s for set_voice_volume",
     81                   __func__, dlerror());
     82             goto error;
     83         }
     84     }
     85     return sd;
     86 
     87 error:
     88     free(sd);
     89     return 0;
     90 }
     91 
     92 static void close_speaker_bundle(struct speaker_data *sd)
     93 {
     94     if (sd != NULL) {
     95         dlclose(sd->speaker_bundle);
     96         free(sd);
     97         sd = NULL;
     98     }
     99 }
    100 
    101 void *audio_extn_extspk_init(struct audio_device *adev)
    102 {
    103     struct speaker_data *data = open_speaker_bundle();
    104 
    105     if (data)
    106         data->adev = adev;
    107 
    108     return data;
    109 }
    110 
    111 void audio_extn_extspk_deinit(void *extn)
    112 {
    113     struct speaker_data *data = (struct speaker_data*)extn;
    114     close_speaker_bundle(data);
    115 }
    116 
    117 void audio_extn_extspk_update(void* extn)
    118 {
    119     struct speaker_data *data = (struct speaker_data*)extn;
    120 
    121     if (data) {
    122         bool speaker_on = false;
    123         bool earpiece_on = false;
    124         struct listnode *node;
    125         struct audio_usecase *usecase;
    126         list_for_each(node, &data->adev->usecase_list) {
    127             usecase = node_to_item(node, struct audio_usecase, list);
    128             if (usecase->devices & AUDIO_DEVICE_OUT_EARPIECE) {
    129                 if(data->adev->snd_dev_ref_cnt[usecase->out_snd_device] != 0) {
    130                     earpiece_on = true;
    131                 }
    132             }
    133             if (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) {
    134                 if(data->adev->snd_dev_ref_cnt[usecase->out_snd_device] != 0) {
    135                     speaker_on = true;
    136                 }
    137             }
    138         }
    139         data->set_earpiece_on(earpiece_on);
    140         data->set_speaker_on(speaker_on);
    141     }
    142 }
    143 
    144 void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode)
    145 {
    146     struct speaker_data *data = (struct speaker_data*)extn;
    147 
    148     if (data)
    149         data->set_mode(mode);
    150 }
    151 
    152 void audio_extn_extspk_set_voice_vol(void* extn, float vol)
    153 {
    154     struct speaker_data *data = (struct speaker_data*)extn;
    155 
    156     if (data)
    157         data->set_voice_vol(vol);
    158 }
    159