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