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 // ----------------------------------------------------------------------------
34
35 using namespace android;
36
37 enum AudioError {
38 kAudioStatusOk = 0,
39 kAudioStatusError = 1,
40 kAudioStatusMediaServerDied = 100
41 };
42
check_AudioSystem_Command(status_t status)43 static int check_AudioSystem_Command(status_t status)
44 {
45 if (status == NO_ERROR) {
46 return kAudioStatusOk;
47 } else {
48 return kAudioStatusError;
49 }
50 }
51
52 static int
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)53 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
54 {
55 return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
56 }
57
58 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)59 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
60 {
61 bool state = false;
62 AudioSystem::isMicrophoneMuted(&state);
63 return state;
64 }
65
66 static jboolean
android_media_AudioSystem_isMusicActive(JNIEnv * env,jobject thiz)67 android_media_AudioSystem_isMusicActive(JNIEnv *env, jobject thiz)
68 {
69 bool state = false;
70 AudioSystem::isMusicActive(&state);
71 return state;
72 }
73
74 static int
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)75 android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
76 {
77 const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
78 String8 c_keyValuePairs8;
79 if (keyValuePairs) {
80 c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
81 env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
82 }
83 int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
84 return status;
85 }
86
87 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)88 android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
89 {
90 const jchar* c_keys = env->GetStringCritical(keys, 0);
91 String8 c_keys8;
92 if (keys) {
93 c_keys8 = String8(c_keys, env->GetStringLength(keys));
94 env->ReleaseStringCritical(keys, c_keys);
95 }
96 return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
97 }
98
android_media_AudioSystem_error_callback(status_t err)99 void android_media_AudioSystem_error_callback(status_t err)
100 {
101 JNIEnv *env = AndroidRuntime::getJNIEnv();
102 jclass clazz = env->FindClass("android/media/AudioSystem");
103
104 int error;
105
106 switch (err) {
107 case DEAD_OBJECT:
108 error = kAudioStatusMediaServerDied;
109 break;
110 case NO_ERROR:
111 error = kAudioStatusOk;
112 break;
113 default:
114 error = kAudioStatusError;
115 break;
116 }
117
118 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
119 }
120
121 static int
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address)122 android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
123 {
124 const char *c_address = env->GetStringUTFChars(device_address, NULL);
125 int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <AudioSystem::audio_devices>(device),
126 static_cast <AudioSystem::device_connection_state>(state),
127 c_address));
128 env->ReleaseStringUTFChars(device_address, c_address);
129 return status;
130 }
131
132 static int
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)133 android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
134 {
135 const char *c_address = env->GetStringUTFChars(device_address, NULL);
136 int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <AudioSystem::audio_devices>(device),
137 c_address));
138 env->ReleaseStringUTFChars(device_address, c_address);
139 return state;
140 }
141
142 static int
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state)143 android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
144 {
145 return check_AudioSystem_Command(AudioSystem::setPhoneState(state));
146 }
147
148 static int
android_media_AudioSystem_setRingerMode(JNIEnv * env,jobject thiz,jint mode,jint mask)149 android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask)
150 {
151 return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask));
152 }
153
154 static int
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)155 android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
156 {
157 return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <AudioSystem::force_use>(usage),
158 static_cast <AudioSystem::forced_config>(config)));
159 }
160
161 static int
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)162 android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
163 {
164 return static_cast <int>(AudioSystem::getForceUse(static_cast <AudioSystem::force_use>(usage)));
165 }
166
167 static int
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)168 android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
169 {
170 return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <AudioSystem::stream_type>(stream),
171 indexMin,
172 indexMax));
173 }
174
175 static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index)176 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
177 {
178 return check_AudioSystem_Command(AudioSystem::setStreamVolumeIndex(static_cast <AudioSystem::stream_type>(stream), index));
179 }
180
181 static int
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream)182 android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream)
183 {
184 int index;
185 if (AudioSystem::getStreamVolumeIndex(static_cast <AudioSystem::stream_type>(stream), &index) != NO_ERROR) {
186 index = -1;
187 }
188 return index;
189 }
190
191 // ----------------------------------------------------------------------------
192
193 static JNINativeMethod gMethods[] = {
194 {"setParameters", "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
195 {"getParameters", "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
196 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone},
197 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted},
198 {"isMusicActive", "()Z", (void *)android_media_AudioSystem_isMusicActive},
199 {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
200 {"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
201 {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
202 {"setRingerMode", "(II)I", (void *)android_media_AudioSystem_setRingerMode},
203 {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
204 {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
205 {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
206 {"setStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
207 {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex}
208 };
209
210 const char* const kClassPathName = "android/media/AudioSystem";
211
register_android_media_AudioSystem(JNIEnv * env)212 int register_android_media_AudioSystem(JNIEnv *env)
213 {
214 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
215
216 return AndroidRuntime::registerNativeMethods(env,
217 "android/media/AudioSystem", gMethods, NELEM(gMethods));
218 }
219