Home | History | Annotate | Download | only in input
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 package org.chromium.chrome.browser.input;
      6 
      7 import android.app.Activity;
      8 import android.content.Intent;
      9 import android.provider.MediaStore;
     10 import android.test.suitebuilder.annotation.MediumTest;
     11 
     12 import org.chromium.base.test.util.Feature;
     13 import org.chromium.base.test.util.UrlUtils;
     14 import org.chromium.chrome.shell.ChromeShellActivity;
     15 import org.chromium.chrome.shell.ChromeShellActivity.ActivityWindowAndroidFactory;
     16 import org.chromium.chrome.shell.ChromeShellTestBase;
     17 import org.chromium.content.browser.ContentViewCore;
     18 import org.chromium.content.browser.test.util.Criteria;
     19 import org.chromium.content.browser.test.util.CriteriaHelper;
     20 import org.chromium.content.browser.test.util.DOMUtils;
     21 import org.chromium.content.browser.test.util.UiUtils;
     22 import org.chromium.ui.base.ActivityWindowAndroid;
     23 
     24 /**
     25  * Integration test for select file dialog used for <input type="file" />
     26  */
     27 public class SelectFileDialogTest extends ChromeShellTestBase {
     28     private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
     29             "<html><head><meta name=\"viewport\"" +
     30             "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>" +
     31             "<body><form action=\"about:blank\">" +
     32             "<input id=\"input_file\" type=\"file\" /><br/>" +
     33             "<input id=\"input_image\" type=\"file\" accept=\"image/*\" capture /><br/>" +
     34             "<input id=\"input_audio\" type=\"file\" accept=\"audio/*\" capture />" +
     35             "</form>" +
     36             "</body></html>");
     37 
     38     private ContentViewCore mContentViewCore;
     39     private ActivityWindowAndroidForTest mActivityWindowAndroidForTest;
     40 
     41     private static class ActivityWindowAndroidForTest extends ActivityWindowAndroid {
     42         public Intent lastIntent;
     43         public IntentCallback lastCallback;
     44         /**
     45          * @param activity
     46          */
     47         public ActivityWindowAndroidForTest(Activity activity) {
     48             super(activity);
     49         }
     50 
     51         @Override
     52         public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) {
     53             lastIntent = intent;
     54             lastCallback = callback;
     55             return 1;
     56         }
     57     }
     58 
     59     private class IntentSentCriteria implements Criteria {
     60         @Override
     61         public boolean isSatisfied() {
     62             return mActivityWindowAndroidForTest.lastIntent != null;
     63         }
     64     }
     65 
     66     @Override
     67     public void setUp() throws Exception {
     68         super.setUp();
     69 
     70         ChromeShellActivity.setActivityWindowAndroidFactory(new ActivityWindowAndroidFactory() {
     71             @Override
     72             public ActivityWindowAndroid getActivityWindowAndroid(Activity activity) {
     73                 mActivityWindowAndroidForTest = new ActivityWindowAndroidForTest(activity);
     74                 return mActivityWindowAndroidForTest;
     75             }
     76         });
     77         launchChromeShellWithUrl(DATA_URL);
     78         assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
     79 
     80         mContentViewCore = getActivity().getActiveContentViewCore();
     81         // TODO(aurimas) remove this wait once crbug.com/179511 is fixed.
     82         assertWaitForPageScaleFactorMatch(2);
     83         assertTrue(
     84                 DOMUtils.waitForNonZeroNodeBounds(mContentViewCore, "input_file"));
     85     }
     86 
     87     /**
     88      * Tests that clicks on <input type="file" /> trigger intent calls to ActivityWindowAndroid.
     89      */
     90     @MediumTest
     91     @Feature({"TextInput", "Main"})
     92     public void testSelectFileAndCancelRequest() throws Throwable {
     93         DOMUtils.clickNode(this, mContentViewCore, "input_file");
     94         assertTrue("SelectFileDialog never sent an intent.",
     95                 CriteriaHelper.pollForCriteria(new IntentSentCriteria()));
     96         assertEquals(Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction());
     97         resetActivityWindowAndroidForTest();
     98 
     99         DOMUtils.clickNode(this, mContentViewCore, "input_image");
    100         assertTrue("SelectFileDialog never sent an intent.",
    101                 CriteriaHelper.pollForCriteria(new IntentSentCriteria()));
    102         assertEquals(MediaStore.ACTION_IMAGE_CAPTURE,
    103                 mActivityWindowAndroidForTest.lastIntent.getAction());
    104         resetActivityWindowAndroidForTest();
    105 
    106         DOMUtils.clickNode(this, mContentViewCore, "input_audio");
    107         assertTrue("SelectFileDialog never sent an intent.",
    108                 CriteriaHelper.pollForCriteria(new IntentSentCriteria()));
    109         assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION,
    110                 mActivityWindowAndroidForTest.lastIntent.getAction());
    111         resetActivityWindowAndroidForTest();
    112     }
    113 
    114     private void resetActivityWindowAndroidForTest() {
    115         UiUtils.runOnUiThread(getActivity(), new Runnable() {
    116             @Override
    117             public void run() {
    118                 mActivityWindowAndroidForTest.lastCallback.onIntentCompleted(
    119                         mActivityWindowAndroidForTest, Activity.RESULT_CANCELED, null, null);
    120             }
    121         });
    122         mActivityWindowAndroidForTest.lastCallback = null;
    123         mActivityWindowAndroidForTest.lastIntent = null;
    124     }
    125 }
    126