blob: 09c0953e1a4dfc18edadb55121270e76a871cc11 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_media_AudioSystem.cpp
2**
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>
31#include <media/AudioTrack.h>
32
Dima Zavin24fc2fb2011-04-19 22:30:36 -070033#include <hardware/audio.h>
34#include <hardware/audio_policy.h>
35
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036// ----------------------------------------------------------------------------
37
38using namespace android;
39
Glenn Kastened0079d2011-04-04 10:50:50 -070040static const char* const kClassPathName = "android/media/AudioSystem";
41
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042enum AudioError {
43 kAudioStatusOk = 0,
44 kAudioStatusError = 1,
45 kAudioStatusMediaServerDied = 100
46};
47
48static int check_AudioSystem_Command(status_t status)
49{
50 if (status == NO_ERROR) {
51 return kAudioStatusOk;
52 } else {
53 return kAudioStatusError;
54 }
55}
56
57static int
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
59{
60 return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
61}
62
63static jboolean
64android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
65{
66 bool state = false;
67 AudioSystem::isMicrophoneMuted(&state);
68 return state;
69}
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071static jboolean
Eric Laurent25101b02011-02-02 09:33:30 -080072android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073{
74 bool state = false;
Eric Laurent25101b02011-02-02 09:33:30 -080075 AudioSystem::isStreamActive(stream, &state, inPastMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 return state;
77}
78
Eric Laurenta553c252009-07-17 12:17:14 -070079static int
80android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081{
Eric Laurenta553c252009-07-17 12:17:14 -070082 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
83 String8 c_keyValuePairs8;
84 if (keyValuePairs) {
85 c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
86 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
87 }
88 int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
89 return status;
90}
91
92static jstring
93android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
94{
95 const jchar* c_keys = env->GetStringCritical(keys, 0);
96 String8 c_keys8;
97 if (keys) {
98 c_keys8 = String8(c_keys, env->GetStringLength(keys));
99 env->ReleaseStringCritical(keys, c_keys);
100 }
101 return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102}
103
Glenn Kastened0079d2011-04-04 10:50:50 -0700104static void
105android_media_AudioSystem_error_callback(status_t err)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106{
107 JNIEnv *env = AndroidRuntime::getJNIEnv();
Eric Laurent0e7a4d92010-10-15 12:33:16 -0700108 if (env == NULL) {
109 return;
110 }
111
Glenn Kastened0079d2011-04-04 10:50:50 -0700112 jclass clazz = env->FindClass(kClassPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
114 int error;
115
116 switch (err) {
117 case DEAD_OBJECT:
118 error = kAudioStatusMediaServerDied;
119 break;
120 case NO_ERROR:
121 error = kAudioStatusOk;
122 break;
123 default:
124 error = kAudioStatusError;
125 break;
126 }
127
128 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
129}
130
Eric Laurenta553c252009-07-17 12:17:14 -0700131static int
132android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
133{
134 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700135 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
136 static_cast <audio_policy_dev_state_t>(state),
Eric Laurenta553c252009-07-17 12:17:14 -0700137 c_address));
138 env->ReleaseStringUTFChars(device_address, c_address);
139 return status;
140}
141
142static int
143android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
144{
145 const char *c_address = env->GetStringUTFChars(device_address, NULL);
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700146 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
Eric Laurenta553c252009-07-17 12:17:14 -0700147 c_address));
148 env->ReleaseStringUTFChars(device_address, c_address);
149 return state;
150}
151
152static int
153android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
154{
155 return check_AudioSystem_Command(AudioSystem::setPhoneState(state));
156}
157
158static int
159android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask)
160{
161 return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask));
162}
163
164static int
165android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
166{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700167 return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
168 static_cast <audio_policy_forced_cfg_t>(config)));
Eric Laurenta553c252009-07-17 12:17:14 -0700169}
170
171static int
172android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
173{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700174 return static_cast <int>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
Eric Laurenta553c252009-07-17 12:17:14 -0700175}
176
177static int
178android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
179{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700180 return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
Eric Laurenta553c252009-07-17 12:17:14 -0700181 indexMin,
182 indexMax));
183}
184
185static int
186android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
187{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700188 return check_AudioSystem_Command(AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), index));
Eric Laurenta553c252009-07-17 12:17:14 -0700189}
190
191static int
192android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream)
193{
194 int index;
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700195 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), &index) != NO_ERROR) {
Eric Laurenta553c252009-07-17 12:17:14 -0700196 index = -1;
197 }
198 return index;
199}
200
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800201static jint
202android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
203{
Dima Zavin24fc2fb2011-04-19 22:30:36 -0700204 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800205}
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207// ----------------------------------------------------------------------------
208
209static JNINativeMethod gMethods[] = {
Eric Laurenta553c252009-07-17 12:17:14 -0700210 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
211 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
213 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
Eric Laurent25101b02011-02-02 09:33:30 -0800214 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
Eric Laurenta553c252009-07-17 12:17:14 -0700215 {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
216 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
217 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
218 {"setRingerMode", "(II)I", (void *)android_media_AudioSystem_setRingerMode},
219 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
220 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
221 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
222 {"setStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
Glenn Kasten8b4b97a2011-02-04 13:54:26 -0800223 {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
224 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225};
226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227int register_android_media_AudioSystem(JNIEnv *env)
228{
229 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
230
231 return AndroidRuntime::registerNativeMethods(env,
Glenn Kastened0079d2011-04-04 10:50:50 -0700232 kClassPathName, gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233}