android_media_ToneGenerator.cpp revision 8a5f9c19b65aebd1972355faf0c8bb90500c7596
1/*
2 **
3 ** Copyright 2008, 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 "ToneGenerator"
19
20#include <stdio.h>
21#include <unistd.h>
22#include <fcntl.h>
23
24#include <jni.h>
25#include <JNIHelp.h>
26#include <android_runtime/AndroidRuntime.h>
27
28#include <utils/Log.h>
29#include <media/AudioSystem.h>
30#include <media/ToneGenerator.h>
31
32// ----------------------------------------------------------------------------
33
34using namespace android;
35
36struct fields_t {
37    jfieldID context;
38};
39static fields_t fields;
40
41static jboolean android_media_ToneGenerator_startTone(JNIEnv *env, jobject thiz, jint toneType, jint durationMs) {
42    ALOGV("android_media_ToneGenerator_startTone: %x", (int)thiz);
43
44    ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
45            fields.context);
46    if (lpToneGen == NULL) {
47        jniThrowRuntimeException(env, "Method called after release()");
48        return false;
49    }
50
51    return lpToneGen->startTone((ToneGenerator::tone_type) toneType, durationMs);
52}
53
54static void android_media_ToneGenerator_stopTone(JNIEnv *env, jobject thiz) {
55    ALOGV("android_media_ToneGenerator_stopTone: %x", (int)thiz);
56
57    ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
58            fields.context);
59
60    ALOGV("ToneGenerator lpToneGen: %x", (unsigned int)lpToneGen);
61    if (lpToneGen == NULL) {
62        jniThrowRuntimeException(env, "Method called after release()");
63        return;
64    }
65    lpToneGen->stopTone();
66}
67
68static jint android_media_ToneGenerator_getAudioSessionId(JNIEnv *env, jobject thiz) {
69    ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
70            fields.context);
71    if (lpToneGen == NULL) {
72        jniThrowRuntimeException(env, "Method called after release()");
73        return 0;
74    }
75    return lpToneGen->getSessionId();
76}
77
78static void android_media_ToneGenerator_release(JNIEnv *env, jobject thiz) {
79    ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
80            fields.context);
81    ALOGV("android_media_ToneGenerator_release lpToneGen: %x", (int)lpToneGen);
82
83    env->SetIntField(thiz, fields.context, 0);
84
85    delete lpToneGen;
86}
87
88static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz,
89        jint streamType, jint volume) {
90    ToneGenerator *lpToneGen = new ToneGenerator((audio_stream_type_t) streamType, AudioSystem::linearToLog(volume), true);
91
92    env->SetIntField(thiz, fields.context, 0);
93
94    ALOGV("android_media_ToneGenerator_native_setup jobject: %x", (int)thiz);
95
96    if (lpToneGen == NULL) {
97        ALOGE("ToneGenerator creation failed");
98        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
99        return;
100    }
101    ALOGV("ToneGenerator lpToneGen: %x", (unsigned int)lpToneGen);
102
103    if (!lpToneGen->isInited()) {
104        ALOGE("ToneGenerator init failed");
105        jniThrowRuntimeException(env, "Init failed");
106        delete lpToneGen;
107        return;
108    }
109
110    // Stow our new C++ ToneGenerator in an opaque field in the Java object.
111    env->SetIntField(thiz, fields.context, (int)lpToneGen);
112
113    ALOGV("ToneGenerator fields.context: %x", env->GetIntField(thiz, fields.context));
114}
115
116static void android_media_ToneGenerator_native_finalize(JNIEnv *env,
117        jobject thiz) {
118    ALOGV("android_media_ToneGenerator_native_finalize jobject: %x", (int)thiz);
119
120    ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
121            fields.context);
122
123    if (lpToneGen != NULL) {
124        ALOGV("delete lpToneGen: %p", lpToneGen);
125        delete lpToneGen;
126    }
127}
128
129// ----------------------------------------------------------------------------
130
131static JNINativeMethod gMethods[] = {
132    { "startTone", "(II)Z", (void *)android_media_ToneGenerator_startTone },
133    { "stopTone", "()V", (void *)android_media_ToneGenerator_stopTone },
134    { "getAudioSessionId", "()I", (void *)android_media_ToneGenerator_getAudioSessionId},
135    { "release", "()V", (void *)android_media_ToneGenerator_release },
136    { "native_setup", "(II)V", (void *)android_media_ToneGenerator_native_setup },
137    { "native_finalize", "()V", (void *)android_media_ToneGenerator_native_finalize }
138};
139
140
141int register_android_media_ToneGenerator(JNIEnv *env) {
142    jclass clazz;
143
144    clazz = env->FindClass("android/media/ToneGenerator");
145    if (clazz == NULL) {
146        ALOGE("Can't find %s", "android/media/ToneGenerator");
147        return -1;
148    }
149
150    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
151    if (fields.context == NULL) {
152        ALOGE("Can't find ToneGenerator.mNativeContext");
153        return -1;
154    }
155    ALOGV("register_android_media_ToneGenerator ToneGenerator fields.context: %x", (unsigned int)fields.context);
156
157    return AndroidRuntime::registerNativeMethods(env,
158            "android/media/ToneGenerator", gMethods, NELEM(gMethods));
159}
160