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