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