blob: 42feab4e3a4999829a0f32c54ad606e57950a46f [file] [log] [blame]
Glenn Kastenb3db2132012-01-19 08:59:58 -08001/*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002**
3** Copyright 2006, The Android Open Source Project
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 "AudioSystem"
Glenn Kastenc81d31c2012-03-13 14:46:23 -070019#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
Glenn Kastenc81d31c2012-03-13 14:46:23 -070021#include <jni.h>
22#include <JNIHelp.h>
23#include <android_runtime/AndroidRuntime.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25#include <media/AudioSystem.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026
Dima Zavin34bb4192011-05-11 14:15:23 -070027#include <system/audio.h>
Dima Zavin290029d2011-06-13 18:16:26 -070028#include <system/audio_policy.h>
Dima Zavin24fc2fb2011-04-19 22:30:36 -070029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030// ----------------------------------------------------------------------------
31
32using namespace android;
33
Glenn Kastened0079d2011-04-04 10:50:50 -070034static const char* const kClassPathName = "android/media/AudioSystem";
35
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036enum AudioError {
37 kAudioStatusOk = 0,
38 kAudioStatusError = 1,
39 kAudioStatusMediaServerDied = 100
40};
41
42static int check_AudioSystem_Command(status_t status)
43{
Eric Laurentdfb881f2013-07-18 14:41:39 -070044 switch (status) {
45 case DEAD_OBJECT:
46 return kAudioStatusMediaServerDied;
47 case NO_ERROR:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 return kAudioStatusOk;
Eric Laurentdfb881f2013-07-18 14:41:39 -070049 default:
50 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 }
Eric Laurentdfb881f2013-07-18 14:41:39 -070052 return kAudioStatusError;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053}
54
Ashok Bhat075e9a12014-01-06 13:45:09 +000055static jint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
57{
Ashok Bhat075e9a12014-01-06 13:45:09 +000058 return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059}
60
61static jboolean
62android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
63{
64 bool state = false;
65 AudioSystem::isMicrophoneMuted(&state);
66 return state;
67}
68
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -080070android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071{
72 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -080073 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 return state;
75}
76
Jean-Michel Trivid6770542012-10-10 12:03:41 -070077static jboolean
Jean-Michel Trivi679d5042013-02-04 16:24:09 -080078android_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
79 jint inPastMs)
80{
81 bool state = false;
82 AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
83 return state;
84}
85
86static jboolean
Jean-Michel Trivid6770542012-10-10 12:03:41 -070087android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
88{
89 bool state = false;
90 AudioSystem::isSourceActive((audio_source_t) source, &state);
91 return state;
92}
93
Ashok Bhat075e9a12014-01-06 13:45:09 +000094static jint
Eric Laurenta553c252009-07-17 12:17:14 -070095android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096{
Eric Laurenta553c252009-07-17 12:17:14 -070097 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
98 String8 c_keyValuePairs8;
99 if (keyValuePairs) {
100 c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
101 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
102 }
103 int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
Ashok Bhat075e9a12014-01-06 13:45:09 +0000104 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700105}
106
107static jstring
108android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
109{
110 const jchar* c_keys = env->GetStringCritical(keys, 0);
111 String8 c_keys8;
112 if (keys) {
113 c_keys8 = String8(c_keys, env->GetStringLength(keys));
114 env->ReleaseStringCritical(keys, c_keys);
115 }
116 return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117}
118
Glenn Kastened0079d2011-04-04 10:50:50 -0700119static void
120android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121{
Eric Laurent539719a2013-07-18 14:08:00 -0700122 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700123 if (env == NULL) {
124 return;
125 }
126
Glenn Kastened0079d2011-04-04 10:50:50 -0700127 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
Eric Laurentdfb881f2013-07-18 14:41:39 -0700129 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
130 "errorCallbackFromNative","(I)V"),
131 check_AudioSystem_Command(err));
Viorel Sumanb637ccf2014-05-30 16:51:07 +0300132
133 env->DeleteLocalRef(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134}
135
Ashok Bhat075e9a12014-01-06 13:45:09 +0000136static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700137android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
138{
139 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700140 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
141 static_cast <audio_policy_dev_state_t>(state),
Eric Laurenta553c252009-07-17 12:17:14 -0700142 c_address));
143 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000144 return (jint) status;
Eric Laurenta553c252009-07-17 12:17:14 -0700145}
146
Ashok Bhat075e9a12014-01-06 13:45:09 +0000147static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700148android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
149{
150 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700151 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700152 c_address));
153 env->ReleaseStringUTFChars(device_address, c_address);
Ashok Bhat075e9a12014-01-06 13:45:09 +0000154 return (jint) state;
Eric Laurenta553c252009-07-17 12:17:14 -0700155}
156
Ashok Bhat075e9a12014-01-06 13:45:09 +0000157static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700158android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
159{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000160 return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700161}
162
Ashok Bhat075e9a12014-01-06 13:45:09 +0000163static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700164android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
165{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000166 return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700167 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700168}
169
Ashok Bhat075e9a12014-01-06 13:45:09 +0000170static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700171android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
172{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000173 return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700174}
175
Ashok Bhat075e9a12014-01-06 13:45:09 +0000176static jint
Eric Laurenta553c252009-07-17 12:17:14 -0700177android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
178{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000179 return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700180 indexMin,
181 indexMax));
182}
183
Ashok Bhat075e9a12014-01-06 13:45:09 +0000184static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800185android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
186 jobject thiz,
187 jint stream,
188 jint index,
189 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700190{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000191 return (jint) check_AudioSystem_Command(
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800192 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
193 index,
194 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700195}
196
Ashok Bhat075e9a12014-01-06 13:45:09 +0000197static jint
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800198android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
199 jobject thiz,
200 jint stream,
201 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700202{
203 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800204 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
205 &index,
206 (audio_devices_t)device)
207 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700208 index = -1;
209 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000210 return (jint) index;
Eric Laurenta553c252009-07-17 12:17:14 -0700211}
212
Ashok Bhat075e9a12014-01-06 13:45:09 +0000213static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400214android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
215{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000216 return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400217}
218
219static jfloat
220android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
221{
222 float value;
223 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
224 value = -1.0;
225 }
226 return value;
227}
228
Ashok Bhat075e9a12014-01-06 13:45:09 +0000229static jint
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400230android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
231{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000232 return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400233}
234
235static jfloat
236android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
237{
238 bool mute;
239 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
240 mute = false;
241 }
242 return mute;
243}
244
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800245static jint
246android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
247{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700248 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800249}
250
Glenn Kastenc6c43652012-09-24 17:32:30 -0700251static jint
252android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
253{
254 return (jint) AudioSystem::getPrimaryOutputSamplingRate();
255}
256
257static jint
258android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
259{
260 return (jint) AudioSystem::getPrimaryOutputFrameCount();
261}
262
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100263static jint
264android_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
265{
266 uint32_t afLatency;
267 if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
268 != NO_ERROR) {
269 afLatency = -1;
270 }
271 return (jint) afLatency;
272}
273
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700274static jint
275android_media_AudioSystem_setLowRamDevice(JNIEnv *env, jobject clazz, jboolean isLowRamDevice)
276{
277 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice);
278}
279
Ashok Bhat075e9a12014-01-06 13:45:09 +0000280static jint
Eric Laurentdfb881f2013-07-18 14:41:39 -0700281android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
282{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000283 return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
Eric Laurentdfb881f2013-07-18 14:41:39 -0700284}
285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286// ----------------------------------------------------------------------------
287
288static JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -0700289 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
290 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
292 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700293 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Jean-Michel Trivi679d5042013-02-04 16:24:09 -0800294 {"isStreamActiveRemotely","(II)Z", (void *)android_media_AudioSystem_isStreamActiveRemotely},
Jean-Michel Trivid6770542012-10-10 12:03:41 -0700295 {"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
Eric Laurenta553c252009-07-17 12:17:14 -0700296 {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
297 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
298 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -0700299 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
300 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
301 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800302 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
303 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400304 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
305 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
306 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
307 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800308 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
Glenn Kastenc6c43652012-09-24 17:32:30 -0700309 {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
310 {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
Oliver Woodman61dcdf32013-06-26 12:43:36 +0100311 {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency},
Glenn Kastenfd116ad2013-07-12 17:10:39 -0700312 {"setLowRamDevice", "(Z)I", (void *)android_media_AudioSystem_setLowRamDevice},
Eric Laurentdfb881f2013-07-18 14:41:39 -0700313 {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314};
315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316int register_android_media_AudioSystem(JNIEnv *env)
317{
318 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 return AndroidRuntime::registerNativeMethods(env,
Glenn Kastened0079d2011-04-04 10:50:50 -0700321 kClassPathName, gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322}