AudioTrack client fast policy

Change-Id: I42ce691df3f586ac061b62237f35a263a0116f1f
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 7d5d772..6de6486 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -139,13 +139,15 @@
      *                     latency of the track. The actual size selected by the AudioTrack could be
      *                     larger if the requested size is not compatible with current audio HAL
      *                     latency.
-     * flags:              Reserved for future use.
+     * flags:              See comments on audio_policy_output_flags_t in <system/audio_policy.h>.
      * cbf:                Callback function. If not null, this function is called periodically
      *                     to request new PCM data.
      * user:               Context for use by the callback receiver.
      * notificationFrames: The callback function is called each time notificationFrames PCM
      *                     frames have been consumed from track input buffer.
      * sessionId:          Specific session ID, or zero to use default.
+     * threadCanCallJava:  Whether callbacks are made from an attached thread and thus can call JNI.
+     *                     If not present in parameter list, then fixed at false.
      */
 
                         AudioTrack( audio_stream_type_t streamType,
@@ -157,7 +159,7 @@
                                     callback_t cbf       = NULL,
                                     void* user           = NULL,
                                     int notificationFrames = 0,
-                                    int sessionId = 0);
+                                    int sessionId        = 0);
 
                         // DEPRECATED
                         explicit AudioTrack( int streamType,
@@ -189,7 +191,7 @@
                                     callback_t cbf      = NULL,
                                     void* user          = NULL,
                                     int notificationFrames = 0,
-                                    int sessionId = 0);
+                                    int sessionId       = 0);
 
     /* Terminates the AudioTrack and unregisters it from AudioFlinger.
      * Also destroys all resources associated with the AudioTrack.
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d73eabd..c619ad7 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -226,7 +226,8 @@
 
     // force direct flag if format is not linear PCM
     if (!audio_is_linear_pcm(format)) {
-        flags = (audio_policy_output_flags_t) (flags | AUDIO_POLICY_OUTPUT_FLAG_DIRECT);
+        flags = (audio_policy_output_flags_t)
+                ((flags | AUDIO_POLICY_OUTPUT_FLAG_DIRECT) & ~AUDIO_POLICY_OUTPUT_FLAG_FAST);
     }
 
     if (!audio_is_output_channel(channelMask)) {
@@ -252,6 +253,7 @@
     mNotificationFramesReq = notificationFrames;
     mSessionId = sessionId;
     mAuxEffectId = 0;
+    mCbf = cbf;
 
     // create the IAudioTrack
     status_t status = createTrack_l(streamType,
@@ -280,7 +282,6 @@
     mSharedBuffer = sharedBuffer;
     mMuted = false;
     mActive = false;
-    mCbf = cbf;
     mUserData = user;
     mLoopCount = 0;
     mMarkerPosition = 0;
@@ -762,6 +763,18 @@
         return NO_INIT;
     }
 
+    // Client decides whether the track is TIMED (see below), but can only express a preference
+    // for FAST.  Server will perform additional tests.
+    if ((flags & AUDIO_POLICY_OUTPUT_FLAG_FAST) && !(
+            // either of these use cases:
+            // use case 1: shared buffer
+            (sharedBuffer != 0) ||
+            // use case 2: callback handler
+            (mCbf != NULL))) {
+        ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
+        flags = (audio_policy_output_flags_t) (flags & ~AUDIO_POLICY_OUTPUT_FLAG_FAST);
+    }
+
     mNotificationFramesAct = mNotificationFramesReq;
     if (!audio_is_linear_pcm(format)) {
         if (sharedBuffer != 0) {
@@ -786,7 +799,7 @@
             if (mNotificationFramesAct > (uint32_t)frameCount/2) {
                 mNotificationFramesAct = frameCount/2;
             }
-            if (frameCount < minFrameCount) {
+            if (frameCount < minFrameCount && !(flags & AUDIO_POLICY_OUTPUT_FLAG_FAST)) {
                 // not ALOGW because it happens all the time when playing key clicks over A2DP
                 ALOGV("Minimum buffer size corrected from %d to %d",
                          frameCount, minFrameCount);
@@ -807,6 +820,10 @@
     if (mIsTimed) {
         trackFlags |= IAudioFlinger::TRACK_TIMED;
     }
+    if (flags & AUDIO_POLICY_OUTPUT_FLAG_FAST) {
+        trackFlags |= IAudioFlinger::TRACK_FAST;
+    }
+
     sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
                                                       streamType,
                                                       sampleRate,