android_media_AudioSystem.cpp revision accb114e59ca51f2a7d370f64de8e98bde158c51
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
38using namespace android;
39
40static const char* const kClassPathName = "android/media/AudioSystem";
41
42enum AudioError {
43    kAudioStatusOk = 0,
44    kAudioStatusError = 1,
45    kAudioStatusMediaServerDied = 100
46};
47
48static int check_AudioSystem_Command(status_t status)
49{
50    if (status == NO_ERROR) {
51        return kAudioStatusOk;
52    } else {
53        return kAudioStatusError;
54    }
55}
56
57static int
58android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
59{
60    return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
61}
62
63static jboolean
64android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
65{
66    bool state = false;
67    AudioSystem::isMicrophoneMuted(&state);
68    return state;
69}
70
71static jboolean
72android_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
79static int
80android_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
92static jstring
93android_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
104static void
105android_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
131static int
132android_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
142static int
143android_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
152static int
153android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
154{
155    return check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
156}
157
158static int
159android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask)
160{
161    return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask));
162}
163
164static int
165android_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
171static int
172android_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
177static int
178android_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
185static int
186android_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
191static int
192android_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
201static jint
202android_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
209static 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
227int 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