Home | History | Annotate | Download | only in jni
      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