1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_TEST_TEST_RENDER_VIEW_HOST_H_
#define CONTENT_TEST_TEST_RENDER_VIEW_HOST_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/input/cursor_manager.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/public/common/page_visibility_state.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_renderer_host.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/gfx/geometry/vector2d_f.h"
#if defined(USE_AURA)
#include "ui/aura/window.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "third_party/blink/public/mojom/webshare/webshare.mojom.h"
#endif
// This file provides a testing framework for mocking out the RenderProcessHost
// layer. It allows you to test RenderViewHost, WebContentsImpl,
// NavigationController, and other layers above that without running an actual
// renderer process.
//
// To use, derive your test base class from RenderViewHostImplTestHarness.
namespace gfx {
class Rect;
}
namespace content {
class FrameTree;
class TestRenderFrameHost;
class TestPageBroadcast;
class TestWebContents;
// TestRenderWidgetHostView ----------------------------------------------------
// Subclass the RenderViewHost's view so that we can call Show(), etc.,
// without having side-effects.
class TestRenderWidgetHostView : public RenderWidgetHostViewBase,
public viz::HostFrameSinkClient {
public:
explicit TestRenderWidgetHostView(RenderWidgetHost* rwh);
~TestRenderWidgetHostView() override;
// RenderWidgetHostView:
void InitAsChild(gfx::NativeView parent_view) override {}
void SetSize(const gfx::Size& size) override {}
void SetBounds(const gfx::Rect& rect) override {}
gfx::NativeView GetNativeView() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
ui::TextInputClient* GetTextInputClient() override;
bool HasFocus() override;
void Hide() override;
bool IsShowing() override;
void WasUnOccluded() override;
void WasOccluded() override;
gfx::Rect GetViewBounds() override;
#if BUILDFLAG(IS_MAC)
void SetActive(bool active) override;
void ShowDefinitionForSelection() override {}
void SpeakSelection() override;
void SetWindowFrameInScreen(const gfx::Rect& rect) override;
void ShowSharePicker(
const std::string& title,
const std::string& text,
const std::string& url,
const std::vector<std::string>& file_paths,
blink::mojom::ShareService::ShareCallback callback) override;
uint64_t GetNSViewId() const override;
#endif // BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_ANDROID)
bool IsTouchSequencePotentiallyActiveOnViz() override;
void RequestInputBackForDragAndDrop(
blink::mojom::DragDataPtr drag_data,
const url::Origin& source_origin,
blink::DragOperationsMask drag_operations_mask,
SkBitmap bitmap,
gfx::Vector2d cursor_offset_in_dip,
gfx::Rect drag_obj_rect_in_dip,
blink::mojom::DragEventSourceInfoPtr event_info) override {}
#endif
// Notified in response to a CommitPending where there is no content for
// TakeFallbackContentFrom to use.
void ClearFallbackSurfaceForCommitPending() override;
// Advances the fallback surface to the first surface after navigation. This
// ensures that stale surfaces are not presented to the user for an indefinite
// period of time.
void ResetFallbackToFirstNavigationSurface() override {}
void TakeFallbackContentFrom(RenderWidgetHostView* view) override;
void EnsureSurfaceSynchronizedForWebTest() override;
// RenderWidgetHostViewBase:
uint32_t GetCaptureSequenceNumber() const override;
void InitAsPopup(RenderWidgetHostView* parent_host_view,
const gfx::Rect& bounds,
const gfx::Rect& anchor_rect) override {}
void Focus() override {}
void SetIsLoading(bool is_loading) override {}
void UpdateCursor(const ui::Cursor& cursor) override;
void RenderProcessGone() override;
void ShowWithVisibility(PageVisibilityState page_visibility) override;
void Destroy() override;
void UpdateTooltipUnderCursor(const std::u16string& tooltip_text) override {}
void UpdateTooltipFromKeyboard(const std::u16string& tooltip_text,
const gfx::Rect& bounds) override {}
void ClearKeyboardTriggeredTooltip() override {}
gfx::Rect GetBoundsInRootWindow() override;
const viz::LocalSurfaceId& IncrementSurfaceIdForNavigation() override;
blink::mojom::PointerLockResult LockPointer(bool) override;
blink::mojom::PointerLockResult ChangePointerLock(bool) override;
void UnlockPointer() override;
const viz::FrameSinkId& GetFrameSinkId() const override;
const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
viz::SurfaceId GetCurrentSurfaceId() const override;
std::unique_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
override;
ui::Compositor* GetCompositor() override;
input::CursorManager* GetCursorManager() override;
void InvalidateLocalSurfaceIdAndAllocationGroup() override {}
bool is_showing() const { return is_showing_; }
bool is_occluded() const { return is_occluded_; }
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnFrameTokenChanged(uint32_t frame_token,
base::TimeTicks activation_time) override;
const ui::Cursor& last_cursor() const { return last_cursor_; }
void SetCompositor(ui::Compositor* compositor) { compositor_ = compositor; }
// Clears `clear_fallback_surface_for_commit_pending_called_` and
// `take_fallback_content_from_called_`.
void ClearFallbackSurfaceCalled();
bool clear_fallback_surface_for_commit_pending_called() const {
return clear_fallback_surface_for_commit_pending_called_;
}
bool take_fallback_content_from_called() const {
return take_fallback_content_from_called_;
}
protected:
// RenderWidgetHostViewBase:
void UpdateBackgroundColor() override;
std::optional<DisplayFeature> GetDisplayFeature() override;
void DisableDisplayFeatureOverrideForEmulation() override;
void OverrideDisplayFeatureForEmulation(
const DisplayFeature* display_feature) override;
void NotifyHostAndDelegateOnWasShown(
blink::mojom::RecordContentToVisibleTimeRequestPtr) override;
void RequestSuccessfulPresentationTimeFromHostOrDelegate(
blink::mojom::RecordContentToVisibleTimeRequestPtr) override;
void CancelSuccessfulPresentationTimeRequestForHostAndDelegate() override;
viz::FrameSinkId frame_sink_id_;
private:
bool is_showing_;
bool is_occluded_;
PageVisibilityState page_visibility_ = PageVisibilityState::kHidden;
#if !BUILDFLAG(IS_IOS)
ui::DummyTextInputClient text_input_client_;
#endif
ui::Cursor last_cursor_;
// Latest capture sequence number which is incremented when the caller
// requests surfaces be synchronized via
// EnsureSurfaceSynchronizedForWebTest().
uint32_t latest_capture_sequence_number_ = 0u;
bool clear_fallback_surface_for_commit_pending_called_ = false;
bool take_fallback_content_from_called_ = false;
#if defined(USE_AURA)
std::unique_ptr<aura::Window> window_;
#endif
std::optional<DisplayFeature> display_feature_;
raw_ptr<ui::Compositor, DanglingUntriaged> compositor_ = nullptr;
input::CursorManager cursor_manager_;
};
// TestRenderWidgetHostViewChildFrame -----------------------------------------
// Test version of RenderWidgetHostViewChildFrame to use in unit tests.
class TestRenderWidgetHostViewChildFrame
: public RenderWidgetHostViewChildFrame {
public:
explicit TestRenderWidgetHostViewChildFrame(RenderWidgetHost* rwh);
~TestRenderWidgetHostViewChildFrame() override = default;
blink::WebInputEvent::Type last_gesture_seen() { return last_gesture_seen_; }
void Reset();
void SetCompositor(ui::Compositor* compositor);
ui::Compositor* GetCompositor() override;
private:
void SetBounds(const gfx::Rect& rect) override {}
void Hide() override {}
void SetInsets(const gfx::Insets& insets) override {}
void SendInitialPropertiesIfNeeded() override {}
void ShowWithVisibility(PageVisibilityState) override {}
void DidNavigate() override {}
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo&) override;
blink::WebInputEvent::Type last_gesture_seen_ =
blink::WebInputEvent::Type::kUndefined;
raw_ptr<ui::Compositor> compositor_;
};
// TestRenderViewHost ----------------------------------------------------------
// TODO(brettw) this should use a TestWebContents which should be generalized
// from the WebContentsImpl test. We will probably also need that class' version
// of CreateRenderViewForRenderManager when more complicated tests start using
// this.
//
// Note that users outside of content must use this class by getting
// the separate RenderViewHostTester interface via
// RenderViewHostTester::For(rvh) on the RenderViewHost they want to
// drive tests on.
//
// Users within content may directly static_cast from a
// RenderViewHost* to a TestRenderViewHost*.
//
// The reasons we do it this way rather than extending the parallel
// inheritance hierarchy we have for RenderWidgetHost/RenderViewHost
// vs. RenderWidgetHostImpl/RenderViewHostImpl are:
//
// a) Extending the parallel class hierarchy further would require
// more classes to use virtual inheritance. This is a complexity that
// is better to avoid, especially when it would be introduced in the
// production code solely to facilitate testing code.
//
// b) While users outside of content only need to drive tests on a
// RenderViewHost, content needs a test version of the full
// RenderViewHostImpl so that it can test all methods on that concrete
// class (e.g. overriding a method such as
// RenderViewHostImpl::CreateRenderView). This would have complicated
// the dual class hierarchy even further.
//
// The reason we do it this way instead of using composition is
// similar to (b) above, essentially it gets very tricky. By using
// the split interface we avoid complexity within content and maintain
// reasonable utility for embedders.
class TestRenderViewHost : public RenderViewHostImpl,
public RenderViewHostTester {
public:
TestRenderViewHost(
FrameTree* frame_tree,
SiteInstanceGroup* group,
const StoragePartitionConfig& storage_partition_config,
std::unique_ptr<RenderWidgetHostImpl> widget,
RenderViewHostDelegate* delegate,
int32_t routing_id,
int32_t main_frame_routing_id,
scoped_refptr<BrowsingContextState> main_browsing_context_state,
CreateRenderViewHostCase create_case);
TestRenderViewHost(const TestRenderViewHost&) = delete;
TestRenderViewHost& operator=(const TestRenderViewHost&) = delete;
// RenderViewHostImpl overrides.
MockRenderProcessHost* GetProcess() const override;
bool CreateRenderView(
const std::optional<blink::FrameToken>& opener_frame_token,
int proxy_route_id,
bool window_was_created_with_opener,
const std::optional<base::UnguessableToken>& navigation_metrics_token)
override;
bool IsTestRenderViewHost() const override;
// RenderViewHostTester implementation.
void SimulateWasHidden() override;
void SimulateWasShown() override;
blink::web_pref::WebPreferences TestComputeWebPreferences() override;
bool CreateTestRenderView() override;
void TestOnUpdateStateWithFile(const base::FilePath& file_path);
void TestStartDragging(const DropData& drop_data, SkBitmap bitmap = {});
// If set, *delete_counter is incremented when this object destructs.
void set_delete_counter(int* delete_counter) {
delete_counter_ = delete_counter;
}
// The opener frame route id passed to CreateRenderView().
const std::optional<blink::FrameToken>& opener_frame_token() const {
return opener_frame_token_;
}
private:
FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, FilterNavigate);
~TestRenderViewHost() override;
void SendNavigateWithTransitionAndResponseCode(const GURL& url,
ui::PageTransition transition,
int response_code);
// Calls OnNavigate on the RenderViewHost with the given information.
// Sets the rest of the parameters in the message to the "typical" values.
// This is a helper function for simulating the most common types of loads.
void SendNavigateWithParameters(
const GURL& url,
ui::PageTransition transition,
const GURL& original_request_url,
int response_code,
const base::FilePath* file_path_for_history_item);
// See set_delete_counter() above. May be NULL.
raw_ptr<int> delete_counter_;
// See opener_frame_token() above.
std::optional<blink::FrameToken> opener_frame_token_;
std::unique_ptr<TestPageBroadcast> page_broadcast_;
};
// Adds methods to get straight at the impl classes.
class RenderViewHostImplTestHarness : public RenderViewHostTestHarness {
public:
RenderViewHostImplTestHarness();
RenderViewHostImplTestHarness(const RenderViewHostImplTestHarness&) = delete;
RenderViewHostImplTestHarness& operator=(
const RenderViewHostImplTestHarness&) = delete;
~RenderViewHostImplTestHarness() override;
// contents() is equivalent to static_cast<TestWebContents*>(web_contents())
TestWebContents* contents();
// RVH/RFH getters are shorthand for oft-used bits of web_contents().
// test_rvh() is equivalent to any of the following:
// contents()->GetPrimaryMainFrame()->GetRenderViewHost()
// contents()->GetRenderViewHost()
// static_cast<TestRenderViewHost*>(rvh())
//
// Since most functionality will eventually shift from RVH to RFH, you may
// prefer to use the GetPrimaryMainFrame() method in tests.
TestRenderViewHost* test_rvh();
// main_test_rfh() is equivalent to contents()->GetPrimaryMainFrame()
// TODO(nick): Replace all uses with contents()->GetPrimaryMainFrame()
TestRenderFrameHost* main_test_rfh();
private:
ui::test::ScopedSetSupportedResourceScaleFactors
scoped_set_supported_scale_factors_{{ui::k100Percent}};
};
} // namespace content
#endif // CONTENT_TEST_TEST_RENDER_VIEW_HOST_H_
|