auto import from //depot/cupcake/@135843
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
new file mode 100644
index 0000000..288433a
--- /dev/null
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+
+#define LOG_TAG "AudioRecord-JNI"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include "utils/Log.h"
+#include "media/AudioSystem.h"
+#include "media/AudioRecord.h"
+
+
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+static const char* const kClassPathName = "android/media/AudioRecord";
+
+struct fields_t {
+    // these fields provide access from C++ to the...
+    jclass    audioRecordClass;      //... AudioRecord class
+    jmethodID postNativeEventInJava; //... event post callback method
+    int       PCM16;                 //...  format constants
+    int       PCM8;                  //...  format constants
+    int       SOURCE_DEFAULT;        //...  record source constants
+    int       SOURCE_MIC;            //...  record source constants
+    jfieldID  nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
+    jfieldID  nativeCallbackCookie;    // provides access to the AudioRecord callback data
+};
+static fields_t javaAudioRecordFields;
+
+struct audiorecord_callback_cookie {
+    jclass      audioRecord_class;
+    jobject     audioRecord_ref;
+ };
+
+// ----------------------------------------------------------------------------
+
+#define AUDIORECORD_SUCCESS                         0
+#define AUDIORECORD_ERROR                           -1
+#define AUDIORECORD_ERROR_BAD_VALUE                 -2
+#define AUDIORECORD_ERROR_INVALID_OPERATION         -3
+#define AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT      -16
+#define AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT -17
+#define AUDIORECORD_ERROR_SETUP_INVALIDFORMAT       -18
+#define AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE   -19
+#define AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED    -20
+
+jint android_media_translateRecorderErrorCode(int code) {
+    switch(code) {
+    case NO_ERROR:
+        return AUDIORECORD_SUCCESS;
+    case BAD_VALUE:
+        return AUDIORECORD_ERROR_BAD_VALUE;
+    case INVALID_OPERATION:
+        return AUDIORECORD_ERROR_INVALID_OPERATION;
+    default:
+        return AUDIORECORD_ERROR;
+    }   
+}
+
+
+// ----------------------------------------------------------------------------
+static void recorderCallback(int event, void* user, void *info) {
+    if (event == AudioRecord::EVENT_MORE_DATA) {
+        // set size to 0 to signal we're not using the callback to read more data
+        AudioRecord::Buffer* pBuff = (AudioRecord::Buffer*)info;
+        pBuff->size = 0;  
+    
+    } else if (event == AudioRecord::EVENT_MARKER) {
+        audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
+        JNIEnv *env = AndroidRuntime::getJNIEnv();
+        if (user && env) {
+            env->CallStaticVoidMethod(
+                callbackInfo->audioRecord_class, 
+                javaAudioRecordFields.postNativeEventInJava,
+                callbackInfo->audioRecord_ref, event, 0,0, NULL);
+            if (env->ExceptionCheck()) {
+                env->ExceptionDescribe();
+                env->ExceptionClear();
+            }
+        }
+
+    } else if (event == AudioRecord::EVENT_NEW_POS) {
+        audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
+        JNIEnv *env = AndroidRuntime::getJNIEnv();
+        if (user && env) {
+            env->CallStaticVoidMethod(
+                callbackInfo->audioRecord_class, 
+                javaAudioRecordFields.postNativeEventInJava,
+                callbackInfo->audioRecord_ref, event, 0,0, NULL);
+            if (env->ExceptionCheck()) {
+                env->ExceptionDescribe();
+                env->ExceptionClear();
+            }
+        }
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+static int
+android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+        jint source, jint sampleRateInHertz, jint nbChannels, 
+        jint audioFormat, jint buffSizeInBytes)
+{
+    //LOGV(">> Entering android_media_AudioRecord_setup");
+    //LOGV("sampleRate=%d, audioFormat=%d, nbChannels=%d, buffSizeInBytes=%d",
+    //     sampleRateInHertz, audioFormat, nbChannels,     buffSizeInBytes);
+
+    if ((nbChannels == 0) || (nbChannels > 2)) {
+        LOGE("Error creating AudioRecord: channel count is not 1 or 2.");
+        return AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT;
+    }
+
+    // compare the format against the Java constants
+    if ((audioFormat != javaAudioRecordFields.PCM16) 
+        && (audioFormat != javaAudioRecordFields.PCM8)) {
+        LOGE("Error creating AudioRecord: unsupported audio format.");
+        return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
+    }
+
+    int bytesPerSample = audioFormat==javaAudioRecordFields.PCM16 ? 2 : 1;
+    int format = audioFormat==javaAudioRecordFields.PCM16 ? 
+            AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT;
+
+    if (buffSizeInBytes == 0) {
+         LOGE("Error creating AudioRecord: frameCount is 0.");
+        return AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT;
+    }
+    int frameSize = nbChannels * bytesPerSample;
+    size_t frameCount = buffSizeInBytes / frameSize;
+    
+    // compare the source against the Java constants
+    AudioRecord::stream_type arSource;
+    if (source == javaAudioRecordFields.SOURCE_DEFAULT) {
+        arSource = AudioRecord::DEFAULT_INPUT;
+    } else if (source == javaAudioRecordFields.SOURCE_MIC) {
+        arSource = AudioRecord::MIC_INPUT;
+    } else {
+        LOGE("Error creating AudioRecord: unknown source.");
+        return AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE;
+    }
+     
+    audiorecord_callback_cookie *lpCallbackData = NULL;
+    AudioRecord* lpRecorder = NULL;
+
+    // create an uninitialized AudioRecord object
+    lpRecorder = new AudioRecord();
+        if(lpRecorder == NULL) {
+        LOGE("Error creating AudioRecord instance.");
+        return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
+    }
+    
+    // create the callback information:
+    // this data will be passed with every AudioRecord callback
+    jclass clazz = env->GetObjectClass(thiz);
+    if (clazz == NULL) {
+        LOGE("Can't find %s when setting up callback.", kClassPathName);
+        goto native_track_failure;
+    }
+    lpCallbackData = new audiorecord_callback_cookie;
+    lpCallbackData->audioRecord_class = (jclass)env->NewGlobalRef(clazz);
+    // we use a weak reference so the AudioRecord object can be garbage collected.
+    lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
+    
+    lpRecorder->set(arSource,
+        sampleRateInHertz,
+        format,        // word length, PCM
+        nbChannels,
+        frameCount,
+        0,             // flags
+        recorderCallback,// callback_t
+        lpCallbackData,// void* user
+        0,             // notificationFrames,
+        true);         // threadCanCallJava)
+
+    if(lpRecorder->initCheck() != NO_ERROR) {
+        LOGE("Error creating AudioRecord instance: initialization check failed.");
+        goto native_init_failure;
+    }
+
+    // save our newly created C++ AudioRecord in the "nativeRecorderInJavaObj" field 
+    // of the Java object
+    env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)lpRecorder);
+    
+    // save our newly created callback information in the "nativeCallbackCookie" field
+    // of the Java object (in mNativeCallbackCookie) so we can free the memory in finalize()
+    env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, (int)lpCallbackData);
+    
+    return AUDIORECORD_SUCCESS;
+    
+    // failure:
+native_init_failure:
+    delete lpCallbackData;
+    
+native_track_failure:
+    delete lpRecorder;
+
+    env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
+    env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+    
+    return AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
+}
+
+
+
+// ----------------------------------------------------------------------------
+static void
+android_media_AudioRecord_start(JNIEnv *env, jobject thiz)
+{
+    AudioRecord *lpRecorder = 
+            (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    if (lpRecorder == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+    
+    lpRecorder->start();
+}
+
+
+// ----------------------------------------------------------------------------
+static void
+android_media_AudioRecord_stop(JNIEnv *env, jobject thiz)
+{
+    AudioRecord *lpRecorder = 
+            (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    if (lpRecorder == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+
+    lpRecorder->stop();
+    //LOGV("Called lpRecorder->stop()");
+}
+
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioRecord_finalize(JNIEnv *env,  jobject thiz) {
+    
+    // delete the AudioRecord object
+    AudioRecord *lpRecorder = 
+            (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+
+    if (lpRecorder) {
+        LOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
+        lpRecorder->stop();
+        delete lpRecorder;
+    }
+    
+    // delete the callback information
+    audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetIntField(
+        thiz, javaAudioRecordFields.nativeCallbackCookie);
+    if (lpCookie) {
+        LOGV("deleting lpCookie: %x\n", (int)lpCookie);
+        delete lpCookie;
+    }
+
+}
+
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioRecord_release(JNIEnv *env,  jobject thiz) {
+       
+    // do everything a call to finalize would
+    android_media_AudioRecord_finalize(env, thiz);
+    // + reset the native resources in the Java object so any attempt to access
+    // them after a call to release fails.
+    env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
+    env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInByteArray(JNIEnv *env,  jobject thiz,
+                                                        jbyteArray javaAudioData,
+                                                        jint offsetInBytes, jint sizeInBytes) {
+    jbyte* recordBuff = NULL;
+    AudioRecord *lpRecorder = NULL;
+
+    // get the audio recorder from which we'll read new audio samples
+    lpRecorder = 
+            (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    if (lpRecorder == NULL) {
+        LOGE("Unable to retrieve AudioRecord object, can't record");
+        return 0;
+    }
+
+    if (!javaAudioData) {
+        LOGE("Invalid Java array to store recorded audio, can't record");
+        return 0;
+    }
+
+    // get the pointer to where we'll record the audio
+    recordBuff = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL);
+
+    if (recordBuff == NULL) {
+        LOGE("Error retrieving destination for recorded audio data, can't record");
+        return 0;
+    }
+
+    // read the new audio data from the native AudioRecord object
+    ssize_t recorderBuffSize = lpRecorder->frameCount()*lpRecorder->frameSize();
+    ssize_t readSize = lpRecorder->read(recordBuff + offsetInBytes, 
+                                        sizeInBytes > (jint)recorderBuffSize ? 
+                                            (jint)recorderBuffSize : sizeInBytes );
+    env->ReleasePrimitiveArrayCritical(javaAudioData, recordBuff, 0);
+
+    return (jint) readSize;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInShortArray(JNIEnv *env,  jobject thiz,
+                                                        jshortArray javaAudioData,
+                                                        jint offsetInShorts, jint sizeInShorts) {
+
+    return (android_media_AudioRecord_readInByteArray(env, thiz,
+                                                        (jbyteArray) javaAudioData,
+                                                        offsetInShorts*2, sizeInShorts*2)
+            / 2);
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_readInDirectBuffer(JNIEnv *env,  jobject thiz,
+                                                  jobject jBuffer, jint sizeInBytes) {
+    AudioRecord *lpRecorder = NULL;
+    //LOGV("Entering android_media_AudioRecord_readInBuffer");
+
+    // get the audio recorder from which we'll read new audio samples
+    lpRecorder = 
+        (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    if(lpRecorder==NULL)
+        return 0;
+
+    // direct buffer and direct access supported?
+    long capacity = env->GetDirectBufferCapacity(jBuffer);
+    if(capacity == -1) {
+        // buffer direct access is not supported
+        LOGE("Buffer direct access is not supported, can't record");
+        return 0;
+    }
+    //LOGV("capacity = %ld", capacity);
+    jbyte* nativeFromJavaBuf = (jbyte*) env->GetDirectBufferAddress(jBuffer);
+    if(nativeFromJavaBuf==NULL) {
+        LOGE("Buffer direct access is not supported, can't record");
+        return 0;
+    } 
+
+    // read new data from the recorder
+    return (jint) lpRecorder->read(nativeFromJavaBuf, 
+                                   capacity < sizeInBytes ? capacity : sizeInBytes);
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_set_marker_pos(JNIEnv *env,  jobject thiz, 
+        jint markerPos) {
+            
+    AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+                thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+                
+    if (lpRecorder) {
+        return 
+            android_media_translateRecorderErrorCode( lpRecorder->setMarkerPosition(markerPos) );   
+    } else {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioRecord pointer for setMarkerPosition()");
+        return AUDIORECORD_ERROR;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_marker_pos(JNIEnv *env,  jobject thiz) {
+    
+    AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+                thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    uint32_t markerPos = 0;
+                
+    if (lpRecorder) {
+        lpRecorder->getMarkerPosition(&markerPos);
+        return (jint)markerPos;
+    } else {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioRecord pointer for getMarkerPosition()");
+        return AUDIORECORD_ERROR;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_set_pos_update_period(JNIEnv *env,  jobject thiz,
+        jint period) {
+            
+    AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+                thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+                
+    if (lpRecorder) {
+        return 
+            android_media_translateRecorderErrorCode( lpRecorder->setPositionUpdatePeriod(period) );   
+    } else {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioRecord pointer for setPositionUpdatePeriod()");
+        return AUDIORECORD_ERROR;
+    }            
+}
+
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_pos_update_period(JNIEnv *env,  jobject thiz) {
+    
+    AudioRecord *lpRecorder = (AudioRecord *)env->GetIntField(
+                thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+    uint32_t period = 0;
+                
+    if (lpRecorder) {
+        lpRecorder->getPositionUpdatePeriod(&period);
+        return (jint)period;
+    } else {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioRecord pointer for getPositionUpdatePeriod()");
+        return AUDIORECORD_ERROR;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+// returns the minimum required size for the successful creation of an AudioRecord instance.
+// returns 0 if the parameter combination is not supported.
+// return -1 if there was an error querying the buffer size.
+static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env,  jobject thiz,
+    jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
+    
+    size_t inputBuffSize = 0;
+    LOGV(">> android_media_AudioRecord_get_min_buff_size(%d, %d, %d)", sampleRateInHertz, nbChannels, audioFormat);
+    
+    status_t result = AudioSystem::getInputBufferSize(
+                        sampleRateInHertz, 
+                        (audioFormat == javaAudioRecordFields.PCM16 ? 
+                            AudioSystem::PCM_16_BIT : AudioSystem::PCM_8_BIT), 
+                        nbChannels, &inputBuffSize);
+    switch(result) {
+    case(NO_ERROR):
+        if(inputBuffSize == 0) {
+            LOGV("Recording parameters are not supported: %dHz, %d channel(s), (java) format %d",
+                sampleRateInHertz, nbChannels, audioFormat);
+            return 0;
+        } else {
+            // the minimum buffer size is twice the hardware input buffer size
+            return 2*inputBuffSize;
+        }
+        break;
+    case(PERMISSION_DENIED):
+    default:
+        return -1; 
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+static JNINativeMethod gMethods[] = {
+    // name,               signature,  funcPtr
+    {"native_start",         "()V",    (void *)android_media_AudioRecord_start},
+    {"native_stop",          "()V",    (void *)android_media_AudioRecord_stop},
+    {"native_setup",         "(Ljava/lang/Object;IIIII)I",
+                                       (void *)android_media_AudioRecord_setup},
+    {"native_finalize",      "()V",    (void *)android_media_AudioRecord_finalize},
+    {"native_release",       "()V",    (void *)android_media_AudioRecord_release},
+    {"native_read_in_byte_array", 
+                             "([BII)I", (void *)android_media_AudioRecord_readInByteArray},
+    {"native_read_in_short_array",
+                             "([SII)I", (void *)android_media_AudioRecord_readInShortArray},
+    {"native_read_in_direct_buffer","(Ljava/lang/Object;I)I",
+                                       (void *)android_media_AudioRecord_readInDirectBuffer},
+    {"native_set_marker_pos","(I)I",   (void *)android_media_AudioRecord_set_marker_pos},
+    {"native_get_marker_pos","()I",    (void *)android_media_AudioRecord_get_marker_pos},
+    {"native_set_pos_update_period",
+                             "(I)I",   (void *)android_media_AudioRecord_set_pos_update_period},
+    {"native_get_pos_update_period",
+                             "()I",    (void *)android_media_AudioRecord_get_pos_update_period},
+    {"native_get_min_buff_size",
+                             "(III)I",   (void *)android_media_AudioRecord_get_min_buff_size},
+};
+
+// field names found in android/media/AudioRecord.java
+#define JAVA_POSTEVENT_CALLBACK_NAME  "postEventFromNative"
+#define JAVA_CONST_PCM16_NAME         "ENCODING_PCM_16BIT"
+#define JAVA_CONST_PCM8_NAME          "ENCODING_PCM_8BIT"
+#define JAVA_CONST_SOURCEDEFAULT_NAME "SOURCE_DEFAULT"
+#define JAVA_CONST_SOURCEMIC_NAME     "SOURCE_MIC"
+#define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME  "mNativeRecorderInJavaObj"
+#define JAVA_NATIVECALLBACKINFO_FIELD_NAME       "mNativeCallbackCookie"
+
+#define JAVA_AUDIOFORMAT_CLASS_NAME "android/media/AudioFormat"
+
+// ----------------------------------------------------------------------------
+
+extern bool android_media_getIntConstantFromClass(JNIEnv* pEnv, 
+                jclass theClass, const char* className, const char* constName, int* constVal);
+
+// ----------------------------------------------------------------------------
+int register_android_media_AudioRecord(JNIEnv *env)
+{
+    javaAudioRecordFields.audioRecordClass = NULL;
+    javaAudioRecordFields.postNativeEventInJava = NULL;
+    javaAudioRecordFields.nativeRecorderInJavaObj = NULL;
+    javaAudioRecordFields.nativeCallbackCookie = NULL;
+    
+
+    // Get the AudioRecord class
+    javaAudioRecordFields.audioRecordClass = env->FindClass(kClassPathName);
+    if (javaAudioRecordFields.audioRecordClass == NULL) {
+        LOGE("Can't find %s", kClassPathName);
+        return -1;
+    }
+    
+    // Get the postEvent method
+    javaAudioRecordFields.postNativeEventInJava = env->GetStaticMethodID(
+            javaAudioRecordFields.audioRecordClass,
+            JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    if (javaAudioRecordFields.postNativeEventInJava == NULL) {
+        LOGE("Can't find AudioRecord.%s", JAVA_POSTEVENT_CALLBACK_NAME);
+        return -1;
+    }
+
+    // Get the variables
+    //    mNativeRecorderInJavaObj
+    javaAudioRecordFields.nativeRecorderInJavaObj = 
+        env->GetFieldID(javaAudioRecordFields.audioRecordClass,
+                        JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME, "I");
+    if (javaAudioRecordFields.nativeRecorderInJavaObj == NULL) {
+        LOGE("Can't find AudioRecord.%s", JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME);
+        return -1;
+    }
+    //     mNativeCallbackCookie
+    javaAudioRecordFields.nativeCallbackCookie = env->GetFieldID(
+            javaAudioRecordFields.audioRecordClass,
+            JAVA_NATIVECALLBACKINFO_FIELD_NAME, "I");
+    if (javaAudioRecordFields.nativeCallbackCookie == NULL) {
+        LOGE("Can't find AudioRecord.%s", JAVA_NATIVECALLBACKINFO_FIELD_NAME);
+        return -1;
+    }
+
+    // Get the format constants from the AudioFormat class
+    jclass audioFormatClass = NULL;
+    audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
+    if (audioFormatClass == NULL) {
+        LOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
+        return -1;
+    }
+    if ( !android_media_getIntConstantFromClass(env, audioFormatClass, 
+                JAVA_AUDIOFORMAT_CLASS_NAME, 
+                JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
+           || !android_media_getIntConstantFromClass(env, audioFormatClass, 
+                JAVA_AUDIOFORMAT_CLASS_NAME, 
+                JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8)) ) {
+        // error log performed in getIntConstantFromClass() 
+        return -1;
+    }
+
+    // Get the recording source constants from the AudioRecord class
+    if ( !android_media_getIntConstantFromClass(env, javaAudioRecordFields.audioRecordClass, 
+                kClassPathName,
+                JAVA_CONST_SOURCEDEFAULT_NAME, &(javaAudioRecordFields.SOURCE_DEFAULT))
+        || !android_media_getIntConstantFromClass(env, javaAudioRecordFields.audioRecordClass, 
+                kClassPathName,
+                JAVA_CONST_SOURCEMIC_NAME, &(javaAudioRecordFields.SOURCE_MIC)) ) {
+        // error log performed in getIntConstantFromClass() 
+        return -1;
+    }
+
+    return AndroidRuntime::registerNativeMethods(env,
+            kClassPathName, gMethods, NELEM(gMethods));
+}
+
+// ----------------------------------------------------------------------------