// 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 ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_H_
#define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_H_
#include <list>
#include <memory>
#include <string>
#include <utility>
#include "android_webview/browser/aw_browser_permission_request_delegate.h"
#include "android_webview/browser/aw_render_process_gone_delegate.h"
#include "android_webview/browser/find_helper.h"
#include "android_webview/browser/gfx/browser_view_renderer.h"
#include "android_webview/browser/gfx/browser_view_renderer_client.h"
#include "android_webview/browser/icon_helper.h"
#include "android_webview/browser/metrics/visibility_metrics_logger.h"
#include "android_webview/browser/permission/permission_callback.h"
#include "android_webview/browser/permission/permission_request_handler_client.h"
#include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
#include "android_webview/browser/safe_browsing/aw_safe_browsing_allowlist_manager.h"
#include "android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h"
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/functional/callback_forward.h"
#include "components/content_relationship_verification/digital_asset_links_handler.h"
#include "components/js_injection/browser/js_communication_host.h"
#include "content/public/browser/web_contents_observer.h"
class SkBitmap;
namespace content {
class WebContents;
}
namespace android_webview {
class AwContentsClientBridge;
class AwPdfExporter;
class AwWebContentsDelegate;
class PermissionRequestHandler;
// Native side of java-class of same name.
//
// Object lifetime:
// For most purposes the java and native objects can be considered to have
// 1:1 lifetime and relationship. The exception is the java instance that
// hosts a popup will be rebound to a second native instance (carrying the
// popup content) and discard the 'default' native instance it made on
// construction. A native instance is only bound to at most one Java peer over
// its entire lifetime - see Init() and SetPendingWebContentsForPopup() for the
// construction points, and SetJavaPeers() where these paths join.
//
// Lifetime: WebView
class AwContents : public FindHelper::Listener,
public IconHelper::Listener,
public AwRenderViewHostExtClient,
public BrowserViewRendererClient,
public PermissionRequestHandlerClient,
public AwBrowserPermissionRequestDelegate,
public AwRenderProcessGoneDelegate,
public content::WebContentsObserver,
public AwSafeBrowsingUIManager::UIManagerClient,
public VisibilityMetricsLogger::Client,
public AwSafeBrowsingAllowlistSetObserver {
public:
// Returns the AwContents instance associated with |web_contents|, or NULL.
static AwContents* FromWebContents(content::WebContents* web_contents);
static std::string GetLocale();
static std::string GetLocaleList();
AwContents(std::unique_ptr<content::WebContents> web_contents);
AwContents(const AwContents&) = delete;
AwContents& operator=(const AwContents&) = delete;
~AwContents() override;
AwRenderViewHostExt* render_view_host_ext() {
return render_view_host_ext_.get();
}
// |handler| is an instance of
// org.chromium.android_webview.AwHttpAuthHandler.
bool OnReceivedHttpAuthRequest(const base::android::JavaRef<jobject>& handler,
const std::string& host,
const std::string& realm);
void SetOffscreenPreRaster(bool enabled);
// Methods called from Java.
void SetJavaPeers(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& aw_contents,
const base::android::JavaParamRef<jobject>& web_contents_delegate,
const base::android::JavaParamRef<jobject>& contents_client_bridge,
const base::android::JavaParamRef<jobject>& io_thread_client,
const base::android::JavaParamRef<jobject>&
intercept_navigation_delegate);
void InitializeAndroidAutofill(JNIEnv* env);
base::android::ScopedJavaLocalRef<jobject> GetWebContents(JNIEnv* env);
base::android::ScopedJavaLocalRef<jobject> GetBrowserContext(JNIEnv* env);
void SetCompositorFrameConsumer(JNIEnv* env, jlong compositor_frame_consumer);
base::android::ScopedJavaLocalRef<jobject> GetRenderProcess(JNIEnv* env);
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
void Destroy(JNIEnv* env);
void DocumentHasImages(JNIEnv* env,
const base::android::JavaParamRef<jobject>& message);
void GenerateMHTML(JNIEnv* env,
const base::android::JavaParamRef<jstring>& jpath,
const base::android::JavaParamRef<jobject>& callback);
void CreatePdfExporter(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& pdfExporter);
void AddVisitedLinks(
JNIEnv* env,
const base::android::JavaParamRef<jobjectArray>& jvisited_links);
base::android::ScopedJavaLocalRef<jbyteArray> GetCertificate(JNIEnv* env);
void RequestNewHitTestDataAt(JNIEnv* env,
jfloat x,
jfloat y,
jfloat touch_major);
void UpdateLastHitTestData(JNIEnv* env);
void OnSizeChanged(JNIEnv* env, int w, int h, int ow, int oh);
void OnConfigurationChanged(JNIEnv* env);
void SetViewVisibility(JNIEnv* env, bool visible);
void SetWindowVisibility(JNIEnv* env, bool visible);
void SetIsPaused(JNIEnv* env, bool paused);
void OnAttachedToWindow(JNIEnv* env, int w, int h);
void OnDetachedFromWindow(JNIEnv* env);
bool IsVisible(JNIEnv* env);
bool IsDisplayingInterstitialForTesting(JNIEnv* env);
base::android::ScopedJavaLocalRef<jbyteArray> GetOpaqueState(JNIEnv* env);
jboolean RestoreFromOpaqueState(
JNIEnv* env,
const base::android::JavaParamRef<jbyteArray>& state);
void FocusFirstNode(JNIEnv* env);
void SetBackgroundColor(JNIEnv* env, jint color);
void ZoomBy(JNIEnv* env, jfloat delta);
void OnComputeScroll(JNIEnv* env, jlong animation_time_millis);
bool OnDraw(JNIEnv* env,
const base::android::JavaParamRef<jobject>& canvas,
jboolean is_hardware_accelerated,
jint scroll_x,
jint scroll_y,
jint visible_left,
jint visible_top,
jint visible_right,
jint visible_bottom,
jboolean force_auxiliary_bitmap_rendering);
jfloat GetVelocityInPixelsPerSecond(JNIEnv* env);
bool NeedToDrawBackgroundColor(JNIEnv* env);
jlong CapturePicture(JNIEnv* env, int width, int height);
void EnableOnNewPicture(JNIEnv* env, jboolean enabled);
void InsertVisualStateCallback(
JNIEnv* env,
jlong request_id,
const base::android::JavaParamRef<jobject>& callback);
void ClearView(JNIEnv* env);
void SetExtraHeadersForUrl(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& url,
const base::android::JavaParamRef<jstring>& extra_headers);
void InvokeGeolocationCallback(
JNIEnv* env,
jboolean value,
const base::android::JavaParamRef<jstring>& origin);
jint GetEffectivePriority(JNIEnv* env);
js_injection::JsCommunicationHost* GetJsCommunicationHost();
jint AddDocumentStartJavaScript(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& script,
const base::android::JavaParamRef<jobjectArray>& allowed_origin_rules);
void RemoveDocumentStartJavaScript(JNIEnv* env, jint script_id);
base::android::ScopedJavaLocalRef<jstring> AddWebMessageListener(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& listener,
const base::android::JavaParamRef<jstring>& js_object_name,
const base::android::JavaParamRef<jobjectArray>& allowed_origins);
void RemoveWebMessageListener(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& js_object_name);
std::vector<jni_zero::ScopedJavaLocalRef<jobject>> GetWebMessageListenerInfos(
JNIEnv* env);
std::vector<jni_zero::ScopedJavaLocalRef<jobject>>
GetDocumentStartupJavascripts(JNIEnv* env);
void FlushBackForwardCache(JNIEnv* env, jint reason);
void CancelAllPrerendering(JNIEnv* env);
bool GetViewTreeForceDarkState() { return view_tree_force_dark_state_; }
// PermissionRequestHandlerClient implementation.
void OnPermissionRequest(base::android::ScopedJavaLocalRef<jobject> j_request,
AwPermissionRequest* request) override;
void OnPermissionRequestCanceled(AwPermissionRequest* request) override;
PermissionRequestHandler* GetPermissionRequestHandler() {
return permission_request_handler_.get();
}
void PreauthorizePermission(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& origin,
jlong resources);
// AwBrowserPermissionRequestDelegate implementation.
void RequestProtectedMediaIdentifierPermission(
const GURL& origin,
PermissionCallback callback) override;
void CancelProtectedMediaIdentifierPermissionRequests(
const GURL& origin) override;
void RequestGeolocationPermission(const GURL& origin,
PermissionCallback callback) override;
void CancelGeolocationPermissionRequests(const GURL& origin) override;
void RequestMIDISysexPermission(const GURL& origin,
PermissionCallback callback) override;
void CancelMIDISysexPermissionRequests(const GURL& origin) override;
void RequestStorageAccess(const url::Origin& top_level_origin,
PermissionCallback callback) override;
// Find-in-page API and related methods.
void FindAllAsync(JNIEnv* env,
const base::android::JavaParamRef<jstring>& search_string);
void FindNext(JNIEnv* env, jboolean forward);
void ClearMatches(JNIEnv* env);
FindHelper* GetFindHelper();
// Per WebView Javascript Policy
bool IsJavaScriptAllowed();
// Per WebView Cookie Policy
bool AllowThirdPartyCookies();
// FindHelper::Listener implementation.
void OnFindResultReceived(int active_ordinal,
int match_count,
bool finished) override;
// IconHelper::Listener implementation.
bool ShouldDownloadFavicon(const GURL& icon_url) override;
void OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) override;
void OnReceivedTouchIconUrl(const std::string& url,
const bool precomposed) override;
// AwRenderViewHostExtClient implementation.
void OnWebLayoutPageScaleFactorChanged(float page_scale_factor) override;
void OnWebLayoutContentsSizeChanged(const gfx::Size& contents_size) override;
// BrowserViewRendererClient implementation.
void PostInvalidate(bool inside_vsync) override;
void OnNewPicture() override;
gfx::Point GetLocationOnScreen() override;
void OnViewTreeForceDarkStateChanged(
bool view_tree_force_dark_state) override;
void SetPreferredFrameInterval(
base::TimeDelta preferred_frame_interval) override;
// |new_value| is in physical pixel scale.
void ScrollContainerViewTo(const gfx::Point& new_value) override;
void UpdateScrollState(const gfx::Point& max_scroll_offset,
const gfx::SizeF& contents_size_dip,
float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor) override;
void DidOverscroll(const gfx::Vector2d& overscroll_delta,
const gfx::Vector2dF& overscroll_velocity,
bool inside_vsync) override;
ui::TouchHandleDrawable* CreateDrawable() override;
void ClearCache(JNIEnv* env, jboolean include_disk_files);
// See //android_webview/docs/how-does-on-create-window-work.md for more
// details.
void SetPendingWebContentsForPopup(
std::unique_ptr<content::WebContents> pending);
jlong ReleasePopupAwContents(JNIEnv* env);
void ScrollTo(JNIEnv* env, jint x, jint y);
void RestoreScrollAfterTransition(JNIEnv* env, jint x, jint y);
void SmoothScroll(JNIEnv* env,
jint target_x,
jint target_y,
jlong duration_ms);
void SetDipScale(JNIEnv* env, jfloat dip_scale);
base::android::ScopedJavaLocalRef<jstring> GetScheme(JNIEnv* env);
void OnInputEvent(JNIEnv* env);
void SetJsOnlineProperty(JNIEnv* env, jboolean network_up);
void TrimMemory(JNIEnv* env, jint level, jboolean visible);
void GrantFileSchemeAccesstoChildProcess(JNIEnv* env);
void ResumeLoadingCreatedPopupWebContents(JNIEnv* env);
void RendererUnresponsive(content::RenderProcessHost* render_process_host);
void RendererResponsive(content::RenderProcessHost* render_process_host);
bool UseLegacyGeolocationPermissionAPI();
// content::WebContentsObserver overrides
void PrimaryPageChanged(content::Page& page) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) override;
void RenderViewReady() override;
// AwSafeBrowsingUIManager::UIManagerClient implementation
bool CanShowInterstitial() override;
int GetErrorUiType() override;
// VisibilityMetricsLogger::Client implementation
VisibilityMetricsLogger::VisibilityInfo GetVisibilityInfo() override;
// AwRenderProcessGoneDelegate overrides
RenderProcessGoneResult OnRenderProcessGone(int child_process_id,
bool crashed) override;
// AwSafeBrowsingAllowlistSetObserver overrides
void OnSafeBrowsingAllowListSet() override;
private:
// Geolocation API support
void ShowGeolocationPrompt(const GURL& origin, PermissionCallback);
void HideGeolocationPrompt(const GURL& origin);
void SetDipScaleInternal(float dip_scale);
JavaObjectWeakGlobalRef java_ref_;
BrowserViewRenderer browser_view_renderer_; // Must outlive |web_contents_|.
std::unique_ptr<content::WebContents> web_contents_;
std::unique_ptr<AwWebContentsDelegate> web_contents_delegate_;
std::unique_ptr<AwContentsClientBridge> contents_client_bridge_;
std::unique_ptr<AwRenderViewHostExt> render_view_host_ext_;
std::unique_ptr<FindHelper> find_helper_;
std::unique_ptr<IconHelper> icon_helper_;
// See //android_webview/docs/how-does-on-create-window-work.md for more
// details for |pending_contents_|.
std::unique_ptr<AwContents> pending_contents_;
std::unique_ptr<AwPdfExporter> pdf_exporter_;
std::unique_ptr<PermissionRequestHandler> permission_request_handler_;
std::unique_ptr<js_injection::JsCommunicationHost> js_communication_host_;
std::unique_ptr<content_relationship_verification::DigitalAssetLinksHandler>
asset_link_handler_;
bool view_tree_force_dark_state_ = false;
std::string scheme_;
// GURL is supplied by the content layer as requesting frame.
// Callback is supplied by the content layer, and is invoked with the result
// from the permission prompt.
typedef std::pair<const GURL, PermissionCallback> OriginCallback;
// The first element in the list is always the currently pending request.
std::list<OriginCallback> pending_geolocation_prompts_;
base::TimeDelta preferred_frame_interval_;
};
} // namespace android_webview
#endif // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_H_