Home | History | Annotate | Download | only in testapp
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.databinding.testapp;
     17 
     18 import android.app.Instrumentation;
     19 import android.content.Context;
     20 import android.databinding.testapp.databinding.TwoWayBinding;
     21 import android.databinding.testapp.vo.TwoWayBindingObject;
     22 import android.os.SystemClock;
     23 import android.text.Spannable;
     24 import android.text.SpannableString;
     25 import android.text.style.BackgroundColorSpan;
     26 import android.view.MotionEvent;
     27 import android.view.View;
     28 import android.view.ViewConfiguration;
     29 import android.view.ViewGroup;
     30 import android.widget.EditText;
     31 import android.widget.TabHost.TabSpec;
     32 
     33 import java.util.Calendar;
     34 import java.util.concurrent.CountDownLatch;
     35 import java.util.concurrent.TimeUnit;
     36 
     37 public class TwoWayBindingAdapterTest extends BaseDataBinderTest<TwoWayBinding> {
     38 
     39     TwoWayBindingObject mBindingObject;
     40 
     41     public TwoWayBindingAdapterTest() {
     42         super(TwoWayBinding.class);
     43     }
     44 
     45     @Override
     46     protected void setUp() throws Exception {
     47         super.setUp();
     48         initBinder(new Runnable() {
     49             @Override
     50             public void run() {
     51                 Context context = getBinder().getRoot().getContext();
     52                 mBindingObject = new TwoWayBindingObject(context);
     53                 getBinder().setObj(mBindingObject);
     54                 getBinder().executePendingBindings();
     55             }
     56         });
     57     }
     58 
     59     public void testListViewSelectedItemPosition() throws Throwable {
     60         makeVisible(mBinder.listView);
     61         runTestOnUiThread(new Runnable() {
     62             @Override
     63             public void run() {
     64                 assertEquals(0, mBindingObject.selectedItemPosition.get());
     65                 assertEquals(0, mBinder.listView.getSelectedItemPosition());
     66                 mBinder.listView.setSelection(1);
     67             }
     68         });
     69         long timeout = SystemClock.uptimeMillis() + 500;
     70         while (mBindingObject.selectedItemPosition.get() == 0 &&
     71                 SystemClock.uptimeMillis() < timeout) {
     72             Thread.sleep(1);
     73         }
     74         runTestOnUiThread(new Runnable() {
     75             @Override
     76             public void run() {
     77                 assertEquals(1, mBinder.listView.getSelectedItemPosition());
     78                 assertEquals(1, mBindingObject.selectedItemPosition.get());
     79             }
     80         });
     81     }
     82 
     83     private void clickView(final View view, float offsetX) throws Throwable {
     84         final int[] xy = new int[2];
     85         final int[] viewSize = new int[2];
     86         do {
     87             runTestOnUiThread(new Runnable() {
     88                 @Override
     89                 public void run() {
     90                     view.getLocationOnScreen(xy);
     91                     viewSize[0] = view.getWidth();
     92                     viewSize[1] = view.getHeight();
     93                 }
     94             });
     95         } while (xy[0] < 0 || xy[1] < 0);
     96 
     97         final float x = xy[0] + offsetX;
     98         final float y = xy[1] + (viewSize[1] / 2f);
     99 
    100         Instrumentation inst = getInstrumentation();
    101 
    102         long downTime = SystemClock.uptimeMillis();
    103         long eventTime = SystemClock.uptimeMillis();
    104 
    105         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
    106                 MotionEvent.ACTION_DOWN, x, y, 0);
    107         inst.sendPointerSync(event);
    108         inst.waitForIdleSync();
    109 
    110         eventTime = SystemClock.uptimeMillis();
    111         final int touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
    112         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
    113                 x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
    114         inst.sendPointerSync(event);
    115         inst.waitForIdleSync();
    116 
    117         eventTime = SystemClock.uptimeMillis();
    118         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
    119         inst.sendPointerSync(event);
    120         inst.waitForIdleSync();
    121     }
    122 
    123     private void clickChild(View view, float offsetX) throws Throwable {
    124         View childView = view;
    125         while (childView != null) {
    126             childView.callOnClick();
    127             if (childView instanceof ViewGroup) {
    128                 final ViewGroup viewGroup = (ViewGroup) childView;
    129                 if (viewGroup.getChildCount() > 0) {
    130                     childView = viewGroup.getChildAt(0);
    131                 } else {
    132                     childView = null;
    133                 }
    134             } else {
    135                 clickView(childView, offsetX);
    136                 childView = null;
    137             }
    138         }
    139     }
    140 
    141     public void testCalendarViewDate() throws Throwable {
    142         makeVisible(mBinder.calendarView);
    143         runTestOnUiThread(new Runnable() {
    144             @Override
    145             public void run() {
    146                 assertTrue(mBindingObject.date.get() != 0);
    147                 assertDatesMatch(mBindingObject.date.get(), mBinder.calendarView.getDate());
    148             }
    149         });
    150         final long[] date = new long[2];
    151         float offsetX = 0;
    152         long timeout = SystemClock.uptimeMillis() + 1500;
    153         do {
    154             // Just randomly poke at the CalendarView to set the date
    155             clickChild(mBinder.calendarView, offsetX);
    156             offsetX += 48;
    157             runTestOnUiThread(new Runnable() {
    158                 @Override
    159                 public void run() {
    160                     date[0] = mBinder.calendarView.getDate();
    161                     if (date[1] == 0) {
    162                         date[1] = date[0];
    163                     }
    164                 }
    165             });
    166         } while (date[0] == date[1] && SystemClock.uptimeMillis() < timeout);
    167 
    168         timeout = SystemClock.uptimeMillis() + 100;
    169         while (mBindingObject.date.get() == 0 && SystemClock.uptimeMillis() < timeout) {
    170             Thread.sleep(1);
    171         }
    172 
    173         assertDatesMatch(date[0], mBindingObject.date.get());
    174     }
    175 
    176     public void assertDatesMatch(long expectedTimeMillis, long testTimeMillis) {
    177         Calendar expected = Calendar.getInstance();
    178         expected.setTimeInMillis(expectedTimeMillis);
    179         Calendar testValue = Calendar.getInstance();
    180         testValue.setTimeInMillis(testTimeMillis);
    181         assertEquals(expected.get(Calendar.YEAR), testValue.get(Calendar.YEAR));
    182         assertEquals(expected.get(Calendar.MONTH), testValue.get(Calendar.MONTH));
    183         assertEquals(expected.get(Calendar.DAY_OF_MONTH),
    184                 testValue.get(Calendar.DAY_OF_MONTH));
    185     }
    186 
    187     public void testCheckBoxChecked() throws Throwable {
    188         makeVisible(mBinder.checkBox);
    189         runTestOnUiThread(new Runnable() {
    190             @Override
    191             public void run() {
    192                 assertFalse(mBindingObject.checked.get());
    193                 assertFalse(mBinder.checkBox.isChecked());
    194                 mBinder.checkBox.setChecked(true);
    195             }
    196         });
    197 
    198         final long timeout = SystemClock.uptimeMillis() + 500;
    199         while (!mBindingObject.checked.get() && SystemClock.uptimeMillis() < timeout) {
    200             Thread.sleep(1);
    201         }
    202 
    203         runTestOnUiThread(new Runnable() {
    204             @Override
    205             public void run() {
    206                 assertTrue(mBinder.checkBox.isChecked());
    207                 assertTrue(mBindingObject.checked.get());
    208             }
    209         });
    210     }
    211 
    212     private boolean focusOn(final View view) throws Throwable {
    213         runTestOnUiThread(new Runnable() {
    214             @Override
    215             public void run() {
    216                 view.requestFocus();
    217             }
    218         });
    219         long timeout = SystemClock.uptimeMillis() + 500;
    220         final boolean[] focused = new boolean[1];
    221         while (SystemClock.uptimeMillis() < timeout) {
    222             runTestOnUiThread(new Runnable() {
    223                 @Override
    224                 public void run() {
    225                     focused[0] = view.isFocused();
    226                 }
    227             });
    228             if (focused[0]) {
    229                 return true;
    230             }
    231         }
    232         return false;
    233     }
    234 
    235     public void testNumberPickerNumber() throws Throwable {
    236         makeVisible(mBinder.textView, mBinder.numberPicker);
    237         assertTrue(focusOn(mBinder.textView));
    238         final EditText[] pickerText = new EditText[1];
    239         runTestOnUiThread(new Runnable() {
    240             @Override
    241             public void run() {
    242                 assertEquals(1, mBindingObject.number.get());
    243                 assertEquals(1, mBinder.numberPicker.getValue());
    244                 for (int i = 0; i < mBinder.numberPicker.getChildCount(); i++) {
    245                     View view = mBinder.numberPicker.getChildAt(i);
    246                     if (view instanceof EditText) {
    247                         pickerText[0] = (EditText) view;
    248                         break;
    249                     }
    250                 }
    251             }
    252         });
    253         assertNotNull(pickerText[0]);
    254         assertTrue(focusOn(pickerText[0]));
    255         runTestOnUiThread(new Runnable() {
    256             @Override
    257             public void run() {
    258                 pickerText[0].setText("10");
    259             }
    260         });
    261         assertTrue(focusOn(mBinder.textView));
    262 
    263         final long timeout = SystemClock.uptimeMillis() + 10;
    264         while (mBindingObject.number.get() == 1 && SystemClock.uptimeMillis() < timeout) {
    265             Thread.sleep(1);
    266         }
    267 
    268         runTestOnUiThread(new Runnable() {
    269             @Override
    270             public void run() {
    271                 assertEquals(10, mBinder.numberPicker.getValue());
    272                 assertEquals(10, mBindingObject.number.get());
    273             }
    274         });
    275     }
    276 
    277     public void testRatingBarRating() throws Throwable {
    278         makeVisible(mBinder.ratingBar);
    279         runTestOnUiThread(new Runnable() {
    280             @Override
    281             public void run() {
    282                 assertEquals(1f, mBindingObject.rating.get());
    283                 assertEquals(1f, mBinder.ratingBar.getRating());
    284                 mBinder.ratingBar.setRating(2.5f);
    285             }
    286         });
    287 
    288         final long timeout = SystemClock.uptimeMillis() + 500;
    289         while (mBindingObject.rating.get() == 1f && SystemClock.uptimeMillis() < timeout) {
    290             Thread.sleep(1);
    291         }
    292 
    293         runTestOnUiThread(new Runnable() {
    294             @Override
    295             public void run() {
    296                 assertEquals(2.5f, mBinder.ratingBar.getRating());
    297                 assertEquals(2.5f, mBindingObject.rating.get());
    298             }
    299         });
    300     }
    301 
    302     public void testSeekBarProgress() throws Throwable {
    303         makeVisible(mBinder.seekBar);
    304         runTestOnUiThread(new Runnable() {
    305             @Override
    306             public void run() {
    307                 assertEquals(1, mBindingObject.progress.get());
    308                 assertEquals(1, mBinder.seekBar.getProgress());
    309                 mBinder.seekBar.setProgress(30);
    310             }
    311         });
    312 
    313         final long timeout = SystemClock.uptimeMillis() + 500;
    314         while (mBindingObject.progress.get() == 1 && SystemClock.uptimeMillis() < timeout) {
    315             Thread.sleep(1);
    316         }
    317 
    318         runTestOnUiThread(new Runnable() {
    319             @Override
    320             public void run() {
    321                 assertEquals(30, mBinder.seekBar.getProgress());
    322                 assertEquals(30, mBindingObject.progress.get());
    323             }
    324         });
    325     }
    326 
    327     public void testTabHostCurrentTab() throws Throwable {
    328         makeVisible(mBinder.tabhost);
    329         runTestOnUiThread(new Runnable() {
    330             @Override
    331             public void run() {
    332                 mBinder.tabhost.setup();
    333                 TabSpec tab1 = mBinder.tabhost.newTabSpec("Tab1");
    334                 TabSpec tab2 = mBinder.tabhost.newTabSpec("Tab2");
    335 
    336                 tab1.setIndicator("tab1");
    337                 tab1.setContent(R.id.foo);
    338                 tab2.setIndicator("tab2");
    339                 tab2.setContent(R.id.bar);
    340                 mBinder.tabhost.addTab(tab1);
    341                 mBinder.tabhost.addTab(tab2);
    342                 mBinder.tabhost.setCurrentTab(1);
    343             }
    344         });
    345 
    346         final long timeout = SystemClock.uptimeMillis() + 500;
    347         while (mBindingObject.currentTab.get() == 0 && SystemClock.uptimeMillis() < timeout) {
    348             Thread.sleep(1);
    349         }
    350 
    351         runTestOnUiThread(new Runnable() {
    352             @Override
    353             public void run() {
    354                 assertEquals(1, mBinder.tabhost.getCurrentTab());
    355                 assertEquals(1, mBindingObject.currentTab.get());
    356             }
    357         });
    358     }
    359 
    360     public void testTextViewText() throws Throwable {
    361         makeVisible(mBinder.textView);
    362         runTestOnUiThread(new Runnable() {
    363             @Override
    364             public void run() {
    365                 assertEquals(null, mBindingObject.text.get());
    366                 assertEquals("", mBinder.textView.getText().toString());
    367                 mBinder.textView.setText("Hello World");
    368             }
    369         });
    370 
    371         final long timeout = SystemClock.uptimeMillis() + 500;
    372         while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) {
    373             Thread.sleep(1);
    374         }
    375 
    376         runTestOnUiThread(new Runnable() {
    377             @Override
    378             public void run() {
    379                 assertEquals("Hello World", mBinder.textView.getText().toString());
    380                 assertEquals("Hello World", mBindingObject.text.get());
    381             }
    382         });
    383     }
    384 
    385     public void testDatePicker() throws Throwable {
    386         makeVisible(mBinder.datePicker);
    387         runTestOnUiThread(new Runnable() {
    388             @Override
    389             public void run() {
    390                 assertEquals(1972, mBindingObject.year.get());
    391                 assertEquals(9, mBindingObject.month.get());
    392                 assertEquals(21, mBindingObject.day.get());
    393                 assertEquals(1972, mBinder.datePicker.getYear());
    394                 assertEquals(9, mBinder.datePicker.getMonth());
    395                 assertEquals(21, mBinder.datePicker.getDayOfMonth());
    396                 mBinder.datePicker.updateDate(2003, 4, 17);
    397             }
    398         });
    399 
    400         final long timeout = SystemClock.uptimeMillis() + 500;
    401         while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) {
    402             Thread.sleep(1);
    403         }
    404 
    405         runTestOnUiThread(new Runnable() {
    406             @Override
    407             public void run() {
    408                 assertEquals(2003, mBindingObject.year.get());
    409                 assertEquals(4, mBindingObject.month.get());
    410                 assertEquals(17, mBindingObject.day.get());
    411             }
    412         });
    413     }
    414 
    415     public void testExpressions1() throws Throwable {
    416         makeVisible(mBinder.expressions1);
    417         runTestOnUiThread(new Runnable() {
    418             @Override
    419             public void run() {
    420                 assertEquals(1972, mBindingObject.year.get());
    421                 assertEquals(9, mBindingObject.month.get());
    422                 assertEquals(21, mBindingObject.day.get());
    423                 assertEquals(1972000, mBinder.expressions1.getYear());
    424                 assertEquals(2, mBinder.expressions1.getMonth());
    425                 assertEquals(22, mBinder.expressions1.getDayOfMonth());
    426                 mBinder.expressions1.updateDate(2003000, 3, 18);
    427             }
    428         });
    429 
    430         final long timeout = SystemClock.uptimeMillis() + 500;
    431         while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) {
    432             Thread.sleep(1);
    433         }
    434 
    435         runTestOnUiThread(new Runnable() {
    436             @Override
    437             public void run() {
    438                 assertEquals(2003, mBindingObject.year.get());
    439                 assertEquals(8, mBindingObject.month.get());
    440                 assertEquals(17, mBindingObject.day.get());
    441             }
    442         });
    443     }
    444 
    445     public void testExpressions2() throws Throwable {
    446         makeVisible(mBinder.expressions2);
    447         runTestOnUiThread(new Runnable() {
    448             @Override
    449             public void run() {
    450                 assertEquals(1972, mBindingObject.year.get());
    451                 assertEquals(9, mBindingObject.month.get());
    452                 assertEquals(21, mBindingObject.day.get());
    453                 assertEquals(1, mBinder.expressions2.getYear());
    454                 assertEquals(9, mBinder.expressions2.getMonth());
    455                 assertEquals(21, mBinder.expressions2.getDayOfMonth());
    456                 mBinder.expressions2.updateDate(2, 4, 17);
    457             }
    458         });
    459 
    460         final long timeout = SystemClock.uptimeMillis() + 500;
    461         while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) {
    462             Thread.sleep(1);
    463         }
    464 
    465         runTestOnUiThread(new Runnable() {
    466             @Override
    467             public void run() {
    468                 assertEquals(2000, mBindingObject.year.get());
    469                 assertEquals(4, mBindingObject.month.get());
    470                 assertEquals(17, mBindingObject.day.get());
    471             }
    472         });
    473     }
    474 
    475     public void testExpressions3() throws Throwable {
    476         makeVisible(mBinder.expressions3);
    477         runTestOnUiThread(new Runnable() {
    478             @Override
    479             public void run() {
    480                 assertEquals((Integer)1, mBindingObject.list.get(1));
    481                 assertEquals((Integer)2, mBindingObject.map.get("two"));
    482                 assertEquals(2, mBindingObject.array.get()[1]);
    483                 assertEquals(1, mBinder.expressions3.getYear());
    484                 assertEquals(2, mBinder.expressions3.getMonth());
    485                 assertEquals(2, mBinder.expressions3.getDayOfMonth());
    486                 mBinder.expressions3.updateDate(2003, 4, 17);
    487             }
    488         });
    489 
    490         final long timeout = SystemClock.uptimeMillis() + 500;
    491         while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) {
    492             Thread.sleep(1);
    493         }
    494 
    495         runTestOnUiThread(new Runnable() {
    496             @Override
    497             public void run() {
    498                 assertEquals((Integer)2003, mBindingObject.list.get(1));
    499                 assertEquals((Integer)4, mBindingObject.map.get("two"));
    500                 assertEquals(17, mBindingObject.array.get()[1]);
    501             }
    502         });
    503     }
    504 
    505     public void testExpressions4() throws Throwable {
    506         makeVisible(mBinder.expressions4);
    507         runTestOnUiThread(new Runnable() {
    508             @Override
    509             public void run() {
    510                 assertEquals(1972, mBindingObject.year.get());
    511                 assertEquals(9, mBindingObject.month.get());
    512                 assertEquals(21, mBindingObject.day.get());
    513                 assertEquals(50, mBinder.expressions4.getYear());
    514                 assertEquals(5, mBinder.expressions4.getMonth());
    515                 assertEquals(21, mBinder.expressions4.getDayOfMonth());
    516                 mBinder.expressions4.updateDate(49, 4, 17);
    517             }
    518         });
    519 
    520         final long timeout = SystemClock.uptimeMillis() + 500;
    521         while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) {
    522             Thread.sleep(1);
    523         }
    524 
    525         runTestOnUiThread(new Runnable() {
    526             @Override
    527             public void run() {
    528                 assertEquals(2040, mBindingObject.year.get());
    529                 assertEquals(6, mBindingObject.month.get());
    530                 assertEquals(17, mBindingObject.day.get());
    531             }
    532         });
    533     }
    534 
    535     public void testChaining() throws Throwable {
    536         makeVisible(mBinder.checkBox, mBinder.checkBox2);
    537         runTestOnUiThread(new Runnable() {
    538             @Override
    539             public void run() {
    540                 assertTrue(mBinder.checkBox2.isChecked());
    541                 mBindingObject.checked.set(true);
    542                 mBinder.executePendingBindings();
    543                 assertFalse(mBinder.checkBox2.isChecked());
    544             }
    545         });
    546     }
    547 
    548     public void testTwoWayChaining() throws Throwable {
    549         makeVisible(mBinder.checkBox3, mBinder.checkBox4);
    550         runTestOnUiThread(new Runnable() {
    551             @Override
    552             public void run() {
    553                 assertFalse(mBinder.checkBox3.isChecked());
    554                 assertTrue(mBinder.checkBox4.isChecked());
    555                 mBinder.checkBox3.setChecked(true);
    556                 mBinder.executePendingBindings();
    557                 assertTrue(mBinder.checkBox3.isChecked());
    558                 assertFalse(mBinder.checkBox4.isChecked());
    559             }
    560         });
    561     }
    562 
    563     public void testIncludedTwoWay1() throws Throwable {
    564         makeVisible(mBinder.included.editText1, mBinder.textView);
    565         runTestOnUiThread(new Runnable() {
    566             @Override
    567             public void run() {
    568                 assertEquals(null, mBindingObject.text.get());
    569                 assertEquals("", mBinder.textView.getText().toString());
    570                 assertEquals("", mBinder.included.editText1.getText().toString());
    571                 mBinder.included.editText1.setText("Hello World");
    572             }
    573         });
    574 
    575         final long timeout = SystemClock.uptimeMillis() + 500;
    576         while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) {
    577             Thread.sleep(1);
    578         }
    579 
    580         runTestOnUiThread(new Runnable() {
    581             @Override
    582             public void run() {
    583                 assertEquals("Hello World", mBinder.included.editText1.getText().toString());
    584                 assertEquals("Hello World", mBinder.textView.getText().toString());
    585                 assertEquals("Hello World", mBindingObject.text.get());
    586             }
    587         });
    588     }
    589 
    590     public void testIncludedTwoWay2() throws Throwable {
    591         makeVisible(mBinder.included.editText2, mBinder.textView);
    592         runTestOnUiThread(new Runnable() {
    593             @Override
    594             public void run() {
    595                 assertEquals(null, mBindingObject.text.get());
    596                 assertEquals("", mBinder.textView.getText().toString());
    597                 assertEquals("", mBinder.included.editText2.getText().toString());
    598                 mBinder.included.editText2.setText("Hello World");
    599             }
    600         });
    601 
    602         final long timeout = SystemClock.uptimeMillis() + 500;
    603         while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) {
    604             Thread.sleep(1);
    605         }
    606 
    607         runTestOnUiThread(new Runnable() {
    608             @Override
    609             public void run() {
    610                 assertEquals("Hello World", mBinder.included.editText2.getText().toString());
    611                 assertEquals("Hello World", mBinder.textView.getText().toString());
    612                 assertEquals("Hello World", mBindingObject.text.get());
    613             }
    614         });
    615     }
    616 
    617     public void testNoEditableLoop() throws Throwable {
    618         makeVisible(mBinder.editText1, mBinder.editText2);
    619 
    620         final SpannableString text = new SpannableString("Hello World Also");
    621         BackgroundColorSpan highlight = new BackgroundColorSpan(0xFFFFFF80);
    622         text.setSpan(highlight, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    623 
    624         mBindingObject.textLatch = new CountDownLatch(2);
    625         runTestOnUiThread(new Runnable() {
    626             @Override
    627             public void run() {
    628                 assertEquals("", mBinder.editText1.getText().toString());
    629                 assertEquals(0, mBindingObject.text1Changes);
    630                 assertEquals(0, mBindingObject.text2Changes);
    631 
    632                 // Change the text of one of the controls
    633                 mBinder.editText1.setText("Hello World");
    634             }
    635         });
    636 
    637         assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
    638         mBindingObject.textLatch = new CountDownLatch(2);
    639 
    640         runTestOnUiThread(new Runnable() {
    641             @Override
    642             public void run() {
    643                 assertNotNull(mBindingObject.editText.get());
    644                 assertEquals("Hello World", mBindingObject.editText.get().toString());
    645                 // They should both be set
    646                 assertEquals(1, mBindingObject.text1Changes);
    647                 assertEquals(1, mBindingObject.text2Changes);
    648 
    649                 // Edit the span, but the text remains the same.
    650                 mBinder.editText2.setText(text);
    651             }
    652         });
    653 
    654         assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
    655         mBindingObject.textLatch = new CountDownLatch(1);
    656 
    657         runTestOnUiThread(new Runnable() {
    658             @Override
    659             public void run() {
    660                 // The one control should notify a change, but not the other.
    661                 assertEquals(2, mBindingObject.text1Changes);
    662                 assertEquals(2, mBindingObject.text2Changes);
    663 
    664                 // No more changes should occur
    665                 mBinder.executePendingBindings();
    666             }
    667         });
    668 
    669         assertFalse(mBindingObject.textLatch.await(200, TimeUnit.MILLISECONDS));
    670         mBindingObject.textLatch = new CountDownLatch(2);
    671 
    672         runTestOnUiThread(new Runnable() {
    673             @Override
    674             public void run() {
    675                 // Nothing changed:
    676                 assertEquals(2, mBindingObject.text1Changes);
    677                 assertEquals(2, mBindingObject.text2Changes);
    678 
    679                 // Now try changing the value to the same thing. Because the
    680                 // value is Spannable, it will set it to the EditText
    681                 // and then get back a String in the onTextChanged.
    682                 mBindingObject.editText.set(text);
    683             }
    684         });
    685 
    686         assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
    687 
    688         runTestOnUiThread(new Runnable() {
    689             @Override
    690             public void run() {
    691                 assertEquals(3, mBindingObject.text1Changes);
    692                 assertEquals(3, mBindingObject.text2Changes);
    693                 assertEquals("Hello World Also", mBindingObject.editText.get());
    694             }
    695         });
    696     }
    697 
    698     public void testStringConversions() throws Throwable {
    699         makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
    700                 mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
    701                 mBinder.convertDouble, mBinder.convertChar);
    702         runTestOnUiThread(new Runnable() {
    703             @Override
    704             public void run() {
    705                 mBinder.convertBool.setText("True");
    706                 mBinder.convertByte.setText("123");
    707                 mBinder.convertShort.setText("1234");
    708                 mBinder.convertInt.setText("12345");
    709                 mBinder.convertLong.setText("123456");
    710                 mBinder.convertFloat.setText("1.2345");
    711                 mBinder.convertDouble.setText("1.23456");
    712                 mBinder.convertChar.setText("a");
    713             }
    714         });
    715 
    716         final long timeout = SystemClock.uptimeMillis() + 500;
    717         while (!mBindingObject.booleanField.get() && SystemClock.uptimeMillis() < timeout) {
    718             Thread.sleep(1);
    719         }
    720         getInstrumentation().waitForIdleSync();
    721         assertTrue(mBindingObject.booleanField.get());
    722         assertEquals(123, mBindingObject.byteField.get());
    723         assertEquals(1234, mBindingObject.shortField.get());
    724         assertEquals(12345, mBindingObject.intField.get());
    725         assertEquals(123456, mBindingObject.longField.get());
    726         assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
    727         assertEquals(1.23456, mBindingObject.doubleField.get(), 0.000001);
    728         assertEquals('a', mBindingObject.charField.get());
    729     }
    730 
    731     public void testBadStringConversions() throws Throwable {
    732         makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
    733                 mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
    734                 mBinder.convertDouble, mBinder.convertChar);
    735         mBindingObject.booleanField.set(true);
    736         mBindingObject.charField.set('1');
    737         mBindingObject.byteField.set((byte) 1);
    738         mBindingObject.shortField.set((short) 12);
    739         mBindingObject.intField.set(123);
    740         mBindingObject.longField.set(1234);
    741         mBindingObject.floatField.set(1.2345f);
    742         mBindingObject.doubleField.set(1.23456);
    743         runTestOnUiThread(new Runnable() {
    744             @Override
    745             public void run() {
    746                 mBinder.executePendingBindings();
    747                 mBinder.convertBool.setText("foobar");
    748                 mBinder.convertByte.setText("fred");
    749                 mBinder.convertShort.setText("wilma");
    750                 mBinder.convertInt.setText("barney");
    751                 mBinder.convertLong.setText("betty");
    752                 mBinder.convertFloat.setText("pebbles");
    753                 mBinder.convertDouble.setText("bam-bam");
    754                 mBinder.convertChar.setText("");
    755             }
    756         });
    757 
    758         final long timeout = SystemClock.uptimeMillis() + 500;
    759         while (mBindingObject.booleanField.get() && SystemClock.uptimeMillis() < timeout) {
    760             Thread.sleep(1);
    761         }
    762         getInstrumentation().waitForIdleSync();
    763         assertFalse(mBindingObject.booleanField.get());
    764         assertEquals(1, mBindingObject.byteField.get());
    765         assertEquals(12, mBindingObject.shortField.get());
    766         assertEquals(123, mBindingObject.intField.get());
    767         assertEquals(1234, mBindingObject.longField.get());
    768         assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
    769         assertEquals(1.23456, mBindingObject.doubleField.get(), 0.00001);
    770         assertEquals('1', mBindingObject.charField.get());
    771     }
    772 
    773     private void makeVisible(final View... views) throws Throwable {
    774         runTestOnUiThread(new Runnable() {
    775             @Override
    776             public void run() {
    777                 mBinder.calendarView.setVisibility(View.GONE);
    778                 mBinder.listView.setVisibility(View.GONE);
    779                 mBinder.checkBox.setVisibility(View.GONE);
    780                 mBinder.numberPicker.setVisibility(View.GONE);
    781                 mBinder.ratingBar.setVisibility(View.GONE);
    782                 mBinder.seekBar.setVisibility(View.GONE);
    783                 mBinder.tabhost.setVisibility(View.GONE);
    784                 mBinder.textView.setVisibility(View.GONE);
    785                 mBinder.timePicker.setVisibility(View.GONE);
    786                 mBinder.datePicker.setVisibility(View.GONE);
    787                 mBinder.expressions1.setVisibility(View.GONE);
    788                 mBinder.expressions2.setVisibility(View.GONE);
    789                 mBinder.expressions3.setVisibility(View.GONE);
    790                 mBinder.expressions4.setVisibility(View.GONE);
    791                 mBinder.checkBox2.setVisibility(View.GONE);
    792                 mBinder.checkBox3.setVisibility(View.GONE);
    793                 mBinder.checkBox4.setVisibility(View.GONE);
    794                 mBinder.editText1.setVisibility(View.GONE);
    795                 mBinder.editText2.setVisibility(View.GONE);
    796                 mBinder.included.editText1.setVisibility(View.GONE);
    797                 mBinder.included.editText2.setVisibility(View.GONE);
    798                 mBinder.convertBool.setVisibility(View.GONE);
    799                 mBinder.convertByte.setVisibility(View.GONE);
    800                 mBinder.convertShort.setVisibility(View.GONE);
    801                 mBinder.convertInt.setVisibility(View.GONE);
    802                 mBinder.convertLong.setVisibility(View.GONE);
    803                 mBinder.convertFloat.setVisibility(View.GONE);
    804                 mBinder.convertDouble.setVisibility(View.GONE);
    805                 mBinder.convertChar.setVisibility(View.GONE);
    806                 for (View view : views) {
    807                     view.setVisibility(View.VISIBLE);
    808                 }
    809             }
    810         });
    811         getInstrumentation().waitForIdleSync();
    812     }
    813 }
    814