Merge "Fix WifiInfoTest flakiness" 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/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
index dd73475..7e86ce7 100644
--- a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -108,7 +108,7 @@
public void testCancel() throws Throwable {
startAnimation(mValueAnimator);
Thread.sleep(100);
- mValueAnimator.cancel();
+ cancelAnimation(mValueAnimator);
assertFalse(mValueAnimator.isRunning());
}
@@ -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,21 @@
};
this.runTestOnUiThread(animationRunnable);
}
-}
+ private void cancelAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ Thread animationRunnable = new Thread() {
+ public void run() {
+ mValueAnimator.cancel();
+ }
+ };
+ 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/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
new file mode 100644
index 0000000..5accd77
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+package android.net.wifi.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.net.wifi.p2p.WifiP2pManager;
+import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED;
+import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED;
+import android.test.AndroidTestCase;
+
+public class ConcurrencyTest extends AndroidTestCase {
+ private class MySync {
+ int expectedWifiState;
+ int expectedP2pState;
+ }
+
+ private WifiManager mWifiManager;
+ private MySync mMySync = new MySync();
+
+ private static final String TAG = "WifiInfoTest";
+ private static final int TIMEOUT_MSEC = 6000;
+ private static final int WAIT_MSEC = 60;
+ private static final int DURATION = 10000;
+ private IntentFilter mIntentFilter;
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ synchronized (mMySync) {
+ mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_DISABLED);
+ mMySync.notify();
+ }
+ } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
+ synchronized (mMySync) {
+ mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,
+ WifiP2pManager.WIFI_P2P_STATE_DISABLED);
+ mMySync.notify();
+ }
+ }
+ }
+ };
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (!WifiFeature.isWifiSupported(getContext()) &&
+ !WifiFeature.isP2pSupported(getContext())) {
+ // skip the test if WiFi && p2p are not supported
+ return;
+ }
+ mIntentFilter = new IntentFilter();
+ mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
+
+ mContext.registerReceiver(mReceiver, mIntentFilter);
+ mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+ assertNotNull(mWifiManager);
+ if (mWifiManager.isWifiEnabled()) {
+ assertTrue(mWifiManager.setWifiEnabled(false));
+ Thread.sleep(DURATION);
+ }
+ assertTrue(!mWifiManager.isWifiEnabled());
+ mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED;
+ mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext()) &&
+ !WifiFeature.isP2pSupported(getContext())) {
+ // skip the test if WiFi and p2p are not supported
+ super.tearDown();
+ return;
+ }
+ mContext.unregisterReceiver(mReceiver);
+
+ if (mWifiManager.isWifiEnabled()) {
+ assertTrue(mWifiManager.setWifiEnabled(false));
+ Thread.sleep(DURATION);
+ }
+ super.tearDown();
+ }
+
+ private void waitForBroadcasts() {
+ synchronized (mMySync) {
+ long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+ while (System.currentTimeMillis() < timeout
+ && (mMySync.expectedWifiState != WifiManager.WIFI_STATE_ENABLED ||
+ mMySync.expectedP2pState != WifiP2pManager.WIFI_P2P_STATE_ENABLED)) {
+ try {
+ mMySync.wait(WAIT_MSEC);
+ } catch (InterruptedException e) { }
+ }
+ }
+ }
+
+ public void testConcurrency() {
+ // Cannot support p2p alone
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ assertTrue(!WifiFeature.isP2pSupported(getContext()));
+ return;
+ }
+
+ if (!WifiFeature.isP2pSupported(getContext())) {
+ // skip the test if p2p is not supported
+ return;
+ }
+
+ // Enable wifi
+ assertTrue(mWifiManager.setWifiEnabled(true));
+
+ waitForBroadcasts();
+
+ assertTrue(mMySync.expectedWifiState == WifiManager.WIFI_STATE_ENABLED);
+ assertTrue(mMySync.expectedP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED);
+ }
+
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
index d7a83c3..63fa1dd 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
@@ -24,5 +24,9 @@
PackageManager packageManager = context.getPackageManager();
return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
}
-}
+ static boolean isP2pSupported(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
+ }
+}
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());
}