• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 using namespace android;
39 
40 static const char* const kClassPathName = "android/media/AudioSystem";
41 
42 enum AudioError {
43     kAudioStatusOk = 0,
44     kAudioStatusError = 1,
45     kAudioStatusMediaServerDied = 100
46 };
47 
check_AudioSystem_Command(status_t status)48 static int check_AudioSystem_Command(status_t status)
49 {
50     if (status == NO_ERROR) {
51         return kAudioStatusOk;
52     } else {
53         return kAudioStatusError;
54     }
55 }
56 
57 static int
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)58 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
59 {
60     return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
61 }
62 
63 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)64 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
65 {
66     bool state = false;
67     AudioSystem::isMicrophoneMuted(&state);
68     return state;
69 }
70 
71 static jboolean
android_media_AudioSystem_isStreamActive(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)72 android_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 
79 static int
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)80 android_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 
92 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)93 android_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 
104 static void
android_media_AudioSystem_error_callback(status_t err)105 android_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 
131 static int
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address)132 android_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 
142 static int
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)143 android_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 
152 static int
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state)153 android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
154 {
155     return check_AudioSystem_Command(AudioSystem::setPhoneState(state));
156 }
157 
158 static int
android_media_AudioSystem_setRingerMode(JNIEnv * env,jobject thiz,jint mode,jint mask)159 android_media_AudioSystem_setRingerMode(JNIEnv *env, jobject thiz, jint mode, jint mask)
160 {
161     return check_AudioSystem_Command(AudioSystem::setRingerMode(mode, mask));
162 }
163 
164 static int
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)165 android_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 
171 static int
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)172 android_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 
177 static int
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)178 android_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 
185 static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index)186 android_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 
191 static int
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream)192 android_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 
201 static jint
android_media_AudioSystem_getDevicesForStream(JNIEnv * env,jobject thiz,jint stream)202 android_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 
209 static 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 
register_android_media_AudioSystem(JNIEnv * env)227 int 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