RemoteViewsTest.java revision 7b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12f
17da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos/* 27da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * Copyright (C) 2016 The Android Open Source Project 37da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * 47da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 57da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * you may not use this file except in compliance with the License. 67da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * You may obtain a copy of the License at 77da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * 87da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * http://www.apache.org/licenses/LICENSE-2.0 97da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * 107da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * Unless required by applicable law or agreed to in writing, software 117da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 127da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * See the License for the specific language governing permissions and 147da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * limitations under the License 157da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos */ 167da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 178376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovpackage android.widget; 187da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 197da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.content.Context; 207da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.graphics.Bitmap; 217da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.graphics.drawable.BitmapDrawable; 227da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.graphics.drawable.Drawable; 237b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyalimport android.os.AsyncTask; 245d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyalimport android.os.Parcel; 257da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.support.test.InstrumentationRegistry; 267da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.support.test.filters.SmallTest; 277da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport android.support.test.runner.AndroidJUnit4; 288376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport android.view.View; 297b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyalimport android.view.ViewGroup; 307da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 317da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport com.android.frameworks.coretests.R; 327da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 338376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport org.junit.Before; 348376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport org.junit.Rule; 358376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport org.junit.Test; 368376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport org.junit.rules.ExpectedException; 378376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikovimport org.junit.runner.RunWith; 388376f9eaa0bd41a9c7ce7ada4cb7c2cda28ef64cKirill Grouchnikov 397da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport static org.junit.Assert.assertEquals; 407da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roosimport static org.junit.Assert.assertSame; 415d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyalimport static org.junit.Assert.assertTrue; 427da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 437b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyalimport java.util.ArrayList; 447b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyalimport java.util.Arrays; 457b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyalimport java.util.concurrent.CountDownLatch; 467b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 477da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos/** 487da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos * Tests for RemoteViews. 497da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos */ 507da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos@RunWith(AndroidJUnit4.class) 517da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos@SmallTest 527da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roospublic class RemoteViewsTest { 537da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 545d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal // This can point to any other package which exists on the device. 555d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal private static final String OTHER_PACKAGE = "com.android.systemui"; 565d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 577da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Rule 587da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public final ExpectedException exception = ExpectedException.none(); 597da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 607da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos private Context mContext; 617da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos private String mPackage; 627da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos private LinearLayout mContainer; 637da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 647da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Before 657da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void setup() { 667da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos mContext = InstrumentationRegistry.getContext(); 674d10db7fdd1dc86684f31ec582872072fb02c350Adrian Roos mPackage = mContext.getPackageName(); 687da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos mContainer = new LinearLayout(mContext); 697da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 707da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 717da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 727da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_doesNotCopyBitmap() { 737da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 747da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); 757da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 767da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.setImageViewBitmap(R.id.image, bitmap); 777da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews clone = original.clone(); 787da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos View inflated = clone.apply(mContext, mContainer); 797da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 807da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos Drawable drawable = ((ImageView) inflated.findViewById(R.id.image)).getDrawable(); 817da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos assertSame(bitmap, ((BitmapDrawable)drawable).getBitmap()); 827da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 837da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 847da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 857da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_originalCanStillBeApplied() { 867da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 877da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 887da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews clone = original.clone(); 897da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 907da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos clone.apply(mContext, mContainer); 917da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 927da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 937da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 947da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_clones() { 957da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 967da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 977da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews clone = original.clone(); 987da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.setTextViewText(R.id.text, "test"); 997da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos View inflated = clone.apply(mContext, mContainer); 1007da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1017da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos TextView textView = (TextView) inflated.findViewById(R.id.text); 1027da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos assertEquals("", textView.getText()); 1037da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 1047da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1057da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 1067da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_child_fails() { 1077da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 1087da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews child = new RemoteViews(mPackage, R.layout.remote_views_test); 1097da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1107da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.addView(R.id.layout, child); 1117da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1127da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos exception.expect(IllegalStateException.class); 1137da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews clone = child.clone(); 1147da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 1157da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1167da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 1177da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_repeatedly() { 1187da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 1197da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1207da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.clone(); 1217da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.clone(); 1227da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1237da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos original.apply(mContext, mContainer); 1247da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 1257da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1267da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos @Test 1277da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos public void clone_chained() { 1287da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 1297da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1307da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos RemoteViews clone = original.clone().clone(); 1317da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1327da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos clone.apply(mContext, mContainer); 1337da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos } 1347da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos 1355d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal @Test 1365d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal public void parcelSize_nestedViews() { 1375d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); 1385d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal // We don't care about the actual layout id. 1395d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal RemoteViews child = new RemoteViews(mPackage, 33); 1405d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal int expectedSize = getParcelSize(original) + getParcelSize(child); 1415d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal original.addView(R.id.layout, child); 1425d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1435d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal // The application info will get written only once. 1445d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertTrue(getParcelSize(original) < expectedSize); 1455d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertEquals(getParcelSize(original), getParcelSize(original.clone())); 1465d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1475d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal original = new RemoteViews(mPackage, R.layout.remote_views_test); 1485d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal child = new RemoteViews(OTHER_PACKAGE, 33); 1495d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal expectedSize = getParcelSize(original) + getParcelSize(child); 1505d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal original.addView(R.id.layout, child); 1515d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1525d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal // Both the views will get written completely along with an additional view operation 1535d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertTrue(getParcelSize(original) > expectedSize); 1545d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertEquals(getParcelSize(original), getParcelSize(original.clone())); 1555d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal } 1565d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1575d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal @Test 1585d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal public void parcelSize_differentOrientation() { 1595d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test); 1605d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal RemoteViews portrait = new RemoteViews(mPackage, 33); 1615d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1625d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal // The application info will get written only once. 1635d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal RemoteViews views = new RemoteViews(landscape, portrait); 1645d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertTrue(getParcelSize(views) < (getParcelSize(landscape) + getParcelSize(portrait))); 1655d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal assertEquals(getParcelSize(views), getParcelSize(views.clone())); 1665d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal } 1675d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal 1685d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal private int getParcelSize(RemoteViews view) { 1695d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal Parcel parcel = Parcel.obtain(); 1705d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal view.writeToParcel(parcel, 0); 1715d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal int size = parcel.dataSize(); 1725d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal parcel.recycle(); 1735d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal return size; 1745d8bcdf6a575aa9e6eadb17e90ea21f5e4fc9c6bSunny Goyal } 1757b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 1767b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Test 1777b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void asyncApply_fail() throws Exception { 1787b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_test_bad_1); 1797b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewAppliedListener listener = new ViewAppliedListener(); 1807b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); 1817b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 1827b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal boolean exceptionThrown = false; 1837b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal try { 1847b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal listener.waitAndGetView(); 1857b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } catch (Exception e) { 1867b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal exceptionThrown = true; 1877b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 1887b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertTrue(exceptionThrown); 1897b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 1907b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 1917b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Test 1927b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void asyncApply() throws Exception { 1937b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); 1947b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.setTextViewText(R.id.text, "Dummy"); 1957b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 1967b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View syncView = views.apply(mContext, mContainer); 1977b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 1987b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewAppliedListener listener = new ViewAppliedListener(); 1997b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); 2007b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View asyncView = listener.waitAndGetView(); 2017b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2027b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTree(syncView, asyncView, "Dummy"); 2037b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2047b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2057b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Test 2067b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void asyncApply_viewStub() throws Exception { 2077b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_viewstub); 2087b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.setInt(R.id.viewStub, "setLayoutResource", R.layout.remote_views_text); 2097b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // This will cause the view to be inflated 2107b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.setViewVisibility(R.id.viewStub, View.INVISIBLE); 2117b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.setTextViewText(R.id.stub_inflated, "Dummy"); 2127b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2137b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View syncView = views.apply(mContext, mContainer); 2147b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2157b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewAppliedListener listener = new ViewAppliedListener(); 2167b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); 2177b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View asyncView = listener.waitAndGetView(); 2187b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2197b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTree(syncView, asyncView, "Dummy"); 2207b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2217b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2227b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Test 2237b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void asyncApply_nestedViews() throws Exception { 2247b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_host); 2257b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.removeAllViews(R.id.container); 2267b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.addView(R.id.container, createViewChained(1, "row1-c1", "row1-c2", "row1-c3")); 2277b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.addView(R.id.container, createViewChained(5, "row2-c1", "row2-c2")); 2287b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.addView(R.id.container, createViewChained(2, "row3-c1", "row3-c2")); 2297b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2307b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View syncView = views.apply(mContext, mContainer); 2317b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2327b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewAppliedListener listener = new ViewAppliedListener(); 2337b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); 2347b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View asyncView = listener.waitAndGetView(); 2357b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2367b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTree(syncView, asyncView, 2377b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal "row1-c1", "row1-c2", "row1-c3", "row2-c1", "row2-c2", "row3-c1", "row3-c2"); 2387b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2397b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2407b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Test 2417b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void asyncApply_viewstub_nestedViews() throws Exception { 2427b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews viewstub = new RemoteViews(mPackage, R.layout.remote_views_viewstub); 2437b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal viewstub.setInt(R.id.viewStub, "setLayoutResource", R.layout.remote_view_host); 2447b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // This will cause the view to be inflated 2457b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal viewstub.setViewVisibility(R.id.viewStub, View.INVISIBLE); 2467b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal viewstub.addView(R.id.stub_inflated, createViewChained(1, "row1-c1", "row1-c2", "row1-c3")); 2477b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2487b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_host); 2497b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.removeAllViews(R.id.container); 2507b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.addView(R.id.container, viewstub); 2517b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.addView(R.id.container, createViewChained(5, "row2-c1", "row2-c2")); 2527b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2537b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View syncView = views.apply(mContext, mContainer); 2547b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2557b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewAppliedListener listener = new ViewAppliedListener(); 2567b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); 2577b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal View asyncView = listener.waitAndGetView(); 2587b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2597b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTree(syncView, asyncView, "row1-c1", "row1-c2", "row1-c3", "row2-c1", "row2-c2"); 2607b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2617b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2627b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private RemoteViews createViewChained(int depth, String... texts) { 2637b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews result = new RemoteViews(mPackage, R.layout.remote_view_host); 2647b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2657b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // Create depth 2667b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews parent = result; 2677b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal while(depth > 0) { 2687b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal depth--; 2697b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews child = new RemoteViews(mPackage, R.layout.remote_view_host); 2707b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal parent.addView(R.id.container, child); 2717b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal parent = child; 2727b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2737b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2747b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // Add texts 2757b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal for (String text : texts) { 2767b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal RemoteViews child = new RemoteViews(mPackage, R.layout.remote_views_text); 2777b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal child.setTextViewText(R.id.text, text); 2787b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal parent.addView(R.id.container, child); 2797b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2807b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal return result; 2817b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2827b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2837b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private void verifyViewTree(View v1, View v2, String... texts) { 2847b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ArrayList<String> expectedTexts = new ArrayList<>(Arrays.asList(texts)); 2857b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTreeRecur(v1, v2, expectedTexts); 2867b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // Verify that all expected texts were found 2877b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertEquals(0, expectedTexts.size()); 2887b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 2897b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2907b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private void verifyViewTreeRecur(View v1, View v2, ArrayList<String> expectedTexts) { 2917b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertEquals(v1.getClass(), v2.getClass()); 2927b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 2937b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal if (v1 instanceof TextView) { 2947b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal String text = ((TextView) v1).getText().toString(); 2957b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertEquals(text, ((TextView) v2).getText().toString()); 2967b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal // Verify that the text was one of the expected texts and remove it from the list 2977b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertTrue(expectedTexts.remove(text)); 2987b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } else if (v1 instanceof ViewGroup) { 2997b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewGroup vg1 = (ViewGroup) v1; 3007b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal ViewGroup vg2 = (ViewGroup) v2; 3017b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal assertEquals(vg1.getChildCount(), vg2.getChildCount()); 3027b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal for (int i = vg1.getChildCount() - 1; i >= 0; i--) { 3037b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal verifyViewTreeRecur(vg1.getChildAt(i), vg2.getChildAt(i), expectedTexts); 3047b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3057b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3067b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3077b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3087b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private class ViewAppliedListener implements RemoteViews.OnViewAppliedListener { 3097b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3107b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private final CountDownLatch mLatch = new CountDownLatch(1); 3117b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private View mView; 3127b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal private Exception mError; 3137b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3147b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Override 3157b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void onViewApplied(View v) { 3167b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal mView = v; 3177b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal mLatch.countDown(); 3187b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3197b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3207b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal @Override 3217b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public void onError(Exception e) { 3227b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal mError = e; 3237b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal mLatch.countDown(); 3247b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3257b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3267b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal public View waitAndGetView() throws Exception { 3277b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal mLatch.await(); 3287b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal 3297b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal if (mError != null) { 3307b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal throw new Exception(mError); 3317b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3327b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal return mView; 3337b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3347b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal } 3357da889d81d2ff4c1704dc0a64389947fb30de5d8Adrian Roos} 336