Merge "Add wifi & p2p Concurrency test" into jb-dev
diff --git a/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java b/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
index 32cc3ed..c5bc671 100644
--- a/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
+++ b/suite/audio_quality/client/src/com/android/cts/audiotest/AudioProtocol.java
@@ -110,17 +110,16 @@
     @Override
     public void onMarkerReached(AudioTrack track) {
         Log.d(TAG, "playback completed");
+        track.stop();
+        track.flush();
+        track.release();
+        mPlaybackThread.quitLoop();
+        mPlaybackThread = null;
         try {
             sendSimpleReplyHeader(CMD_START_PLAYBACK, PROTOCOL_OK);
         } catch (IOException e) {
             // maybe socket already closed. don't do anything
             Log.e(TAG, "ignore exception", e);
-        } finally {
-            track.stop();
-            track.flush();
-            track.release();
-            mPlaybackThread.quitLoop(false);
-            mPlaybackThread = null;
         }
     }
 
@@ -199,7 +198,7 @@
             mRecord = null;
         }
         if (mRecordThread != null) {
-            mRecordThread.quitLoop(true);
+            mRecordThread.quitLoop();
             mRecordThread = null;
         }
         if (mPlayback != null) {
@@ -211,7 +210,7 @@
             mPlayback = null;
         }
         if (mPlaybackThread != null) {
-            mPlaybackThread.quitLoop(true);
+            mPlaybackThread.quitLoop();
             mPlaybackThread = null;
         }
         mDataMap.clear();
@@ -246,8 +245,6 @@
             if (samplingRate != 44100) {
                 throw new ProtocolError("wrong rate");
             }
-            //FIXME cannot start playback again
-            //TODO repeat
             //FIXME in MODE_STATIC, setNotificationMarkerPosition does not work with full length
             mPlaybackThread = new LoopThread(new Runnable() {
 
@@ -259,9 +256,16 @@
                     }
                     int type = (mode == 0) ? AudioManager.STREAM_VOICE_CALL :
                         AudioManager.STREAM_MUSIC;
+                    int bufferSize = AudioTrack.getMinBufferSize(samplingRate,
+                            stereo ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO,
+                            AudioFormat.ENCODING_PCM_16BIT);
+                    bufferSize = bufferSize * 4;
+                    if (bufferSize < 256 * 1024) {
+                        bufferSize = 256 * 1024;
+                    }
                     mPlayback = new AudioTrack(type, samplingRate,
                             stereo ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO,
-                            AudioFormat.ENCODING_PCM_16BIT, data.capacity(),
+                            AudioFormat.ENCODING_PCM_16BIT, bufferSize,
                             AudioTrack.MODE_STREAM);
                     float minVolume = mPlayback.getMinVolume();
                     float maxVolume = mPlayback.getMaxVolume();
@@ -269,7 +273,10 @@
                     mPlayback.setStereoVolume(newVolume, newVolume);
                     Log.d(TAG, "setting volume " + newVolume + " max " + maxVolume +
                             " min " + minVolume + " received " + volume);
-                    mPlayback.write(data.array(), 0, data.capacity());
+                    int dataWritten = 0;
+                    int dataToWrite = (bufferSize < data.capacity())? bufferSize : data.capacity();
+                    mPlayback.write(data.array(), 0, dataToWrite);
+                    dataWritten = dataToWrite;
                     mPlayback.setPlaybackPositionUpdateListener(AudioProtocol.this);
 
                     int endMarker = data.capacity()/(stereo ? 4 : 2);
@@ -278,6 +285,12 @@
                             " set.. res " + res + " stereo? " + stereo + " mode " + mode +
                             " end " + endMarker);
                     mPlayback.play();
+                    while (dataWritten < data.capacity()) {
+                        int dataLeft = data.capacity() - dataWritten;
+                        dataToWrite = (bufferSize < dataLeft)? bufferSize : dataLeft;
+                        mPlayback.write(data.array(), dataWritten, dataToWrite);
+                        dataWritten += dataToWrite;
+                    }
                 }
             });
             mPlaybackThread.start();
@@ -299,7 +312,7 @@
             mPlayback = null;
         }
         if (mPlaybackThread != null) {
-            mPlaybackThread.quitLoop(true);
+            mPlaybackThread.quitLoop();
             mPlaybackThread = null;
         }
         sendSimpleReplyHeader(CMD_STOP_PLAYBACK, PROTOCOL_OK);
@@ -393,7 +406,7 @@
             mRecord = null;
         }
         if (mRecordThread != null) {
-            mRecordThread.quitLoop(true);
+            mRecordThread.quitLoop();
             mRecordThread = null;
         }
         sendSimpleReplyHeader(CMD_STOP_RECORDING, PROTOCOL_OK);
@@ -437,10 +450,10 @@
             Looper.loop();
         }
         // should be called outside this thread
-        public void quitLoop(boolean wait) {
+        public void quitLoop() {
             mLooper.quit();
             try {
-                if (wait) {
+                if (Thread.currentThread() != this) {
                     join();
                 }
             } catch (InterruptedException e) {
diff --git a/suite/audio_quality/test_description/dut_speaker_calibration.xml b/suite/audio_quality/test_description/dut_speaker_calibration.xml
index 9cc655b..f0ddf17 100644
--- a/suite/audio_quality/test_description/dut_speaker_calibration.xml
+++ b/suite/audio_quality/test_description/dut_speaker_calibration.xml
@@ -22,7 +22,7 @@
 	</setup>
 
 	<action> <!-- 1 action -->
-		<!--  equivalent of for loop. all children will be completed before moving to the next 
+		<!--  equivalent of for loop. all children will be completed before moving to the next
 		      stage.repeat up to 100 times unless stopped by some condition -->
 		<sequential repeat="20" index="i">
 			<!--  sync start : execute only sync complete : execute + complete
diff --git a/suite/audio_quality/test_description/test/dut_speaker_play.xml b/suite/audio_quality/test_description/test/dut_speaker_play.xml
new file mode 100644
index 0000000..d2e35e8
--- /dev/null
+++ b/suite/audio_quality/test_description/test/dut_speaker_play.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2012 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.
+-->
+
+<case name="dut_speaker_play" version="1.0" description="Play DUT speaker for some time">
+	<setup> <!-- 1 setup -->
+		<!-- prepare sound source id: to be used in output, sine 1000Hz, 20000ms long -->
+		<sound id="sound1" type="sin:32000:100:5000" preload="1" />
+	</setup>
+
+
+	<action> <!-- 1 action -->
+		<!--  equivalent of for loop. all children will be completed before moving to the next 
+		      stage.repeat up to 100 times unless stopped by some condition -->
+		<sequential repeat="20" index="i">
+			<!--  sync start : execute only sync complete : execute + complete
+			      For sync start, complete will be called when the parent completes -->
+			<output device="DUT" id="sound1" gain="100" sync="start" waitforcompletion="1" />
+		</sequential>
+	</action>
+</case>
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index e96acda..31ad973 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -137,7 +137,8 @@
 
         <activity android:name="android.media.cts.MediaStubActivity"
             android:label="MediaStubActivity"
-            android:screenOrientation="nosensor">
+            android:screenOrientation="nosensor"
+            android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
diff --git a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
index dd73475..509be58 100644
--- a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -137,7 +137,7 @@
         for(int j = 0; j < 9; j++){
             assertTrue(fractions[j] >= 0.0);
             assertTrue(fractions[j] <= 1.0);
-            assertTrue(fractions[j + 1] != fractions[j]);
+            assertTrue(errorMessage(fractions), fractions[j + 1] != fractions[j]);
         }
     }
 
@@ -148,7 +148,7 @@
         float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue()", 200l, null);
 
         for(int j = 0; j < 9; j++){
-            assertTrue(animatedValues[j + 1] != animatedValues[j]);
+            assertTrue(errorMessage(animatedValues), animatedValues[j + 1] != animatedValues[j]);
         }
     }
     public void testGetAnimatedValue_PropertyName() throws Throwable {
@@ -160,7 +160,7 @@
         float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue(property)", 200l,
             property);
         for(int j = 0; j < 9; j++){
-            assertTrue(animatedValues[j + 1] != animatedValues[j]);
+            assertTrue(errorMessage(animatedValues), animatedValues[j + 1] != animatedValues[j]);
         }
     }
 
@@ -257,5 +257,13 @@
         };
         this.runTestOnUiThread(animationRunnable);
     }
+
+    private String errorMessage(float[] values) {
+        StringBuilder message = new StringBuilder();
+        for (int i = 0; i < values.length; i++) {
+            message.append(values[i]).append(" ");
+        }
+        return message.toString();
+    }
 }
 
diff --git a/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java
index 932a5d5..c84919a 100644
--- a/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java
+++ b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java
@@ -17,6 +17,7 @@
 package android.graphics2.cts;
 
 import android.graphics2.cts.TextureViewCameraActivity;
+import android.hardware.Camera;
 import android.test.ActivityInstrumentationTestCase2;
 
 
@@ -30,10 +31,16 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        if (Camera.getNumberOfCameras() < 1) {
+            return;
+        }
         mActivity = getActivity();
     }
 
     public void testTextureViewActivity() throws InterruptedException {
+        if (Camera.getNumberOfCameras() < 1) {
+            return;
+        }
         assertTrue(mActivity.waitForCompletion(WAIT_TIMEOUT_IN_SECS));
     }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 02b18de..3274d13 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -314,7 +314,7 @@
      * from the time setDisplay() was called
      */
     public void testVideoSurfaceResetting() throws Exception {
-        final int tolerance = 66 * 3 / 2; /* Test video is 15fps... 66 ms per frame */
+        final int tolerance = 150;
         final int audioLatencyTolerance = 1000;  /* covers audio path latency variability */
         final int seekPos = 5000;
 
diff --git a/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java b/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
index 4eec25c..60666ae 100644
--- a/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SlidingDrawerTest.java
@@ -123,7 +123,7 @@
             }
         });
         assertTrue(drawer.isMoving());
-        assertFalse(drawer.isOpened());
+        assertOpened(false, drawer);
         assertEquals(View.GONE, content.getVisibility());
 
         new PollingCheck() {
@@ -132,7 +132,7 @@
                 return !drawer.isMoving();
             }
         }.run();
-        assertTrue(drawer.isOpened());
+        assertOpened(true, drawer);
         assertEquals(View.VISIBLE, content.getVisibility());
 
         runTestOnUiThread(new Runnable() {
@@ -141,7 +141,7 @@
             }
         });
         assertTrue(drawer.isMoving());
-        assertTrue(drawer.isOpened());
+        assertOpened(true, drawer);
         assertEquals(View.GONE, content.getVisibility());
 
         new PollingCheck() {
@@ -150,7 +150,7 @@
                 return !drawer.isMoving();
             }
         }.run();
-        assertFalse(drawer.isOpened());
+        assertOpened(false, drawer);
         assertEquals(View.GONE, content.getVisibility());
     }