blob: bff59945893bb254d1b47df2b0f2ad506b18699f [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"
19#include "utils/Log.h"
20
21#include <stdio.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <math.h>
25
26#include "jni.h"
27#include "JNIHelp.h"
28#include "android_runtime/AndroidRuntime.h"
29
30#include <media/AudioSystem.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Dima Zavin34bb4192011-05-11 14:15:23 -070032#include <system/audio.h>
Dima Zavin290029d2011-06-13 18:16:26 -070033#include <system/audio_policy.h>
Dima Zavin24fc2fb2011-04-19 22:30:36 -070034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035// ----------------------------------------------------------------------------
36
37using namespace android;
38
Glenn Kastened0079d2011-04-04 10:50:50 -070039static const char* const kClassPathName = "android/media/AudioSystem";
40
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041enum AudioError {
42 kAudioStatusOk = 0,
43 kAudioStatusError = 1,
44 kAudioStatusMediaServerDied = 100
45};
46
47static int check_AudioSystem_Command(status_t status)
48{
49 if (status == NO_ERROR) {
50 return kAudioStatusOk;
51 } else {
52 return kAudioStatusError;
53 }
54}
55
56static int
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
58{
59 return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
60}
61
62static jboolean
63android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
64{
65 bool state = false;
66 AudioSystem::isMicrophoneMuted(&state);
67 return state;
68}
69
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -080071android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072{
73 bool state = false;
Glenn Kastenbc1d77b2012-01-12 16:38:12 -080074 AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 return state;
76}
77
Eric Laurenta553c252009-07-17 12:17:14 -070078static int
79android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080{
Eric Laurenta553c252009-07-17 12:17:14 -070081 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
82 String8 c_keyValuePairs8;
83 if (keyValuePairs) {
84 c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
85 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
86 }
87 int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
88 return status;
89}
90
91static jstring
92android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
93{
94 const jchar* c_keys = env->GetStringCritical(keys, 0);
95 String8 c_keys8;
96 if (keys) {
97 c_keys8 = String8(c_keys, env->GetStringLength(keys));
98 env->ReleaseStringCritical(keys, c_keys);
99 }
100 return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101}
102
Glenn Kastened0079d2011-04-04 10:50:50 -0700103static void
104android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105{
106 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700107 if (env == NULL) {
108 return;
109 }
110
Glenn Kastened0079d2011-04-04 10:50:50 -0700111 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
113 int error;
114
115 switch (err) {
116 case DEAD_OBJECT:
117 error = kAudioStatusMediaServerDied;
118 break;
119 case NO_ERROR:
120 error = kAudioStatusOk;
121 break;
122 default:
123 error = kAudioStatusError;
124 break;
125 }
126
127 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
128}
129
Eric Laurenta553c252009-07-17 12:17:14 -0700130static int
131android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
132{
133 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700134 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
135 static_cast <audio_policy_dev_state_t>(state),
Eric Laurenta553c252009-07-17 12:17:14 -0700136 c_address));
137 env->ReleaseStringUTFChars(device_address, c_address);
138 return status;
139}
140
141static int
142android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
143{
144 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700145 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700146 c_address));
147 env->ReleaseStringUTFChars(device_address, c_address);
148 return state;
149}
150
151static int
152android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
153{
Glenn Kastenaccb1142012-01-04 11:00:47 -0800154 return check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
Eric Laurenta553c252009-07-17 12:17:14 -0700155}
156
157static int
Eric Laurenta553c252009-07-17 12:17:14 -0700158android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
159{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700160 return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
161 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700162}
163
164static int
165android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
166{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700167 return static_cast <int>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700168}
169
170static int
171android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
172{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700173 return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700174 indexMin,
175 indexMax));
176}
177
178static int
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800179android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
180 jobject thiz,
181 jint stream,
182 jint index,
183 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700184{
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800185 return check_AudioSystem_Command(
186 AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
187 index,
188 (audio_devices_t)device));
Eric Laurenta553c252009-07-17 12:17:14 -0700189}
190
191static int
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800192android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
193 jobject thiz,
194 jint stream,
195 jint device)
Eric Laurenta553c252009-07-17 12:17:14 -0700196{
197 int index;
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800198 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
199 &index,
200 (audio_devices_t)device)
201 != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700202 index = -1;
203 }
204 return index;
205}
206
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400207static int
208android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
209{
210 return check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
211}
212
213static jfloat
214android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
215{
216 float value;
217 if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
218 value = -1.0;
219 }
220 return value;
221}
222
223static int
224android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
225{
226 return check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
227}
228
229static jfloat
230android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
231{
232 bool mute;
233 if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
234 mute = false;
235 }
236 return mute;
237}
238
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800239static jint
240android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
241{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700242 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800243}
244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245// ----------------------------------------------------------------------------
246
247static JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -0700248 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
249 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
251 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Eric Laurent25101b02011-02-02 09:33:30 -0800252 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Eric Laurenta553c252009-07-17 12:17:14 -0700253 {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
254 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
255 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
Eric Laurenta553c252009-07-17 12:17:14 -0700256 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
257 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
258 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
Eric Laurent9bc8358d2011-11-18 16:43:31 -0800259 {"setStreamVolumeIndex","(III)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
260 {"getStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
Mike Lockwoodcbdb49d2011-10-20 12:54:05 -0400261 {"setMasterVolume", "(F)I", (void *)android_media_AudioSystem_setMasterVolume},
262 {"getMasterVolume", "()F", (void *)android_media_AudioSystem_getMasterVolume},
263 {"setMasterMute", "(Z)I", (void *)android_media_AudioSystem_setMasterMute},
264 {"getMasterMute", "()Z", (void *)android_media_AudioSystem_getMasterMute},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800265 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266};
267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268int register_android_media_AudioSystem(JNIEnv *env)
269{
270 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 return AndroidRuntime::registerNativeMethods(env,
Glenn Kastened0079d2011-04-04 10:50:50 -0700273 kClassPathName, gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274}