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