1b3db213eb55acb661e4b9ea40bcc00af4b76fab9Glenn Kasten/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Copyright 2008, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "ToneGenerator" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <jni.h> 25c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <JNIHelp.h> 26c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <android_runtime/AndroidRuntime.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <utils/Log.h> 29c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <media/AudioSystem.h> 30c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <media/ToneGenerator.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct fields_t { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID context; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic fields_t fields; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4196c08a69ea0b95d1d8a8edb67f73bd9548e09f16Eric Laurentstatic jboolean android_media_ToneGenerator_startTone(JNIEnv *env, jobject thiz, jint toneType, jint durationMs) { 420765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("android_media_ToneGenerator_startTone: %x", (int)thiz); 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz, 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields.context); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lpToneGen == NULL) { 4769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowRuntimeException(env, "Method called after release()"); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5123f7ad39ef52c0ac0a94934a71b6802c0a806b7fGlenn Kasten return lpToneGen->startTone((ToneGenerator::tone_type) toneType, durationMs); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_ToneGenerator_stopTone(JNIEnv *env, jobject thiz) { 550765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("android_media_ToneGenerator_stopTone: %x", (int)thiz); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz, 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields.context); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 600765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("ToneGenerator lpToneGen: %x", (unsigned int)lpToneGen); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lpToneGen == NULL) { 6269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowRuntimeException(env, "Method called after release()"); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lpToneGen->stopTone(); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurentstatic jint android_media_ToneGenerator_getAudioSessionId(JNIEnv *env, jobject thiz) { 69505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz, 70505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent fields.context); 71505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent if (lpToneGen == NULL) { 72505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent jniThrowRuntimeException(env, "Method called after release()"); 73505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent return 0; 74505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent } 75505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent return lpToneGen->getSessionId(); 76505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent} 77505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_ToneGenerator_release(JNIEnv *env, jobject thiz) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz, 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields.context); 810765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("android_media_ToneGenerator_release lpToneGen: %x", (int)lpToneGen); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(thiz, fields.context, 0); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 851137be1a686fdfc9f02c3aca7c33f28006df4742Glenn Kasten delete lpToneGen; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz, 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint streamType, jint volume) { 90bc1d77b6cbce23fbe25f7231651037ae195bc90eGlenn Kasten ToneGenerator *lpToneGen = new ToneGenerator((audio_stream_type_t) streamType, AudioSystem::linearToLog(volume), true); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(thiz, fields.context, 0); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 940765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("android_media_ToneGenerator_native_setup jobject: %x", (int)thiz); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lpToneGen == NULL) { 970765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGE("ToneGenerator creation failed"); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1010765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("ToneGenerator lpToneGen: %x", (unsigned int)lpToneGen); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!lpToneGen->isInited()) { 1040765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGE("ToneGenerator init failed"); 10569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowRuntimeException(env, "Init failed"); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stow our new C++ ToneGenerator in an opaque field in the Java object. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(thiz, fields.context, (int)lpToneGen); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1120765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("ToneGenerator fields.context: %x", env->GetIntField(thiz, fields.context)); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_ToneGenerator_native_finalize(JNIEnv *env, 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject thiz) { 1170765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("android_media_ToneGenerator_native_finalize jobject: %x", (int)thiz); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz, 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields.context); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1220765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten if (lpToneGen != NULL) { 1230765c448ab7d51355a7b1e82d359acfcf169f481Glenn Kasten ALOGV("delete lpToneGen: %p", lpToneGen); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete lpToneGen; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 13196c08a69ea0b95d1d8a8edb67f73bd9548e09f16Eric Laurent { "startTone", "(II)Z", (void *)android_media_ToneGenerator_startTone }, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "stopTone", "()V", (void *)android_media_ToneGenerator_stopTone }, 133505e5c8859f596ed58489be565d6e029314b2ac8Eric Laurent { "getAudioSessionId", "()I", (void *)android_media_ToneGenerator_getAudioSessionId}, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "release", "()V", (void *)android_media_ToneGenerator_release }, 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "native_setup", "(II)V", (void *)android_media_ToneGenerator_native_setup }, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "native_finalize", "()V", (void *)android_media_ToneGenerator_native_finalize } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_media_ToneGenerator(JNIEnv *env) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clazz = env->FindClass("android/media/ToneGenerator"); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 1453762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find %s", "android/media/ToneGenerator"); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fields.context == NULL) { 1513762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Can't find ToneGenerator.mNativeContext"); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("register_android_media_ToneGenerator ToneGenerator fields.context: %x", (unsigned int)fields.context); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods(env, 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android/media/ToneGenerator", gMethods, NELEM(gMethods)); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 159