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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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