Merge "Revert "Revert "AudioTrack: Add getUnderrunCount()"""
diff --git a/api/current.txt b/api/current.txt
index f92518f..6e03e0f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19365,6 +19365,7 @@
field public static final deprecated int NUM_STREAMS = 5; // 0x5
field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+ field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -20725,6 +20726,7 @@
field public static final int DEFAULT = 0; // 0x0
field public static final int MIC = 1; // 0x1
field public static final int REMOTE_SUBMIX = 8; // 0x8
+ field public static final int UNPROCESSED = 9; // 0x9
field public static final int VOICE_CALL = 4; // 0x4
field public static final int VOICE_COMMUNICATION = 7; // 0x7
field public static final int VOICE_DOWNLINK = 3; // 0x3
diff --git a/api/system-current.txt b/api/system-current.txt
index 6bba573..12b9b32 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20670,6 +20670,7 @@
field public static final deprecated int NUM_STREAMS = 5; // 0x5
field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+ field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -22035,6 +22036,7 @@
field public static final int MIC = 1; // 0x1
field public static final int RADIO_TUNER = 1998; // 0x7ce
field public static final int REMOTE_SUBMIX = 8; // 0x8
+ field public static final int UNPROCESSED = 9; // 0x9
field public static final int VOICE_CALL = 4; // 0x4
field public static final int VOICE_COMMUNICATION = 7; // 0x7
field public static final int VOICE_DOWNLINK = 3; // 0x3
diff --git a/api/test-current.txt b/api/test-current.txt
index 66c856f..5e07343 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19373,6 +19373,7 @@
field public static final deprecated int NUM_STREAMS = 5; // 0x5
field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+ field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -20733,6 +20734,7 @@
field public static final int DEFAULT = 0; // 0x0
field public static final int MIC = 1; // 0x1
field public static final int REMOTE_SUBMIX = 8; // 0x8
+ field public static final int UNPROCESSED = 9; // 0x9
field public static final int VOICE_CALL = 4; // 0x4
field public static final int VOICE_COMMUNICATION = 7; // 0x7
field public static final int VOICE_DOWNLINK = 3; // 0x3
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index b2d9b934..8472f78 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -609,7 +609,7 @@
* This download has successfully completed.
* Warning: there might be other status values that indicate success
* in the future.
- * Use isSucccess() to capture the entire category.
+ * Use isStatusSuccess() to capture the entire category.
*/
public static final int STATUS_SUCCESS = 200;
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index bc83b7f..61f185e 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -656,18 +656,59 @@
}
// ----------------------------------------------------------------------------
-static jint android_media_AudioTrack_get_native_frame_count(JNIEnv *env, jobject thiz) {
+static jint android_media_AudioTrack_get_buffer_size_frames(JNIEnv *env, jobject thiz) {
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
- "Unable to retrieve AudioTrack pointer for frameCount()");
+ "Unable to retrieve AudioTrack pointer for getBufferSizeInFrames()");
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+
+ ssize_t result = lpTrack->getBufferSizeInFrames();
+ if (result < 0) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Internal error detected in getBufferSizeInFrames() = " + result);
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ return (jint)result;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_set_buffer_size_frames(JNIEnv *env,
+ jobject thiz, jint bufferSizeInFrames) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for setBufferSizeInFrames()");
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ // Value will be coerced into the valid range.
+ // But internal values are unsigned, size_t, so we need to clip
+ // against zero here where it is signed.
+ if (bufferSizeInFrames < 0) {
+ bufferSizeInFrames = 0;
+ }
+ ssize_t result = lpTrack->setBufferSizeInFrames(bufferSizeInFrames);
+ if (result < 0) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Internal error detected in setBufferSizeInFrames() = " + result);
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ return (jint)result;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_buffer_capacity_frames(JNIEnv *env, jobject thiz) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for getBufferCapacityInFrames()");
return (jint)AUDIO_JAVA_ERROR;
}
return lpTrack->frameCount();
}
-
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz,
jint sampleRateInHz) {
@@ -1084,8 +1125,12 @@
{"native_write_short", "([SIIIZ)I",(void *)android_media_AudioTrack_writeArray<jshortArray>},
{"native_write_float", "([FIIIZ)I",(void *)android_media_AudioTrack_writeArray<jfloatArray>},
{"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume},
- {"native_get_native_frame_count",
- "()I", (void *)android_media_AudioTrack_get_native_frame_count},
+ {"native_get_buffer_size_frames",
+ "()I", (void *)android_media_AudioTrack_get_buffer_size_frames},
+ {"native_set_buffer_size_frames",
+ "(I)I", (void *)android_media_AudioTrack_set_buffer_size_frames},
+ {"native_get_buffer_capacity_frames",
+ "()I", (void *)android_media_AudioTrack_get_buffer_capacity_frames},
{"native_set_playback_rate",
"(I)I", (void *)android_media_AudioTrack_set_playback_rate},
{"native_get_playback_rate",
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b6150e0..53a733d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2362,6 +2362,9 @@
(range of 18 - 21 kHz). -->
<bool name="config_supportSpeakerNearUltrasound">true</bool>
+ <!-- Whether the Unprocessed audio source supports the required frequency range and level -->
+ <bool name="config_supportAudioSourceUnprocessed">false</bool>
+
<!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
<bool name="config_eap_sim_based_auth_supported">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3641061..dc288d5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -303,6 +303,7 @@
<java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
<java-symbol type="bool" name="config_supportMicNearUltrasound" />
<java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
+ <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
<java-symbol type="bool" name="config_freeformWindowManagement" />
<java-symbol type="string" name="config_defaultPictureInPictureBounds" />
<java-symbol type="string" name="config_centeredPictureInPictureBounds" />
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index e92f294..606447b5 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -223,10 +223,19 @@
@SystemApi
public final static int FLAG_BYPASS_MUTE = 0x1 << 7;
+ /**
+ * @hide
+ * Flag requesting a low latency path.
+ * When using this flag, the sample rate must match the native sample rate
+ * of the device. Effects processing is also unavailable.
+ */
+ public final static int FLAG_LOW_LATENCY = 0x1 << 8;
+
private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
- FLAG_BYPASS_MUTE;
- private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC;
+ FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY;
+ private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
+ FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
private int mUsage = USAGE_UNKNOWN;
private int mContentType = CONTENT_TYPE_UNKNOWN;
@@ -520,8 +529,9 @@
* instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
* @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
* {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
- * {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
- * {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
+ * {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
+ * {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION} or
+ * {@link MediaRecorder.AudioSource#UNPROCESSED}
* @return the same Builder instance.
*/
@SystemApi
@@ -532,6 +542,7 @@
case MediaRecorder.AudioSource.CAMCORDER:
case MediaRecorder.AudioSource.VOICE_RECOGNITION:
case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
+ case MediaRecorder.AudioSource.UNPROCESSED:
mSource = preset;
break;
default:
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ea1690f..5ad6b08 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3305,12 +3305,19 @@
"android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
/**
+ * Used as a key for {@link #getProperty} to determine if the unprocessed audio source is
+ * available and supported with the expected frequency range and level response.
+ */
+ public static final String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED =
+ "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
+ /**
* Returns the value of the property with the specified key.
* @param key One of the strings corresponding to a property key: either
* {@link #PROPERTY_OUTPUT_SAMPLE_RATE},
* {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER},
- * {@link #PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND}, or
- * {@link #PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND}.
+ * {@link #PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND},
+ * {@link #PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND}, or
+ * {@link #PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED}.
* @return A string representing the associated value for that property key,
* or null if there is no value for that key.
*/
@@ -3329,6 +3336,9 @@
} else if (PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND.equals(key)) {
return String.valueOf(getContext().getResources().getBoolean(
com.android.internal.R.bool.config_supportSpeakerNearUltrasound));
+ } else if (PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED.equals(key)) {
+ return String.valueOf(getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_supportAudioSourceUnprocessed));
} else {
// null or unknown key
return null;
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 775d05b..4319840 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1052,8 +1052,68 @@
}
}
+// TODO Change getBufferCapacityInFrames() reference below to
+// {@link #getBufferCapacityInFrames()} after @hide is removed.
+// TODO Change setBufferSizeInFrames(int) reference below to
+// {@link #setBufferSizeInFrames(int)} after @hide is removed.
/**
- * Returns the frame count of the native <code>AudioTrack</code> buffer.
+ * Returns the effective size of the <code>AudioTrack</code> buffer
+ * that the application writes to.
+ * <p> This will be less than or equal to the result of
+ * getBufferCapacityInFrames().
+ * It will be equal if setBufferSizeInFrames(int) has never been called.
+ * <p> If the track is subsequently routed to a different output sink, the buffer
+ * size and capacity may enlarge to accommodate.
+ * <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+ * e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+ * the size of the native <code>AudioTrack</code> buffer in bytes.
+ * <p> See also {@link AudioManager#getProperty(String)} for key
+ * {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+ * @return current size in frames of the <code>AudioTrack</code> buffer.
+ * @throws IllegalStateException
+ */
+ public int getBufferSizeInFrames() {
+ return native_get_buffer_size_frames();
+ }
+
+// TODO Change getBufferCapacityInFrames() reference below to
+// {@link #getBufferCapacityInFrames()} after @hide is removed.
+ /**
+ * Limits the effective size of the <code>AudioTrack</code> buffer
+ * that the application writes to.
+ * <p> A write to this AudioTrack will not fill the buffer beyond this limit.
+ * If a blocking write is used then the write will block until the the data
+ * can fit within this limit.
+ * <p>Changing this limit modifies the latency associated with
+ * the buffer for this track. A smaller size will give lower latency
+ * but there may be more glitches due to buffer underruns.
+ * <p>The actual size used may not be equal to this requested size.
+ * It will be limited to a valid range with a maximum of
+ * getBufferCapacityInFrames().
+ * It may also be adjusted slightly for internal reasons.
+ * If bufferSizeInFrames is less than zero then {@link #ERROR_BAD_VALUE}
+ * will be returned.
+ * <p>This method is only supported for PCM audio.
+ * It is not supported for compressed audio tracks.
+ *
+ * @param bufferSizeInFrames requested buffer size
+ * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+ * {@link #ERROR_INVALID_OPERATION}
+ * @throws IllegalStateException
+ * @hide
+ */
+ public int setBufferSizeInFrames(int bufferSizeInFrames) {
+ if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
+ if (bufferSizeInFrames < 0) {
+ return ERROR_BAD_VALUE;
+ }
+ return native_set_buffer_size_frames(bufferSizeInFrames);
+ }
+
+ /**
+ * Returns the maximum size of the native <code>AudioTrack</code> buffer.
* <p> If the track's creation mode is {@link #MODE_STATIC},
* it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
* A static track's native frame count will not change.
@@ -1068,11 +1128,12 @@
* the size of the native <code>AudioTrack</code> buffer in bytes.
* <p> See also {@link AudioManager#getProperty(String)} for key
* {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
- * @return current size in frames of the <code>AudioTrack</code> buffer.
+ * @return maximum size in frames of the <code>AudioTrack</code> buffer.
* @throws IllegalStateException
+ * @hide
*/
- public int getBufferSizeInFrames() {
- return native_get_native_frame_count();
+ public int getBufferCapacityInFrames() {
+ return native_get_buffer_capacity_frames();
}
/**
@@ -1083,7 +1144,7 @@
*/
@Deprecated
protected int getNativeFrameCount() {
- return native_get_native_frame_count();
+ return native_get_buffer_capacity_frames();
}
/**
@@ -2719,7 +2780,9 @@
private native final int native_reload_static();
- private native final int native_get_native_frame_count();
+ private native final int native_get_buffer_size_frames();
+ private native final int native_set_buffer_size_frames(int bufferSizeInFrames);
+ private native final int native_get_buffer_capacity_frames();
private native final void native_setVolume(float leftVolume, float rightVolume);
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 8ac86b0..504c6d0 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -251,6 +251,10 @@
*/
public static final int REMOTE_SUBMIX = 8;
+ /** Microphone audio source tuned for unprocessed (raw) sound if available, behaves like
+ * {@link #DEFAULT} otherwise. */
+ public static final int UNPROCESSED = 9;
+
/**
* Audio source for capturing broadcast radio tuner output.
* @hide
@@ -405,7 +409,7 @@
* @see android.media.MediaRecorder.AudioSource
*/
public static final int getAudioSourceMax() {
- return AudioSource.REMOTE_SUBMIX;
+ return AudioSource.UNPROCESSED;
}
/**