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