1 /* //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
33 #include <system/audio.h>
34 #include <system/audio_policy.h>
35
36 // ----------------------------------------------------------------------------
37
38 using namespace android;
39
40 static const char* const kClassPathName = "android/media/AudioSystem";
41
42 enum AudioError {
43 kAudioStatusOk = 0,
44 kAudioStatusError = 1,
45 kAudioStatusMediaServerDied = 100
46 };
47
check_AudioSystem_Command(status_t status)48 static int check_AudioSystem_Command(status_t status)
49 {
50 if (status == NO_ERROR) {
51 return kAudioStatusOk;
52 } else {
53 return kAudioStatusError;
54 }
55 }
56
57 static int
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)58 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
59 {
60 return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
61 }
62
63 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)64 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
65 {
66 bool state = false;
67 AudioSystem::isMicrophoneMuted(&state);
68 return state;
69 }
70
71 static jboolean
android_media_AudioSystem_isStreamActive(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)72 android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
73 {
74 bool state = false;
75 AudioSystem::isStreamActive(stream, &state, inPastMs);
76 return state;
77 }
78
79 static int
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)80 android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
81 {
82 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
92 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)93 android_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());
102 }
103
104 static void
android_media_AudioSystem_error_callback(status_t err)105 android_media_AudioSystem_error_callback(status_t err)
106 {
107 JNIEnv *env = AndroidRuntime::getJNIEnv();
108 if (env == NULL) {
109 return;
110 }
111
112 jclass clazz = env->FindClass(kClassPathName);
113
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
131 static int
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address)132 android_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);
135 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
136 static_cast <audio_policy_dev_state_t>(state),
137 c_address));
138 env->ReleaseStringUTFChars(device_address, c_address);
139 return status;
140 }
141
142 static int
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)143 android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
144 {
145 const char *c_address = env->GetStringUTFChars(device_address, NULL);
146 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
147 c_address));
148 env->ReleaseStringUTFChars(device_address, c_address);
149 return state;
150 }
151
152 static int
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state)153 android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
154 {
155 return check_AudioSystem_Command(AudioSystem::setPhoneState(state));
156 }
157
158 static int
android_media_AudioSystem_setRingerMode(JNIEnv * env,jobject thiz,jint mode,jint mask)159 android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask)
160 {
161 return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask));
162 }
163
164 static int
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)165 android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
166 {
167 return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
168 static_cast <audio_policy_forced_cfg_t>(config)));
169 }
170
171 static int
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)172 android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
173 {
174 return static_cast <int>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
175 }
176
177 static int
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)178 android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
179 {
180 return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
181 indexMin,
182 indexMax));
183 }
184
185 static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index)186 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
187 {
188 return check_AudioSystem_Command(AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), index));
189 }
190
191 static int
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream)192 android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream)
193 {
194 int index;
195 if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream), &index) != NO_ERROR) {
196 index = -1;
197 }
198 return index;
199 }
200
201 static jint
android_media_AudioSystem_getDevicesForStream(JNIEnv * env,jobject thiz,jint stream)202 android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
203 {
204 return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
205 }
206
207 // ----------------------------------------------------------------------------
208
209 static JNINativeMethod gMethods[] = {
210 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
211 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
212 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
213 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
214 {"isStreamActive", "(II)Z", (void *)android_media_AudioSystem_isStreamActive},
215 {"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},
223 {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
224 {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
225 };
226
register_android_media_AudioSystem(JNIEnv * env)227 int register_android_media_AudioSystem(JNIEnv *env)
228 {
229 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
230
231 return AndroidRuntime::registerNativeMethods(env,
232 kClassPathName, gMethods, NELEM(gMethods));
233 }
234