• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
32 #include <system/audio.h>
33 #include <system/audio_policy.h>
34 
35 // ----------------------------------------------------------------------------
36 
37 using namespace android;
38 
39 static const char* const kClassPathName = "android/media/AudioSystem";
40 
41 enum AudioError {
42     kAudioStatusOk = 0,
43     kAudioStatusError = 1,
44     kAudioStatusMediaServerDied = 100
45 };
46 
check_AudioSystem_Command(status_t status)47 static int check_AudioSystem_Command(status_t status)
48 {
49     if (status == NO_ERROR) {
50         return kAudioStatusOk;
51     } else {
52         return kAudioStatusError;
53     }
54 }
55 
56 static int
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)57 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
58 {
59     return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
60 }
61 
62 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)63 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
64 {
65     bool state = false;
66     AudioSystem::isMicrophoneMuted(&state);
67     return state;
68 }
69 
70 static jboolean
android_media_AudioSystem_isStreamActive(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)71 android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
72 {
73     bool state = false;
74     AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
75     return state;
76 }
77 
78 static jboolean
android_media_AudioSystem_isSourceActive(JNIEnv * env,jobject thiz,jint source)79 android_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
80 {
81     bool state = false;
82     AudioSystem::isSourceActive((audio_source_t) source, &state);
83     return state;
84 }
85 
86 static int
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)87 android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
88 {
89     const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
90     String8 c_keyValuePairs8;
91     if (keyValuePairs) {
92         c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
93         env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
94     }
95     int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
96     return status;
97 }
98 
99 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)100 android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
101 {
102     const jchar* c_keys = env->GetStringCritical(keys, 0);
103     String8 c_keys8;
104     if (keys) {
105         c_keys8 = String8(c_keys, env->GetStringLength(keys));
106         env->ReleaseStringCritical(keys, c_keys);
107     }
108     return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
109 }
110 
111 static void
android_media_AudioSystem_error_callback(status_t err)112 android_media_AudioSystem_error_callback(status_t err)
113 {
114     JNIEnv *env = AndroidRuntime::getJNIEnv();
115     if (env == NULL) {
116         return;
117     }
118 
119     jclass clazz = env->FindClass(kClassPathName);
120 
121     int error;
122 
123     switch (err) {
124     case DEAD_OBJECT:
125         error = kAudioStatusMediaServerDied;
126         break;
127     case NO_ERROR:
128         error = kAudioStatusOk;
129         break;
130     default:
131         error = kAudioStatusError;
132         break;
133     }
134 
135     env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
136 }
137 
138 static int
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address)139 android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
140 {
141     const char *c_address = env->GetStringUTFChars(device_address, NULL);
142     int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
143                                           static_cast <audio_policy_dev_state_t>(state),
144                                           c_address));
145     env->ReleaseStringUTFChars(device_address, c_address);
146     return status;
147 }
148 
149 static int
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)150 android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
151 {
152     const char *c_address = env->GetStringUTFChars(device_address, NULL);
153     int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
154                                           c_address));
155     env->ReleaseStringUTFChars(device_address, c_address);
156     return state;
157 }
158 
159 static int
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state)160 android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
161 {
162     return check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
163 }
164 
165 static int
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)166 android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
167 {
168     return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
169                                                            static_cast <audio_policy_forced_cfg_t>(config)));
170 }
171 
172 static int
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)173 android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
174 {
175     return static_cast <int>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
176 }
177 
178 static int
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)179 android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
180 {
181     return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
182                                                                    indexMin,
183                                                                    indexMax));
184 }
185 
186 static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index,jint device)187 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
188                                                jobject thiz,
189                                                jint stream,
190                                                jint index,
191                                                jint device)
192 {
193     return check_AudioSystem_Command(
194             AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
195                                               index,
196                                               (audio_devices_t)device));
197 }
198 
199 static int
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint device)200 android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
201                                                jobject thiz,
202                                                jint stream,
203                                                jint device)
204 {
205     int index;
206     if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
207                                           &index,
208                                           (audio_devices_t)device)
209             != NO_ERROR) {
210         index = -1;
211     }
212     return index;
213 }
214 
215 static int
android_media_AudioSystem_setMasterVolume(JNIEnv * env,jobject thiz,jfloat value)216 android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
217 {
218     return check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
219 }
220 
221 static jfloat
android_media_AudioSystem_getMasterVolume(JNIEnv * env,jobject thiz)222 android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
223 {
224     float value;
225     if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
226         value = -1.0;
227     }
228     return value;
229 }
230 
231 static int
android_media_AudioSystem_setMasterMute(JNIEnv * env,jobject thiz,jboolean mute)232 android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
233 {
234     return check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
235 }
236 
237 static jfloat
android_media_AudioSystem_getMasterMute(JNIEnv * env,jobject thiz)238 android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
239 {
240     bool mute;
241     if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
242         mute = false;
243     }
244     return mute;
245 }
246 
247 static jint
android_media_AudioSystem_getDevicesForStream(JNIEnv * env,jobject thiz,jint stream)248 android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
249 {
250     return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
251 }
252 
253 static jint
android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv * env,jobject clazz)254 android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
255 {
256     return (jint) AudioSystem::getPrimaryOutputSamplingRate();
257 }
258 
259 static jint
android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv * env,jobject clazz)260 android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
261 {
262     return (jint) AudioSystem::getPrimaryOutputFrameCount();
263 }
264 
265 // ----------------------------------------------------------------------------
266 
267 static JNINativeMethod gMethods[] = {
268     {"setParameters",        "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
269     {"getParameters",        "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
270     {"muteMicrophone",      "(Z)I",     (void *)android_media_AudioSystem_muteMicrophone},
271     {"isMicrophoneMuted",   "()Z",      (void *)android_media_AudioSystem_isMicrophoneMuted},
272     {"isStreamActive",      "(II)Z",    (void *)android_media_AudioSystem_isStreamActive},
273     {"isSourceActive",      "(I)Z",     (void *)android_media_AudioSystem_isSourceActive},
274     {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
275     {"getDeviceConnectionState", "(ILjava/lang/String;)I",  (void *)android_media_AudioSystem_getDeviceConnectionState},
276     {"setPhoneState",       "(I)I",     (void *)android_media_AudioSystem_setPhoneState},
277     {"setForceUse",         "(II)I",    (void *)android_media_AudioSystem_setForceUse},
278     {"getForceUse",         "(I)I",     (void *)android_media_AudioSystem_getForceUse},
279     {"initStreamVolume",    "(III)I",   (void *)android_media_AudioSystem_initStreamVolume},
280     {"setStreamVolumeIndex","(III)I",   (void *)android_media_AudioSystem_setStreamVolumeIndex},
281     {"getStreamVolumeIndex","(II)I",    (void *)android_media_AudioSystem_getStreamVolumeIndex},
282     {"setMasterVolume",     "(F)I",     (void *)android_media_AudioSystem_setMasterVolume},
283     {"getMasterVolume",     "()F",      (void *)android_media_AudioSystem_getMasterVolume},
284     {"setMasterMute",       "(Z)I",     (void *)android_media_AudioSystem_setMasterMute},
285     {"getMasterMute",       "()Z",      (void *)android_media_AudioSystem_getMasterMute},
286     {"getDevicesForStream", "(I)I",     (void *)android_media_AudioSystem_getDevicesForStream},
287     {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
288     {"getPrimaryOutputFrameCount",   "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
289 };
290 
register_android_media_AudioSystem(JNIEnv * env)291 int register_android_media_AudioSystem(JNIEnv *env)
292 {
293     AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
294 
295     return AndroidRuntime::registerNativeMethods(env,
296                 kClassPathName, gMethods, NELEM(gMethods));
297 }
298