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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 250 android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz) 251 { 252 return (jint) AudioSystem::getPrimaryOutputSamplingRate(); 253 } 254 255 static jint 256 android_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz) 257 { 258 return (jint) AudioSystem::getPrimaryOutputFrameCount(); 259 } 260 261 static jint 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 273 android_media_AudioSystem_setLowRamDevice(JNIEnv *env, jobject clazz, jboolean isLowRamDevice) 274 { 275 return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice); 276 } 277 278 static int 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 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