@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; }
@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); } }
/** * 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(); }
/** 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); }
@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; }
@Override protected void setUp() throws Exception { super.setUp(); mTab = getActivity().getActivityTab(); mTab.addObserver(mTabObserver); mOnTitleUpdatedHelper = new CallbackHelper(); }
@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()); }
/** * 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; } }); }
/** * 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; }
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(); }
/** * 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; }
/** 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); } }
/** * 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; }
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; }
/** * 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()); }
/** * 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)); }
@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); }
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)); }
private void updateUrlBar() { Tab tab = getActivityTab(); if (tab == null || mUrlBar == null) return; mUrlBar.update(tab.getUrl(), tab.getSecurityLevel()); }
/** * 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: ´) 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; }
/** * 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()); }
/** * 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()); }
/** * 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(); }