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