/** * Loads an URL. This will perform minimal amounts of sanitizing of the URL to attempt to make it * valid. * * @param url The URL to be loaded by the shell. */ public void loadUrl(String url) { if (url == null) return; if (TextUtils.equals(url, mContentView.getUrl())) { mContentView.reload(); } else { mContentView.loadUrl(new LoadUrlParams(sanitizeUrl(url))); } mUrlTextView.clearFocus(); }
/** * Initializes the ContentView based on the native tab contents pointer passed in. * * @param nativeTabContents The pointer to the native tab contents object. */ @SuppressWarnings("unused") @CalledByNative private void initFromNativeTabContents(int nativeTabContents) { mContentView = ContentView.newInstance( getContext(), nativeTabContents, mWindow, ContentView.PERSONALITY_CHROME); if (mContentView.getUrl() != null) mUrlTextView.setText(mContentView.getUrl()); ((FrameLayout) findViewById(R.id.contentview_holder)) .addView( mContentView, new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); mContentView.requestFocus(); }
/** * Navigates this Tab's {@link ContentView} to a sanitized version of {@code url}. * * @param url The potentially unsanitized URL to navigate to. */ public void loadUrlWithSanitization(String url) { if (url == null) return; // Sanitize the URL. url = nativeFixupUrl(mNativeTabBaseAndroidImpl, url); // Invalid URLs will just return empty. if (TextUtils.isEmpty(url)) return; if (TextUtils.equals(url, mContentView.getUrl())) { mContentView.reload(); } else { mContentView.loadUrl(new LoadUrlParams(url)); } }
private void render() { if (mPendingRenders > 0) mPendingRenders--; // Waiting for the content view contents to be ready avoids compositing // when the surface texture is still empty. if (mCurrentContentView == null) return; ContentViewCore contentViewCore = mCurrentContentView.getContentViewCore(); if (contentViewCore == null || !contentViewCore.isReady()) { return; } boolean didDraw = nativeComposite(mNativeContentViewRenderView); if (didDraw) { mPendingSwapBuffers++; if (mSurfaceView.getBackground() != null) { post( new Runnable() { @Override public void run() { mSurfaceView.setBackgroundResource(0); } }); } } }
@CalledByNative private void requestRender() { ContentViewCore contentViewCore = mCurrentContentView != null ? mCurrentContentView.getContentViewCore() : null; boolean rendererHasFrame = contentViewCore != null && contentViewCore.consumePendingRendererFrame(); if (rendererHasFrame && mPendingSwapBuffers + mPendingRenders < MAX_SWAP_BUFFER_COUNT) { TraceEvent.instant("requestRender:now"); mNeedToRender = false; mPendingRenders++; // The handler can be null if we are detached from the window. Calling // {@link View#post(Runnable)} properly handles this case, but we lose the front of // queue behavior. That is okay for this edge case. Handler handler = getHandler(); if (handler != null) { handler.postAtFrontOfQueue(mRenderRunnable); } else { post(mRenderRunnable); } mVSyncAdapter.requestUpdate(); } else if (mPendingRenders <= 0) { assert mPendingRenders == 0; TraceEvent.instant("requestRender:later"); mNeedToRender = true; mVSyncAdapter.requestUpdate(); } }
/** Makes the passed ContentView the one displayed by this ContentViewRenderView. */ public void setCurrentContentView(ContentView contentView) { assert mNativeContentViewRenderView != 0; mCurrentContentView = contentView; ContentViewCore contentViewCore = contentView != null ? contentView.getContentViewCore() : null; nativeSetCurrentContentView( mNativeContentViewRenderView, contentViewCore != null ? contentViewCore.getNativeContentViewCore() : 0); if (contentViewCore != null) { contentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight()); mVSyncAdapter.setVSyncListener(contentViewCore.getVSyncListener(mVSyncAdapter)); } }
@CalledByNative private void onSwapBuffersCompleted() { TraceEvent.instant("onSwapBuffersCompleted"); if (!mFirstFrameReceived && mCurrentContentView != null && mCurrentContentView.getContentViewCore().isReady()) { mFirstFrameReceived = true; if (mFirstRenderedFrameListener != null) { mFirstRenderedFrameListener.onFirstFrameReceived(); } } if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) requestRender(); if (mPendingSwapBuffers > 0) mPendingSwapBuffers--; }
/** * @param context The Context the view is running in. * @param nativeWebContentsPtr A native pointer to the WebContents this tab represents. * @param window The NativeWindow should represent this tab. */ public TabBase(Context context, int nativeWebContentsPtr, NativeWindow window) { mWindow = window; // Build the WebContents and the ContentView/ContentViewCore if (nativeWebContentsPtr == 0) { nativeWebContentsPtr = ContentViewUtil.createNativeWebContents(false); } mContentView = ContentView.newInstance( context, nativeWebContentsPtr, mWindow, ContentView.PERSONALITY_CHROME); mNativeTabBaseAndroidImpl = nativeInit(nativeWebContentsPtr, window.getNativePointer()); // Build the WebContentsDelegate mWebContentsDelegate = new TabBaseChromeWebContentsDelegateAndroid(); nativeInitWebContentsDelegate(mNativeTabBaseAndroidImpl, mWebContentsDelegate); // To be called after everything is initialized. mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeTabBaseAndroidImpl)); }
private void destroyContentView() { if (mContentView == null) return; mContentView.destroy(); mContentView = null; }
/** * Tests that bringing up an Autofill and clicking on the first entry fills out the expected * Autofill information. */ @MediumTest @Feature({"autofill"}) public void testClickAutofillPopupSuggestion() throws InterruptedException, ExecutionException, TimeoutException { // The TestInputMethodManagerWrapper intercepts showSoftInput so that a keyboard is never // brought up. final ContentView view = getActivity().getActiveContentView(); final TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(view.getContentViewCore()); view.getContentViewCore().getImeAdapterForTest().setInputMethodManagerWrapper(immw); // Add an Autofill profile. AutofillProfile profile = new AutofillProfile( "" /* guid */, ORIGIN, FIRST_NAME + " " + LAST_NAME, COMPANY_NAME, ADDRESS_LINE1, ADDRESS_LINE2, CITY, STATE, ZIP_CODE, COUNTRY, PHONE_NUMBER, EMAIL); mHelper.setProfile(profile); assertEquals(1, mHelper.getNumberOfProfiles()); // Click the input field for the first name. final TestCallbackHelperContainer viewClient = new TestCallbackHelperContainer(view); assertTrue(DOMUtils.waitForNonZeroNodeBounds(view, viewClient, "fn")); DOMUtils.clickNode(this, view, viewClient, "fn"); waitForKeyboardShowRequest(immw, 1); view.getContentViewCore().getInputConnectionForTest().setComposingText("J", 1); waitForAnchorViewAdd(view); View anchorView = view.findViewById(R.id.autofill_popup_window); assertTrue(anchorView.getTag() instanceof AutofillPopup); final AutofillPopup popup = (AutofillPopup) anchorView.getTag(); waitForAutofillPopopShow(popup); TouchCommon touchCommon = new TouchCommon(this); touchCommon.singleClickViewRelative(popup.getListView(), 10, 10); waitForInputFieldFill(view, viewClient); assertEquals( "First name did not match", FIRST_NAME, DOMUtils.getNodeValue(view, viewClient, "fn")); assertEquals( "Last name did not match", LAST_NAME, DOMUtils.getNodeValue(view, viewClient, "ln")); assertEquals( "Address line 1 did not match", ADDRESS_LINE1, DOMUtils.getNodeValue(view, viewClient, "a1")); assertEquals( "Address line 2 did not match", ADDRESS_LINE2, DOMUtils.getNodeValue(view, viewClient, "a2")); assertEquals("City did not match", CITY, DOMUtils.getNodeValue(view, viewClient, "ct")); assertEquals("Zip code des not match", ZIP_CODE, DOMUtils.getNodeValue(view, viewClient, "zc")); assertEquals("Email does not match", EMAIL, DOMUtils.getNodeValue(view, viewClient, "em")); assertEquals( "Phone number does not match", PHONE_NUMBER, DOMUtils.getNodeValue(view, viewClient, "ph")); }
private ContentViewCore getContentViewCore() { Shell shell = shellManager.getActiveShell(); ContentView cv = shell != null ? shell.getContentView() : null; return cv != null ? cv.getContentViewCore() : null; }