Merge "AudioSystem: native to JAVA status translation"
diff --git a/core/jni/android_media_AudioErrors.h b/core/jni/android_media_AudioErrors.h
new file mode 100644
index 0000000..4907830
--- /dev/null
+++ b/core/jni/android_media_AudioErrors.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef ANDROID_MEDIA_AUDIOERRORS_H
+#define ANDROID_MEDIA_AUDIOERRORS_H
+
+#include <utils/Errors.h>
+
+namespace android {
+// status codes used by JAVA APIs. Translation from native error codes is done by
+// nativeToJavaStatus()
+// must be kept in sync with values in
+// frameworks/base/media/java/android/media/AudioSystem.java.
+enum {
+    AUDIO_JAVA_SUCCESS            = 0,
+    AUDIO_JAVA_ERROR              = -1,
+    AUDIO_JAVA_BAD_VALUE          = -2,
+    AUDIO_JAVA_INVALID_OPERATION  = -3,
+    AUDIO_JAVA_PERMISSION_DENIED  = -4,
+    AUDIO_JAVA_NO_INIT            = -5,
+    AUDIO_JAVA_DEAD_OBJECT        = -6,
+};
+
+static inline jint nativeToJavaStatus(status_t status) {
+    switch (status) {
+    case NO_ERROR:
+        return AUDIO_JAVA_SUCCESS;
+    case BAD_VALUE:
+        return AUDIO_JAVA_BAD_VALUE;
+    case INVALID_OPERATION:
+        return AUDIO_JAVA_INVALID_OPERATION;
+    case PERMISSION_DENIED:
+        return AUDIO_JAVA_PERMISSION_DENIED;
+    case NO_INIT:
+        return AUDIO_JAVA_NO_INIT;
+    case DEAD_OBJECT:
+        return AUDIO_JAVA_DEAD_OBJECT;
+    default:
+        return AUDIO_JAVA_ERROR;
+    }
+}
+}; // namespace android
+#endif // ANDROID_MEDIA_AUDIOERRORS_H
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 09bdc61..a54eba1 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -27,6 +27,7 @@
 #include <media/AudioRecord.h>
 
 #include "android_media_AudioFormat.h"
+#include "android_media_AudioErrors.h"
 
 // ----------------------------------------------------------------------------
 
@@ -55,29 +56,12 @@
 
 // ----------------------------------------------------------------------------
 
-#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_INVALIDCHANNELMASK -17
 #define AUDIORECORD_ERROR_SETUP_INVALIDFORMAT       -18
 #define AUDIORECORD_ERROR_SETUP_INVALIDSOURCE       -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) {
 
@@ -197,13 +181,13 @@
 
     if (jSession == NULL) {
         ALOGE("Error creating AudioRecord: invalid session ID pointer");
-        return (jint) AUDIORECORD_ERROR;
+        return (jint) AUDIO_JAVA_ERROR;
     }
 
     jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
     if (nSession == NULL) {
         ALOGE("Error creating AudioRecord: Error retrieving session id pointer");
-        return (jint) AUDIORECORD_ERROR;
+        return (jint) AUDIO_JAVA_ERROR;
     }
     int sessionId = nSession[0];
     env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
@@ -259,7 +243,7 @@
     // of the Java object (in mNativeCallbackCookie) so we can free the memory in finalize()
     env->SetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie, (jlong)lpCallbackData);
 
-    return (jint) AUDIORECORD_SUCCESS;
+    return (jint) AUDIO_JAVA_SUCCESS;
 
     // failure:
 native_init_failure:
@@ -280,10 +264,10 @@
     sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
     if (lpRecorder == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return (jint) AUDIORECORD_ERROR;
+        return (jint) AUDIO_JAVA_ERROR;
     }
 
-    return (jint) android_media_translateRecorderErrorCode(
+    return nativeToJavaStatus(
             lpRecorder->start((AudioSystem::sync_event_t)event, triggerSession));
 }
 
@@ -383,7 +367,7 @@
     env->ReleaseByteArrayElements(javaAudioData, recordBuff, 0);
 
     if (readSize < 0) {
-        readSize = AUDIORECORD_ERROR_INVALID_OPERATION;
+        readSize = (jint)AUDIO_JAVA_INVALID_OPERATION;
     }
     return (jint) readSize;
 }
@@ -428,7 +412,7 @@
     env->ReleaseShortArrayElements(javaAudioData, recordBuff, 0);
 
     if (readSize < 0) {
-        readSize = AUDIORECORD_ERROR_INVALID_OPERATION;
+        readSize = (jint)AUDIO_JAVA_INVALID_OPERATION;
     } else {
         readSize /= sizeof(short);
     }
@@ -461,7 +445,7 @@
     ssize_t readSize = lpRecorder->read(nativeFromJavaBuf,
                                    capacity < sizeInBytes ? capacity : sizeInBytes);
     if (readSize < 0) {
-        readSize = AUDIORECORD_ERROR_INVALID_OPERATION;
+        readSize = (jint)AUDIO_JAVA_INVALID_OPERATION;
     }
     return (jint)readSize;
 }
@@ -475,9 +459,9 @@
     if (lpRecorder == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioRecord pointer for setMarkerPosition()");
-        return AUDIORECORD_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateRecorderErrorCode( lpRecorder->setMarkerPosition(markerPos) );
+    return nativeToJavaStatus( lpRecorder->setMarkerPosition(markerPos) );
 }
 
 
@@ -490,7 +474,7 @@
     if (lpRecorder == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioRecord pointer for getMarkerPosition()");
-        return AUDIORECORD_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     lpRecorder->getMarkerPosition(&markerPos);
     return (jint)markerPos;
@@ -506,9 +490,9 @@
     if (lpRecorder == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioRecord pointer for setPositionUpdatePeriod()");
-        return AUDIORECORD_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateRecorderErrorCode( lpRecorder->setPositionUpdatePeriod(period) );
+    return nativeToJavaStatus( lpRecorder->setPositionUpdatePeriod(period) );
 }
 
 
@@ -521,7 +505,7 @@
     if (lpRecorder == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioRecord pointer for getPositionUpdatePeriod()");
-        return AUDIORECORD_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     lpRecorder->getPositionUpdatePeriod(&period);
     return (jint)period;
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 5fcb5f3..e548e91 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -32,6 +32,7 @@
 #include <binder/MemoryBase.h>
 
 #include "android_media_AudioFormat.h"
+#include "android_media_AudioErrors.h"
 
 // ----------------------------------------------------------------------------
 
@@ -94,31 +95,12 @@
 // ----------------------------------------------------------------------------
 #define DEFAULT_OUTPUT_SAMPLE_RATE   44100
 
-#define AUDIOTRACK_SUCCESS                         0
-#define AUDIOTRACK_ERROR                           -1
-#define AUDIOTRACK_ERROR_BAD_VALUE                 -2
-#define AUDIOTRACK_ERROR_INVALID_OPERATION         -3
 #define AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM         -16
 #define AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK  -17
 #define AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT       -18
 #define AUDIOTRACK_ERROR_SETUP_INVALIDSTREAMTYPE   -19
 #define AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED    -20
 
-
-jint android_media_translateErrorCode(int code) {
-    switch (code) {
-    case NO_ERROR:
-        return AUDIOTRACK_SUCCESS;
-    case BAD_VALUE:
-        return AUDIOTRACK_ERROR_BAD_VALUE;
-    case INVALID_OPERATION:
-        return AUDIOTRACK_ERROR_INVALID_OPERATION;
-    default:
-        return AUDIOTRACK_ERROR;
-    }
-}
-
-
 // ----------------------------------------------------------------------------
 static void audioCallback(int event, void* user, void *info) {
 
@@ -249,13 +231,13 @@
 
     if (jSession == NULL) {
         ALOGE("Error creating AudioTrack: invalid session ID pointer");
-        return (jint) AUDIOTRACK_ERROR;
+        return (jint) AUDIO_JAVA_ERROR;
     }
 
     jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
     if (nSession == NULL) {
         ALOGE("Error creating AudioTrack: Error retrieving session id pointer");
-        return (jint) AUDIOTRACK_ERROR;
+        return (jint) AUDIO_JAVA_ERROR;
     }
     int sessionId = nSession[0];
     env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
@@ -346,7 +328,7 @@
     //ALOGV("storing lpJniStorage: %x\n", (long)lpJniStorage);
     env->SetLongField(thiz, javaAudioTrackFields.jniData, (jlong)lpJniStorage);
 
-    return (jint) AUDIOTRACK_SUCCESS;
+    return (jint) AUDIO_JAVA_SUCCESS;
 
     // failures:
 native_init_failure:
@@ -596,7 +578,7 @@
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         ALOGE("Error retrieving source of audio data to play, can't play");
-        return AUDIOTRACK_ERROR_BAD_VALUE;
+        return (jint)AUDIO_JAVA_BAD_VALUE;
     }
 
     jint written = writeToTrack(lpTrack, javaAudioFormat, bytes.get(), byteOffset,
@@ -695,7 +677,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for frameCount()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
 
     return lpTrack->frameCount();
@@ -709,9 +691,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for setSampleRate()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));
+    return nativeToJavaStatus(lpTrack->setSampleRate(sampleRateInHz));
 }
 
 
@@ -721,7 +703,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for getSampleRate()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     return (jint) lpTrack->getSampleRate();
 }
@@ -734,9 +716,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for setMarkerPosition()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->setMarkerPosition(markerPos) );
+    return nativeToJavaStatus( lpTrack->setMarkerPosition(markerPos) );
 }
 
 
@@ -748,7 +730,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for getMarkerPosition()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     lpTrack->getMarkerPosition(&markerPos);
     return (jint)markerPos;
@@ -762,9 +744,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for setPositionUpdatePeriod()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->setPositionUpdatePeriod(period) );
+    return nativeToJavaStatus( lpTrack->setPositionUpdatePeriod(period) );
 }
 
 
@@ -776,7 +758,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for getPositionUpdatePeriod()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     lpTrack->getPositionUpdatePeriod(&period);
     return (jint)period;
@@ -790,9 +772,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for setPosition()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->setPosition(position) );
+    return nativeToJavaStatus( lpTrack->setPosition(position) );
 }
 
 
@@ -804,7 +786,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for getPosition()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     lpTrack->getPosition(&position);
     return (jint)position;
@@ -818,7 +800,7 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for latency()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     return (jint)lpTrack->latency();
 }
@@ -830,7 +812,7 @@
 
     if (lpTrack == NULL) {
         ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
     AudioTimestamp timestamp;
     status_t status = lpTrack->getTimestamp(timestamp);
@@ -838,13 +820,13 @@
         jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL);
         if (nTimestamp == NULL) {
             ALOGE("Unable to get array for getTimestamp()");
-            return AUDIOTRACK_ERROR;
+            return (jint)AUDIO_JAVA_ERROR;
         }
         nTimestamp[0] = (jlong) timestamp.mPosition;
         nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec);
         env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0);
     }
-    return (jint) android_media_translateErrorCode(status);
+    return (jint) nativeToJavaStatus(status);
 }
 
 
@@ -855,9 +837,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for setLoop()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->setLoop(loopStart, loopEnd, loopCount) );
+    return nativeToJavaStatus( lpTrack->setLoop(loopStart, loopEnd, loopCount) );
 }
 
 
@@ -867,9 +849,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for reload()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->reload() );
+    return nativeToJavaStatus( lpTrack->reload() );
 }
 
 
@@ -952,9 +934,9 @@
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve AudioTrack pointer for attachAuxEffect()");
-        return AUDIOTRACK_ERROR;
+        return (jint)AUDIO_JAVA_ERROR;
     }
-    return android_media_translateErrorCode( lpTrack->attachAuxEffect(effectId) );
+    return nativeToJavaStatus( lpTrack->attachAuxEffect(effectId) );
 }
 
 // ----------------------------------------------------------------------------
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 384e120..d4e85c8 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -61,25 +61,25 @@
      */
     public static final int RECORDSTATE_RECORDING = 3;// matches SL_RECORDSTATE_RECORDING
 
-    // Error codes:
-    // to keep in sync with frameworks/base/core/jni/android_media_AudioRecord.cpp
     /**
      * Denotes a successful operation.
      */
-    public static final int SUCCESS                 = 0;
+    public  static final int SUCCESS                               = AudioSystem.SUCCESS;
     /**
      * Denotes a generic operation failure.
      */
-    public static final int ERROR                   = -1;
+    public  static final int ERROR                                 = AudioSystem.ERROR;
     /**
      * Denotes a failure due to the use of an invalid value.
      */
-    public static final int ERROR_BAD_VALUE         = -2;
+    public  static final int ERROR_BAD_VALUE                       = AudioSystem.BAD_VALUE;
     /**
      * Denotes a failure due to the improper use of a method.
      */
-    public static final int ERROR_INVALID_OPERATION = -3;
+    public  static final int ERROR_INVALID_OPERATION               = AudioSystem.INVALID_OPERATION;
 
+    // Error codes:
+    // to keep in sync with frameworks/base/core/jni/android_media_AudioRecord.cpp
     private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT      = -16;
     private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK  = -17;
     private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT       = -18;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 327c10c..5ddb198 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -199,6 +199,17 @@
         }
     }
 
+    /*
+     * Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...)
+     * Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h
+     */
+    public static final int SUCCESS            = 0;
+    public static final int ERROR              = -1;
+    public static final int BAD_VALUE          = -2;
+    public static final int INVALID_OPERATION  = -3;
+    public static final int PERMISSION_DENIED  = -4;
+    public static final int NO_INIT            = -5;
+    public static final int DEAD_OBJECT        = -6;
 
     /*
      * AudioPolicyService methods
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1a64cff..1baaaa4 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -125,25 +125,25 @@
      */
     public static final int STATE_NO_STATIC_DATA = 2;
 
-    // Error codes:
-    // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
     /**
      * Denotes a successful operation.
      */
-    public  static final int SUCCESS                               = 0;
+    public  static final int SUCCESS                               = AudioSystem.SUCCESS;
     /**
      * Denotes a generic operation failure.
      */
-    public  static final int ERROR                                 = -1;
+    public  static final int ERROR                                 = AudioSystem.ERROR;
     /**
      * Denotes a failure due to the use of an invalid value.
      */
-    public  static final int ERROR_BAD_VALUE                       = -2;
+    public  static final int ERROR_BAD_VALUE                       = AudioSystem.BAD_VALUE;
     /**
      * Denotes a failure due to the improper use of a method.
      */
-    public  static final int ERROR_INVALID_OPERATION               = -3;
+    public  static final int ERROR_INVALID_OPERATION               = AudioSystem.INVALID_OPERATION;
 
+    // Error codes:
+    // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
     private static final int ERROR_NATIVESETUP_AUDIOSYSTEM         = -16;
     private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK  = -17;
     private static final int ERROR_NATIVESETUP_INVALIDFORMAT       = -18;