I try to fix call recording in my app since lolipop update in my Galaxy S5. As a base I am using google sample project from here: Sample.
And this is the main part of
I found the solution to fix Galaxy S5 call recording.
Main thing is to call this:
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
in the loop when the call is started.
First get the desired function:
open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY);
set_parameters = (int (*)(int, void *)) dlsym(open_media,
"_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");
Next we need audio_io_handle_t
and String8&
object:
audio_io_handle_t
- is audio session id increased by 1, You can get it from AudioRecord.getAudioSessionId
String8&
this is more difficult:
//First inicialize function
create_string = (void (*)(void *, const char *)) dlsym(open_util,
"_ZN7android7String8C2EPKc");
//next call this function to convert string to required object
create_string(&str8, str);
When we have all needed parts we can call setParameters function:
//remember to call this in loop when recording is starting
set_parameters(id + 1, &str8);
That how variable declaration looks:
int (*set_parameters)(int, void *);
void (*create_string)(void *, const char *);
void *str8 = 0;
const char *str = "input_source=4";
@ChanchalShelar
@Peter @AkshatVajpayee
This is how my .cpp file looks:
void *open_media;
void *open_util;
int (*set_parameters)(int, void *);
void (*create_string)(void *, const char *);
void *str8 = 0;
const char *str = "input_source=4";
extern "C" {
JNIEXPORT bool JNICALL
Java_com_sample_NativeAudio_init(JNIEnv *env, jclass);
JNIEXPORT int JNICALL
Java_com_sample_NativeAudio_setParameters(JNIEnv *env, jclass, int id);
}
void get_string8() {
create_string = (void (*)(void *, const char *)) dlsym(open_util, "_ZN7android7String8C2EPKc");
if (!create_string) {
LOGD("There is no create_string function");
} else {
LOGD("create_string function OK");
}
create_string(&str8, str);
if (!str8) {
LOGD("Filed to create str8");
} else {
LOGD("create str8 success");
}
}
JNIEXPORT int JNICALL Java_com_sample_NativeAudio_setParameters(JNIEnv *env,
jclass type, int id) {
if (set_parameters) {
return set_parameters(id + 1, &str8);
}
return 0;
}
JNIEXPORT bool JNICALL Java_com_sample_NativeAudio_init(JNIEnv *env, jclass type) {
open_util = dlopen("/system/lib/libutils.so", RTLD_LAZY);
if (open_util) {
get_string8();
} else {
return false;
}
open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY);
if (open_media) {
set_parameters = (int (*)(int, void *)) dlsym(open_media,
"_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");
} else {
return false;
}
return true;
}
You need to use ndk. Here are examples of the functions that need to be done.
Load libmedia.so and libutils.so
int load(JNIEnv *env, jobject thiz) {
void *handleLibMedia;
void *handleLibUtils;
int result = -1;
lspr func = NULL;
pthread_t newthread = (pthread_t) thiz;
handleLibMedia = dlopen("libmedia.so", RTLD_NOW | RTLD_GLOBAL);
if (handleLibMedia != NULL) {
func = dlsym(handleLibMedia, "_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");
if (func != NULL) {
result = 0;
}
audioSetParameters = (lasp) func;
} else {
result = -1;
}
handleLibUtils = dlopen("libutils.so", RTLD_NOW | RTLD_GLOBAL);
if (handleLibUtils != NULL) {
fstr = dlsym(handleLibUtils, "_ZN7android7String8C2EPKc");
if (fstr == NULL) {
result = -1;
}
} else {
result = -1;
}
cmd = CM_D;
int resultTh = pthread_create(&newthread, NULL, taskAudioSetParam, NULL);
return result;}
Function setParameters
int setParam(jint i, jint as) {
pthread_mutex_lock(&mt);
audioSession = (int) (as + 1);
kvp = "input_source=4";
kvps = toString8(kvp);
cmd = (int) i;
pthread_cond_signal(&cnd);
pthread_mutex_unlock(&mt);
return 0;}
Task AudioSetParameters
void *taskAudioSetParam(void *threadid) {
while (1) {
pthread_mutex_lock(&mt);
if (cmd == CM_D) {
pthread_cond_wait(&cnd, &mt);
} else if (audioSetParameters != NULL) {
audioSetParameters(audioSession, kvps);
}
pthread_mutex_unlock(&mt);
}
}
There is a library and an example of use https://github.com/ViktorDegtyarev/CallRecLib