Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 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 
     17 package android.widget.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertNotNull;
     22 import static org.junit.Assert.assertNull;
     23 import static org.junit.Assert.assertSame;
     24 import static org.junit.Assert.assertTrue;
     25 
     26 import android.app.Activity;
     27 import android.app.Instrumentation;
     28 import android.app.Instrumentation.ActivityMonitor;
     29 import android.app.PendingIntent;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.content.res.ColorStateList;
     33 import android.graphics.Bitmap;
     34 import android.graphics.BitmapFactory;
     35 import android.graphics.drawable.BitmapDrawable;
     36 import android.graphics.drawable.Icon;
     37 import android.net.Uri;
     38 import android.os.Bundle;
     39 import android.os.Parcel;
     40 import android.text.TextUtils;
     41 import android.util.TypedValue;
     42 import android.view.View;
     43 import android.view.ViewGroup;
     44 import android.widget.AbsoluteLayout;
     45 import android.widget.AnalogClock;
     46 import android.widget.Button;
     47 import android.widget.Chronometer;
     48 import android.widget.DatePicker;
     49 import android.widget.EditText;
     50 import android.widget.FrameLayout;
     51 import android.widget.GridLayout;
     52 import android.widget.GridView;
     53 import android.widget.ImageButton;
     54 import android.widget.ImageView;
     55 import android.widget.LinearLayout;
     56 import android.widget.ListView;
     57 import android.widget.NumberPicker;
     58 import android.widget.ProgressBar;
     59 import android.widget.RatingBar;
     60 import android.widget.RelativeLayout;
     61 import android.widget.RemoteViews;
     62 import android.widget.RemoteViews.ActionException;
     63 import android.widget.SeekBar;
     64 import android.widget.StackView;
     65 import android.widget.TextClock;
     66 import android.widget.TextView;
     67 import android.widget.ViewFlipper;
     68 import android.widget.cts.util.TestUtils;
     69 
     70 import androidx.test.InstrumentationRegistry;
     71 import androidx.test.annotation.UiThreadTest;
     72 import androidx.test.filters.LargeTest;
     73 import androidx.test.filters.MediumTest;
     74 import androidx.test.rule.ActivityTestRule;
     75 import androidx.test.runner.AndroidJUnit4;
     76 
     77 import com.android.compatibility.common.util.WidgetTestUtils;
     78 
     79 import org.junit.Before;
     80 import org.junit.Rule;
     81 import org.junit.Test;
     82 import org.junit.rules.ExpectedException;
     83 import org.junit.runner.RunWith;
     84 
     85 import java.io.File;
     86 import java.io.FileOutputStream;
     87 import java.io.IOException;
     88 import java.io.InputStream;
     89 import java.io.OutputStream;
     90 
     91 /**
     92  * Test {@link RemoteViews}.
     93  */
     94 @MediumTest
     95 @RunWith(AndroidJUnit4.class)
     96 public class RemoteViewsTest {
     97     private static final String PACKAGE_NAME = "android.widget.cts";
     98 
     99     private static final int INVALID_ID = -1;
    100 
    101     private static final long TEST_TIMEOUT = 5000;
    102 
    103     @Rule
    104     public ActivityTestRule<RemoteViewsCtsActivity> mActivityRule =
    105             new ActivityTestRule<>(RemoteViewsCtsActivity.class);
    106 
    107     @Rule
    108     public ExpectedException mExpectedException = ExpectedException.none();
    109 
    110     private Instrumentation mInstrumentation;
    111 
    112     private Context mContext;
    113 
    114     private RemoteViews mRemoteViews;
    115 
    116     private View mResult;
    117 
    118     @UiThreadTest
    119     @Before
    120     public void setup() {
    121         mInstrumentation = InstrumentationRegistry.getInstrumentation();
    122         mContext = mInstrumentation.getTargetContext();
    123         mRemoteViews = new RemoteViews(PACKAGE_NAME, R.layout.remoteviews_good);
    124         mResult = mRemoteViews.apply(mContext, null);
    125 
    126         // Add our host view to the activity behind this test. This is similar to how launchers
    127         // add widgets to the on-screen UI.
    128         ViewGroup root = (ViewGroup) mActivityRule.getActivity().findViewById
    129                 (R.id.remoteView_host);
    130         FrameLayout.MarginLayoutParams lp = new FrameLayout.MarginLayoutParams(
    131                 ViewGroup.LayoutParams.MATCH_PARENT,
    132                 ViewGroup.LayoutParams.MATCH_PARENT);
    133         mResult.setLayoutParams(lp);
    134 
    135         root.addView(mResult);
    136     }
    137 
    138     @Test
    139     public void testConstructor() {
    140         new RemoteViews(PACKAGE_NAME, R.layout.remoteviews_good);
    141 
    142         new RemoteViews(Parcel.obtain());
    143     }
    144 
    145     @Test
    146     public void testGetPackage() {
    147         assertEquals(PACKAGE_NAME, mRemoteViews.getPackage());
    148 
    149         mRemoteViews = new RemoteViews(null, R.layout.remoteviews_good);
    150         assertNull(mRemoteViews.getPackage());
    151     }
    152 
    153     @Test
    154     public void testGetLayoutId() {
    155         assertEquals(R.layout.remoteviews_good, mRemoteViews.getLayoutId());
    156 
    157         mRemoteViews = new RemoteViews(PACKAGE_NAME, R.layout.listview_layout);
    158         assertEquals(R.layout.listview_layout, mRemoteViews.getLayoutId());
    159 
    160         mRemoteViews = new RemoteViews(PACKAGE_NAME, INVALID_ID);
    161         assertEquals(INVALID_ID, mRemoteViews.getLayoutId());
    162 
    163         mRemoteViews = new RemoteViews(PACKAGE_NAME, 0);
    164         assertEquals(0, mRemoteViews.getLayoutId());
    165     }
    166 
    167     @Test
    168     public void testSetContentDescription() throws Throwable {
    169         View view = mResult.findViewById(R.id.remoteView_frame);
    170 
    171         assertNull(view.getContentDescription());
    172 
    173         CharSequence contentDescription = mContext.getString(R.string.remote_content_description);
    174         mRemoteViews.setContentDescription(R.id.remoteView_frame, contentDescription);
    175         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    176         assertTrue(TextUtils.equals(contentDescription, view.getContentDescription()));
    177     }
    178 
    179     @Test
    180     public void testSetViewVisibility() throws Throwable {
    181         View view = mResult.findViewById(R.id.remoteView_chronometer);
    182         assertEquals(View.VISIBLE, view.getVisibility());
    183 
    184         mRemoteViews.setViewVisibility(R.id.remoteView_chronometer, View.INVISIBLE);
    185         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    186         assertEquals(View.INVISIBLE, view.getVisibility());
    187 
    188         mRemoteViews.setViewVisibility(R.id.remoteView_chronometer, View.GONE);
    189         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    190         assertEquals(View.GONE, view.getVisibility());
    191 
    192         mRemoteViews.setViewVisibility(R.id.remoteView_chronometer, View.VISIBLE);
    193         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    194         assertEquals(View.VISIBLE, view.getVisibility());
    195     }
    196 
    197     @Test
    198     public void testSetTextViewText() throws Throwable {
    199         TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
    200         assertEquals("", textView.getText().toString());
    201 
    202         String expected = "This is content";
    203         mRemoteViews.setTextViewText(R.id.remoteView_text, expected);
    204         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    205         assertEquals(expected, textView.getText().toString());
    206 
    207         mRemoteViews.setTextViewText(R.id.remoteView_text, null);
    208         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    209         assertEquals("", textView.getText().toString());
    210 
    211         mExpectedException.expect(ActionException.class);
    212         mRemoteViews.setTextViewText(R.id.remoteView_absolute, "");
    213         mRemoteViews.reapply(mContext, mResult);
    214     }
    215 
    216     @Test
    217     public void testSetTextViewTextSize() throws Throwable {
    218         TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
    219 
    220         mRemoteViews.setTextViewTextSize(R.id.remoteView_text, TypedValue.COMPLEX_UNIT_SP, 18);
    221         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    222         assertEquals(mContext.getResources().getDisplayMetrics().scaledDensity * 18,
    223                 textView.getTextSize(), 0.001f);
    224 
    225         mExpectedException.expect(Throwable.class);
    226         mRemoteViews.setTextViewTextSize(R.id.remoteView_absolute, TypedValue.COMPLEX_UNIT_SP, 20);
    227         mRemoteViews.reapply(mContext, mResult);
    228     }
    229 
    230     @Test
    231     public void testSetIcon() throws Throwable {
    232         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    233         assertNull(image.getDrawable());
    234 
    235         Icon iconBlack = Icon.createWithResource(mContext, R.drawable.icon_black);
    236         mRemoteViews.setIcon(R.id.remoteView_image, "setImageIcon", iconBlack);
    237         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    238         assertNotNull(image.getDrawable());
    239         BitmapDrawable dBlack = (BitmapDrawable) mContext.getDrawable(R.drawable.icon_black);
    240         WidgetTestUtils.assertEquals(dBlack.getBitmap(),
    241                 ((BitmapDrawable) image.getDrawable()).getBitmap());
    242     }
    243 
    244     @Test
    245     public void testSetImageViewIcon() throws Throwable {
    246         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    247         assertNull(image.getDrawable());
    248 
    249         Icon iconBlue = Icon.createWithResource(mContext, R.drawable.icon_blue);
    250         mRemoteViews.setImageViewIcon(R.id.remoteView_image, iconBlue);
    251         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    252         assertNotNull(image.getDrawable());
    253         BitmapDrawable dBlue = (BitmapDrawable) mContext.getDrawable(R.drawable.icon_blue);
    254         WidgetTestUtils.assertEquals(dBlue.getBitmap(),
    255                 ((BitmapDrawable) image.getDrawable()).getBitmap());
    256 
    257     }
    258 
    259     @Test
    260     public void testSetImageViewResource() throws Throwable {
    261         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    262         assertNull(image.getDrawable());
    263 
    264         mRemoteViews.setImageViewResource(R.id.remoteView_image, R.drawable.testimage);
    265         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    266         assertNotNull(image.getDrawable());
    267         BitmapDrawable d = (BitmapDrawable) mContext.getDrawable(R.drawable.testimage);
    268         WidgetTestUtils.assertEquals(d.getBitmap(),
    269                 ((BitmapDrawable) image.getDrawable()).getBitmap());
    270 
    271         mExpectedException.expect(ActionException.class);
    272         mRemoteViews.setImageViewResource(R.id.remoteView_absolute, R.drawable.testimage);
    273         mRemoteViews.reapply(mContext, mResult);
    274     }
    275 
    276     @Test
    277     public void testSetImageViewUri() throws Throwable {
    278         String path = getTestImagePath();
    279         File imageFile = new File(path);
    280 
    281         try {
    282             createSampleImage(imageFile, R.raw.testimage);
    283 
    284             Uri uri = Uri.parse(path);
    285             ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    286             assertNull(image.getDrawable());
    287 
    288             mRemoteViews.setImageViewUri(R.id.remoteView_image, uri);
    289             mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    290 
    291             Bitmap imageViewBitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
    292             Bitmap expectedBitmap = WidgetTestUtils.getUnscaledAndDitheredBitmap(
    293                     mContext.getResources(), R.raw.testimage, imageViewBitmap.getConfig());
    294             WidgetTestUtils.assertEquals(expectedBitmap, imageViewBitmap);
    295         } finally {
    296             imageFile.delete();
    297         }
    298     }
    299 
    300     /**
    301      * Returns absolute file path of location where test image should be stored
    302      */
    303     private String getTestImagePath() {
    304         return mContext.getFilesDir() + "/test.jpg";
    305     }
    306 
    307     @Test
    308     public void testSetChronometer() throws Throwable {
    309         long base1 = 50;
    310         long base2 = -50;
    311         Chronometer chronometer = (Chronometer) mResult.findViewById(R.id.remoteView_chronometer);
    312 
    313         mRemoteViews.setChronometer(R.id.remoteView_chronometer, base1, "HH:MM:SS",
    314                 false);
    315         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    316         assertEquals(base1, chronometer.getBase());
    317         assertEquals("HH:MM:SS", chronometer.getFormat());
    318 
    319         mRemoteViews.setChronometer(R.id.remoteView_chronometer, base2, "HH:MM:SS",
    320                 false);
    321         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    322         assertEquals(base2, chronometer.getBase());
    323         assertEquals("HH:MM:SS", chronometer.getFormat());
    324 
    325         mRemoteViews.setChronometer(R.id.remoteView_chronometer, base1, "invalid",
    326                 true);
    327         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    328         assertEquals(base1, chronometer.getBase());
    329         assertEquals("invalid", chronometer.getFormat());
    330 
    331         mExpectedException.expect(ActionException.class);
    332         mRemoteViews.setChronometer(R.id.remoteView_absolute, base1, "invalid", true);
    333         mRemoteViews.reapply(mContext, mResult);
    334     }
    335 
    336     @Test
    337     public void testSetChronometerCountDown() throws Throwable {
    338         Chronometer chronometer = (Chronometer) mResult.findViewById(R.id.remoteView_chronometer);
    339 
    340         mRemoteViews.setChronometerCountDown(R.id.remoteView_chronometer, true);
    341         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    342         assertTrue(chronometer.isCountDown());
    343 
    344         mRemoteViews.setChronometerCountDown(R.id.remoteView_chronometer, false);
    345         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    346         assertFalse(chronometer.isCountDown());
    347 
    348         mExpectedException.expect(ActionException.class);
    349         mRemoteViews.setChronometerCountDown(R.id.remoteView_absolute, true);
    350         mRemoteViews.reapply(mContext, mResult);
    351     }
    352 
    353     @Test
    354     public void testSetProgressBar() throws Throwable {
    355         ProgressBar progress = (ProgressBar) mResult.findViewById(R.id.remoteView_progress);
    356         assertEquals(100, progress.getMax());
    357         assertEquals(0, progress.getProgress());
    358         // the view uses style progressBarHorizontal, so the default is false
    359         assertFalse(progress.isIndeterminate());
    360 
    361         mRemoteViews.setProgressBar(R.id.remoteView_progress, 80, 50, true);
    362         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    363         // make the bar indeterminate will not affect max and progress
    364         assertEquals(100, progress.getMax());
    365         assertEquals(0, progress.getProgress());
    366         assertTrue(progress.isIndeterminate());
    367 
    368         mRemoteViews.setProgressBar(R.id.remoteView_progress, 60, 50, false);
    369         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    370         assertEquals(60, progress.getMax());
    371         assertEquals(50, progress.getProgress());
    372         assertFalse(progress.isIndeterminate());
    373 
    374         mExpectedException.expect(ActionException.class);
    375         mRemoteViews.setProgressBar(R.id.remoteView_relative, 60, 50, false);
    376         mRemoteViews.reapply(mContext, mResult);
    377     }
    378 
    379     @Test
    380     public void testApply() {
    381         assertNotNull(mResult);
    382         assertNotNull(mResult.findViewById(R.id.remoteViews_good));
    383         assertNotNull(mResult.findViewById(R.id.remoteView_absolute));
    384         assertNotNull(mResult.findViewById(R.id.remoteView_chronometer));
    385         assertNotNull(mResult.findViewById(R.id.remoteView_frame));
    386         assertNotNull(mResult.findViewById(R.id.remoteView_image));
    387         assertNotNull(mResult.findViewById(R.id.remoteView_linear));
    388         assertNotNull(mResult.findViewById(R.id.remoteView_progress));
    389         assertNotNull(mResult.findViewById(R.id.remoteView_relative));
    390         assertNotNull(mResult.findViewById(R.id.remoteView_text));
    391     }
    392 
    393     @Test
    394     public void testReapply() throws Throwable {
    395         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    396         assertNull(image.getDrawable());
    397 
    398         mRemoteViews.setImageViewResource(R.id.remoteView_image, R.drawable.testimage);
    399         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, image));
    400         assertNotNull(image.getDrawable());
    401         BitmapDrawable d = (BitmapDrawable) mContext
    402                 .getResources().getDrawable(R.drawable.testimage);
    403         WidgetTestUtils.assertEquals(d.getBitmap(),
    404                 ((BitmapDrawable) image.getDrawable()).getBitmap());
    405     }
    406 
    407     @Test
    408     public void testOnLoadClass() {
    409         mRemoteViews = new RemoteViews(Parcel.obtain());
    410 
    411         assertTrue(mRemoteViews.onLoadClass(AbsoluteLayout.class));
    412         assertTrue(mRemoteViews.onLoadClass(AnalogClock.class));
    413         assertTrue(mRemoteViews.onLoadClass(Button.class));
    414         assertTrue(mRemoteViews.onLoadClass(Chronometer.class));
    415         assertTrue(mRemoteViews.onLoadClass(FrameLayout.class));
    416         assertTrue(mRemoteViews.onLoadClass(GridLayout.class));
    417         assertTrue(mRemoteViews.onLoadClass(GridView.class));
    418         assertTrue(mRemoteViews.onLoadClass(ImageButton.class));
    419         assertTrue(mRemoteViews.onLoadClass(ImageView.class));
    420         assertTrue(mRemoteViews.onLoadClass(LinearLayout.class));
    421         assertTrue(mRemoteViews.onLoadClass(ListView.class));
    422         assertTrue(mRemoteViews.onLoadClass(ProgressBar.class));
    423         assertTrue(mRemoteViews.onLoadClass(RelativeLayout.class));
    424         assertTrue(mRemoteViews.onLoadClass(StackView.class));
    425         assertTrue(mRemoteViews.onLoadClass(TextClock.class));
    426         assertTrue(mRemoteViews.onLoadClass(TextView.class));
    427         assertTrue(mRemoteViews.onLoadClass(ViewFlipper.class));
    428 
    429         // those classes without annotation @RemoteView
    430         assertFalse(mRemoteViews.onLoadClass(EditText.class));
    431         assertFalse(mRemoteViews.onLoadClass(DatePicker.class));
    432         assertFalse(mRemoteViews.onLoadClass(NumberPicker.class));
    433         assertFalse(mRemoteViews.onLoadClass(RatingBar.class));
    434         assertFalse(mRemoteViews.onLoadClass(SeekBar.class));
    435     }
    436 
    437     @Test
    438     public void testDescribeContents() {
    439         mRemoteViews = new RemoteViews(Parcel.obtain());
    440         mRemoteViews.describeContents();
    441     }
    442 
    443     @Test
    444     public void testWriteToParcel() {
    445         mRemoteViews.setTextViewText(R.id.remoteView_text, "This is content");
    446         mRemoteViews.setViewVisibility(R.id.remoteView_frame, View.GONE);
    447         Parcel p = Parcel.obtain();
    448         mRemoteViews.writeToParcel(p, 0);
    449         p.setDataPosition(0);
    450 
    451         // the package and layout are successfully written into parcel
    452         mRemoteViews = RemoteViews.CREATOR.createFromParcel(p);
    453         View result = mRemoteViews.apply(mContext, null);
    454         assertEquals(PACKAGE_NAME, mRemoteViews.getPackage());
    455         assertEquals(R.layout.remoteviews_good, mRemoteViews.getLayoutId());
    456         assertEquals("This is content", ((TextView) result.findViewById(R.id.remoteView_text))
    457                 .getText().toString());
    458         assertEquals(View.GONE, result.findViewById(R.id.remoteView_frame).getVisibility());
    459 
    460         p = Parcel.obtain();
    461 
    462         // currently the flag is not used
    463         mRemoteViews.writeToParcel(p, -1);
    464 
    465         p.recycle();
    466 
    467         RemoteViews[] remote = RemoteViews.CREATOR.newArray(1);
    468         assertNotNull(remote);
    469         assertEquals(1, remote.length);
    470     }
    471 
    472     @Test(expected=NullPointerException.class)
    473     public void testWriteNullToParcel() {
    474         mRemoteViews.writeToParcel(null, 0);
    475     }
    476 
    477     @Test(expected=NegativeArraySizeException.class)
    478     public void testCreateNegativeSizedArray() {
    479         RemoteViews.CREATOR.newArray(-1);
    480     }
    481 
    482     @Test
    483     public void testSetImageViewBitmap() throws Throwable {
    484         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    485         assertNull(image.getDrawable());
    486 
    487         Bitmap bitmap =
    488                 BitmapFactory.decodeResource(mContext.getResources(), R.drawable.testimage);
    489         mRemoteViews.setImageViewBitmap(R.id.remoteView_image, bitmap);
    490         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    491         assertNotNull(image.getDrawable());
    492         WidgetTestUtils.assertEquals(bitmap, ((BitmapDrawable) image.getDrawable()).getBitmap());
    493 
    494         mExpectedException.expect(ActionException.class);
    495         mRemoteViews.setImageViewBitmap(R.id.remoteView_absolute, bitmap);
    496         mRemoteViews.reapply(mContext, mResult);
    497     }
    498 
    499     @Test
    500     public void testSetBitmap() throws Throwable {
    501         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    502         assertNull(image.getDrawable());
    503 
    504         Bitmap bitmap =
    505                 BitmapFactory.decodeResource(mContext.getResources(), R.drawable.testimage);
    506         mRemoteViews.setBitmap(R.id.remoteView_image, "setImageBitmap", bitmap);
    507         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    508         assertNotNull(image.getDrawable());
    509         WidgetTestUtils.assertEquals(bitmap, ((BitmapDrawable) image.getDrawable()).getBitmap());
    510 
    511         mExpectedException.expect(ActionException.class);
    512         mRemoteViews.setBitmap(R.id.remoteView_absolute, "setImageBitmap", bitmap);
    513         mRemoteViews.reapply(mContext, mResult);
    514     }
    515 
    516     @Test
    517     public void testSetBoolean() throws Throwable {
    518         ProgressBar progress = (ProgressBar) mResult.findViewById(R.id.remoteView_progress);
    519         // the view uses style progressBarHorizontal, so the default is false
    520         assertFalse(progress.isIndeterminate());
    521 
    522         mRemoteViews.setBoolean(R.id.remoteView_progress, "setIndeterminate", true);
    523         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    524         assertTrue(progress.isIndeterminate());
    525 
    526         mExpectedException.expect(ActionException.class);
    527         mRemoteViews.setBoolean(R.id.remoteView_relative, "setIndeterminate", false);
    528         mRemoteViews.reapply(mContext, mResult);
    529     }
    530 
    531     @Test
    532     public void testSetCharSequence() throws Throwable {
    533         TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
    534         assertEquals("", textView.getText().toString());
    535 
    536         String expected = "test setCharSequence";
    537         mRemoteViews.setCharSequence(R.id.remoteView_text, "setText", expected);
    538         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    539         assertEquals(expected, textView.getText().toString());
    540 
    541         mRemoteViews.setCharSequence(R.id.remoteView_text, "setText", null);
    542         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    543         assertEquals("", textView.getText().toString());
    544 
    545         mExpectedException.expect(ActionException.class);
    546         mRemoteViews.setCharSequence(R.id.remoteView_absolute, "setText", "");
    547         mRemoteViews.reapply(mContext, mResult);
    548     }
    549 
    550     @Test
    551     public void testSetInt() throws Throwable {
    552         View view = mResult.findViewById(R.id.remoteView_chronometer);
    553         assertEquals(View.VISIBLE, view.getVisibility());
    554 
    555         mRemoteViews.setInt(R.id.remoteView_chronometer, "setVisibility", View.INVISIBLE);
    556         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    557         assertEquals(View.INVISIBLE, view.getVisibility());
    558 
    559         mRemoteViews.setInt(R.id.remoteView_chronometer, "setVisibility", View.GONE);
    560         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    561         assertEquals(View.GONE, view.getVisibility());
    562 
    563         mRemoteViews.setInt(R.id.remoteView_chronometer, "setVisibility", View.VISIBLE);
    564         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    565         assertEquals(View.VISIBLE, view.getVisibility());
    566     }
    567 
    568     @Test
    569     public void testSetString() throws Throwable {
    570         String format = "HH:MM:SS";
    571         Chronometer chronometer = (Chronometer) mResult.findViewById(R.id.remoteView_chronometer);
    572         assertNull(chronometer.getFormat());
    573 
    574         mRemoteViews.setString(R.id.remoteView_chronometer, "setFormat", format);
    575         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    576         assertEquals(format, chronometer.getFormat());
    577 
    578         mExpectedException.expect(ActionException.class);
    579         mRemoteViews.setString(R.id.remoteView_image, "setFormat", format);
    580         mRemoteViews.reapply(mContext, mResult);
    581     }
    582 
    583     @Test
    584     public void testSetUri() throws Throwable {
    585         String path = getTestImagePath();
    586         File imagefile = new File(path);
    587 
    588         try {
    589             createSampleImage(imagefile, R.raw.testimage);
    590 
    591             Uri uri = Uri.parse(path);
    592             ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
    593             assertNull(image.getDrawable());
    594 
    595             mRemoteViews.setUri(R.id.remoteView_image, "setImageURI", uri);
    596             mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    597 
    598             Bitmap imageViewBitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
    599             Bitmap expectedBitmap = WidgetTestUtils.getUnscaledAndDitheredBitmap(
    600                     mContext.getResources(), R.raw.testimage, imageViewBitmap.getConfig());
    601             WidgetTestUtils.assertEquals(expectedBitmap, imageViewBitmap);
    602 
    603             mExpectedException.expect(ActionException.class);
    604             mRemoteViews.setUri(R.id.remoteView_absolute, "setImageURI", uri);
    605             mRemoteViews.reapply(mContext, mResult);
    606         } finally {
    607             // remove the test image file
    608             imagefile.delete();
    609         }
    610     }
    611 
    612     @Test
    613     public void testSetTextColor() throws Throwable {
    614         TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
    615 
    616         mRemoteViews.setTextColor(R.id.remoteView_text, R.color.testcolor1);
    617         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    618         assertSame(ColorStateList.valueOf(R.color.testcolor1), textView.getTextColors());
    619 
    620         mRemoteViews.setTextColor(R.id.remoteView_text, R.color.testcolor2);
    621         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    622         assertSame(ColorStateList.valueOf(R.color.testcolor2), textView.getTextColors());
    623 
    624         mExpectedException.expect(ActionException.class);
    625         mRemoteViews.setTextColor(R.id.remoteView_absolute, R.color.testcolor1);
    626         mRemoteViews.reapply(mContext, mResult);
    627     }
    628 
    629     @Test
    630     public void testSetTextCompoundDrawables() throws Throwable {
    631         TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
    632 
    633         TestUtils.verifyCompoundDrawables(textView, -1, -1, -1, -1);
    634 
    635         mRemoteViews.setTextViewCompoundDrawables(R.id.remoteView_text, R.drawable.start,
    636                 R.drawable.pass, R.drawable.failed, 0);
    637         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    638         TestUtils.verifyCompoundDrawables(textView, R.drawable.start, R.drawable.failed,
    639                 R.drawable.pass, -1);
    640 
    641         mRemoteViews.setTextViewCompoundDrawables(R.id.remoteView_text, 0,
    642                 R.drawable.icon_black, R.drawable.icon_red, R.drawable.icon_green);
    643         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    644         TestUtils.verifyCompoundDrawables(textView, -1,  R.drawable.icon_red, R.drawable.icon_black,
    645                 R.drawable.icon_green);
    646 
    647         mExpectedException.expect(Throwable.class);
    648         mRemoteViews.setTextViewCompoundDrawables(R.id.remoteView_absolute, 0,
    649                 R.drawable.start, R.drawable.failed, 0);
    650         mRemoteViews.reapply(mContext, mResult);
    651     }
    652 
    653     @Test
    654     public void testSetTextCompoundDrawablesRelative() throws Throwable {
    655         TextView textViewLtr = (TextView) mResult.findViewById(R.id.remoteView_text_ltr);
    656         TextView textViewRtl = (TextView) mResult.findViewById(R.id.remoteView_text_rtl);
    657 
    658         TestUtils.verifyCompoundDrawables(textViewLtr, -1, -1, -1, -1);
    659         TestUtils.verifyCompoundDrawables(textViewRtl, -1, -1, -1, -1);
    660 
    661         mRemoteViews.setTextViewCompoundDrawablesRelative(R.id.remoteView_text_ltr,
    662                 R.drawable.start, R.drawable.pass, R.drawable.failed, 0);
    663         mRemoteViews.setTextViewCompoundDrawablesRelative(R.id.remoteView_text_rtl,
    664                 R.drawable.start, R.drawable.pass, R.drawable.failed, 0);
    665         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    666         TestUtils.verifyCompoundDrawables(textViewLtr, R.drawable.start, R.drawable.failed,
    667                 R.drawable.pass, -1);
    668         TestUtils.verifyCompoundDrawables(textViewRtl, R.drawable.failed, R.drawable.start,
    669                 R.drawable.pass, -1);
    670 
    671         mRemoteViews.setTextViewCompoundDrawablesRelative(R.id.remoteView_text_ltr, 0,
    672                 R.drawable.icon_black, R.drawable.icon_red, R.drawable.icon_green);
    673         mRemoteViews.setTextViewCompoundDrawablesRelative(R.id.remoteView_text_rtl, 0,
    674                 R.drawable.icon_black, R.drawable.icon_red, R.drawable.icon_green);
    675         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    676         TestUtils.verifyCompoundDrawables(textViewLtr, -1, R.drawable.icon_red,
    677                 R.drawable.icon_black, R.drawable.icon_green);
    678         TestUtils.verifyCompoundDrawables(textViewRtl, R.drawable.icon_red, -1,
    679                 R.drawable.icon_black, R.drawable.icon_green);
    680 
    681         mExpectedException.expect(Throwable.class);
    682         mRemoteViews.setTextViewCompoundDrawablesRelative(R.id.remoteView_absolute, 0,
    683                 R.drawable.start, R.drawable.failed, 0);
    684         mRemoteViews.reapply(mContext, mResult);
    685     }
    686 
    687     @LargeTest
    688     @Test
    689     public void testSetOnClickPendingIntent() throws Throwable {
    690         Uri uri = Uri.parse("ctstest://RemoteView/test");
    691         ActivityMonitor am = mInstrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
    692                 null, false);
    693         View view = mResult.findViewById(R.id.remoteView_image);
    694         view.performClick();
    695         Activity newActivity = am.waitForActivityWithTimeout(TEST_TIMEOUT);
    696         assertNull(newActivity);
    697 
    698         Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    699         PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
    700         mRemoteViews.setOnClickPendingIntent(R.id.remoteView_image, pendingIntent);
    701         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    702         mActivityRule.runOnUiThread(() -> view.performClick());
    703         newActivity = am.waitForActivityWithTimeout(TEST_TIMEOUT);
    704         assertNotNull(newActivity);
    705         assertTrue(newActivity instanceof MockURLSpanTestActivity);
    706         newActivity.finish();
    707     }
    708 
    709     @Test
    710     public void testSetLong() throws Throwable {
    711         long base1 = 50;
    712         long base2 = -50;
    713         Chronometer chronometer = (Chronometer) mResult.findViewById(R.id.remoteView_chronometer);
    714 
    715         mRemoteViews.setLong(R.id.remoteView_chronometer, "setBase", base1);
    716         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    717         assertEquals(base1, chronometer.getBase());
    718 
    719         mRemoteViews.setLong(R.id.remoteView_chronometer, "setBase", base2);
    720         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    721         assertEquals(base2, chronometer.getBase());
    722 
    723         mExpectedException.expect(ActionException.class);
    724         mRemoteViews.setLong(R.id.remoteView_absolute, "setBase", base1);
    725         mRemoteViews.reapply(mContext, mResult);
    726     }
    727 
    728     @Test
    729     public void testSetFloat() throws Throwable {
    730         LinearLayout linearLayout = (LinearLayout) mResult.findViewById(R.id.remoteView_linear);
    731         assertTrue(linearLayout.getWeightSum() <= 0.0f);
    732 
    733         mRemoteViews.setFloat(R.id.remoteView_linear, "setWeightSum", 0.5f);
    734         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    735         assertEquals(0.5f, linearLayout.getWeightSum(), 0.001f);
    736 
    737         mExpectedException.expect(ActionException.class);
    738         mRemoteViews.setFloat(R.id.remoteView_absolute, "setWeightSum", 1.0f);
    739         mRemoteViews.reapply(mContext, mResult);
    740     }
    741 
    742     @Test
    743     public void testSetByte() throws Throwable {
    744         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    745         assertEquals(0, customView.getByteField());
    746 
    747         byte b = 100;
    748         mRemoteViews.setByte(R.id.remoteView_custom, "setByteField", b);
    749         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    750         assertEquals(b, customView.getByteField());
    751 
    752         mExpectedException.expect(ActionException.class);
    753         mRemoteViews.setByte(R.id.remoteView_absolute, "setByteField", b);
    754         mRemoteViews.reapply(mContext, mResult);
    755     }
    756 
    757     @Test
    758     public void testSetChar() throws Throwable {
    759         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    760         assertEquals('\u0000', customView.getCharField());
    761 
    762         mRemoteViews.setChar(R.id.remoteView_custom, "setCharField", 'q');
    763         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    764         assertEquals('q', customView.getCharField());
    765 
    766         mExpectedException.expect(ActionException.class);
    767         mRemoteViews.setChar(R.id.remoteView_absolute, "setCharField", 'w');
    768         mRemoteViews.reapply(mContext, mResult);
    769     }
    770 
    771     @Test
    772     public void testSetDouble() throws Throwable {
    773         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    774         assertEquals(0.0, customView.getDoubleField(), 0.0f);
    775 
    776         mRemoteViews.setDouble(R.id.remoteView_custom, "setDoubleField", 0.5);
    777         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    778         assertEquals(0.5, customView.getDoubleField(), 0.001f);
    779 
    780         mExpectedException.expect(ActionException.class);
    781         mRemoteViews.setDouble(R.id.remoteView_absolute, "setDoubleField", 1.0);
    782         mRemoteViews.reapply(mContext, mResult);
    783     }
    784 
    785     @Test
    786     public void testSetShort() throws Throwable {
    787         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    788         assertEquals(0, customView.getShortField());
    789 
    790         short s = 25;
    791         mRemoteViews.setShort(R.id.remoteView_custom, "setShortField", s);
    792         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    793         assertEquals(s, customView.getShortField());
    794 
    795         mExpectedException.expect(ActionException.class);
    796         mRemoteViews.setShort(R.id.remoteView_absolute, "setShortField", s);
    797         mRemoteViews.reapply(mContext, mResult);
    798     }
    799 
    800     @Test
    801     public void testSetBundle() throws Throwable {
    802         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    803         assertNull(customView.getBundleField());
    804 
    805         final Bundle bundle = new Bundle();
    806         bundle.putString("STR", "brexit");
    807         bundle.putInt("INT", 2016);
    808         mRemoteViews.setBundle(R.id.remoteView_custom, "setBundleField", bundle);
    809         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    810         final Bundle fromRemote = customView.getBundleField();
    811         assertEquals("brexit", fromRemote.getString("STR", ""));
    812         assertEquals(2016, fromRemote.getInt("INT", 0));
    813 
    814         mExpectedException.expect(ActionException.class);
    815         mRemoteViews.setBundle(R.id.remoteView_absolute, "setBundleField", bundle);
    816         mRemoteViews.reapply(mContext, mResult);
    817     }
    818 
    819     @Test
    820     public void testSetIntent() throws Throwable {
    821         MyRemotableView customView = (MyRemotableView) mResult.findViewById(R.id.remoteView_custom);
    822         assertNull(customView.getIntentField());
    823 
    824         final Intent intent = new Intent(mContext, SwitchCtsActivity.class);
    825         intent.putExtra("STR", "brexit");
    826         intent.putExtra("INT", 2016);
    827         mRemoteViews.setIntent(R.id.remoteView_custom, "setIntentField", intent);
    828         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    829         final Intent fromRemote = customView.getIntentField();
    830         assertEquals(SwitchCtsActivity.class.getName(), fromRemote.getComponent().getClassName());
    831         assertEquals("brexit", fromRemote.getStringExtra("STR"));
    832         assertEquals(2016, fromRemote.getIntExtra("INT", 0));
    833 
    834         mExpectedException.expect(ActionException.class);
    835         mRemoteViews.setIntent(R.id.remoteView_absolute, "setIntentField", intent);
    836         mRemoteViews.reapply(mContext, mResult);
    837     }
    838 
    839     @Test
    840     public void testRemoveAllViews() throws Throwable {
    841         ViewGroup root = (ViewGroup) mResult.findViewById(R.id.remoteViews_good);
    842         assertTrue(root.getChildCount() > 0);
    843 
    844         mRemoteViews.removeAllViews(R.id.remoteViews_good);
    845         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    846         assertEquals(0, root.getChildCount());
    847     }
    848 
    849     @Test
    850     public void testAddView() throws Throwable {
    851         ViewGroup root = (ViewGroup) mResult.findViewById(R.id.remoteViews_good);
    852         int originalChildCount = root.getChildCount();
    853 
    854         assertNull(root.findViewById(R.id.remoteView_frame_extra));
    855 
    856         // Create a RemoteViews wrapper around a layout and add it to our root
    857         RemoteViews extra = new RemoteViews(PACKAGE_NAME, R.layout.remoteviews_extra);
    858         mRemoteViews.addView(R.id.remoteViews_good, extra);
    859         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    860 
    861         // Verify that our root has that layout as its last (new) child
    862         assertEquals(originalChildCount + 1, root.getChildCount());
    863         assertNotNull(root.findViewById(R.id.remoteView_frame_extra));
    864         assertEquals(R.id.remoteView_frame_extra, root.getChildAt(originalChildCount).getId());
    865     }
    866 
    867     @Test
    868     public void testSetLabelFor() throws Throwable {
    869         View labelView = mResult.findViewById(R.id.remoteView_label);
    870         assertEquals(View.NO_ID, labelView.getLabelFor());
    871 
    872         mRemoteViews.setLabelFor(R.id.remoteView_label, R.id.remoteView_text);
    873         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    874         assertEquals(R.id.remoteView_text, labelView.getLabelFor());
    875     }
    876 
    877     @Test
    878     public void testSetAccessibilityTraversalAfter() throws Throwable {
    879         View textView = mResult.findViewById(R.id.remoteView_text);
    880 
    881         mRemoteViews.setAccessibilityTraversalAfter(R.id.remoteView_text, R.id.remoteView_frame);
    882         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    883         assertEquals(R.id.remoteView_frame, textView.getAccessibilityTraversalAfter());
    884 
    885         mRemoteViews.setAccessibilityTraversalAfter(R.id.remoteView_text, R.id.remoteView_linear);
    886         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    887         assertEquals(R.id.remoteView_linear, textView.getAccessibilityTraversalAfter());
    888     }
    889 
    890     @Test
    891     public void testSetAccessibilityTraversalBefore() throws Throwable {
    892         View textView = mResult.findViewById(R.id.remoteView_text);
    893 
    894         mRemoteViews.setAccessibilityTraversalBefore(R.id.remoteView_text, R.id.remoteView_frame);
    895         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    896         assertEquals(R.id.remoteView_frame, textView.getAccessibilityTraversalBefore());
    897 
    898         mRemoteViews.setAccessibilityTraversalBefore(R.id.remoteView_text, R.id.remoteView_linear);
    899         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    900         assertEquals(R.id.remoteView_linear, textView.getAccessibilityTraversalBefore());
    901     }
    902 
    903     @Test
    904     public void testSetViewPadding() throws Throwable {
    905         View textView = mResult.findViewById(R.id.remoteView_text);
    906 
    907         mRemoteViews.setViewPadding(R.id.remoteView_text, 10, 20, 30, 40);
    908         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    909         assertEquals(10, textView.getPaddingLeft());
    910         assertEquals(20, textView.getPaddingTop());
    911         assertEquals(30, textView.getPaddingRight());
    912         assertEquals(40, textView.getPaddingBottom());
    913 
    914         mRemoteViews.setViewPadding(R.id.remoteView_text, 40, 30, 20, 10);
    915         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
    916         assertEquals(40, textView.getPaddingLeft());
    917         assertEquals(30, textView.getPaddingTop());
    918         assertEquals(20, textView.getPaddingRight());
    919         assertEquals(10, textView.getPaddingBottom());
    920     }
    921 
    922     private void createSampleImage(File imagefile, int resid) throws IOException {
    923         try (InputStream source = mContext.getResources().openRawResource(resid);
    924              OutputStream target = new FileOutputStream(imagefile)) {
    925 
    926             byte[] buffer = new byte[1024];
    927             for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
    928                 target.write(buffer, 0, len);
    929             }
    930         }
    931     }
    932 }
    933