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