@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); // Tabs' listener array is safe to modify during use: its // iteration pattern is based on snapshots. Tabs.unregisterOnTabsChangedListener(this); }
/** * Load <code>url</code> using reflection and the internal <code>org.mozilla.gecko.Tabs</code> * API. * * <p>This method does not wait for any confirmation from Gecko before returning. */ protected final void loadUrl(final String url) { try { Tabs.getInstance().loadUrl(url); } catch (Exception e) { mAsserter.dumpLog("Exception in loadUrl", e); throw new RuntimeException(e); } }
/** * Replaces the page URL with "Switch to tab" if there is already a tab open with that URL. Only * looks for tabs that are either private or non-private, depending on the current selected tab. */ protected void updateDisplayedUrl() { final Tab selectedTab = Tabs.getInstance().getSelectedTab(); final boolean isPrivate = (selectedTab != null) && (selectedTab.isPrivate()); // We always want to display the underlying page url, however for readermode pages // we navigate to the about:reader equivalent, hence we need to use that url when finding // existing tabs final String navigationUrl = mHasReaderCacheItem ? ReaderModeUtils.getAboutReaderForUrl(mPageUrl) : mPageUrl; Tab tab = Tabs.getInstance().getFirstTabForUrl(navigationUrl, isPrivate); if (!mShowIcons || tab == null) { setUrl(mPageUrl); setSwitchToTabIcon(NO_ICON); } else { setUrl(R.string.switch_to_tab); setSwitchToTabIcon(R.drawable.ic_url_bar_tab); } }
/** * This function is invoked by Gecko via JNI; be careful when modifying signature. The compositor * invokes this function just before compositing a frame where the document is different from the * document composited on the last frame. In these cases, the viewport information we have in Java * is no longer valid and needs to be replaced with the new viewport information provided. * setPageRect will never be invoked on the same frame that this function is invoked on; and this * function will always be called prior to syncViewportInfo. */ public void setFirstPaintViewport( float offsetX, float offsetY, float zoom, float pageLeft, float pageTop, float pageRight, float pageBottom, float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { synchronized (this) { final ImmutableViewportMetrics newMetrics = getViewportMetrics() .setViewportOrigin(offsetX, offsetY) .setZoomFactor(zoom) .setPageRect( new RectF(pageLeft, pageTop, pageRight, pageBottom), new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom)); // Since we have switched to displaying a different document, we need to update any // viewport-related state we have lying around. This includes mGeckoViewport and // mViewportMetrics. Usually this information is updated via handleViewportMessage // while we remain on the same document. post( new Runnable() { public void run() { mGeckoViewport = newMetrics; } }); setViewportMetrics(newMetrics); Tab tab = Tabs.getInstance().getSelectedTab(); mView.setBackgroundColor(tab.getBackgroundColor()); setZoomConstraints(tab.getZoomConstraints()); // At this point, we have just switched to displaying a different document than we // we previously displaying. This means we need to abort any panning/zooming animations // that are in progress and send an updated display port request to browser.js as soon // as possible. We accomplish this by passing true to abortPanZoomAnimation, which // sends the request after aborting the animation. The display port request is actually // a full viewport update, which is fine because if browser.js has somehow moved to // be out of sync with this first-paint viewport, then we force them back in sync. abortPanZoomAnimation(); // Indicate that the document is about to be composited so the // LayerView background can be removed. if (mView.getPaintState() == LayerView.PAINT_START) { mView.setPaintState(LayerView.PAINT_BEFORE_FIRST); } } DisplayPortCalculator.resetPageState(); mDrawTimingQueue.reset(); }
public DisplayPortMetrics getDisplayPort( boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) { Tabs tabs = Tabs.getInstance(); if (tabs.isSelectedTab(tabs.getTab(tabId)) && isBrowserContentDisplayed) { // for foreground tabs, send the viewport update unless the document // displayed is different from the content document. In that case, just // calculate the display port. return handleViewportMessage( metrics, pageSizeUpdate ? ViewportMessageType.PAGE_SIZE : ViewportMessageType.UPDATE); } else { // for background tabs, request a new display port calculation, so that // when we do switch to that tab, we have the correct display port and // don't need to draw twice (once to allow the first-paint viewport to // get to java, and again once java figures out the display port). return DisplayPortCalculator.calculate(metrics, null); } }
@Override public void onBackPressed() { final Tabs tabs = Tabs.getInstance(); final Tab tab = tabs.getSelectedTab(); // Give Gecko a chance to handle the back press first, then fallback to the Java UI. GeckoAppShell.sendRequestToGecko( new GeckoRequest("Browser:OnBackPressed", null) { @Override public void onResponse(NativeJSObject nativeJSObject) { if (!nativeJSObject.getBoolean("handled")) { // Default behavior is Gecko didn't prevent. onDefault(); } } @Override public void onError(NativeJSObject error) { // Default behavior is Gecko didn't prevent, via failure. onDefault(); } // Return from Gecko thread, then back-press through the Java UI. private void onDefault() { ThreadUtils.postToUiThread( new Runnable() { @Override public void run() { if (tab.doBack()) { return; } finish(); } }); } }); }
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); Tabs.registerOnTabsChangedListener(this); }