• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "audio_hw_primary"
18 /*#define LOG_NDEBUG 0*/
19 
20 #include <dlfcn.h>
21 #include <stdlib.h>
22 
23 #include <utils/Log.h>
24 #include <cutils/properties.h>
25 
26 #include "ril_interface.h"
27 
28 #define VOLUME_STEPS_DEFAULT  "5"
29 #define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
30 
31 /* Function pointers */
32 void *(*_ril_open_client)(void);
33 int (*_ril_close_client)(void *);
34 int (*_ril_connect)(void *);
35 int (*_ril_is_connected)(void *);
36 int (*_ril_disconnect)(void *);
37 int (*_ril_set_call_volume)(void *, enum ril_sound_type, int);
38 int (*_ril_set_call_audio_path)(void *, enum ril_audio_path);
39 int (*_ril_register_unsolicited_handler)(void *, int, void *);
40 int (*_ril_get_wb_amr)(void *, void *);
41 
42 /* Audio WB AMR callback */
43 void (*_audio_set_wb_amr_callback)(void *, int);
44 void *callback_data = NULL;
45 
ril_register_set_wb_amr_callback(void * function,void * data)46 void ril_register_set_wb_amr_callback(void *function, void *data)
47 {
48     _audio_set_wb_amr_callback = function;
49     callback_data = data;
50 }
51 
52 /* This is the callback function that the RIL uses to
53 set the wideband AMR state */
ril_set_wb_amr_callback(void * ril_client,const void * data,size_t datalen)54 static int ril_set_wb_amr_callback(void *ril_client,
55                                    const void *data,
56                                    size_t datalen)
57 {
58     int enable = ((int *)data)[0];
59 
60     if (!callback_data || !_audio_set_wb_amr_callback)
61         return -1;
62 
63     _audio_set_wb_amr_callback(callback_data, enable);
64 
65     return 0;
66 }
67 
ril_connect_if_required(struct ril_handle * ril)68 static int ril_connect_if_required(struct ril_handle *ril)
69 {
70     if (_ril_is_connected(ril->client))
71         return 0;
72 
73     if (_ril_connect(ril->client) != RIL_CLIENT_ERR_SUCCESS) {
74         ALOGE("ril_connect() failed");
75         return -1;
76     }
77 
78     /* get wb amr status to set pcm samplerate depending on
79        wb amr status when ril is connected. */
80     if(_ril_get_wb_amr)
81         _ril_get_wb_amr(ril->client, ril_set_wb_amr_callback);
82 
83     return 0;
84 }
85 
ril_open(struct ril_handle * ril)86 int ril_open(struct ril_handle *ril)
87 {
88     char property[PROPERTY_VALUE_MAX];
89 
90     if (!ril)
91         return -1;
92 
93     ril->handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW);
94 
95     if (!ril->handle) {
96         ALOGE("Cannot open '%s'", RIL_CLIENT_LIBPATH);
97         return -1;
98     }
99 
100     _ril_open_client = dlsym(ril->handle, "OpenClient_RILD");
101     _ril_close_client = dlsym(ril->handle, "CloseClient_RILD");
102     _ril_connect = dlsym(ril->handle, "Connect_RILD");
103     _ril_is_connected = dlsym(ril->handle, "isConnected_RILD");
104     _ril_disconnect = dlsym(ril->handle, "Disconnect_RILD");
105     _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume");
106     _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath");
107     _ril_register_unsolicited_handler = dlsym(ril->handle,
108                                               "RegisterUnsolicitedHandler");
109     /* since this function is not supported in all RILs, don't require it */
110     _ril_get_wb_amr = dlsym(ril->handle, "GetWB_AMR");
111 
112     if (!_ril_open_client || !_ril_close_client || !_ril_connect ||
113         !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume ||
114         !_ril_set_call_audio_path || !_ril_register_unsolicited_handler) {
115         ALOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH);
116         dlclose(ril->handle);
117         return -1;
118     }
119 
120     ril->client = _ril_open_client();
121     if (!ril->client) {
122         ALOGE("ril_open_client() failed");
123         dlclose(ril->handle);
124         return -1;
125     }
126 
127     /* register the wideband AMR callback */
128     _ril_register_unsolicited_handler(ril->client, RIL_UNSOL_WB_AMR_STATE,
129                                       ril_set_wb_amr_callback);
130 
131     property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
132     ril->volume_steps_max = atoi(property);
133     /* this catches the case where VOLUME_STEPS_PROPERTY does not contain
134     an integer */
135     if (ril->volume_steps_max == 0)
136         ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
137 
138     return 0;
139 }
140 
ril_close(struct ril_handle * ril)141 int ril_close(struct ril_handle *ril)
142 {
143     if (!ril || !ril->handle || !ril->client)
144         return -1;
145 
146     if ((_ril_disconnect(ril->client) != RIL_CLIENT_ERR_SUCCESS) ||
147         (_ril_close_client(ril->client) != RIL_CLIENT_ERR_SUCCESS)) {
148         ALOGE("ril_disconnect() or ril_close_client() failed");
149         return -1;
150     }
151 
152     dlclose(ril->handle);
153     return 0;
154 }
155 
ril_set_call_volume(struct ril_handle * ril,enum ril_sound_type sound_type,float volume)156 int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type,
157                         float volume)
158 {
159     if (ril_connect_if_required(ril))
160         return 0;
161 
162     return _ril_set_call_volume(ril->client, sound_type,
163                                 (int)(volume * ril->volume_steps_max));
164 }
165 
ril_set_call_audio_path(struct ril_handle * ril,enum ril_audio_path path)166 int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path)
167 {
168     if (ril_connect_if_required(ril))
169         return 0;
170 
171     return _ril_set_call_audio_path(ril->client, path);
172 }
173