/* * Copyright (C) 2013 The CyanogenMod Project * Copyright (C) 2017 Andreas Schneider * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "audio_hw_ril" /*#define LOG_NDEBUG 0*/ #include #include #include #include #include #include #include "ril_interface.h" #define VOLUME_STEPS_DEFAULT "5" #define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps" /* Audio WB AMR callback */ /* * TODO: * struct audio_device { * HRilClient client; * void *data * } * static struct audio_device _audio_devices[64]; * * When registering a call back we should store it in the array and when * the callback is triggered find the data pointer based on the client * passed in. */ static ril_wb_amr_callback _wb_amr_callback; static void *_wb_amr_data = NULL; /* This is the callback function that the RIL uses to set the wideband AMR state */ static int ril_internal_wb_amr_callback(HRilClient client __unused, const void *data, size_t datalen) { int wb_amr_type = 0; if (_wb_amr_data == NULL || _wb_amr_callback == NULL) { return -1; } if (datalen != 1) { return -1; } wb_amr_type = *((int *)data); _wb_amr_callback(_wb_amr_data, wb_amr_type); return 0; } static int ril_connect_if_required(struct ril_handle *ril) { int ok; int rc; if (ril->client == NULL) { ALOGE("ril->client is NULL"); return -1; } ok = isConnected_RILD(ril->client); if (ok) { return 0; } rc = Connect_RILD(ril->client); if (rc != RIL_CLIENT_ERR_SUCCESS) { ALOGE("FATAL: Failed to connect to RILD: %s", strerror(errno)); return -1; } return 0; } int ril_open(struct ril_handle *ril) { char property[PROPERTY_VALUE_MAX]; if (ril == NULL) { return -1; } ril->client = OpenClient_RILD(); if (ril->client == NULL) { ALOGE("OpenClient_RILD() failed"); return -1; } property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT); ril->volume_steps_max = atoi(property); /* * This catches the case where VOLUME_STEPS_PROPERTY does not contain * an integer */ if (ril->volume_steps_max == 0) { ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT); } return 0; } int ril_close(struct ril_handle *ril) { int rc; if (ril == NULL || ril->client == NULL) { return -1; } rc = Disconnect_RILD(ril->client); if (rc != RIL_CLIENT_ERR_SUCCESS) { ALOGE("Disconnect_RILD failed"); return -1; } rc = CloseClient_RILD(ril->client); if (rc != RIL_CLIENT_ERR_SUCCESS) { ALOGE("CloseClient_RILD() failed"); return -1; } ril->client = NULL; return 0; } int ril_set_wb_amr_callback(struct ril_handle *ril, ril_wb_amr_callback fn, void *data) { int rc; if (fn == NULL || data == NULL) { return -1; } _wb_amr_callback = fn; _wb_amr_data = data; ALOGV("%s: RegisterUnsolicitedHandler(%d, %p)", __func__, RIL_UNSOL_SNDMGR_WB_AMR_REPORT, ril_set_wb_amr_callback); /* register the wideband AMR callback */ rc = RegisterUnsolicitedHandler(ril->client, RIL_UNSOL_SNDMGR_WB_AMR_REPORT, (RilOnUnsolicited)ril_internal_wb_amr_callback); if (rc != RIL_CLIENT_ERR_SUCCESS) { ALOGE("%s: Failed to register WB_AMR callback", __func__); ril_close(ril); return -1; } return 0; } int ril_set_call_volume(struct ril_handle *ril, enum _SoundType sound_type, float volume) { int rc; rc = ril_connect_if_required(ril); if (rc != 0) { ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc)); return 0; } rc = SetCallVolume(ril->client, sound_type, (int)(volume * ril->volume_steps_max)); if (rc != 0) { ALOGE("%s: SetCallVolume() failed, rc=%d", __func__, rc); } return rc; } int ril_set_call_audio_path(struct ril_handle *ril, enum _AudioPath path) { int rc; rc = ril_connect_if_required(ril); if (rc != 0) { ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc)); return 0; } rc = SetCallAudioPath(ril->client, path); if (rc != 0) { ALOGE("%s: SetCallAudioPath() failed, rc=%d", __func__, rc); } return rc; } int ril_set_call_clock_sync(struct ril_handle *ril, enum _SoundClockCondition condition) { int rc; rc = ril_connect_if_required(ril); if (rc != 0) { ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc)); return 0; } rc = SetCallClockSync(ril->client, condition); if (rc != 0) { ALOGE("%s: SetCallClockSync() failed, rc=%d", __func__, rc); } return rc; } int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition) { int rc; rc = ril_connect_if_required(ril); if (rc != 0) { ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc)); return 0; } rc = SetMute(ril->client, condition); if (rc != 0) { ALOGE("%s: SetMute() failed, rc=%d", __func__, rc); } return rc; } int ril_set_two_mic_control(struct ril_handle *ril, enum __TwoMicSolDevice device, enum __TwoMicSolReport report) { int rc; rc = ril_connect_if_required(ril); if (rc != 0) { ALOGE("%s: Failed to connect to RIL (%s)", __func__, strerror(rc)); return 0; } rc = SetTwoMicControl(ril->client, device, report); if (rc != 0) { ALOGE("%s: SetTwoMicControl() failed, rc=%d", __func__, rc); } return rc; }