예제 #1
0
  @Override
  public Tab createNewTab(LoadUrlParams loadUrlParams, TabLaunchType type, Tab parent) {
    AsyncTabCreationParams asyncParams = new AsyncTabCreationParams(loadUrlParams);

    // Figure out how the page will be launched.
    if (TextUtils.equals(UrlConstants.NTP_URL, loadUrlParams.getUrl())) {
      asyncParams.setDocumentLaunchMode(ChromeLauncherActivity.LAUNCH_MODE_RETARGET);
    } else if (type == TabLaunchType.FROM_LONGPRESS_BACKGROUND) {
      if (!parent.isIncognito() && mIsIncognito) {
        // Incognito tabs opened from regular tabs open in the foreground for privacy
        // concerns.
        asyncParams.setDocumentLaunchMode(ChromeLauncherActivity.LAUNCH_MODE_FOREGROUND);
      } else {
        asyncParams.setDocumentLaunchMode(ChromeLauncherActivity.LAUNCH_MODE_AFFILIATED);
      }
    }

    // Classify the startup type.
    if (parent != null && TextUtils.equals(UrlConstants.NTP_URL, parent.getUrl())) {
      asyncParams.setDocumentStartedBy(DocumentMetricIds.STARTED_BY_CHROME_HOME_MOST_VISITED);
    } else if (type == TabLaunchType.FROM_LONGPRESS_BACKGROUND
        || type == TabLaunchType.FROM_LONGPRESS_FOREGROUND) {
      asyncParams.setDocumentStartedBy(DocumentMetricIds.STARTED_BY_CONTEXT_MENU);
    } else if (type == TabLaunchType.FROM_MENU_OR_OVERVIEW) {
      asyncParams.setDocumentStartedBy(DocumentMetricIds.STARTED_BY_OPTIONS_MENU);
    }

    // Tab is created aysnchronously.  Can't return anything, yet.
    createNewTab(asyncParams, type, parent == null ? Tab.INVALID_TAB_ID : parent.getId());
    return null;
  }
예제 #2
0
 @Override
 public void setTitleToPageTitle() {
   Tab currentTab = getToolbarDataProvider().getTab();
   if (currentTab == null || TextUtils.isEmpty(currentTab.getTitle())) {
     mTitleBar.setText("");
     return;
   }
   mTitleBar.setText(currentTab.getTitle());
 }
  @Override
  public void requestFileAccess(final long callbackId) {
    if (mTab == null) {
      // TODO(tedchoc): Show toast (only when activity is alive).
      DownloadController.getInstance().onRequestFileAccessResult(callbackId, false);
      return;
    }
    final String storagePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
    final Activity activity = mTab.getWindowAndroid().getActivity().get();

    if (activity == null) {
      DownloadController.getInstance().onRequestFileAccessResult(callbackId, false);
    } else if (mTab.getWindowAndroid().canRequestPermission(storagePermission)) {
      View view = activity.getLayoutInflater().inflate(R.layout.update_permissions_dialog, null);
      TextView dialogText = (TextView) view.findViewById(R.id.text);
      dialogText.setText(R.string.missing_storage_permission_download_education_text);

      final PermissionCallback permissionCallback =
          new PermissionCallback() {
            @Override
            public void onRequestPermissionsResult(String[] permissions, int[] grantResults) {
              DownloadController.getInstance()
                  .onRequestFileAccessResult(
                      callbackId,
                      grantResults.length > 0
                          && grantResults[0] == PackageManager.PERMISSION_GRANTED);
            }
          };

      AlertDialog.Builder builder =
          new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
              .setView(view)
              .setPositiveButton(
                  R.string.infobar_update_permissions_button_text,
                  new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                      mTab.getWindowAndroid()
                          .requestPermissions(new String[] {storagePermission}, permissionCallback);
                    }
                  })
              .setOnCancelListener(
                  new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                      DownloadController.getInstance().onRequestFileAccessResult(callbackId, false);
                    }
                  });
      builder.create().show();
    } else if (!mTab.getWindowAndroid().isPermissionRevokedByPolicy(storagePermission)) {
      nativeLaunchPermissionUpdateInfoBar(mTab, storagePermission, callbackId);
    } else {
      // TODO(tedchoc): Show toast.
      DownloadController.getInstance().onRequestFileAccessResult(callbackId, false);
    }
  }
예제 #4
0
  /**
   * Types the passed text in the omnibox to trigger a navigation. You can pass a URL or a search
   * term. This code triggers suggestions and prerendering; unless you are testing these features
   * specifically, you should use loadUrl() which is less prone to flakyness.
   *
   * @param url The URL to navigate to.
   * @return the URL in the omnibox.
   * @throws InterruptedException
   */
  private String typeInOmniboxAndNavigate(final String url) throws InterruptedException {
    final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
    assertNotNull("urlBar is null", urlBar);
    ThreadUtils.runOnUiThreadBlocking(
        new Runnable() {
          @Override
          public void run() {
            urlBar.requestFocus();
            urlBar.setText(url);
          }
        });
    final LocationBarLayout locationBar =
        (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
    OmniboxTestUtils.waitForOmniboxSuggestions(locationBar);

    Tab currentTab = getActivity().getActivityTab();
    final CallbackHelper loadedCallback = new CallbackHelper();
    final AtomicBoolean tabCrashReceived = new AtomicBoolean();
    currentTab.addObserver(
        new EmptyTabObserver() {
          @Override
          public void onPageLoadFinished(Tab tab) {
            loadedCallback.notifyCalled();
            tab.removeObserver(this);
          }

          @Override
          public void onCrash(Tab tab, boolean sadTabShown) {
            tabCrashReceived.set(true);
            tab.removeObserver(this);
          }
        });

    // Loads the url.
    KeyUtils.singleKeyEventView(getInstrumentation(), urlBar, KeyEvent.KEYCODE_ENTER);

    boolean pageLoadReceived = true;
    try {
      loadedCallback.waitForCallback(0);
    } catch (TimeoutException ex) {
      pageLoadReceived = false;
    }

    assertTrue(
        "Neither PAGE_LOAD_FINISHED nor a TAB_CRASHED event was received",
        pageLoadReceived || tabCrashReceived.get());
    getInstrumentation().waitForIdleSync();

    // The URL has been set before the page notification was broadcast, so it is safe to access.
    return urlBar.getText().toString();
  }
예제 #5
0
  /** Test Opening a link and verify that the desired page is loaded. */
  @MediumTest
  @Feature({"Navigation"})
  public void testOpenLink() throws InterruptedException, TimeoutException {
    String url1 = TestHttpServerClient.getUrl("chrome/test/data/android/google.html");
    String url2 = TestHttpServerClient.getUrl("chrome/test/data/android/about.html");

    navigateAndObserve(url1, url1);
    assertWaitForPageScaleFactorMatch(0.5f);

    Tab tab = getActivity().getActivityTab();

    DOMUtils.clickNode(this, tab.getContentViewCore(), "aboutLink");
    ChromeTabUtils.waitForTabPageLoaded(tab, url2);
    assertEquals("Desired Link not open", url2, getActivity().getActivityTab().getUrl());
  }
 /**
  * Displays Auto sign-in snackbar, which communicates to the users that they were signed in to the
  * web site.
  */
 @CalledByNative
 private static void showSnackbar(Tab tab, String text) {
   SnackbarManager snackbarManager = tab.getSnackbarManager();
   if (snackbarManager == null) return;
   AutoSigninSnackbarController snackbarController =
       new AutoSigninSnackbarController(snackbarManager, tab);
   Snackbar snackbar = Snackbar.make(text, snackbarController);
   Resources resources = tab.getWindowAndroid().getActivity().get().getResources();
   int backgroundColor =
       ApiCompatibilityUtils.getColor(
           resources, R.color.smart_lock_auto_signin_snackbar_background_color);
   Bitmap icon = BitmapFactory.decodeResource(resources, R.drawable.account_management_no_picture);
   snackbar.setSingleLine(false).setBackgroundColor(backgroundColor).setProfileImage(icon);
   snackbarManager.showSnackbar(snackbar);
 }
예제 #7
0
  @Override
  protected boolean isStartedUpCorrectly(Intent intent) {
    int tabId = ActivityDelegate.getTabIdFromIntent(getIntent());

    // Fire a MAIN Intent to send the user back through ChromeLauncherActivity.
    Log.e(TAG, "User shouldn't be here.  Sending back to ChromeLauncherActivity.");

    // Try to bring this tab forward after migration.
    Intent tabbedIntent = null;
    if (tabId != Tab.INVALID_TAB_ID) tabbedIntent = Tab.createBringTabToFrontIntent(tabId);

    if (tabbedIntent == null) {
      tabbedIntent = new Intent(Intent.ACTION_MAIN);
      tabbedIntent.setPackage(getPackageName());
    }

    // Launch the other Activity in its own task so it stays when this one finishes.
    tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);

    startActivity(tabbedIntent);
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);

    Log.e(TAG, "Discarding Intent: Tab = " + tabId);
    return false;
  }
 /**
  * For certain download types(OMA for example), android DownloadManager should handle them. Call
  * this function to intercept those downloads.
  *
  * @param url URL to be downloaded.
  * @return whether the DownloadManager should intercept the download.
  */
 public boolean shouldInterceptContextMenuDownload(String url) {
   Uri uri = Uri.parse(url);
   String scheme = uri.normalizeScheme().getScheme();
   if (!"http".equals(scheme) && !"https".equals(scheme)) return false;
   String path = uri.getPath();
   // OMA downloads have extension "dm" or "dd". For the latter, it
   // can be handled when native download completes.
   if (path != null && (path.endsWith(".dm"))) {
     final DownloadInfo downloadInfo = new DownloadInfo.Builder().setUrl(url).build();
     if (mTab == null) return true;
     WindowAndroid window = mTab.getWindowAndroid();
     if (window.hasPermission(permission.WRITE_EXTERNAL_STORAGE)) {
       onDownloadStartNoStream(downloadInfo);
     } else if (window.canRequestPermission(permission.WRITE_EXTERNAL_STORAGE)) {
       PermissionCallback permissionCallback =
           new PermissionCallback() {
             @Override
             public void onRequestPermissionsResult(String[] permissions, int[] grantResults) {
               if (grantResults.length > 0
                   && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                 onDownloadStartNoStream(downloadInfo);
               }
             }
           };
       window.requestPermissions(
           new String[] {permission.WRITE_EXTERNAL_STORAGE}, permissionCallback);
     }
     return true;
   }
   return false;
 }
예제 #9
0
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   mTab = getActivity().getActivityTab();
   mTab.addObserver(mTabObserver);
   mOnTitleUpdatedHelper = new CallbackHelper();
 }
예제 #10
0
  @SmallTest
  @Feature({"Tab"})
  public void testTitleDelayUpdate() throws Throwable {
    final String oldTitle = "oldTitle";
    final String newTitle = "newTitle";

    loadUrl(
        "data:text/html;charset=utf-8,<html><head><title>"
            + oldTitle
            + "</title></head><body/></html>");
    assertEquals("title does not match initial title", oldTitle, mTab.getTitle());
    int currentCallCount = mOnTitleUpdatedHelper.getCallCount();
    runJavaScriptCodeInCurrentTab("document.title='" + newTitle + "';");
    mOnTitleUpdatedHelper.waitForCallback(currentCallCount);
    assertEquals("title does not update", newTitle, mTab.getTitle());
  }
예제 #11
0
  /**
   * Tests that a WebappActivity can be brought forward by firing an Intent with
   * TabOpenType.BRING_TAB_TO_FRONT.
   */
  @MediumTest
  @Feature({"Webapps"})
  public void testBringTabToFront() throws Exception {
    // Start the WebappActivity.
    final WebappActivity firstActivity =
        startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON);
    final int webappTabId = firstActivity.getActivityTab().getId();

    // Return home.
    final Context context = getInstrumentation().getTargetContext();
    ApplicationTestUtils.fireHomeScreenIntent(context);
    getInstrumentation().waitForIdleSync();

    // Bring the WebappActivity back via an Intent.
    Intent intent = Tab.createBringTabToFrontIntent(webappTabId);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);

    // When Chrome is back in the foreground, confirm that the correct Activity was restored.
    // Because of Android killing Activities willy-nilly, it may not be the same Activity, but
    // it should have the same Tab ID.
    getInstrumentation().waitForIdleSync();
    ApplicationTestUtils.waitUntilChromeInForeground();
    CriteriaHelper.pollInstrumentationThread(
        new Criteria() {
          @Override
          public boolean isSatisfied() {
            Activity lastActivity = ApplicationStatus.getLastTrackedFocusedActivity();
            if (!isWebappActivityReady(lastActivity)) return false;

            WebappActivity webappActivity = (WebappActivity) lastActivity;
            return webappActivity.getActivityTab().getId() == webappTabId;
          }
        });
  }
예제 #12
0
  /**
   * Displays the download manager UI. Note the UI is different on tablets and on phones.
   *
   * @return Whether the UI was shown.
   */
  public static boolean showDownloadManager(@Nullable Activity activity, @Nullable Tab tab) {
    if (!isDownloadHomeEnabled()) return false;

    // Figure out what tab was last being viewed by the user.
    if (activity == null) activity = ApplicationStatus.getLastTrackedFocusedActivity();
    if (tab == null && activity instanceof ChromeTabbedActivity) {
      tab = ((ChromeTabbedActivity) activity).getActivityTab();
    }

    Context appContext = ContextUtils.getApplicationContext();
    if (DeviceFormFactor.isTablet(appContext)) {
      // Download Home shows up as a tab on tablets.
      LoadUrlParams params = new LoadUrlParams(UrlConstants.DOWNLOADS_URL);
      if (tab == null || !tab.isInitialized()) {
        // Open a new tab, which pops Chrome into the foreground.
        TabDelegate delegate = new TabDelegate(false);
        delegate.createNewTab(params, TabLaunchType.FROM_CHROME_UI, null);
      } else {
        // Download Home shows up inside an existing tab, but only if the last Activity was
        // the ChromeTabbedActivity.
        tab.loadUrl(params);

        // Bring Chrome to the foreground, if possible.
        Intent intent = Tab.createBringTabToFrontIntent(tab.getId());
        if (intent != null) {
          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          IntentUtils.safeStartActivity(appContext, intent);
        }
      }
    } else {
      // Download Home shows up as a new Activity on phones.
      Intent intent = new Intent();
      intent.setClass(appContext, DownloadActivity.class);
      if (tab != null) intent.putExtra(EXTRA_IS_OFF_THE_RECORD, tab.isIncognito());
      if (activity == null) {
        // Stands alone in its own task.
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        appContext.startActivity(intent);
      } else {
        // Sits on top of another Activity.
        intent.putExtra(IntentHandler.EXTRA_PARENT_COMPONENT, activity.getComponentName());
        activity.startActivity(intent);
      }
    }

    return true;
  }
예제 #13
0
  private void displayNavigationPopup(boolean isForward, View anchorView) {
    Tab tab = getToolbarDataProvider().getTab();
    if (tab == null || tab.getWebContents() == null) return;
    mNavigationPopup =
        new NavigationPopup(
            tab.getProfile(),
            getContext(),
            tab.getWebContents().getNavigationController(),
            isForward);

    mNavigationPopup.setAnchorView(anchorView);

    int menuWidth = getResources().getDimensionPixelSize(R.dimen.menu_width);
    mNavigationPopup.setWidth(menuWidth);

    if (mNavigationPopup.shouldBeShown()) mNavigationPopup.show();
  }
예제 #14
0
  /**
   * Whether the user should be allowed to download the current page.
   *
   * @param tab Tab displaying the page that will be downloaded.
   * @return Whether the "Download Page" button should be enabled.
   */
  public static boolean isAllowedToDownloadPage(Tab tab) {
    if (tab == null) return false;

    // Don't allow downloading internal pages.
    if (tab.getUrl().startsWith(UrlConstants.CHROME_SCHEME)) return false;
    if (tab.getUrl().startsWith(UrlConstants.CHROME_NATIVE_SCHEME)) return false;
    if (tab.isShowingErrorPage()) return false;
    if (tab.isShowingInterstitialPage()) return false;

    // Don't allow re-downloading the currently displayed offline page.
    if (tab.isOfflinePage()) return false;

    // Offline pages isn't supported in Incognito.
    if (tab.isIncognito()) return false;

    return true;
  }
예제 #15
0
 /** Close a blank tab just opened for the download purpose. */
 private void closeBlankTab() {
   WebContents contents = mTab.getWebContents();
   boolean isInitialNavigation =
       contents == null || contents.getNavigationController().isInitialNavigation();
   if (isInitialNavigation) {
     // Tab is created just for download, close it.
     mTabModelSelector.closeTab(mTab);
   }
 }
예제 #16
0
  /**
   * Brings a live WebappActivity back to the foreground if one exists for the given tab ID.
   *
   * @param tabId ID of the Tab to bring back to the foreground.
   * @return True if a live WebappActivity was found, false otherwise.
   */
  public static boolean bringWebappToFront(int tabId) {
    if (tabId == Tab.INVALID_TAB_ID) return false;

    for (WeakReference<Activity> activityRef : ApplicationStatus.getRunningActivities()) {
      Activity activity = activityRef.get();
      if (activity == null || !(activity instanceof WebappActivity)) continue;

      WebappActivity webappActivity = (WebappActivity) activity;
      if (webappActivity.getActivityTab() != null
          && webappActivity.getActivityTab().getId() == tabId) {
        Tab tab = webappActivity.getActivityTab();
        tab.getTabWebContentsDelegateAndroid().activateContents();
        return true;
      }
    }

    return false;
  }
예제 #17
0
 private String getTabBodyText(Tab tab) {
   try {
     return JavaScriptUtils.executeJavaScriptAndWaitForResult(
         tab.getWebContents(), "document.body.innerText");
   } catch (InterruptedException ex) {
     assert false : "Unexpected InterruptedException";
   } catch (TimeoutException ex) {
     assert false : "Unexpected TimeoutException";
   }
   return null;
 }
 /**
  * Close a blank tab just opened for the download purpose.
  *
  * @return true iff the tab was (already) closed.
  */
 private boolean closeBlankTab() {
   if (mTab == null) {
     // We do not want caller to dismiss infobar.
     return true;
   }
   WebContents contents = mTab.getWebContents();
   boolean isInitialNavigation =
       contents == null || contents.getNavigationController().isInitialNavigation();
   if (isInitialNavigation) {
     // Tab is created just for download, close it.
     return mTabModelSelector.closeTab(mTab);
   }
   return false;
 }
예제 #19
0
  /**
   * Test Opening a link and verify that TabObserver#onPageLoadStarted gives the old and new URL.
   */
  @MediumTest
  @Feature({"Navigation"})
  public void testTabObserverOnPageLoadStarted() throws InterruptedException, TimeoutException {
    final String url1 = TestHttpServerClient.getUrl("chrome/test/data/android/google.html");
    final String url2 = TestHttpServerClient.getUrl("chrome/test/data/android/about.html");

    navigateAndObserve(url1, url1);
    assertWaitForPageScaleFactorMatch(0.5f);

    TabObserver onPageLoadStartedObserver =
        new EmptyTabObserver() {
          @Override
          public void onPageLoadStarted(Tab tab, String newUrl) {
            tab.removeObserver(this);
            assertEquals(url1, tab.getUrl());
            assertEquals(url2, newUrl);
          }
        };
    Tab tab = getActivity().getActivityTab();
    tab.addObserver(onPageLoadStartedObserver);
    DOMUtils.clickNode(this, tab.getContentViewCore(), "aboutLink");
    ChromeTabUtils.waitForTabPageLoaded(tab, url2);
    assertEquals("Desired Link not open", url2, getActivity().getActivityTab().getUrl());
  }
예제 #20
0
  /**
   * Request user confirmation on a dangerous download.
   *
   * @param downloadInfo Information about the download.
   */
  private void confirmDangerousDownload(DownloadInfo downloadInfo) {
    // A Dangerous file is already pending user confirmation, ignore the new download.
    if (mPendingRequest != null) return;

    mPendingRequest = downloadInfo;

    // TODO(dfalcantara): Ask ainslie@ for an icon to use for this InfoBar.
    int drawableId = 0;
    final String titleText = nativeGetDownloadWarningText(mPendingRequest.getFileName());
    final String okButtonText = mContext.getResources().getString(R.string.ok);
    final String cancelButtonText = mContext.getResources().getString(R.string.cancel);

    mTab.getInfoBarContainer()
        .addInfoBar(
            new ConfirmInfoBar(
                this, drawableId, null, titleText, null, okButtonText, cancelButtonText));
  }
예제 #21
0
  @SmallTest
  @Feature({"Tab"})
  public void testTabRestoredIfKilledWhileActivityStopped() throws Exception {
    // Ensure the tab is showing before stopping the activity.
    ThreadUtils.runOnUiThreadBlocking(
        new Runnable() {
          @Override
          public void run() {
            mTab.show(TabSelectionType.FROM_NEW);
          }
        });

    assertFalse(mTab.needsReload());
    assertFalse(mTab.isHidden());
    assertFalse(mTab.isShowingSadTab());

    // Stop the activity and simulate a killed renderer.
    ApplicationTestUtils.fireHomeScreenIntent(getInstrumentation().getTargetContext());
    ThreadUtils.runOnUiThreadBlocking(
        new Runnable() {
          @Override
          public void run() {
            mTab.simulateRendererKilledForTesting(false);
          }
        });

    assertTrue(mTab.needsReload());
    assertTrue(mTab.isHidden());
    assertFalse(mTab.isShowingSadTab());

    ApplicationTestUtils.launchChrome(getInstrumentation().getTargetContext());

    // The tab should be restored and visible.
    assertFalse(mTab.isHidden());
    assertFalse(mTab.needsReload());
    assertFalse(mTab.isShowingSadTab());
  }
  /**
   * Creates an instance of a {@link AutoSigninSnackbarController}.
   *
   * @param snackbarManager The manager that helps to show up snackbar.
   */
  private AutoSigninSnackbarController(SnackbarManager snackbarManager, Tab tab) {
    mTab = tab;
    mSnackbarManager = snackbarManager;
    mTabObserver =
        new EmptyTabObserver() {
          @Override
          public void onHidden(Tab tab) {
            AutoSigninSnackbarController.this.dismissAutoSigninSnackbar();
          }

          @Override
          public void onDestroyed(Tab tab) {
            AutoSigninSnackbarController.this.dismissAutoSigninSnackbar();
          }

          @Override
          public void onCrash(Tab tab, boolean sadTabShown) {
            AutoSigninSnackbarController.this.dismissAutoSigninSnackbar();
          }
        };
    mTab.addObserver(mTabObserver);
  }
예제 #23
0
  private void runForegroundingTest(boolean viaActivateContents) throws Exception {
    // Start the WebappActivity.
    final WebappActivity activity =
        startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON);
    assertTrue(isNumberOfRunningActivitiesCorrect(1));

    // Return home.
    final Context context = getInstrumentation().getTargetContext();
    ApplicationTestUtils.fireHomeScreenIntent(context);
    getInstrumentation().waitForIdleSync();

    if (viaActivateContents) {
      // Bring it back via the Tab.
      activity.getActivityTab().getTabWebContentsDelegateAndroid().activateContents();
    } else {
      // Bring the WebappActivity back via an Intent.
      int webappTabId = activity.getActivityTab().getId();
      Intent intent = Tab.createBringTabToFrontIntent(webappTabId);
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      context.startActivity(intent);
    }

    // When Chrome is back in the foreground, confirm that the original Activity was restored.
    getInstrumentation().waitForIdleSync();
    ApplicationTestUtils.waitUntilChromeInForeground();
    assertTrue(
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return activity == ApplicationStatus.getLastTrackedFocusedActivity()
                    && activity.hasWindowFocus();
              }
            }));
    assertTrue(isNumberOfRunningActivitiesCorrect(1));
  }
예제 #24
0
 private void updateUrlBar() {
   Tab tab = getActivityTab();
   if (tab == null || mUrlBar == null) return;
   mUrlBar.update(tab.getUrl(), tab.getSecurityLevel());
 }
예제 #25
0
  /**
   * This should be called from the Activity's onKeyDown() to handle keyboard shortcuts.
   *
   * <p>Note: onKeyDown() is called after the active view or web page has had a chance to handle the
   * key event. So the keys handled here *can* be overridden by any view or web page.
   *
   * @param event The KeyEvent to handle.
   * @param activity The ChromeActivity in which the key was pressed.
   * @param isCurrentTabVisible Whether page-related actions are valid, e.g. reload, zoom in. This
   *     should be false when in the tab switcher.
   * @param tabSwitchingEnabled Whether shortcuts that switch between tabs are enabled (e.g.
   *     Ctrl+Tab, Ctrl+3).
   * @return Whether the key event was handled.
   */
  public static boolean onKeyDown(
      KeyEvent event,
      ChromeActivity activity,
      boolean isCurrentTabVisible,
      boolean tabSwitchingEnabled) {
    int keyCode = event.getKeyCode();
    if (event.getRepeatCount() != 0 || KeyEvent.isModifierKey(keyCode)) return false;
    if (KeyEvent.isGamepadButton(keyCode)) {
      if (isGamepadAPIActive(activity)) return false;
    } else if (!event.isCtrlPressed()
        && !event.isAltPressed()
        && keyCode != KeyEvent.KEYCODE_F3
        && keyCode != KeyEvent.KEYCODE_F5
        && keyCode != KeyEvent.KEYCODE_F10
        && keyCode != KeyEvent.KEYCODE_FORWARD) {
      return false;
    }

    TabModel curModel = activity.getCurrentTabModel();
    int count = curModel.getCount();

    int metaState = getMetaState(event);
    int keyCodeAndMeta = keyCode | metaState;

    switch (keyCodeAndMeta) {
      case CTRL | SHIFT | KeyEvent.KEYCODE_T:
        activity.onMenuOrKeyboardAction(R.id.open_recently_closed_tab, false);
        return true;
      case CTRL | KeyEvent.KEYCODE_T:
        activity.onMenuOrKeyboardAction(
            curModel.isIncognito() ? R.id.new_incognito_tab_menu_id : R.id.new_tab_menu_id, false);
        return true;
      case CTRL | KeyEvent.KEYCODE_N:
        activity.onMenuOrKeyboardAction(R.id.new_tab_menu_id, false);
        return true;
      case CTRL | SHIFT | KeyEvent.KEYCODE_N:
        activity.onMenuOrKeyboardAction(R.id.new_incognito_tab_menu_id, false);
        return true;
        // Alt+E represents a special character ´ (latin code: &#180) in Android.
        // If an EditText or ContentView has focus, Alt+E will be swallowed by
        // the default dispatchKeyEvent and cannot open the menu.
      case ALT | KeyEvent.KEYCODE_E:
      case ALT | KeyEvent.KEYCODE_F:
      case KeyEvent.KEYCODE_F10:
      case KeyEvent.KEYCODE_BUTTON_Y:
        activity.onMenuOrKeyboardAction(R.id.show_menu, false);
        return true;
    }

    if (isCurrentTabVisible) {
      if (tabSwitchingEnabled && (metaState == CTRL || metaState == ALT)) {
        int numCode = keyCode - KeyEvent.KEYCODE_0;
        if (numCode > 0 && numCode <= Math.min(count, 8)) {
          // Ctrl+1 to Ctrl+8: select tab by index
          TabModelUtils.setIndex(curModel, numCode - 1);
          return true;
        } else if (numCode == 9 && count != 0) {
          // Ctrl+9: select last tab
          TabModelUtils.setIndex(curModel, count - 1);
          return true;
        }
      }

      switch (keyCodeAndMeta) {
        case CTRL | KeyEvent.KEYCODE_TAB:
        case CTRL | KeyEvent.KEYCODE_PAGE_DOWN:
        case KeyEvent.KEYCODE_BUTTON_R1:
          if (tabSwitchingEnabled && count > 1) {
            TabModelUtils.setIndex(curModel, (curModel.index() + 1) % count);
          }
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_TAB:
        case CTRL | KeyEvent.KEYCODE_PAGE_UP:
        case KeyEvent.KEYCODE_BUTTON_L1:
          if (tabSwitchingEnabled && count > 1) {
            TabModelUtils.setIndex(curModel, (curModel.index() + count - 1) % count);
          }
          return true;
        case CTRL | KeyEvent.KEYCODE_W:
        case CTRL | KeyEvent.KEYCODE_F4:
        case KeyEvent.KEYCODE_BUTTON_B:
          TabModelUtils.closeCurrentTab(curModel);
          return true;
        case CTRL | KeyEvent.KEYCODE_F:
        case CTRL | KeyEvent.KEYCODE_G:
        case CTRL | SHIFT | KeyEvent.KEYCODE_G:
        case KeyEvent.KEYCODE_F3:
        case SHIFT | KeyEvent.KEYCODE_F3:
          activity.onMenuOrKeyboardAction(R.id.find_in_page_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_L:
        case ALT | KeyEvent.KEYCODE_D:
        case KeyEvent.KEYCODE_BUTTON_X:
          activity.onMenuOrKeyboardAction(R.id.focus_url_bar, false);
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_B:
          activity.onMenuOrKeyboardAction(R.id.all_bookmarks_menu_id, false);
          return true;
        case KeyEvent.KEYCODE_BOOKMARK:
        case CTRL | KeyEvent.KEYCODE_D:
          activity.onMenuOrKeyboardAction(R.id.bookmark_this_page_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_H:
          activity.onMenuOrKeyboardAction(R.id.open_history_menu_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_P:
          activity.onMenuOrKeyboardAction(R.id.print_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_PLUS:
        case CTRL | KeyEvent.KEYCODE_EQUALS:
        case CTRL | SHIFT | KeyEvent.KEYCODE_PLUS:
        case CTRL | SHIFT | KeyEvent.KEYCODE_EQUALS:
        case KeyEvent.KEYCODE_ZOOM_IN:
          ContentViewCore cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomIn();
          return true;
        case CTRL | KeyEvent.KEYCODE_MINUS:
        case KeyEvent.KEYCODE_ZOOM_OUT:
          cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomOut();
          return true;
        case CTRL | KeyEvent.KEYCODE_0:
          cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomReset();
          return true;
        case SHIFT | CTRL | KeyEvent.KEYCODE_R:
        case CTRL | KeyEvent.KEYCODE_R:
        case SHIFT | KeyEvent.KEYCODE_F5:
        case KeyEvent.KEYCODE_F5:
          Tab tab = activity.getActivityTab();
          if (tab != null) {
            if ((keyCodeAndMeta & SHIFT) == SHIFT) {
              tab.reloadIgnoringCache();
            } else {
              tab.reload();
            }

            if (activity.getToolbarManager() != null
                && tab.getWebContents() != null
                && tab.getWebContents().focusLocationBarByDefault()) {
              activity.getToolbarManager().revertLocationBarChanges();
            } else {
              tab.requestFocus();
            }
          }
          return true;
        case ALT | KeyEvent.KEYCODE_DPAD_LEFT:
          tab = activity.getActivityTab();
          if (tab != null && tab.canGoBack()) tab.goBack();
          return true;
        case ALT | KeyEvent.KEYCODE_DPAD_RIGHT:
        case KeyEvent.KEYCODE_FORWARD:
        case KeyEvent.KEYCODE_BUTTON_START:
          tab = activity.getActivityTab();
          if (tab != null && tab.canGoForward()) tab.goForward();
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_SLASH: // i.e. Ctrl+?
          activity.onMenuOrKeyboardAction(R.id.help_id, false);
          return true;
      }
    }

    return false;
  }
예제 #26
0
  /**
   * Initializes a new {@link CastSessionImpl} instance.
   *
   * @param apiClient The Google Play Services client used to create the session.
   * @param sessionId The session identifier to use with the Cast SDK.
   * @param origin The origin of the frame requesting the route.
   * @param tabId The id of the tab containing the frame requesting the route.
   * @param isIncognito Whether the route is beging requested from an Incognito profile.
   * @param source The {@link MediaSource} corresponding to this session.
   * @param routeProvider The {@link CastMediaRouteProvider} instance managing this session.
   */
  public CastSessionImpl(
      GoogleApiClient apiClient,
      String sessionId,
      ApplicationMetadata metadata,
      String applicationStatus,
      CastDevice castDevice,
      String origin,
      int tabId,
      boolean isIncognito,
      MediaSource source,
      CastMediaRouteProvider routeProvider) {
    mSessionId = sessionId;
    mRouteProvider = routeProvider;
    mApiClient = apiClient;
    mSource = source;
    mApplicationMetadata = metadata;
    mApplicationStatus = applicationStatus;
    mCastDevice = castDevice;
    mMessageHandler = mRouteProvider.getMessageHandler();
    mMessageChannel = new CastMessagingChannel(this);
    updateNamespaces();

    final Context context = ContextUtils.getApplicationContext();

    if (mNamespaces.contains(CastMessageHandler.MEDIA_NAMESPACE)) {
      mMediaPlayer = new RemoteMediaPlayer();
      mMediaPlayer.setOnStatusUpdatedListener(
          new RemoteMediaPlayer.OnStatusUpdatedListener() {
            @Override
            public void onStatusUpdated() {
              MediaStatus mediaStatus = mMediaPlayer.getMediaStatus();
              if (mediaStatus == null) return;

              int playerState = mediaStatus.getPlayerState();
              if (playerState == MediaStatus.PLAYER_STATE_PAUSED
                  || playerState == MediaStatus.PLAYER_STATE_PLAYING) {
                mNotificationBuilder.setPaused(playerState != MediaStatus.PLAYER_STATE_PLAYING);
                mNotificationBuilder.setActions(
                    MediaNotificationInfo.ACTION_STOP | MediaNotificationInfo.ACTION_PLAY_PAUSE);
              } else {
                mNotificationBuilder.setActions(MediaNotificationInfo.ACTION_STOP);
              }
              MediaNotificationManager.show(context, mNotificationBuilder.build());
            }
          });
      mMediaPlayer.setOnMetadataUpdatedListener(
          new RemoteMediaPlayer.OnMetadataUpdatedListener() {
            @Override
            public void onMetadataUpdated() {
              setNotificationMetadata(mNotificationBuilder);
              MediaNotificationManager.show(context, mNotificationBuilder.build());
            }
          });
    }

    Intent contentIntent = Tab.createBringTabToFrontIntent(tabId);
    if (contentIntent != null) {
      contentIntent.putExtra(
          MediaNotificationUma.INTENT_EXTRA_NAME, MediaNotificationUma.SOURCE_PRESENTATION);
    }
    mNotificationBuilder =
        new MediaNotificationInfo.Builder()
            .setPaused(false)
            .setOrigin(origin)
            // TODO(avayvod): the same session might have more than one tab id. Should we track
            // the last foreground alive tab and update the notification with it?
            .setTabId(tabId)
            .setPrivate(isIncognito)
            .setActions(MediaNotificationInfo.ACTION_STOP)
            .setContentIntent(contentIntent)
            .setIcon(R.drawable.ic_notification_media_route)
            .setDefaultLargeIcon(R.drawable.cast_playing_square)
            .setId(R.id.presentation_notification)
            .setListener(this);
    setNotificationMetadata(mNotificationBuilder);
    MediaNotificationManager.show(context, mNotificationBuilder.build());
  }
예제 #27
0
 /**
  * Records metrics related to downloading a page. Should be called after a tap on the download
  * page button.
  *
  * @param tab The Tab containing the page being downloaded.
  */
 public static void recordDownloadPageMetrics(Tab tab) {
   RecordHistogram.recordPercentageHistogram(
       "OfflinePages.SavePage.PercentLoaded", tab.getProgress());
 }
예제 #28
0
 /**
  * Trigger the download of an Offline Page.
  *
  * @param context Context to pull resources from.
  */
 public static void downloadOfflinePage(Context context, Tab tab) {
   final OfflinePageDownloadBridge bridge = new OfflinePageDownloadBridge(tab.getProfile());
   bridge.startDownload(tab);
   bridge.destroy();
   DownloadUtils.recordDownloadPageMetrics(tab);
 }
 @Override
 public void onDismissForEachType(boolean isTimeout) {
   mTab.removeObserver(mTabObserver);
 }
 /** Opens the history page. */
 public void openHistoryPage() {
   if (mIsDestroyed) return;
   mTab.loadUrl(new LoadUrlParams(UrlConstants.HISTORY_URL));
   StartupMetrics.getInstance().recordOpenedHistory();
 }