Merge "Tests for Condition." into nyc-dev
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordNotificationTest.java b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
similarity index 93%
rename from tests/tests/media/src/android/media/cts/AudioRecordNotificationTest.java
rename to tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
index 6a29aed..28d873c 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
@@ -22,13 +22,13 @@
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioRecord;
-import android.media.AudioRecordConfiguration;
+import android.media.AudioRecordingConfiguration;
 import android.media.MediaRecorder;
 import android.os.Looper;
 import android.util.Log;
 
-public class AudioRecordNotificationTest extends CtsAndroidTestCase {
-    private final static String TAG = "AudioRecordNotificationTest";
+public class AudioRecordingConfigurationTest extends CtsAndroidTestCase {
+    private final static String TAG = "AudioRecordingConfigurationTest";
 
     private final static int TEST_SAMPLE_RATE = 16000;
     private final static int TEST_AUDIO_SOURCE = MediaRecorder.AudioSource.VOICE_RECOGNITION;
@@ -97,7 +97,7 @@
         AudioManager am = new AudioManager(getContext());
         assertNotNull("Could not create AudioManager", am);
 
-        AudioRecordConfiguration[] configs = am.getActiveRecordConfigurations();
+        AudioRecordingConfiguration[] configs = am.getActiveRecordingConfigurations();
         assertNotNull("Invalid null array of record configurations before recording", configs);
 
         assertEquals(AudioRecord.STATE_INITIALIZED, mAudioRecord.getState());
@@ -106,7 +106,7 @@
         Thread.sleep(TEST_TIMING_TOLERANCE_MS);
 
         // recording is active, verify there is an active record configuration
-        configs = am.getActiveRecordConfigurations();
+        configs = am.getActiveRecordingConfigurations();
         assertNotNull("Invalid null array of record configurations during recording", configs);
         assertTrue("no active record configurations (empty array) during recording",
                 configs.length > 0);
@@ -120,7 +120,7 @@
         // stopping recording: verify there are less active record configurations
         mAudioRecord.stop();
         Thread.sleep(TEST_TIMING_TOLERANCE_MS);
-        configs = am.getActiveRecordConfigurations();
+        configs = am.getActiveRecordingConfigurations();
         assertTrue("end of recording not reported in record configs",
                 configs.length < nbConfigsDuringRecording);
     }
@@ -178,7 +178,7 @@
         }
 
         @Override
-        public void onRecordConfigChanged(AudioRecordConfiguration[] configs) {
+        public void onRecordConfigChanged(AudioRecordingConfiguration[] configs) {
             mCalled = true;
             mParamMatch = verifyAudioConfig(mTestSource, mTestSession, mAudioRecord.getFormat(),
                     mAudioRecord.getRoutedDevice(), configs);
@@ -192,7 +192,7 @@
     }
 
     private static boolean verifyAudioConfig(int source, int session, AudioFormat format,
-            AudioDeviceInfo device, AudioRecordConfiguration[] configs) {
+            AudioDeviceInfo device, AudioRecordingConfiguration[] configs) {
         for (int i = 0 ; i < configs.length ; i++) {
             if ((configs[i].getClientAudioSource() == source)
                     && (configs[i].getClientAudioSessionId() == session)
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index e311cc7..980398d 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -39,12 +39,12 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver.OnDrawListener;
 import android.view.animation.LayoutAnimationController;
-import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.cts.util.ViewTestUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -129,24 +129,19 @@
     }
 
     private void setAdapter(final ArrayAdapter<String> adapter) {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(adapter);
             }
         });
-        mInstrumentation.waitForIdleSync();
     }
 
     public void testAccessDividerHeight() {
-        final HasDrawnListener drawListener = new HasDrawnListener();
-
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
-                mListView.getViewTreeObserver().addOnDrawListener(drawListener);
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         Drawable d = mListView.getDivider();
         final Rect r = d.getBounds();
@@ -157,46 +152,25 @@
             }
         }.run();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
-                drawListener.reset();
                 mListView.setDividerHeight(20);
             }
         });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(drawListener.hasDrawn());
+
         assertEquals(20, mListView.getDividerHeight());
         assertEquals(20, r.bottom - r.top);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
-                drawListener.reset();
                 mListView.setDividerHeight(10);
             }
         });
-        mInstrumentation.waitForIdleSync();
-        assertTrue(drawListener.hasDrawn());
+
         assertEquals(10, mListView.getDividerHeight());
         assertEquals(10, r.bottom - r.top);
     }
 
-    static class HasDrawnListener implements OnDrawListener {
-        private boolean mHasDrawn;
-
-        @Override
-        public void onDraw() {
-            mHasDrawn = true;
-        }
-
-        public boolean hasDrawn() {
-            return mHasDrawn;
-        }
-
-        public void reset() {
-            mHasDrawn = false;
-        }
-    }
-
     public void testAccessItemsCanFocus() {
         mListView.setItemsCanFocus(true);
         assertTrue(mListView.getItemsCanFocus());
@@ -208,22 +182,20 @@
     }
 
     public void testAccessAdapter() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         assertSame(mAdapter_countries, mListView.getAdapter());
         assertEquals(mCountryList.length, mListView.getCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_names);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         assertSame(mAdapter_names, mListView.getAdapter());
         assertEquals(mNameList.length, mListView.getCount());
@@ -313,7 +285,6 @@
                 mListView.setFooterDividersEnabled(true);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(0, mListView.getFooterViewsCount());
 
         mInstrumentation.runOnMainSync(new Runnable() {
@@ -321,7 +292,6 @@
                 mListView.addFooterView(footerView1, null, true);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(1, mListView.getFooterViewsCount());
 
         mInstrumentation.runOnMainSync(new Runnable() {
@@ -333,27 +303,24 @@
         mInstrumentation.waitForIdleSync();
         assertEquals(2, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.removeFooterView(footerView1);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(1, mListView.getFooterViewsCount());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.removeFooterView(footerView2);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(0, mListView.getFooterViewsCount());
     }
 
@@ -366,7 +333,6 @@
                 mListView.setHeaderDividersEnabled(true);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(0, mListView.getHeaderViewsCount());
 
         mInstrumentation.runOnMainSync(new Runnable() {
@@ -374,7 +340,6 @@
                 mListView.addHeaderView(headerView2, null, true);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(1, mListView.getHeaderViewsCount());
 
         mInstrumentation.runOnMainSync(new Runnable() {
@@ -382,7 +347,6 @@
                 mListView.addHeaderView(headerView1);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(2, mListView.getHeaderViewsCount());
     }
 
@@ -414,32 +378,29 @@
                 return super.getCount() + 1;
             }
         };
-        runTestOnUiThread(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             @Override
             public void run() {
                 mListView.setAdapter(adapter);
             }
         });
-        getInstrumentation().waitForIdleSync();
 
-        runTestOnUiThread(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             @Override
             public void run() {
                 adapter.notifyDataSetChanged();
             }
         });
-        getInstrumentation().waitForIdleSync();
 
         assertEquals(0, mismatch.size());
     }
 
     public void testAccessDivider() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         Drawable defaultDrawable = mListView.getDivider();
         final Rect r = defaultDrawable.getBounds();
@@ -452,57 +413,51 @@
 
         final Drawable d = mActivity.getResources().getDrawable(R.drawable.scenery);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setDivider(d);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertSame(d, mListView.getDivider());
         assertEquals(d.getBounds().height(), mListView.getDividerHeight());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setDividerHeight(10);
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertEquals(10, mListView.getDividerHeight());
         assertEquals(10, d.getBounds().height());
     }
 
     public void testSetSelection() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setSelection(1);
             }
         });
-        mInstrumentation.waitForIdleSync();
         String item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[1], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setSelectionFromTop(5, 0);
             }
         });
-        mInstrumentation.waitForIdleSync();
         item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[5], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setSelectionAfterHeaderView();
             }
         });
-        mInstrumentation.waitForIdleSync();
         item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[0], item);
     }
@@ -512,20 +467,18 @@
     }
 
     public void testPerformItemClick() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setSelection(2);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         final TextView child = (TextView) mAdapter_countries.getView(2, null, mListView);
         assertNotNull(child);
@@ -564,33 +517,30 @@
     }
 
     public void testDispatchKeyEvent() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
                 mListView.requestFocus();
             }
         });
-        mInstrumentation.waitForIdleSync();
         assertTrue(mListView.hasFocus());
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setSelection(1);
             }
         });
-        mInstrumentation.waitForIdleSync();
         String item = (String) mListView.getSelectedItem();
         assertEquals(mCountryList[1], item);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
                 mListView.dispatchKeyEvent(keyEvent);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
                 mListView.dispatchKeyEvent(keyEvent);
@@ -598,18 +548,16 @@
                 mListView.dispatchKeyEvent(keyEvent);
             }
         });
-        mInstrumentation.waitForIdleSync();
         item = (String)mListView.getSelectedItem();
         assertEquals(mCountryList[4], item);
     }
 
     public void testRequestChildRectangleOnScreen() {
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             public void run() {
                 mListView.setAdapter(mAdapter_countries);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         TextView child = (TextView) mAdapter_countries.getView(0, null, mListView);
         assertNotNull(child);
@@ -828,27 +776,25 @@
         final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity,
                 android.R.layout.simple_list_item_1, items);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView, new Runnable() {
             @Override
             public void run() {
                 listView.setAdapter(adapter);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         final View oldItem = listView.getChildAt(2);
         final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
                 .getText();
         oldItem.setHasTransientState(true);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView, new Runnable() {
             @Override
             public void run() {
                 adapter.remove(adapter.getItem(0));
                 adapter.notifyDataSetChanged();
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         final View newItem = listView.getChildAt(2);
         final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
@@ -863,13 +809,12 @@
         final StableArrayAdapter<String> adapter = new StableArrayAdapter<String>(mActivity,
                 android.R.layout.simple_list_item_1, items);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, mListView, new Runnable() {
             @Override
             public void run() {
                 listView.setAdapter(adapter);
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         final Object tag = new Object();
         final View oldItem = listView.getChildAt(2);
@@ -878,14 +823,13 @@
         oldItem.setHasTransientState(true);
         oldItem.setTag(tag);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView, new Runnable() {
             @Override
             public void run() {
                 adapter.remove(adapter.getItem(0));
                 adapter.notifyDataSetChanged();
             }
         });
-        mInstrumentation.waitForIdleSync();
 
         final View newItem = listView.getChildAt(1);
         final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
diff --git a/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java b/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java
new file mode 100644
index 0000000..ca6c528
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/util/ViewTestUtils.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 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.widget.cts.util;
+
+import junit.framework.Assert;
+
+import android.app.Instrumentation;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnDrawListener;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utilities for testing View behavior.
+ */
+public class ViewTestUtils {
+
+    /**
+     * Runs the specified Runnable on the main thread and ensures that the
+     * specified View's tree is drawn before returning.
+     *
+     * @param instrumentation the instrumentation used to run the test
+     * @param view the view whose tree should be drawn before returning
+     * @param runner the runnable to run on the main thread
+     */
+    public static void runOnMainAndDrawSync(Instrumentation instrumentation,
+            final View view, final Runnable runner) {
+        final Semaphore token = new Semaphore(0);
+        final Runnable releaseToken = new Runnable() {
+            @Override
+            public void run() {
+                token.release();
+            }
+        };
+
+        instrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                final ViewTreeObserver observer = view.getViewTreeObserver();
+                final OnDrawListener listener = new OnDrawListener() {
+                    @Override
+                    public void onDraw() {
+                        observer.removeOnDrawListener(this);
+                        view.post(releaseToken);
+                    }
+                };
+
+                observer.addOnDrawListener(listener);
+                runner.run();
+            }
+        });
+
+        try {
+            Assert.assertTrue("Expected draw pass occurred within 5 seconds",
+                    token.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}