blob: 179e1200da1a7f9e2c59b41b7f6da006075b66f6 [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) {
92 ALOGE("Connect_RILD() failed");
93 return -1;
94 }
95
96 return 0;
97}
98
99int ril_open(struct ril_handle *ril)
100{
101 char property[PROPERTY_VALUE_MAX];
102
103 if (ril == NULL) {
104 return -1;
105 }
106
107 ril->client = OpenClient_RILD();
108 if (ril->client == NULL) {
109 ALOGE("OpenClient_RILD() failed");
110 return -1;
111 }
112
113 property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
114 ril->volume_steps_max = atoi(property);
115
116 /*
117 * This catches the case where VOLUME_STEPS_PROPERTY does not contain
118 * an integer
119 */
120 if (ril->volume_steps_max == 0) {
121 ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
122 }
123
124 return 0;
125}
126
127int ril_close(struct ril_handle *ril)
128{
129 int rc;
130
131 if (ril == NULL || ril->client == NULL) {
132 return -1;
133 }
134
135 rc = Disconnect_RILD(ril->client);
136 if (rc != RIL_CLIENT_ERR_SUCCESS) {
137 ALOGE("Disconnect_RILD failed");
138 return -1;
139 }
140
141 rc = CloseClient_RILD(ril->client);
142 if (rc != RIL_CLIENT_ERR_SUCCESS) {
143 ALOGE("CloseClient_RILD() failed");
144 return -1;
145 }
146 ril->client = NULL;
147
148 return 0;
149}
150
151int ril_set_wb_amr_callback(struct ril_handle *ril,
152 ril_wb_amr_callback fn,
153 void *data)
154{
155 int rc;
156
157 if (fn == NULL || data == NULL) {
158 return -1;
159 }
160
161 _wb_amr_callback = fn;
162 _wb_amr_data = data;
163
164 ALOGV("%s: RegisterUnsolicitedHandler(%d, %p)",
165 __func__,
166 RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
167 ril_set_wb_amr_callback);
168
169 /* register the wideband AMR callback */
170 rc = RegisterUnsolicitedHandler(ril->client,
171 RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
172 (RilOnUnsolicited)ril_internal_wb_amr_callback);
173 if (rc != RIL_CLIENT_ERR_SUCCESS) {
174 ALOGE("%s: Failed to register WB_AMR callback", __func__);
175 ril_close(ril);
176 return -1;
177 }
178
179 return 0;
180}
181
182int ril_set_call_volume(struct ril_handle *ril,
183 enum _SoundType sound_type,
184 float volume)
185{
186 int rc;
187
188 rc = ril_connect_if_required(ril);
189 if (rc != 0) {
190 return 0;
191 }
192
193 rc = SetCallVolume(ril->client,
194 sound_type,
195 (int)(volume * ril->volume_steps_max));
196
197 return rc;
198}
199
200int ril_set_call_audio_path(struct ril_handle *ril, enum _AudioPath path)
201{
202 int rc;
203
204 rc = ril_connect_if_required(ril);
205 if (rc != 0) {
206 return 0;
207 }
208
209 rc = SetCallAudioPath(ril->client, path);
210
211 return rc;
212}
213
214int ril_set_call_clock_sync(struct ril_handle *ril,
215 enum _SoundClockCondition condition)
216{
217 int rc;
218
219 rc = ril_connect_if_required(ril);
220 if (rc != 0) {
221 return 0;
222 }
223
224 rc = SetCallClockSync(ril->client, condition);
225
226 return rc;
227}
228
229int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition)
230{
231 int rc;
232
233 rc = ril_connect_if_required(ril);
234 if (rc != 0) {
235 return 0;
236 }
237
238 rc = SetMute(ril->client, condition);
239
240 return rc;
241}
242
243int ril_set_two_mic_control(struct ril_handle *ril,
244 enum __TwoMicSolDevice device,
245 enum __TwoMicSolReport report)
246{
247 int rc;
248
249 rc = ril_connect_if_required(ril);
250 if (rc != 0) {
251 return 0;
252 }
253
254 rc = SetTwoMicControl(ril->client, device, report);
255
256 return rc;
257}