Verify AudioTrack only uses a valid multichannel configuration

Enforce the same rules as for HDMI output:
- FL/FR must be present
- paired channels must be used in pairs (e.g. no rear left
   without rear right)

Bug 6392126

Change-Id: I0a39e474dcf509cb7eabd8edd1f0e44852d72b51
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index f51a24a..96f01db 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -401,7 +401,7 @@
             mChannels = AudioFormat.CHANNEL_OUT_STEREO;
             break;
         default:
-            if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
+            if (!isMultichannelConfigSupported(channelConfig)) {
                 // input channel configuration features unsupported channels
                 mChannelCount = 0;
                 mChannels = AudioFormat.CHANNEL_INVALID;
@@ -438,6 +438,37 @@
         }
     }
 
+    /**
+     * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
+     * @param channelConfig the mask to validate
+     * @return false if the AudioTrack can't be used with such a mask
+     */
+    private static boolean isMultichannelConfigSupported(int channelConfig) {
+        // check for unsupported channels
+        if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
+            Log.e(TAG, "Channel configuration features unsupported channels");
+            return false;
+        }
+        // check for unsupported multichannel combinations:
+        // - FL/FR must be present
+        // - L/R channels must be paired (e.g. no single L channel)
+        final int frontPair =
+                AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
+        if ((channelConfig & frontPair) != frontPair) {
+                Log.e(TAG, "Front channels must be present in multichannel configurations");
+                return false;
+        }
+        final int backPair =
+                AudioFormat.CHANNEL_OUT_BACK_LEFT | AudioFormat.CHANNEL_OUT_BACK_RIGHT;
+        if ((channelConfig & backPair) != 0) {
+            if ((channelConfig & backPair) != backPair) {
+                Log.e(TAG, "Rear channels can't be used independently");
+                return false;
+            }
+        }
+        return true;
+    }
+
 
     // Convenience method for the contructor's audio buffer size check.
     // preconditions: