blob: e9c7e72cfad755221057abd4e776df218347a400 [file] [log] [blame]
Christopher N. Hessebc52af52017-02-10 21:20:30 +01001/*
2 * Copyright (C) 2013 The CyanogenMod Project
3 * Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_TAG "audio_hw_ril"
19/*#define LOG_NDEBUG 0*/
20
21#include <errno.h>
22#include <dlfcn.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <utils/Log.h>
27#include <cutils/properties.h>
28
29#include "ril_interface.h"
30
31#define VOLUME_STEPS_DEFAULT "5"
32#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
33
34/* Audio WB AMR callback */
35/*
36 * TODO:
37 * struct audio_device {
38 * HRilClient client;
39 * void *data
40 * }
41 * static struct audio_device _audio_devices[64];
42 *
43 * When registering a call back we should store it in the array and when
44 * the callback is triggered find the data pointer based on the client
45 * passed in.
46 */
47static ril_wb_amr_callback _wb_amr_callback;
48static void *_wb_amr_data = NULL;
49
50/* This is the callback function that the RIL uses to
51set the wideband AMR state */
52static int ril_internal_wb_amr_callback(HRilClient client __unused,
53 const void *data,
54 size_t datalen)
55{
56 int enable = 0;
57
58 if (_wb_amr_data == NULL || _wb_amr_callback == NULL) {
59 return -1;
60 }
61
62 if (datalen != 1) {
63 return -1;
64 }
65
66 if (*((int *)data) != 0) {
67 enable = 1;
68 }
69
70 _wb_amr_callback(_wb_amr_data, enable);
71
72 return 0;
73}
74
75static int ril_connect_if_required(struct ril_handle *ril)
76{
77 int ok;
78 int rc;
79
80 if (ril->client == NULL) {
81 ALOGE("ril->client is NULL");
82 return -1;
83 }
84
85 ok = isConnected_RILD(ril->client);
86 if (ok) {
87 return 0;
88 }
89
90 rc = Connect_RILD(ril->client);
91 if (rc != RIL_CLIENT_ERR_SUCCESS) {
Andreas Schneider9c195612017-02-08 19:27:46 +010092 ALOGE("FATAL: Failed to connect to RILD: %s",
93 strerror(errno));
Christopher N. Hessebc52af52017-02-10 21:20:30 +010094 return -1;
95 }
96
97 return 0;
98}
99
100int ril_open(struct ril_handle *ril)
101{
102 char property[PROPERTY_VALUE_MAX];
103
104 if (ril == NULL) {
105 return -1;
106 }
107
108 ril->client = OpenClient_RILD();
109 if (ril->client == NULL) {
110 ALOGE("OpenClient_RILD() failed");
111 return -1;
112 }
113
114 property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
115 ril->volume_steps_max = atoi(property);
116
117 /*
118 * This catches the case where VOLUME_STEPS_PROPERTY does not contain
119 * an integer
120 */
121 if (ril->volume_steps_max == 0) {
122 ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
123 }
124
125 return 0;
126}
127
128int ril_close(struct ril_handle *ril)
129{
130 int rc;
131
132 if (ril == NULL || ril->client == NULL) {
133 return -1;
134 }
135
136 rc = Disconnect_RILD(ril->client);
137 if (rc != RIL_CLIENT_ERR_SUCCESS) {
138 ALOGE("Disconnect_RILD failed");
139 return -1;
140 }
141
142 rc = CloseClient_RILD(ril->client);
143 if (rc != RIL_CLIENT_ERR_SUCCESS) {
144 ALOGE("CloseClient_RILD() failed");
145 return -1;
146 }
147 ril->client = NULL;
148
149 return 0;
150}
151
152int ril_set_wb_amr_callback(struct ril_handle *ril,
153 ril_wb_amr_callback fn,
154 void *data)
155{
156 int rc;
157
158 if (fn == NULL || data == NULL) {
159 return -1;
160 }
161
162 _wb_amr_callback = fn;
163 _wb_amr_data = data;
164
165 ALOGV("%s: RegisterUnsolicitedHandler(%d, %p)",
166 __func__,
167 RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
168 ril_set_wb_amr_callback);
169
170 /* register the wideband AMR callback */
171 rc = RegisterUnsolicitedHandler(ril->client,
172 RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
173 (RilOnUnsolicited)ril_internal_wb_amr_callback);
174 if (rc != RIL_CLIENT_ERR_SUCCESS) {
175 ALOGE("%s: Failed to register WB_AMR callback", __func__);
176 ril_close(ril);
177 return -1;
178 }
179
180 return 0;
181}
182
183int ril_set_call_volume(struct ril_handle *ril,
184 enum _SoundType sound_type,
185 float volume)
186{
187 int rc;
188
189 rc = ril_connect_if_required(ril);
190 if (rc != 0) {
191 return 0;
192 }
193
194 rc = SetCallVolume(ril->client,
195 sound_type,
196 (int)(volume * ril->volume_steps_max));
197
198 return rc;
199}
200
201int ril_set_call_audio_path(struct ril_handle *ril, enum _AudioPath path)
202{
203 int rc;
204
205 rc = ril_connect_if_required(ril);
206 if (rc != 0) {
207 return 0;
208 }
209
210 rc = SetCallAudioPath(ril->client, path);
211
212 return rc;
213}
214
215int ril_set_call_clock_sync(struct ril_handle *ril,
216 enum _SoundClockCondition condition)
217{
218 int rc;
219
220 rc = ril_connect_if_required(ril);
221 if (rc != 0) {
222 return 0;
223 }
224
225 rc = SetCallClockSync(ril->client, condition);
226
227 return rc;
228}
229
230int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition)
231{
232 int rc;
233
234 rc = ril_connect_if_required(ril);
235 if (rc != 0) {
236 return 0;
237 }
238
239 rc = SetMute(ril->client, condition);
240
241 return rc;
242}
243
244int ril_set_two_mic_control(struct ril_handle *ril,
245 enum __TwoMicSolDevice device,
246 enum __TwoMicSolReport report)
247{
248 int rc;
249
250 rc = ril_connect_if_required(ril);
251 if (rc != 0) {
252 return 0;
253 }
254
255 rc = SetTwoMicControl(ril->client, device, report);
256
257 return rc;
258}