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 */
16package android.databinding.testapp;
17
18import android.app.Instrumentation;
19import android.content.Context;
20import android.databinding.testapp.databinding.TwoWayBinding;
21import android.databinding.testapp.vo.TwoWayBindingObject;
22import android.os.SystemClock;
23import android.text.Spannable;
24import android.text.SpannableString;
25import android.text.style.BackgroundColorSpan;
26import android.view.MotionEvent;
27import android.view.View;
28import android.view.ViewConfiguration;
29import android.view.ViewGroup;
30import android.widget.EditText;
31import android.widget.TabHost.TabSpec;
32
33import java.util.Calendar;
34import java.util.concurrent.CountDownLatch;
35import java.util.concurrent.TimeUnit;
36
37public 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