@SmallTest @Feature({"TextSelection", "TextInput"}) public void testCursorPositionAfterHidingActionMode() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); assertWaitForSelectActionBarVisible(true); assertEquals(mContentViewCore.getSelectedText(), "SampleTextArea"); hideSelectActionMode(); assertWaitForSelectActionBarVisible(false); assertTrue( CriteriaHelper.pollForUIThreadCriteria( new Criteria() { @Override public boolean isSatisfied() { return "SampleTextArea" .equals( mContentViewCore .getImeAdapterForTest() .getInputConnectionForTest() .getTextBeforeCursor(50, 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(); } }
// Implements SmartClipProvider @Override public void setSmartClipResultHandler(final Handler resultHandler) { if (resultHandler == null) { mContentViewCore.setSmartClipDataListener(null); return; } mContentViewCore.setSmartClipDataListener( new ContentViewCore.SmartClipDataListener() { @Override public void onSmartClipDataExtracted(String text, String html, Rect clipRect) { Bundle bundle = new Bundle(); bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl()); bundle.putString("title", mContentViewCore.getWebContents().getTitle()); bundle.putParcelable("rect", clipRect); bundle.putString("text", text); bundle.putString("html", html); try { Message msg = Message.obtain(resultHandler, 0); msg.setData(bundle); msg.sendToTarget(); } catch (Exception e) { Log.e(TAG, "Error calling handler for smart clip data: ", e); } } }); }
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); } }); } } }
@Override public boolean performAccessibilityAction(int action, Bundle arguments) { if (mContentViewCore.supportsAccessibilityAction(action)) { return mContentViewCore.performAccessibilityAction(action, arguments); } return super.performAccessibilityAction(action, arguments); }
@SmallTest @Feature({"TextInput"}) public void testActionBarConfiguredCorrectlyForTextArea() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); assertTrue(mContentViewCore.getSelectActionHandler().isSelectionEditable()); assertFalse(mContentViewCore.getSelectActionHandler().isSelectionPassword()); }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarTextAreaCopy() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCopy(); assertClipboardContents(mContentViewCore.getContext(), "SampleTextArea"); }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarPasswordSelectAll() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_password"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSelectAll(); assertTrue(mContentViewCore.hasSelection()); assertWaitForSelectActionBarVisible(true); }
@SmallTest @Feature({"TextInput"}) public void testPastePopupNotShownOnLongPressingDisabledInput() throws Throwable { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text"); assertWaitForPastePopupStatus(true); assertTrue(mContentViewCore.hasInsertion()); DOMUtils.longPressNode(this, mContentViewCore, "disabled_text"); assertWaitForPastePopupStatus(false); assertFalse(mContentViewCore.hasInsertion()); }
void updateZoomControls() { if (mZoomButtonsController == null) return; boolean canZoomIn = mContentViewCore.canZoomIn(); boolean canZoomOut = mContentViewCore.canZoomOut(); if (!canZoomIn && !canZoomOut) { // Hide the zoom in and out buttons if the page cannot zoom mZoomButtonsController.getZoomControls().setVisibility(View.GONE); } else { // Set each one individually, as a page may be able to zoom in or out mZoomButtonsController.setZoomInEnabled(canZoomIn); mZoomButtonsController.setZoomOutEnabled(canZoomOut); } }
/** Disabled due to being flaky. crbug.com/552387 @SmallTest @Feature({"TextInput"}) */ @DisabledTest public void testSelectActionBarInputPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); DOMUtils.clickNode(this, mContentViewCore, "plain_text_1"); DOMUtils.longPressNode(this, mContentViewCore, "input_text"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleTextToCopy"); }
@SmallTest @Feature({"TextSelection"}) public void testSelectionPreservedAfterReshown() throws Throwable { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); setVisibileOnUiThread(false); assertWaitForSelectActionBarVisible(false); assertTrue(mContentViewCore.hasSelection()); setVisibileOnUiThread(true); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); }
/** 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)); } }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarPasswordCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "input_password"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Cut option won't be there for Password, hence no change in Clipboard // Validating with previous Clipboard content assertClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); }
@SmallTest @Feature({"TextSelection"}) public void testSelectActionBarPlainTextPaste() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Paste option won't be available for plain text. // Hence content won't be changed. assertNotSame(mContentViewCore.getSelectedText(), "SampleTextToCopy"); }
private ZoomButtonsController getZoomControls() { if (mZoomButtonsController == null && mContentViewCore.getContentSettings().shouldDisplayZoomControls()) { mZoomButtonsController = new ZoomButtonsController(mContentViewCore.getContainerView()); mZoomButtonsController.setOnZoomListener(new ZoomListener()); // ZoomButtonsController positions the buttons at the bottom, but in // the middle. Change their layout parameters so they appear on the // right. View controls = mZoomButtonsController.getZoomControls(); ViewGroup.LayoutParams params = controls.getLayoutParams(); if (params instanceof FrameLayout.LayoutParams) { ((FrameLayout.LayoutParams) params).gravity = Gravity.RIGHT; } } return mZoomButtonsController; }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarSearchAndShareLaunchesNewTask() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarSearch(); Intent i = getActivity().getLastSentIntent(); int new_task_flag = Intent.FLAG_ACTIVITY_NEW_TASK; assertEquals(i.getFlags() & new_task_flag, new_task_flag); selectActionBarShare(); i = getActivity().getLastSentIntent(); assertEquals(i.getFlags() & new_task_flag, new_task_flag); }
@SmallTest @Feature({"TextSelection"}) public void testSelectActionBarPlainTextCut() throws Exception { copyStringToClipboard("SampleTextToCopy"); DOMUtils.longPressNode(this, mContentViewCore, "plain_text_1"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SamplePlainTextOne"); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Cut option won't be available for plain text. // Hence validating previous Clipboard content. assertClipboardContents(mContentViewCore.getContext(), "SampleTextToCopy"); }
@SmallTest @Feature({"TextSelection"}) public void testSelectionClearedAfterLossOfFocus() throws Throwable { requestFocusOnUiThread(true); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); requestFocusOnUiThread(false); assertWaitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); requestFocusOnUiThread(true); assertWaitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); }
@Override public boolean dispatchKeyEvent(KeyEvent event) { if (isFocused()) { return mContentViewCore.dispatchKeyEvent(event); } else { return super.dispatchKeyEvent(event); } }
@Override public AccessibilityNodeProvider getAccessibilityNodeProvider() { AccessibilityNodeProvider provider = mContentViewCore.getAccessibilityNodeProvider(); if (provider != null) { return provider; } else { return super.getAccessibilityNodeProvider(); } }
@Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { try { TraceEvent.begin("ContentView.onFocusChanged"); super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); mContentViewCore.onFocusChanged(gainFocus); } finally { TraceEvent.end("ContentView.onFocusChanged"); } }
@Override protected void onSizeChanged(int w, int h, int ow, int oh) { try { TraceEvent.begin("ContentView.onSizeChanged"); super.onSizeChanged(w, h, ow, oh); mContentViewCore.onSizeChanged(w, h, ow, oh); } finally { TraceEvent.end("ContentView.onSizeChanged"); } }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarPasswordPaste() throws Exception { copyStringToClipboard("SamplePassword2"); // Select the password field. DOMUtils.longPressNode(this, mContentViewCore, "input_password"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText().length(), "SamplePassword".length()); // Paste "SamplePassword2" into the password field, replacing // "SamplePassword". assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarPaste(); assertWaitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); // Ensure the new text matches the pasted text. Note that we can't // actually compare strings as password field selections only provide // a placeholder with the correct length. DOMUtils.longPressNode(this, mContentViewCore, "input_password"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText().length(), "SamplePassword2".length()); }
@SmallTest @Feature({"TextSelection"}) public void testSelectionPreservedAfterLossOfFocusIfRequested() throws Throwable { requestFocusOnUiThread(true); DOMUtils.longPressNode(this, mContentViewCore, "textarea"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); mContentViewCore.preserveSelectionOnNextLossOfFocus(); requestFocusOnUiThread(false); assertWaitForSelectActionBarVisible(false); assertTrue(mContentViewCore.hasSelection()); requestFocusOnUiThread(true); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); // Losing focus yet again should properly clear the selection. requestFocusOnUiThread(false); assertWaitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ContentViewClient client = mContentViewCore.getContentViewClient(); // Allow the ContentViewClient to override the ContentView's width. int desiredWidthMeasureSpec = client.getDesiredWidthMeasureSpec(); if (MeasureSpec.getMode(desiredWidthMeasureSpec) != MeasureSpec.UNSPECIFIED) { widthMeasureSpec = desiredWidthMeasureSpec; } // Allow the ContentViewClient to override the ContentView's height. int desiredHeightMeasureSpec = client.getDesiredHeightMeasureSpec(); if (MeasureSpec.getMode(desiredHeightMeasureSpec) != MeasureSpec.UNSPECIFIED) { heightMeasureSpec = desiredHeightMeasureSpec; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
@SmallTest @Feature({"TextInput"}) public void testSelectActionBarInputCut() throws Exception { DOMUtils.longPressNode(this, mContentViewCore, "input_text"); assertWaitForSelectActionBarVisible(true); assertTrue(mContentViewCore.hasSelection()); assertEquals(mContentViewCore.getSelectedText(), "SampleInputText"); assertNotNull(mContentViewCore.getSelectActionHandler()); selectActionBarCut(); assertWaitForSelectActionBarVisible(false); assertFalse(mContentViewCore.hasSelection()); assertClipboardContents(mContentViewCore.getContext(), "SampleInputText"); assertEquals(mContentViewCore.getSelectedText(), ""); }
void updateMultiTouchSupport() { mMultiTouchListener.setPermanentlyIgnoreDetectorEvents( !mContentViewCore.getContentSettings().supportsMultiTouchZoom()); }
// Implements SmartClipProvider @Override public void extractSmartClipData(int x, int y, int width, int height) { mContentViewCore.extractSmartClipData(x, y, width, height); }
@Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); mContentViewCore.onVisibilityChanged(changedView, visibility); }