[Default Nav Transition] Remove top controls in NTP screenshot
In order to match the viewport of the webpage screenshot, this CL excludes the area of top controls of NTP and maintain the size of the screenshot. As a result, the bottom part of the screenshot will be filled with the default background color of the NTP because it is impossible to draw off-screen views in Android. Screenshot (with top controls): https://screenshot.googleplex.com/AJFcDYvXCbnvXgj.png Screen record (w/o top controls): http://screencast/cast/NDY4NTA0OTc2ODE4MTc2MHxjODkyNWE0Zi1jOQ Bug: 331814846 Change-Id: Ieb8959ad2f202b15e055346f889a73355cdc4e06 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5560151 Reviewed-by: Rakina Zata Amni <rakina@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Reviewed-by: Khushal Sagar <khushalsagar@chromium.org> Commit-Queue: Lijin Shen <lazzzis@google.com> Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org> Cr-Commit-Position: refs/heads/main@{#1324606}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
4cc0cbba63
commit
7938c61cf2
chrome
android
java
src
org
chromium
chrome
browser
javatests
src
org
chromium
chrome
browser
browser
gesturenav
android
content
browser
web_contents
public
android
java
src
org
chromium
test
android
javatests
src
org
chromium
content_public
browser
test
@ -429,7 +429,8 @@ final class TabWebContentsDelegateAndroidImpl extends TabWebContentsDelegateAndr
|
||||
|
||||
@Override
|
||||
public boolean maybeCopyContentAreaAsBitmap(Callback<Bitmap> callback) {
|
||||
return NativePageBitmapCapturer.maybeCaptureNativeView(mTab, callback);
|
||||
return NativePageBitmapCapturer.maybeCaptureNativeView(
|
||||
mTab, callback, getTopControlsHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,10 +45,12 @@ import org.chromium.chrome.browser.ui.native_page.BasicSmoothTransitionDelegate;
|
||||
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
|
||||
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
||||
import org.chromium.chrome.test.util.ChromeTabUtils;
|
||||
import org.chromium.chrome.test.util.NewTabPageTestUtils;
|
||||
import org.chromium.components.embedder_support.util.UrlConstants;
|
||||
import org.chromium.content_public.browser.LoadUrlParams;
|
||||
import org.chromium.content_public.browser.back_forward_transition.AnimationStage;
|
||||
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
||||
import org.chromium.content_public.browser.test.util.UiUtils;
|
||||
import org.chromium.content_public.common.ContentUrlConstants;
|
||||
import org.chromium.net.test.EmbeddedTestServer;
|
||||
import org.chromium.ui.base.PageTransition;
|
||||
@ -66,6 +68,7 @@ import java.util.concurrent.TimeoutException;
|
||||
message = "crbug.com/1276402 crbug.com/345352689")
|
||||
public class NavigationHandlerTest {
|
||||
private static final String RENDERED_PAGE = "/chrome/test/data/android/navigate/simple.html";
|
||||
private static final String TEST_PAGE = "/chrome/test/data/android/test.html";
|
||||
private static final boolean LEFT_EDGE = true;
|
||||
private static final boolean RIGHT_EDGE = false;
|
||||
|
||||
@ -80,7 +83,10 @@ public class NavigationHandlerTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws InterruptedException {
|
||||
mActivityTestRule.startMainActivityOnBlankPage();
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_PAGE));
|
||||
CompositorAnimationHandler.setTestingMode(true);
|
||||
mNavUtils = new GestureNavigationUtils(mActivityTestRule);
|
||||
mNavigationHandler = mNavUtils.getNavigationHandler();
|
||||
@ -121,12 +127,12 @@ public class NavigationHandlerTest {
|
||||
@Test
|
||||
@SmallTest
|
||||
@EnableFeatures({ChromeFeatureList.BACK_FORWARD_TRANSITIONS})
|
||||
public void testSwipeBackToNTPWithTransition() {
|
||||
public void testSwipeBackToNTPWithTransition() throws InterruptedException {
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
final Tab tab = mActivityTestRule.getActivity().getActivityTab();
|
||||
mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
NewTabPageTestUtils.waitForNtpLoaded(mActivityTestRule.getActivity().getActivityTab());
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(RENDERED_PAGE));
|
||||
|
||||
mNavUtils.swipeFromEdgeAndHold(true);
|
||||
@ -203,9 +209,6 @@ public class NavigationHandlerTest {
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testReleaseGlowWithoutPrecedingPullIgnored() {
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(RENDERED_PAGE));
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
() -> {
|
||||
@ -268,9 +271,6 @@ public class NavigationHandlerTest {
|
||||
public void testSwipeNavigateOnRenderedPage() {
|
||||
// TODO(crbug.com/40899221): Write a test variation running with
|
||||
// ChromeFeatureList.BACK_FORWARD_TRANSITIONS enabled when the feature is completed.
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(RENDERED_PAGE));
|
||||
mActivityTestRule.loadUrl(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
|
||||
|
||||
@ -325,9 +325,6 @@ public class NavigationHandlerTest {
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testSwipeAfterDestroy() {
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(RENDERED_PAGE));
|
||||
TestThreadUtils.runOnUiThreadBlocking(mNavigationHandler::destroy);
|
||||
|
||||
@ -347,9 +344,6 @@ public class NavigationHandlerTest {
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testSwipeAfterTabDestroy() {
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(RENDERED_PAGE));
|
||||
TestThreadUtils.runOnUiThreadBlocking(currentTab()::destroy);
|
||||
|
||||
@ -363,9 +357,6 @@ public class NavigationHandlerTest {
|
||||
@Test
|
||||
@SmallTest
|
||||
public void testSwipeAfterDestroyActivity_NativePage() {
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
InstrumentationRegistry.getInstrumentation().getContext());
|
||||
mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
|
||||
TestThreadUtils.runOnUiThreadBlocking(mActivityTestRule.getActivity()::finish);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org.chromium.chrome.browser.gesturenav;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.filters.MediumTest;
|
||||
@ -23,19 +24,25 @@ import org.chromium.base.test.params.ParameterAnnotations;
|
||||
import org.chromium.base.test.params.ParameterizedRunner;
|
||||
import org.chromium.base.test.util.CallbackHelper;
|
||||
import org.chromium.base.test.util.CommandLineFlags;
|
||||
import org.chromium.base.test.util.DisableIf;
|
||||
import org.chromium.base.test.util.DoNotBatch;
|
||||
import org.chromium.base.test.util.Feature;
|
||||
import org.chromium.base.test.util.Features.EnableFeatures;
|
||||
import org.chromium.base.test.util.UrlUtils;
|
||||
import org.chromium.blink_public.common.BlinkFeatures;
|
||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||
import org.chromium.chrome.browser.flags.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
|
||||
import org.chromium.chrome.browser.fullscreen.FullscreenManagerTestUtils;
|
||||
import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
|
||||
import org.chromium.chrome.browser.tab.TabStateBrowserControlsVisibilityDelegate;
|
||||
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
||||
import org.chromium.chrome.test.util.ChromeRenderTestRule;
|
||||
import org.chromium.chrome.test.util.NewTabPageTestUtils;
|
||||
import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
|
||||
import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites;
|
||||
import org.chromium.components.embedder_support.util.UrlConstants;
|
||||
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
||||
import org.chromium.content_public.browser.test.util.UiUtils;
|
||||
import org.chromium.content_public.browser.test.util.WebContentsUtils;
|
||||
import org.chromium.net.test.EmbeddedTestServer;
|
||||
@ -70,6 +77,15 @@ public class ScreenshotCaptureTest {
|
||||
|
||||
private static final String TEST_PAGE = "/chrome/test/data/android/simple.html";
|
||||
private static final String TEST_PAGE_2 = "/chrome/test/data/android/google.html";
|
||||
private static final String LONG_HTML_TEST_PAGE =
|
||||
UrlUtils.encodeHtmlDataUri(
|
||||
"<html>"
|
||||
+ "<head>"
|
||||
+ " <meta name=\"viewport\" content=\"width=device-width\">"
|
||||
+ "</head>"
|
||||
+ "<body style='height:100000px;'>"
|
||||
+ "</body>"
|
||||
+ "</html>");
|
||||
|
||||
private EmbeddedTestServer mTestServer;
|
||||
private Bitmap mCapturedBitmap;
|
||||
@ -93,9 +109,10 @@ public class ScreenshotCaptureTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Fix the port cause the screenshot includes the url bar
|
||||
mTestServer =
|
||||
EmbeddedTestServer.createAndStartServer(
|
||||
ApplicationProvider.getApplicationContext());
|
||||
EmbeddedTestServer.createAndStartServerWithPort(
|
||||
ApplicationProvider.getApplicationContext(), 46985);
|
||||
|
||||
var mSiteSuggestions = NewTabPageTestUtils.createFakeSiteSuggestions(mTestServer);
|
||||
var mMostVisitedSites = new FakeMostVisitedSites();
|
||||
@ -189,6 +206,91 @@ public class ScreenshotCaptureTest {
|
||||
mRenderTestRule.compareForResult(mCapturedBitmap, "navigate_away_from_ntp_to_webui_page");
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
@Feature({"RenderTest"})
|
||||
// The test is based on 3-button mode. The newer version defaults to gesture mode.
|
||||
@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2)
|
||||
@ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class)
|
||||
public void testNavigatingBackToNtpFromNormalPage(boolean nightModeEnabled)
|
||||
throws IOException, TimeoutException, InterruptedException {
|
||||
mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
NewTabPageTestUtils.waitForNtpLoaded(mActivityTestRule.getActivity().getActivityTab());
|
||||
|
||||
mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
|
||||
|
||||
GestureNavigationUtils mNavUtils = new GestureNavigationUtils(mActivityTestRule);
|
||||
mNavUtils.swipeFromEdgeAndHold(/* leftEdge= */ true);
|
||||
|
||||
CallbackHelper callbackHelper = new CallbackHelper();
|
||||
mActivityTestRule
|
||||
.getWebContents()
|
||||
.captureContentAsBitmapForTesting(
|
||||
bitmap -> {
|
||||
try {
|
||||
mRenderTestRule.compareForResult(
|
||||
bitmap, "navigate_back_to_ntp_from_normal_page");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
callbackHelper.notifyCalled();
|
||||
});
|
||||
callbackHelper.waitForOnly();
|
||||
TestThreadUtils.runOnUiThreadBlocking(() -> mNavUtils.getNavigationHandler().release(true));
|
||||
// Wait animation to be finished. Reduce flakiness caused by being destroyed during a
|
||||
// running animation.
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
@Feature({"RenderTest"})
|
||||
// The test is based on 3-button mode. The newer version defaults to gesture mode.
|
||||
@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2)
|
||||
@ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class)
|
||||
public void testNavigatingBackToNtpFromNormalPageWithoutTopControls(boolean nightModeEnabled)
|
||||
throws Throwable {
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
TabStateBrowserControlsVisibilityDelegate::disablePageLoadDelayForTests);
|
||||
mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
NewTabPageTestUtils.waitForNtpLoaded(mActivityTestRule.getActivity().getActivityTab());
|
||||
FullscreenManagerTestUtils.disableBrowserOverrides();
|
||||
mActivityTestRule.loadUrl(LONG_HTML_TEST_PAGE);
|
||||
BrowserControlsManager browserControlManager =
|
||||
mActivityTestRule.getActivity().getBrowserControlsManager();
|
||||
int browserControlsHeight = browserControlManager.getTopControlsHeight();
|
||||
FullscreenManagerTestUtils.waitForBrowserControlsToBeMoveable(
|
||||
mActivityTestRule, mActivityTestRule.getActivity().getActivityTab());
|
||||
FullscreenManagerTestUtils.scrollBrowserControls(mActivityTestRule, false);
|
||||
|
||||
FullscreenManagerTestUtils.waitForBrowserControlsPosition(
|
||||
mActivityTestRule, -browserControlsHeight);
|
||||
GestureNavigationUtils mNavUtils = new GestureNavigationUtils(mActivityTestRule);
|
||||
mNavUtils.swipeFromEdgeAndHold(/* leftEdge= */ true);
|
||||
|
||||
CallbackHelper callbackHelper = new CallbackHelper();
|
||||
mActivityTestRule
|
||||
.getWebContents()
|
||||
.captureContentAsBitmapForTesting(
|
||||
bitmap -> {
|
||||
try {
|
||||
mRenderTestRule.compareForResult(
|
||||
bitmap,
|
||||
"navigate_back_to_ntp_from_normal_page_without_top_controls");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
callbackHelper.notifyCalled();
|
||||
});
|
||||
callbackHelper.waitForOnly();
|
||||
TestThreadUtils.runOnUiThreadBlocking(() -> mNavUtils.getNavigationHandler().release(true));
|
||||
// Wait animation to be finished. Reduce flakiness caused by being destroyed during a
|
||||
// running animation.
|
||||
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
public void testNotCaptureSadTab() throws TimeoutException, InterruptedException {
|
||||
|
@ -15,6 +15,7 @@ android_library("java") {
|
||||
"//base:base_java",
|
||||
"//chrome/browser/flags:java",
|
||||
"//chrome/browser/tab:java",
|
||||
"//chrome/browser/ui/android/native_page:java",
|
||||
"//third_party/androidx:androidx_annotation_annotation_java",
|
||||
"//third_party/jni_zero:jni_zero_java",
|
||||
"//ui/android:ui_no_recycler_view_java",
|
||||
|
@ -5,7 +5,6 @@ package org.chromium.chrome.browser.gesturenav;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -18,7 +17,7 @@ import org.chromium.base.task.PostTask;
|
||||
import org.chromium.base.task.TaskTraits;
|
||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.ui.resources.dynamics.CaptureObserver;
|
||||
import org.chromium.ui.resources.dynamics.CaptureUtils;
|
||||
import org.chromium.ui.resources.dynamics.SoftwareDraw;
|
||||
|
||||
/** Capture native page as a bitmap. */
|
||||
@ -37,10 +36,11 @@ public class NativePageBitmapCapturer implements UnownedUserData {
|
||||
* @param tab The target tab to be captured.
|
||||
* @param callback Executed with a non-null bitmap if the tab is presenting a native page. Empty
|
||||
* bitmap if capturing fails, such as out of memory error.
|
||||
* @param topControlsHeight Height of the top controls.
|
||||
* @return True if the capture is successfully triggered; otherwise false.
|
||||
*/
|
||||
public static boolean maybeCaptureNativeView(
|
||||
@NonNull Tab tab, @NonNull Callback<Bitmap> callback) {
|
||||
@NonNull Tab tab, @NonNull Callback<Bitmap> callback, int topControlsHeight) {
|
||||
if (!tab.isNativePage()) {
|
||||
return false;
|
||||
}
|
||||
@ -53,25 +53,19 @@ public class NativePageBitmapCapturer implements UnownedUserData {
|
||||
final var capturer = CAPTURER_KEY.retrieveDataFromHost(host);
|
||||
|
||||
View view = tab.getView();
|
||||
Rect viewBound = new Rect(0, 0, view.getWidth(), view.getHeight());
|
||||
|
||||
Bitmap bitmap = CaptureUtils.createBitmap(view.getWidth(), view.getHeight());
|
||||
bitmap.eraseColor(tab.getNativePage().getBackgroundColor());
|
||||
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
float scale = capturer.getScale();
|
||||
|
||||
// TODO(crbug.com/330230340): capture bitmap asynchronously.
|
||||
capturer.mSoftwareDraw.startBitmapCapture(
|
||||
view,
|
||||
viewBound,
|
||||
capturer.getScale(),
|
||||
new CaptureObserver() {
|
||||
@Override
|
||||
public void onCaptureStart(Canvas canvas, Rect dirtyRect) {}
|
||||
|
||||
@Override
|
||||
public void onCaptureEnd() {}
|
||||
},
|
||||
(bitmap) -> {
|
||||
// The screenshot callback must be dispatched asynchronously. See
|
||||
// WebContentsDelegateAndroid#maybeCopyContentAreaAsBitmap.
|
||||
PostTask.postTask(TaskTraits.UI_USER_VISIBLE, () -> callback.onResult(bitmap));
|
||||
});
|
||||
// Translate to exclude the area of the top controls.
|
||||
canvas.translate(0, -topControlsHeight);
|
||||
canvas.scale(scale, scale);
|
||||
view.draw(canvas);
|
||||
PostTask.postTask(TaskTraits.UI_USER_VISIBLE, () -> callback.onResult(bitmap));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@ import org.chromium.base.test.util.CommandLineFlags;
|
||||
import org.chromium.base.test.util.Features;
|
||||
import org.chromium.chrome.browser.flags.ChromeFeatureList;
|
||||
import org.chromium.chrome.browser.flags.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.tab.TabTestUtils;
|
||||
import org.chromium.chrome.browser.tab.TabWebContentsDelegateAndroid;
|
||||
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
|
||||
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
||||
import org.chromium.components.embedder_support.util.UrlConstants;
|
||||
@ -39,6 +41,12 @@ public class NativePageBitmapCapturerTest {
|
||||
@SmallTest
|
||||
public void testWithNativePage() throws TimeoutException {
|
||||
mTabbedActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
|
||||
|
||||
final TabWebContentsDelegateAndroid delegate =
|
||||
TabTestUtils.getTabWebContentsDelegate(
|
||||
mTabbedActivityTestRule.getActivity().getActivityTab());
|
||||
final int topControlsHeight = delegate.getTopControlsHeight();
|
||||
|
||||
CallbackHelper callbackHelper = new CallbackHelper();
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
() -> {
|
||||
@ -47,7 +55,8 @@ public class NativePageBitmapCapturerTest {
|
||||
mTabbedActivityTestRule.getActivity().getActivityTab(),
|
||||
(bitmap) -> {
|
||||
callbackHelper.notifyCalled();
|
||||
}));
|
||||
},
|
||||
topControlsHeight));
|
||||
});
|
||||
|
||||
callbackHelper.waitForOnly();
|
||||
@ -57,6 +66,12 @@ public class NativePageBitmapCapturerTest {
|
||||
@SmallTest
|
||||
public void testWithNonNativePage() {
|
||||
mTabbedActivityTestRule.startMainActivityOnBlankPage();
|
||||
|
||||
final TabWebContentsDelegateAndroid delegate =
|
||||
TabTestUtils.getTabWebContentsDelegate(
|
||||
mTabbedActivityTestRule.getActivity().getActivityTab());
|
||||
final int topControlsHeight = delegate.getTopControlsHeight();
|
||||
|
||||
CallbackHelper callbackHelper = new CallbackHelper();
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
() -> {
|
||||
@ -65,7 +80,8 @@ public class NativePageBitmapCapturerTest {
|
||||
mTabbedActivityTestRule.getActivity().getActivityTab(),
|
||||
(bitmap) -> {
|
||||
callbackHelper.notifyCalled();
|
||||
}));
|
||||
},
|
||||
topControlsHeight));
|
||||
});
|
||||
|
||||
// Capture will be finished before the following task.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "base/android/jni_android.h"
|
||||
#include "base/android/jni_array.h"
|
||||
#include "base/android/jni_string.h"
|
||||
#include "base/check.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/json/json_writer.h"
|
||||
@ -48,6 +49,7 @@
|
||||
#include "ui/gfx/android/java_bitmap.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/snapshot/snapshot.h"
|
||||
#include "url/android/gurl_android.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
@ -256,6 +258,28 @@ WebContentsAndroid::GetJavaObject() {
|
||||
return base::android::ScopedJavaLocalRef<jobject>(obj_);
|
||||
}
|
||||
|
||||
void WebContentsAndroid::CaptureContentAsBitmapForTesting(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& jcallback) {
|
||||
ui::GrabViewSnapshot(
|
||||
web_contents_->GetNativeView(), gfx::Rect(web_contents_->GetSize()),
|
||||
base::BindOnce(
|
||||
&WebContentsAndroid::OnFinishGetContentBitmapForTesting,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
base::android::ScopedJavaGlobalRef<jobject>(env, jcallback)));
|
||||
}
|
||||
|
||||
void WebContentsAndroid::OnFinishGetContentBitmapForTesting(
|
||||
const base::android::JavaRef<jobject>& callback,
|
||||
gfx::Image snapshot) {
|
||||
const SkBitmap bitmap = snapshot.AsBitmap();
|
||||
CHECK(!bitmap.isNull());
|
||||
CHECK(!bitmap.empty());
|
||||
base::android::RunObjectCallbackAndroid(
|
||||
callback,
|
||||
gfx::ConvertToJavaBitmap(bitmap, gfx::OomBehavior::kReturnNullOnOom));
|
||||
}
|
||||
|
||||
void WebContentsAndroid::ClearNativeReference(JNIEnv* env) {
|
||||
return web_contents_->ClearWebContentsAndroid();
|
||||
}
|
||||
|
@ -235,6 +235,13 @@ class CONTENT_EXPORT WebContentsAndroid {
|
||||
void OnContentForNavigationEntryShown(JNIEnv* env);
|
||||
jint GetCurrentBackForwardTransitionStage(JNIEnv* env);
|
||||
|
||||
void CaptureContentAsBitmapForTesting(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& jcallback);
|
||||
void OnFinishGetContentBitmapForTesting(
|
||||
const base::android::JavaRef<jobject>& callback,
|
||||
gfx::Image snapshot);
|
||||
|
||||
// Adds a crash report, like DumpWithoutCrashing(), including the Java stack
|
||||
// trace from which `web_contents` was created. This is meant to help debug
|
||||
// cases where BrowserContext is destroyed before its WebContents.
|
||||
|
@ -25,6 +25,7 @@ import org.jni_zero.CalledByNative;
|
||||
import org.jni_zero.JNINamespace;
|
||||
import org.jni_zero.NativeMethods;
|
||||
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.base.JavaExceptionReporter;
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.ObserverList;
|
||||
@ -1248,9 +1249,16 @@ public class WebContentsImpl implements WebContents, RenderFrameHostDelegate, Wi
|
||||
"Native WebContents already destroyed", mNativeDestroyThrowable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureContentAsBitmapForTesting(Callback<Bitmap> callback) {
|
||||
WebContentsImplJni.get()
|
||||
.captureContentAsBitmapForTesting(mNativeWebContentsAndroid, callback);
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
@NativeMethods
|
||||
public interface Natives {
|
||||
|
||||
// This is static to avoid exposing a public destroy method on the native side of this
|
||||
// class.
|
||||
void destroyWebContents(long webContentsAndroidPtr);
|
||||
@ -1454,5 +1462,8 @@ public class WebContentsImpl implements WebContents, RenderFrameHostDelegate, Wi
|
||||
long nativeWebContentsAndroid,
|
||||
BrowserControlsOffsetTagsInfo oldOffsetTagsInfo,
|
||||
BrowserControlsOffsetTagsInfo offsetTagsInfo);
|
||||
|
||||
void captureContentAsBitmapForTesting(
|
||||
long nativeWebContentsAndroid, Callback<Bitmap> callback);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package org.chromium.content_public.browser;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
@ -11,6 +12,7 @@ import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.blink_public.input.SelectionGranularity;
|
||||
import org.chromium.cc.input.BrowserControlsOffsetTagsInfo;
|
||||
import org.chromium.content_public.browser.back_forward_transition.AnimationStage;
|
||||
@ -621,4 +623,6 @@ public interface WebContents extends Parcelable {
|
||||
void notifyControlsConstraintsChanged(
|
||||
BrowserControlsOffsetTagsInfo oldOffsetTagsInfo,
|
||||
BrowserControlsOffsetTagsInfo offsetTagsInfo);
|
||||
|
||||
void captureContentAsBitmapForTesting(Callback<Bitmap> callback);
|
||||
}
|
||||
|
@ -5,12 +5,14 @@
|
||||
package org.chromium.content_public.browser.test.mock;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.blink_public.input.SelectionGranularity;
|
||||
import org.chromium.cc.input.BrowserControlsOffsetTagsInfo;
|
||||
import org.chromium.content_public.browser.GlobalRenderFrameHostId;
|
||||
@ -375,6 +377,9 @@ public class MockWebContents implements WebContents {
|
||||
return AnimationStage.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureContentAsBitmapForTesting(Callback<Bitmap> callback) {}
|
||||
|
||||
@Override
|
||||
public void notifyControlsConstraintsChanged(
|
||||
BrowserControlsOffsetTagsInfo oldOffsetTagsInfo,
|
||||
|
Reference in New Issue
Block a user