123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602 |
- // Copyright 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/aw_contents.h"
- #include <limits>
- #include <memory>
- #include <string>
- #include <utility>
- #include "android_webview/browser/aw_autofill_client.h"
- #include "android_webview/browser/aw_browser_context.h"
- #include "android_webview/browser/aw_browser_main_parts.h"
- #include "android_webview/browser/aw_contents_client_bridge.h"
- #include "android_webview/browser/aw_contents_io_thread_client.h"
- #include "android_webview/browser/aw_pdf_exporter.h"
- #include "android_webview/browser/aw_render_process.h"
- #include "android_webview/browser/aw_renderer_priority.h"
- #include "android_webview/browser/aw_resource_context.h"
- #include "android_webview/browser/aw_settings.h"
- #include "android_webview/browser/aw_web_contents_delegate.h"
- #include "android_webview/browser/gfx/aw_gl_functor.h"
- #include "android_webview/browser/gfx/aw_picture.h"
- #include "android_webview/browser/gfx/browser_view_renderer.h"
- #include "android_webview/browser/gfx/child_frame.h"
- #include "android_webview/browser/gfx/gpu_service_webview.h"
- #include "android_webview/browser/gfx/java_browser_view_renderer_helper.h"
- #include "android_webview/browser/gfx/render_thread_manager.h"
- #include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
- #include "android_webview/browser/js_java_interaction/aw_web_message_host_factory.h"
- #include "android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.h"
- #include "android_webview/browser/page_load_metrics/page_load_metrics_initialize.h"
- #include "android_webview/browser/permission/aw_permission_request.h"
- #include "android_webview/browser/permission/permission_request_handler.h"
- #include "android_webview/browser/permission/simple_permission_request.h"
- #include "android_webview/browser/state_serializer.h"
- #include "android_webview/browser_jni_headers/AwContents_jni.h"
- #include "android_webview/common/aw_switches.h"
- #include "android_webview/common/devtools_instrumentation.h"
- #include "android_webview/common/mojom/frame.mojom.h"
- #include "base/android/jni_android.h"
- #include "base/android/jni_array.h"
- #include "base/android/jni_string.h"
- #include "base/android/locale_utils.h"
- #include "base/android/scoped_java_ref.h"
- #include "base/atomicops.h"
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/callback_helpers.h"
- #include "base/command_line.h"
- #include "base/feature_list.h"
- #include "base/i18n/rtl.h"
- #include "base/json/json_writer.h"
- #include "base/location.h"
- #include "base/memory/memory_pressure_listener.h"
- #include "base/memory/raw_ptr.h"
- #include "base/no_destructor.h"
- #include "base/pickle.h"
- #include "base/supports_user_data.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/threading/thread_restrictions.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "components/android_autofill/browser/android_autofill_manager.h"
- #include "components/android_autofill/browser/autofill_provider_android.h"
- #include "components/autofill/content/browser/content_autofill_driver_factory.h"
- #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
- #include "components/autofill/core/common/autofill_features.h"
- #include "components/navigation_interception/intercept_navigation_delegate.h"
- #include "components/safe_browsing/core/common/features.h"
- #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
- #include "components/viz/common/surfaces/frame_sink_id.h"
- #include "content/public/browser/android/child_process_importance.h"
- #include "content/public/browser/android/synchronous_compositor.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/browsing_data_remover.h"
- #include "content/public/browser/child_process_security_policy.h"
- #include "content/public/browser/favicon_status.h"
- #include "content/public/browser/navigation_entry.h"
- #include "content/public/browser/navigation_handle.h"
- #include "content/public/browser/page.h"
- #include "content/public/browser/render_frame_host.h"
- #include "content/public/browser/render_process_host.h"
- #include "content/public/browser/render_view_host.h"
- #include "content/public/browser/render_widget_host.h"
- #include "content/public/browser/render_widget_host_iterator.h"
- #include "content/public/browser/ssl_status.h"
- #include "content/public/browser/web_contents.h"
- #include "content/public/common/mhtml_generation_params.h"
- #include "net/base/auth.h"
- #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
- #include "net/cert/x509_certificate.h"
- #include "net/cert/x509_util.h"
- #include "third_party/skia/include/core/SkPicture.h"
- #include "ui/gfx/android/java_bitmap.h"
- #include "ui/gfx/geometry/rect_f.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/gfx/image/image.h"
- #include "url/origin.h"
- #include "url/url_constants.h"
- struct AwDrawSWFunctionTable;
- using autofill::ContentAutofillDriverFactory;
- using base::android::AttachCurrentThread;
- using base::android::ConvertJavaStringToUTF16;
- using base::android::ConvertJavaStringToUTF8;
- using base::android::ConvertUTF16ToJavaString;
- using base::android::ConvertUTF8ToJavaString;
- using base::android::HasException;
- using base::android::JavaParamRef;
- using base::android::JavaRef;
- using base::android::ScopedJavaGlobalRef;
- using base::android::ScopedJavaLocalRef;
- using content::BrowserThread;
- using content::RenderFrameHost;
- using content::WebContents;
- using js_injection::JsCommunicationHost;
- using navigation_interception::InterceptNavigationDelegate;
- namespace android_webview {
- class CompositorFrameConsumer;
- namespace {
- bool g_should_download_favicons = false;
- std::string* g_locale() {
- static base::NoDestructor<std::string> locale;
- return locale.get();
- }
- std::string* g_locale_list() {
- static base::NoDestructor<std::string> locale_list;
- return locale_list.get();
- }
- const void* const kAwContentsUserDataKey = &kAwContentsUserDataKey;
- const void* const kComputedRendererPriorityUserDataKey =
- &kComputedRendererPriorityUserDataKey;
- class AwContentsUserData : public base::SupportsUserData::Data {
- public:
- explicit AwContentsUserData(AwContents* ptr) : contents_(ptr) {}
- static AwContents* GetContents(WebContents* web_contents) {
- if (!web_contents)
- return NULL;
- AwContentsUserData* data = static_cast<AwContentsUserData*>(
- web_contents->GetUserData(kAwContentsUserDataKey));
- return data ? data->contents_.get() : NULL;
- }
- private:
- raw_ptr<AwContents> contents_;
- };
- base::subtle::Atomic32 g_instance_count = 0;
- } // namespace
- class ScopedAllowInitGLBindings {
- public:
- ScopedAllowInitGLBindings() {}
- ~ScopedAllowInitGLBindings() {}
- private:
- base::ScopedAllowBlocking allow_blocking_;
- };
- // static
- AwContents* AwContents::FromWebContents(WebContents* web_contents) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- return AwContentsUserData::GetContents(web_contents);
- }
- // static
- void JNI_AwContents_UpdateDefaultLocale(
- JNIEnv* env,
- const JavaParamRef<jstring>& locale,
- const JavaParamRef<jstring>& locale_list) {
- *g_locale() = ConvertJavaStringToUTF8(env, locale);
- *g_locale_list() = ConvertJavaStringToUTF8(env, locale_list);
- }
- // static
- std::string AwContents::GetLocale() {
- return *g_locale();
- }
- // static
- std::string AwContents::GetLocaleList() {
- return *g_locale_list();
- }
- // static
- AwBrowserPermissionRequestDelegate* AwBrowserPermissionRequestDelegate::FromID(
- int render_process_id,
- int render_frame_id) {
- AwContents* aw_contents =
- AwContents::FromWebContents(content::WebContents::FromRenderFrameHost(
- content::RenderFrameHost::FromID(render_process_id,
- render_frame_id)));
- return aw_contents;
- }
- // static
- AwSafeBrowsingUIManager::UIManagerClient*
- AwSafeBrowsingUIManager::UIManagerClient::FromWebContents(
- WebContents* web_contents) {
- return AwContents::FromWebContents(web_contents);
- }
- // static
- AwRenderProcessGoneDelegate* AwRenderProcessGoneDelegate::FromWebContents(
- content::WebContents* web_contents) {
- return AwContents::FromWebContents(web_contents);
- }
- AwContents::AwContents(std::unique_ptr<WebContents> web_contents)
- : content::WebContentsObserver(web_contents.get()),
- browser_view_renderer_(this, content::GetUIThreadTaskRunner({})),
- web_contents_(std::move(web_contents)) {
- base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
- icon_helper_ = std::make_unique<IconHelper>(web_contents_.get());
- icon_helper_->SetListener(this);
- web_contents_->SetUserData(android_webview::kAwContentsUserDataKey,
- std::make_unique<AwContentsUserData>(this));
- browser_view_renderer_.RegisterWithWebContents(web_contents_.get());
- viz::FrameSinkId frame_sink_id;
- if (web_contents_->GetRenderViewHost()) {
- frame_sink_id =
- web_contents_->GetRenderViewHost()->GetWidget()->GetFrameSinkId();
- }
- browser_view_renderer_.SetActiveFrameSinkId(frame_sink_id);
- render_view_host_ext_ =
- std::make_unique<AwRenderViewHostExt>(this, web_contents_.get());
- InitializePageLoadMetricsForWebContents(web_contents_.get());
- permission_request_handler_ =
- std::make_unique<PermissionRequestHandler>(this, web_contents_.get());
- AwAutofillClient* browser_autofill_manager_delegate =
- AwAutofillClient::FromWebContents(web_contents_.get());
- if (browser_autofill_manager_delegate) {
- InitAutofillIfNecessary(
- browser_autofill_manager_delegate->GetSaveFormData());
- }
- content::SynchronousCompositor::SetClientForWebContents(
- web_contents_.get(), &browser_view_renderer_);
- AwContentsLifecycleNotifier::GetInstance().OnWebViewCreated(this);
- AwBrowserProcess::GetInstance()->visibility_metrics_logger()->AddClient(this);
- }
- void AwContents::SetJavaPeers(
- JNIEnv* env,
- const JavaParamRef<jobject>& aw_contents,
- const JavaParamRef<jobject>& web_contents_delegate,
- const JavaParamRef<jobject>& contents_client_bridge,
- const JavaParamRef<jobject>& io_thread_client,
- const JavaParamRef<jobject>& intercept_navigation_delegate) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // The |aw_content| param is technically spurious as it duplicates |obj| but
- // is passed over anyway to make the binding more explicit.
- java_ref_ = JavaObjectWeakGlobalRef(env, aw_contents);
- web_contents_delegate_ =
- std::make_unique<AwWebContentsDelegate>(env, web_contents_delegate);
- web_contents_->SetDelegate(web_contents_delegate_.get());
- contents_client_bridge_ =
- std::make_unique<AwContentsClientBridge>(env, contents_client_bridge);
- AwContentsClientBridge::Associate(web_contents_.get(),
- contents_client_bridge_.get());
- AwContentsIoThreadClient::Associate(web_contents_.get(), io_thread_client);
- InterceptNavigationDelegate::Associate(
- web_contents_.get(), std::make_unique<InterceptNavigationDelegate>(
- env, intercept_navigation_delegate));
- }
- void AwContents::InitializeAndroidAutofill(JNIEnv* env) {
- // Initialize Android Autofill, this method shall only be called in Android O
- // and beyond.
- // AutofillProvider shall already be created for |web_contents_| from
- // AutofillProvider java.
- DCHECK(autofill::AutofillProvider::FromWebContents(web_contents_.get()));
- // Autocomplete is only supported for Android pre-O, disable it if Android
- // autofill is enabled.
- InitAutofillIfNecessary(/*autocomplete_enabled=*/false);
- }
- void AwContents::SetSaveFormData(bool enabled) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- InitAutofillIfNecessary(enabled);
- // We need to check for the existence, since browser_autofill_manager_delegate
- // may not be created when the setting is false.
- if (AwAutofillClient::FromWebContents(web_contents_.get())) {
- AwAutofillClient::FromWebContents(web_contents_.get())
- ->SetSaveFormData(enabled);
- }
- }
- void AwContents::InitAutofillIfNecessary(bool autocomplete_enabled) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // This method initializes either Android autofill or Chrome autocomplete:
- // - If autofill_provider is available, Android autofill shall be initialized.
- // - Otherwise, initialize Chrome autocomplete if autocomplete_enabled.
- // Check if the autofill driver factory already exists.
- content::WebContents* web_contents = web_contents_.get();
- if (ContentAutofillDriverFactory::FromWebContents(web_contents))
- return;
- // The autofill_provider object shall already be created by the
- // AutofillProvider Java object in Android O and beyond.
- auto* autofill_provider =
- autofill::AutofillProvider::FromWebContents(web_contents);
- // Just return, if the app neither runs on O sdk nor enables autocomplete.
- if (!autofill_provider && !autocomplete_enabled)
- return;
- autofill::AutofillManager::EnableDownloadManager enable_download_manager(
- !autofill::AutofillProvider::is_download_manager_disabled_for_testing());
- AwAutofillClient::CreateForWebContents(web_contents);
- // WebView browser tests may shall use BrowserAutofillManager if
- // `!autofill_provider`.
- ContentAutofillDriverFactory::DriverInitCallback driver_init_hook =
- autofill_provider
- ? base::BindRepeating(&autofill::AndroidDriverInitHook,
- AwAutofillClient::FromWebContents(web_contents),
- enable_download_manager)
- : base::BindRepeating(&autofill::BrowserDriverInitHook,
- AwAutofillClient::FromWebContents(web_contents),
- base::android::GetDefaultLocaleString());
- ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
- web_contents, AwAutofillClient::FromWebContents(web_contents),
- std::move(driver_init_hook));
- }
- void AwContents::SetAwAutofillClient(const JavaRef<jobject>& client) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_setAwAutofillClient(env, obj, client);
- }
- AwContents::~AwContents() {
- DCHECK_EQ(this, AwContents::FromWebContents(web_contents_.get()));
- web_contents_->RemoveUserData(kAwContentsUserDataKey);
- AwContentsClientBridge::Dissociate(web_contents_.get());
- if (find_helper_.get())
- find_helper_->SetListener(NULL);
- if (icon_helper_.get())
- icon_helper_->SetListener(NULL);
- base::subtle::Atomic32 instance_count =
- base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1);
- // When the last WebView is destroyed free all discardable memory allocated by
- // Chromium, because the app process may continue to run for a long time
- // without ever using another WebView.
- if (instance_count == 0) {
- // TODO(timvolodine): consider moving NotifyMemoryPressure to
- // AwContentsLifecycleNotifier (crbug.com/522988).
- base::MemoryPressureListener::NotifyMemoryPressure(
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
- }
- browser_view_renderer_.SetCurrentCompositorFrameConsumer(nullptr);
- AwContentsLifecycleNotifier::GetInstance().OnWebViewDestroyed(this);
- WebContentsObserver::Observe(nullptr);
- AwBrowserProcess::GetInstance()->visibility_metrics_logger()->RemoveClient(
- this);
- }
- base::android::ScopedJavaLocalRef<jobject> AwContents::GetWebContents(
- JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(web_contents_);
- if (!web_contents_)
- return base::android::ScopedJavaLocalRef<jobject>();
- return web_contents_->GetJavaWebContents();
- }
- base::android::ScopedJavaLocalRef<jobject> AwContents::GetBrowserContext(
- JNIEnv* env) {
- if (!web_contents_)
- return base::android::ScopedJavaLocalRef<jobject>();
- return AwBrowserContext::FromWebContents(web_contents_.get())
- ->GetJavaBrowserContext();
- }
- void AwContents::SetCompositorFrameConsumer(JNIEnv* env,
- jlong compositor_frame_consumer) {
- browser_view_renderer_.SetCurrentCompositorFrameConsumer(
- reinterpret_cast<CompositorFrameConsumer*>(compositor_frame_consumer));
- }
- ScopedJavaLocalRef<jobject> AwContents::GetRenderProcess(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::RenderProcessHost* host =
- web_contents_->GetPrimaryMainFrame()->GetProcess();
- if (host->run_renderer_in_process()) {
- return ScopedJavaLocalRef<jobject>();
- }
- AwRenderProcess* render_process =
- AwRenderProcess::GetInstanceForRenderProcessHost(host);
- return render_process->GetJavaObject();
- }
- void AwContents::Destroy(JNIEnv* env) {
- java_ref_.reset();
- delete this;
- }
- static jlong JNI_AwContents_Init(JNIEnv* env, jlong browser_context_pointer) {
- AwBrowserContext* browser_context =
- reinterpret_cast<AwBrowserContext*>(browser_context_pointer);
- std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
- content::WebContents::CreateParams(browser_context)));
- // Return an 'uninitialized' instance; most work is deferred until the
- // subsequent SetJavaPeers() call.
- return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
- }
- static jboolean JNI_AwContents_HasRequiredHardwareExtensions(JNIEnv* env) {
- ScopedAllowInitGLBindings scoped_allow_init_gl_bindings;
- // Make sure GPUInfo is collected. This will initialize GL bindings,
- // collect GPUInfo, and compute GpuFeatureInfo if they have not been
- // already done.
- return GpuServiceWebView::GetInstance()
- ->gpu_info()
- .can_support_threaded_texture_mailbox;
- }
- static void JNI_AwContents_SetAwDrawSWFunctionTable(JNIEnv* env,
- jlong function_table) {
- RasterHelperSetAwDrawSWFunctionTable(
- reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
- }
- static void JNI_AwContents_SetAwDrawGLFunctionTable(JNIEnv* env,
- jlong function_table) {}
- static void JNI_AwContents_UpdateScreenCoverage(
- JNIEnv* env,
- jint global_percentage,
- const base::android::JavaParamRef<jobjectArray>& jschemes,
- const base::android::JavaParamRef<jintArray>& jscheme_percentages) {
- std::vector<std::string> schemes;
- AppendJavaStringArrayToStringVector(env, jschemes, &schemes);
- std::vector<int> scheme_percentages;
- JavaIntArrayToIntVector(env, jscheme_percentages, &scheme_percentages);
- DCHECK(schemes.size() == scheme_percentages.size());
- std::vector<VisibilityMetricsLogger::Scheme> scheme_enums(schemes.size());
- for (size_t i = 0; i < schemes.size(); i++) {
- scheme_enums[i] = VisibilityMetricsLogger::SchemeStringToEnum(schemes[i]);
- }
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->UpdateScreenCoverage(global_percentage, scheme_enums,
- scheme_percentages);
- }
- // static
- jint JNI_AwContents_GetNativeInstanceCount(JNIEnv* env) {
- return base::subtle::NoBarrier_Load(&g_instance_count);
- }
- // static
- ScopedJavaLocalRef<jstring> JNI_AwContents_GetSafeBrowsingLocaleForTesting(
- JNIEnv* env) {
- ScopedJavaLocalRef<jstring> locale =
- ConvertUTF8ToJavaString(env, base::i18n::GetConfiguredLocale());
- return locale;
- }
- namespace {
- void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message,
- bool has_images) {
- Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), has_images,
- message);
- }
- } // namespace
- void AwContents::DocumentHasImages(JNIEnv* env,
- const JavaParamRef<jobject>& message) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ScopedJavaGlobalRef<jobject> j_message;
- j_message.Reset(env, message);
- render_view_host_ext_->DocumentHasImages(
- base::BindOnce(&DocumentHasImagesCallback, j_message));
- }
- namespace {
- void GenerateMHTMLCallback(const JavaRef<jobject>& callback,
- const base::FilePath& path,
- int64_t size) {
- JNIEnv* env = AttachCurrentThread();
- // Android files are UTF8, so the path conversion below is safe.
- Java_AwContents_generateMHTMLCallback(
- env, ConvertUTF8ToJavaString(env, path.AsUTF8Unsafe()), size, callback);
- }
- } // namespace
- void AwContents::GenerateMHTML(JNIEnv* env,
- const JavaParamRef<jstring>& jpath,
- const JavaParamRef<jobject>& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- base::FilePath target_path(ConvertJavaStringToUTF8(env, jpath));
- web_contents_->GenerateMHTML(
- content::MHTMLGenerationParams(target_path),
- base::BindOnce(&GenerateMHTMLCallback,
- ScopedJavaGlobalRef<jobject>(env, callback), target_path));
- }
- void AwContents::CreatePdfExporter(JNIEnv* env,
- const JavaParamRef<jobject>& pdfExporter) {
- pdf_exporter_ =
- std::make_unique<AwPdfExporter>(env, pdfExporter, web_contents_.get());
- }
- bool AwContents::OnReceivedHttpAuthRequest(const JavaRef<jobject>& handler,
- const std::string& host,
- const std::string& realm) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return false;
- ScopedJavaLocalRef<jstring> jhost = ConvertUTF8ToJavaString(env, host);
- ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
- devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
- "onReceivedHttpAuthRequest");
- Java_AwContents_onReceivedHttpAuthRequest(env, obj, handler, jhost, jrealm);
- return true;
- }
- void AwContents::SetOffscreenPreRaster(bool enabled) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.SetOffscreenPreRaster(enabled);
- }
- void AwContents::AddVisitedLinks(
- JNIEnv* env,
- const JavaParamRef<jobjectArray>& jvisited_links) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- std::vector<std::u16string> visited_link_strings;
- base::android::AppendJavaStringArrayToStringVector(env, jvisited_links,
- &visited_link_strings);
- std::vector<GURL> visited_link_gurls;
- std::vector<std::u16string>::const_iterator itr;
- for (itr = visited_link_strings.begin(); itr != visited_link_strings.end();
- ++itr) {
- visited_link_gurls.push_back(GURL(*itr));
- }
- AwBrowserContext::FromWebContents(web_contents_.get())
- ->AddVisitedURLs(visited_link_gurls);
- }
- namespace {
- void ShowGeolocationPromptHelperTask(const JavaObjectWeakGlobalRef& java_ref,
- const GURL& origin) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_ref = java_ref.get(env);
- if (j_ref.obj()) {
- ScopedJavaLocalRef<jstring> j_origin(
- ConvertUTF8ToJavaString(env, origin.spec()));
- devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
- "onGeolocationPermissionsShowPrompt");
- Java_AwContents_onGeolocationPermissionsShowPrompt(env, j_ref, j_origin);
- }
- }
- void ShowGeolocationPromptHelper(const JavaObjectWeakGlobalRef& java_ref,
- const GURL& origin) {
- JNIEnv* env = AttachCurrentThread();
- if (java_ref.get(env).obj()) {
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&ShowGeolocationPromptHelperTask, java_ref, origin));
- }
- }
- } // anonymous namespace
- void AwContents::ShowGeolocationPrompt(const GURL& requesting_frame,
- PermissionCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GURL origin = requesting_frame.DeprecatedGetOriginAsURL();
- bool show_prompt = pending_geolocation_prompts_.empty();
- pending_geolocation_prompts_.emplace_back(origin, std::move(callback));
- if (show_prompt) {
- ShowGeolocationPromptHelper(java_ref_, origin);
- }
- }
- // Invoked from Java
- void AwContents::InvokeGeolocationCallback(
- JNIEnv* env,
- jboolean value,
- const JavaParamRef<jstring>& origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (pending_geolocation_prompts_.empty())
- return;
- GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
- if (callback_origin.DeprecatedGetOriginAsURL() ==
- pending_geolocation_prompts_.front().first) {
- std::move(pending_geolocation_prompts_.front().second).Run(value);
- pending_geolocation_prompts_.pop_front();
- if (!pending_geolocation_prompts_.empty()) {
- ShowGeolocationPromptHelper(java_ref_,
- pending_geolocation_prompts_.front().first);
- }
- }
- }
- void AwContents::HideGeolocationPrompt(const GURL& origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- bool removed_current_outstanding_callback = false;
- std::list<OriginCallback>::iterator it = pending_geolocation_prompts_.begin();
- while (it != pending_geolocation_prompts_.end()) {
- if ((*it).first == origin.DeprecatedGetOriginAsURL()) {
- if (it == pending_geolocation_prompts_.begin()) {
- removed_current_outstanding_callback = true;
- }
- it = pending_geolocation_prompts_.erase(it);
- } else {
- ++it;
- }
- }
- if (removed_current_outstanding_callback) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
- if (j_ref.obj()) {
- devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
- "onGeolocationPermissionsHidePrompt");
- Java_AwContents_onGeolocationPermissionsHidePrompt(env, j_ref);
- }
- if (!pending_geolocation_prompts_.empty()) {
- ShowGeolocationPromptHelper(java_ref_,
- pending_geolocation_prompts_.front().first);
- }
- }
- }
- void AwContents::OnPermissionRequest(
- base::android::ScopedJavaLocalRef<jobject> j_request,
- AwPermissionRequest* request) {
- DCHECK(j_request);
- DCHECK(request);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
- if (!j_ref) {
- permission_request_handler_->CancelRequest(request->GetOrigin(),
- request->GetResources());
- return;
- }
- Java_AwContents_onPermissionRequest(env, j_ref, j_request);
- }
- void AwContents::OnPermissionRequestCanceled(AwPermissionRequest* request) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_request = request->GetJavaObject();
- ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
- if (!j_request || !j_ref)
- return;
- Java_AwContents_onPermissionRequestCanceled(env, j_ref, j_request);
- }
- void AwContents::PreauthorizePermission(JNIEnv* env,
- const JavaParamRef<jstring>& origin,
- jlong resources) {
- permission_request_handler_->PreauthorizePermission(
- GURL(base::android::ConvertJavaStringToUTF8(env, origin)), resources);
- }
- void AwContents::RequestProtectedMediaIdentifierPermission(
- const GURL& origin,
- PermissionCallback callback) {
- permission_request_handler_->SendRequest(
- std::make_unique<SimplePermissionRequest>(
- origin, AwPermissionRequest::ProtectedMediaId, std::move(callback)));
- }
- void AwContents::CancelProtectedMediaIdentifierPermissionRequests(
- const GURL& origin) {
- permission_request_handler_->CancelRequest(
- origin, AwPermissionRequest::ProtectedMediaId);
- }
- void AwContents::RequestGeolocationPermission(const GURL& origin,
- PermissionCallback callback) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
- ShowGeolocationPrompt(origin, std::move(callback));
- return;
- }
- permission_request_handler_->SendRequest(
- std::make_unique<SimplePermissionRequest>(
- origin, AwPermissionRequest::Geolocation, std::move(callback)));
- }
- void AwContents::CancelGeolocationPermissionRequests(const GURL& origin) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- if (Java_AwContents_useLegacyGeolocationPermissionAPI(env, obj)) {
- HideGeolocationPrompt(origin);
- return;
- }
- permission_request_handler_->CancelRequest(origin,
- AwPermissionRequest::Geolocation);
- }
- void AwContents::RequestMIDISysexPermission(const GURL& origin,
- PermissionCallback callback) {
- permission_request_handler_->SendRequest(
- std::make_unique<SimplePermissionRequest>(
- origin, AwPermissionRequest::MIDISysex, std::move(callback)));
- }
- void AwContents::CancelMIDISysexPermissionRequests(const GURL& origin) {
- permission_request_handler_->CancelRequest(
- origin, AwPermissionRequest::AwPermissionRequest::MIDISysex);
- }
- void AwContents::FindAllAsync(JNIEnv* env,
- const JavaParamRef<jstring>& search_string) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
- }
- void AwContents::FindNext(JNIEnv* env, jboolean forward) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetFindHelper()->FindNext(forward);
- }
- void AwContents::ClearMatches(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetFindHelper()->ClearMatches();
- }
- void AwContents::ClearCache(JNIEnv* env, jboolean include_disk_files) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- AwRenderProcess* aw_render_process =
- AwRenderProcess::GetInstanceForRenderProcessHost(
- web_contents_->GetPrimaryMainFrame()->GetProcess());
- aw_render_process->ClearCache();
- if (include_disk_files) {
- content::BrowsingDataRemover* remover =
- web_contents_->GetBrowserContext()->GetBrowsingDataRemover();
- remover->Remove(
- base::Time(), base::Time::Max(),
- content::BrowsingDataRemover::DATA_TYPE_CACHE,
- content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
- content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
- }
- }
- FindHelper* AwContents::GetFindHelper() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!find_helper_.get()) {
- find_helper_ = std::make_unique<FindHelper>(web_contents_.get());
- find_helper_->SetListener(this);
- }
- return find_helper_.get();
- }
- bool AwContents::AllowThirdPartyCookies() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- AwSettings* aw_settings = AwSettings::FromWebContents(web_contents_.get());
- return aw_settings->GetAllowThirdPartyCookies();
- }
- void AwContents::OnFindResultReceived(int active_ordinal,
- int match_count,
- bool finished) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_onFindResultReceived(env, obj, active_ordinal, match_count,
- finished);
- }
- bool AwContents::ShouldDownloadFavicon(const GURL& icon_url) {
- return g_should_download_favicons;
- }
- void AwContents::OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- content::NavigationEntry* entry =
- web_contents_->GetController().GetLastCommittedEntry();
- if (entry) {
- entry->GetFavicon().valid = true;
- entry->GetFavicon().url = icon_url;
- entry->GetFavicon().image = gfx::Image::CreateFrom1xBitmap(bitmap);
- }
- ScopedJavaLocalRef<jobject> java_bitmap =
- gfx::ConvertToJavaBitmap(bitmap, gfx::OomBehavior::kReturnNullOnOom);
- if (!java_bitmap) {
- LOG(WARNING) << "Skipping onReceivedIcon; Not enough memory to convert "
- "icon to Bitmap.";
- return;
- }
- Java_AwContents_onReceivedIcon(env, obj, java_bitmap);
- }
- void AwContents::OnReceivedTouchIconUrl(const std::string& url,
- bool precomposed) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_onReceivedTouchIconUrl(
- env, obj, ConvertUTF8ToJavaString(env, url), precomposed);
- }
- void AwContents::PostInvalidate(bool inside_vsync) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj)
- Java_AwContents_postInvalidate(env, obj, inside_vsync);
- }
- void AwContents::OnNewPicture() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj) {
- devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
- "onNewPicture");
- Java_AwContents_onNewPicture(env, obj);
- }
- }
- void AwContents::OnViewTreeForceDarkStateChanged(
- bool view_tree_force_dark_state) {
- view_tree_force_dark_state_ = view_tree_force_dark_state;
- web_contents_->NotifyPreferencesChanged();
- }
- base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetCertificate(
- JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::NavigationEntry* entry =
- web_contents_->GetController().GetLastCommittedEntry();
- if (!entry || entry->IsInitialEntry() || !entry->GetSSL().certificate) {
- return ScopedJavaLocalRef<jbyteArray>();
- }
- // Convert the certificate and return it
- base::StringPiece der_string = net::x509_util::CryptoBufferAsStringPiece(
- entry->GetSSL().certificate->cert_buffer());
- return base::android::ToJavaByteArray(
- env, reinterpret_cast<const uint8_t*>(der_string.data()),
- der_string.length());
- }
- void AwContents::RequestNewHitTestDataAt(JNIEnv* env,
- jfloat x,
- jfloat y,
- jfloat touch_major) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- gfx::PointF touch_center(x, y);
- gfx::SizeF touch_area(touch_major, touch_major);
- render_view_host_ext_->RequestNewHitTestDataAt(touch_center, touch_area);
- }
- void AwContents::UpdateLastHitTestData(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- android_webview::mojom::HitTestDataPtr data =
- render_view_host_ext_->TakeLastHitTestData();
- if (!data)
- return;
- // Make sure to null the Java object if data is empty/invalid.
- ScopedJavaLocalRef<jstring> extra_data_for_type;
- if (data->extra_data_for_type.length())
- extra_data_for_type =
- ConvertUTF8ToJavaString(env, data->extra_data_for_type);
- ScopedJavaLocalRef<jstring> href;
- if (data->href.length())
- href = ConvertUTF16ToJavaString(env, data->href);
- ScopedJavaLocalRef<jstring> anchor_text;
- if (data->anchor_text.length())
- anchor_text = ConvertUTF16ToJavaString(env, data->anchor_text);
- ScopedJavaLocalRef<jstring> img_src;
- if (data->img_src.is_valid())
- img_src = ConvertUTF8ToJavaString(env, data->img_src.spec());
- Java_AwContents_updateHitTestData(env, obj, static_cast<jint>(data->type),
- extra_data_for_type, href, anchor_text,
- img_src);
- }
- void AwContents::OnSizeChanged(JNIEnv* env, int w, int h, int ow, int oh) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- gfx::Size size(w, h);
- web_contents_->GetNativeView()->OnPhysicalBackingSizeChanged(size);
- web_contents_->GetNativeView()->OnSizeChanged(w, h);
- browser_view_renderer_.OnSizeChanged(w, h);
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- void AwContents::OnConfigurationChanged(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- web_contents()->OnWebPreferencesChanged();
- }
- void AwContents::SetViewVisibility(JNIEnv* env, bool visible) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.SetViewVisibility(visible);
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- void AwContents::SetWindowVisibility(JNIEnv* env, bool visible) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.SetWindowVisibility(visible);
- if (visible)
- AwContentsLifecycleNotifier::GetInstance().OnWebViewWindowBeVisible(this);
- else
- AwContentsLifecycleNotifier::GetInstance().OnWebViewWindowBeInvisible(this);
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- void AwContents::SetIsPaused(JNIEnv* env, bool paused) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.SetIsPaused(paused);
- }
- void AwContents::OnAttachedToWindow(JNIEnv* env, int w, int h) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.OnAttachedToWindow(w, h);
- AwContentsLifecycleNotifier::GetInstance().OnWebViewAttachedToWindow(this);
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- void AwContents::OnDetachedFromWindow(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.OnDetachedFromWindow();
- AwContentsLifecycleNotifier::GetInstance().OnWebViewDetachedFromWindow(this);
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- bool AwContents::IsVisible(JNIEnv* env) {
- return browser_view_renderer_.IsClientVisible();
- }
- bool AwContents::IsDisplayingInterstitialForTesting(JNIEnv* env) {
- security_interstitials::SecurityInterstitialTabHelper*
- security_interstitial_tab_helper = security_interstitials::
- SecurityInterstitialTabHelper::FromWebContents(web_contents_.get());
- return security_interstitial_tab_helper &&
- security_interstitial_tab_helper->IsDisplayingInterstitial();
- }
- base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetOpaqueState(
- JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Required optimization in WebViewClassic to not save any state if
- // there has been no navigations.
- if (!web_contents_->GetController().GetLastCommittedEntry() ||
- web_contents_->GetController()
- .GetLastCommittedEntry()
- ->IsInitialEntry()) {
- return ScopedJavaLocalRef<jbyteArray>();
- }
- base::Pickle pickle;
- WriteToPickle(*web_contents_, &pickle);
- return base::android::ToJavaByteArray(
- env, reinterpret_cast<const uint8_t*>(pickle.data()), pickle.size());
- }
- jboolean AwContents::RestoreFromOpaqueState(
- JNIEnv* env,
- const JavaParamRef<jbyteArray>& state) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // TODO(boliu): This copy can be optimized out if this is a performance
- // problem.
- std::vector<uint8_t> state_vector;
- base::android::JavaByteArrayToByteVector(env, state, &state_vector);
- base::Pickle pickle(reinterpret_cast<const char*>(state_vector.data()),
- state_vector.size());
- base::PickleIterator iterator(pickle);
- return RestoreFromPickle(&iterator, web_contents_.get());
- }
- bool AwContents::OnDraw(JNIEnv* env,
- const 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) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- gfx::Point scroll(scroll_x, scroll_y);
- browser_view_renderer_.PrepareToDraw(
- scroll, gfx::Rect(visible_left, visible_top, visible_right - visible_left,
- visible_bottom - visible_top));
- if (is_hardware_accelerated && browser_view_renderer_.attached_to_window() &&
- !force_auxiliary_bitmap_rendering) {
- return browser_view_renderer_.OnDrawHardware();
- }
- gfx::Size view_size = browser_view_renderer_.size();
- if (view_size.IsEmpty()) {
- TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_EmptySize",
- TRACE_EVENT_SCOPE_THREAD);
- return false;
- }
- // TODO(hush): Right now webview size is passed in as the auxiliary bitmap
- // size, which might hurt performance (only for software draws with auxiliary
- // bitmap). For better performance, get global visible rect, transform it
- // from screen space to view space, then intersect with the webview in
- // viewspace. Use the resulting rect as the auxiliary bitmap.
- std::unique_ptr<SoftwareCanvasHolder> canvas_holder =
- SoftwareCanvasHolder::Create(canvas, scroll, view_size,
- force_auxiliary_bitmap_rendering);
- if (!canvas_holder || !canvas_holder->GetCanvas()) {
- TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoSoftwareCanvas",
- TRACE_EVENT_SCOPE_THREAD);
- return false;
- }
- return browser_view_renderer_.OnDrawSoftware(canvas_holder->GetCanvas());
- }
- bool AwContents::NeedToDrawBackgroundColor(JNIEnv* env) {
- return browser_view_renderer_.NeedToDrawBackgroundColor();
- }
- void AwContents::SetPendingWebContentsForPopup(
- std::unique_ptr<content::WebContents> pending) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (pending_contents_.get()) {
- // TODO(benm): Support holding multiple pop up window requests.
- LOG(WARNING) << "Blocking popup window creation as an outstanding "
- << "popup window is still pending.";
- base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
- pending.release());
- return;
- }
- pending_contents_ = std::make_unique<AwContents>(std::move(pending));
- // Set dip_scale for pending contents, which is necessary for the later
- // SynchronousCompositor and InputHandler setup.
- pending_contents_->SetDipScaleInternal(browser_view_renderer_.dip_scale());
- }
- void AwContents::FocusFirstNode(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- web_contents_->FocusThroughTabTraversal(false);
- }
- void AwContents::SetBackgroundColor(JNIEnv* env, jint color) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- web_contents_->SetPageBaseBackgroundColor(color);
- }
- void AwContents::ZoomBy(JNIEnv* env, jfloat delta) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.ZoomBy(delta);
- }
- void AwContents::OnComputeScroll(JNIEnv* env, jlong animation_time_millis) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.OnComputeScroll(
- base::TimeTicks() + base::Milliseconds(animation_time_millis));
- }
- jlong AwContents::ReleasePopupAwContents(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- return reinterpret_cast<intptr_t>(pending_contents_.release());
- }
- gfx::Point AwContents::GetLocationOnScreen() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return gfx::Point();
- std::vector<int> location;
- base::android::JavaIntArrayToIntVector(
- env, Java_AwContents_getLocationOnScreen(env, obj), &location);
- return gfx::Point(location[0], location[1]);
- }
- void AwContents::ScrollContainerViewTo(const gfx::Point& new_value) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_scrollContainerViewTo(env, obj, new_value.x(), new_value.y());
- }
- void AwContents::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) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_updateScrollState(
- env, obj, max_scroll_offset.x(), max_scroll_offset.y(),
- contents_size_dip.width(), contents_size_dip.height(), page_scale_factor,
- min_page_scale_factor, max_page_scale_factor);
- }
- void AwContents::DidOverscroll(const gfx::Vector2d& overscroll_delta,
- const gfx::Vector2dF& overscroll_velocity,
- bool inside_vsync) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_didOverscroll(env, obj, overscroll_delta.x(),
- overscroll_delta.y(), overscroll_velocity.x(),
- overscroll_velocity.y(), inside_vsync);
- }
- ui::TouchHandleDrawable* AwContents::CreateDrawable() {
- JNIEnv* env = AttachCurrentThread();
- const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return nullptr;
- return reinterpret_cast<ui::TouchHandleDrawable*>(
- Java_AwContents_onCreateTouchHandle(env, obj));
- }
- void AwContents::SetDipScale(JNIEnv* env, jfloat dip_scale) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SetDipScaleInternal(dip_scale);
- }
- base::android::ScopedJavaLocalRef<jstring> AwContents::GetScheme(JNIEnv* env) {
- return ConvertUTF8ToJavaString(env, scheme_);
- }
- void AwContents::OnInputEvent(JNIEnv* env) {
- browser_view_renderer_.OnInputEvent();
- }
- void AwContents::SetDipScaleInternal(float dip_scale) {
- browser_view_renderer_.SetDipScale(dip_scale);
- }
- void AwContents::ScrollTo(JNIEnv* env, jint x, jint y) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.ScrollTo(gfx::Point(x, y));
- }
- void AwContents::RestoreScrollAfterTransition(JNIEnv* env, jint x, jint y) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.RestoreScrollAfterTransition(gfx::Point(x, y));
- }
- void AwContents::SmoothScroll(JNIEnv* env,
- jint target_x,
- jint target_y,
- jlong duration_ms) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- float scale = browser_view_renderer_.page_scale_factor();
- DCHECK_GE(duration_ms, 0);
- render_view_host_ext_->SmoothScroll(target_x / scale, target_y / scale,
- base::Milliseconds(duration_ms));
- }
- void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- Java_AwContents_onWebLayoutPageScaleFactorChanged(env, obj,
- page_scale_factor);
- }
- void AwContents::OnWebLayoutContentsSizeChanged(
- const gfx::Size& contents_size) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- gfx::Size contents_size_css =
- ScaleToRoundedSize(contents_size, 1 / browser_view_renderer_.dip_scale());
- Java_AwContents_onWebLayoutContentsSizeChanged(
- env, obj, contents_size_css.width(), contents_size_css.height());
- }
- jlong AwContents::CapturePicture(JNIEnv* env, int width, int height) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- return reinterpret_cast<intptr_t>(
- new AwPicture(browser_view_renderer_.CapturePicture(width, height)));
- }
- void AwContents::EnableOnNewPicture(JNIEnv* env, jboolean enabled) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.EnableOnNewPicture(enabled);
- }
- namespace {
- void InvokeVisualStateCallback(const JavaObjectWeakGlobalRef& java_ref,
- jlong request_id,
- const JavaRef<jobject>& callback,
- bool result) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref.get(env);
- if (!obj)
- return;
- Java_AwContents_invokeVisualStateCallback(env, obj, callback, request_id);
- }
- } // namespace
- void AwContents::InsertVisualStateCallback(
- JNIEnv* env,
- jlong request_id,
- const JavaParamRef<jobject>& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- web_contents_->GetPrimaryMainFrame()->InsertVisualStateCallback(
- base::BindOnce(&InvokeVisualStateCallback, java_ref_, request_id,
- ScopedJavaGlobalRef<jobject>(env, callback)));
- }
- jint AwContents::GetEffectivePriority(JNIEnv* env) {
- switch (web_contents_->GetPrimaryMainFrame()
- ->GetProcess()
- ->GetEffectiveImportance()) {
- case content::ChildProcessImportance::NORMAL:
- return static_cast<jint>(RendererPriority::WAIVED);
- case content::ChildProcessImportance::MODERATE:
- return static_cast<jint>(RendererPriority::LOW);
- case content::ChildProcessImportance::IMPORTANT:
- return static_cast<jint>(RendererPriority::HIGH);
- }
- NOTREACHED();
- return 0;
- }
- JsCommunicationHost* AwContents::GetJsCommunicationHost() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!js_communication_host_.get()) {
- js_communication_host_ =
- std::make_unique<JsCommunicationHost>(web_contents_.get());
- }
- return js_communication_host_.get();
- }
- jint AwContents::AddDocumentStartJavaScript(
- JNIEnv* env,
- const base::android::JavaParamRef<jstring>& script,
- const base::android::JavaParamRef<jobjectArray>& allowed_origin_rules) {
- std::vector<std::string> native_allowed_origin_rule_strings;
- AppendJavaStringArrayToStringVector(env, allowed_origin_rules,
- &native_allowed_origin_rule_strings);
- auto result = GetJsCommunicationHost()->AddDocumentStartJavaScript(
- base::android::ConvertJavaStringToUTF16(env, script),
- native_allowed_origin_rule_strings);
- if (result.error_message) {
- env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"),
- result.error_message->data());
- return -1;
- }
- DCHECK(result.script_id);
- return result.script_id.value();
- }
- void AwContents::RemoveDocumentStartJavaScript(JNIEnv* env, jint script_id) {
- GetJsCommunicationHost()->RemoveDocumentStartJavaScript(script_id);
- }
- base::android::ScopedJavaLocalRef<jstring> AwContents::AddWebMessageListener(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& listener,
- const base::android::JavaParamRef<jstring>& js_object_name,
- const base::android::JavaParamRef<jobjectArray>& allowed_origin_rules) {
- std::u16string native_js_object_name =
- base::android::ConvertJavaStringToUTF16(env, js_object_name);
- std::vector<std::string> native_allowed_origin_rule_strings;
- AppendJavaStringArrayToStringVector(env, allowed_origin_rules,
- &native_allowed_origin_rule_strings);
- const std::u16string error_message =
- GetJsCommunicationHost()->AddWebMessageHostFactory(
- std::make_unique<AwWebMessageHostFactory>(listener),
- native_js_object_name, native_allowed_origin_rule_strings);
- if (error_message.empty())
- return nullptr;
- return base::android::ConvertUTF16ToJavaString(env, error_message);
- }
- void AwContents::RemoveWebMessageListener(
- JNIEnv* env,
- const base::android::JavaParamRef<jstring>& js_object_name) {
- GetJsCommunicationHost()->RemoveWebMessageHostFactory(
- ConvertJavaStringToUTF16(env, js_object_name));
- }
- base::android::ScopedJavaLocalRef<jobjectArray> AwContents::GetJsObjectsInfo(
- JNIEnv* env,
- const base::android::JavaParamRef<jclass>& clazz) {
- if (js_communication_host_.get()) {
- return AwWebMessageHostFactory::GetWebMessageListenerInfo(
- GetJsCommunicationHost(), env, clazz);
- }
- return nullptr;
- }
- void AwContents::ClearView(JNIEnv* env) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_view_renderer_.ClearView();
- }
- void AwContents::SetExtraHeadersForUrl(
- JNIEnv* env,
- const JavaParamRef<jstring>& url,
- const JavaParamRef<jstring>& jextra_headers) {
- std::string extra_headers;
- if (jextra_headers)
- extra_headers = ConvertJavaStringToUTF8(env, jextra_headers);
- AwResourceContext* resource_context = static_cast<AwResourceContext*>(
- AwBrowserContext::FromWebContents(web_contents_.get())
- ->GetResourceContext());
- resource_context->SetExtraHeaders(GURL(ConvertJavaStringToUTF8(env, url)),
- extra_headers);
- }
- void AwContents::SetJsOnlineProperty(JNIEnv* env, jboolean network_up) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- AwRenderProcess* aw_render_process =
- AwRenderProcess::GetInstanceForRenderProcessHost(
- web_contents_->GetPrimaryMainFrame()->GetProcess());
- aw_render_process->SetJsOnlineProperty(network_up);
- }
- void AwContents::TrimMemory(JNIEnv* env, jint level, jboolean visible) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Constants from Android ComponentCallbacks2.
- enum {
- TRIM_MEMORY_RUNNING_LOW = 10,
- TRIM_MEMORY_UI_HIDDEN = 20,
- TRIM_MEMORY_BACKGROUND = 40,
- TRIM_MEMORY_MODERATE = 60,
- };
- // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
- // it does not indicate memory pressure, but merely that the app is
- // backgrounded.
- if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
- return;
- // Do not release resources on view we expect to get DrawGL soon.
- if (level < TRIM_MEMORY_BACKGROUND && visible)
- return;
- browser_view_renderer_.TrimMemory();
- }
- void AwContents::GrantFileSchemeAccesstoChildProcess(JNIEnv* env) {
- content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestScheme(
- web_contents_->GetPrimaryMainFrame()->GetProcess()->GetID(),
- url::kFileScheme);
- }
- void AwContents::ResumeLoadingCreatedPopupWebContents(JNIEnv* env) {
- web_contents_->ResumeLoadingCreatedWebContents();
- }
- void JNI_AwContents_SetShouldDownloadFavicons(JNIEnv* env) {
- g_should_download_favicons = true;
- }
- void AwContents::RenderViewHostChanged(content::RenderViewHost* old_host,
- content::RenderViewHost* new_host) {
- DCHECK(new_host);
- // At this point, the current RVH may or may not contain a compositor. So
- // compositor_ may be nullptr, in which case
- // BrowserViewRenderer::DidInitializeCompositor() callback is time when the
- // new compositor is constructed.
- browser_view_renderer_.SetActiveFrameSinkId(
- new_host->GetWidget()->GetFrameSinkId());
- }
- void AwContents::PrimaryPageChanged(content::Page& page) {
- const url::Origin& origin = page.GetMainDocument().GetLastCommittedOrigin();
- const std::string& scheme = origin.scheme();
- const std::string& etld_plus1 =
- net::registry_controlled_domains::GetDomainAndRegistry(
- origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- if (scheme_ != scheme) {
- scheme_ = scheme;
- AwBrowserProcess::GetInstance()
- ->visibility_metrics_logger()
- ->ClientVisibilityChanged(this);
- }
- if (scheme == url::kHttpsScheme || scheme == url::kHttpScheme) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
- if (j_ref) {
- uint32_t origin_hash = base::PersistentHash(origin.Serialize());
- uint32_t etld_plus1_hash = base::PersistentHash(etld_plus1);
- jlong j_origin_hash = static_cast<jlong>(origin_hash);
- jlong j_etld_plus1_hash = static_cast<jlong>(etld_plus1_hash);
- Java_AwContents_logOriginVisit(env, j_ref, j_origin_hash);
- Java_AwContents_logSiteVisit(env, j_ref, j_etld_plus1_hash);
- }
- }
- }
- void AwContents::DidFinishNavigation(
- content::NavigationHandle* navigation_handle) {
- // If this request was blocked in any way, broadcast an error.
- net::Error error_code = navigation_handle->GetNetErrorCode();
- if (!net::IsRequestBlockedError(error_code) &&
- error_code != net::ERR_ABORTED) {
- return;
- }
- // We do not call OnReceivedError for requests that were blocked due to an
- // interstitial showing. OnReceivedError is handled directly by the blocking
- // page for interstitials.
- if (web_contents_) {
- // We can't be showing an interstitial if there is no web_contents.
- security_interstitials::SecurityInterstitialTabHelper*
- security_interstitial_tab_helper = security_interstitials::
- SecurityInterstitialTabHelper::FromWebContents(web_contents_.get());
- if (security_interstitial_tab_helper &&
- (security_interstitial_tab_helper->IsInterstitialPendingForNavigation(
- navigation_handle->GetNavigationId()) ||
- security_interstitial_tab_helper->IsDisplayingInterstitial())) {
- return;
- }
- }
- AwContentsClientBridge* client =
- AwContentsClientBridge::FromWebContents(web_contents_.get());
- if (!client)
- return;
- AwWebResourceRequest request(navigation_handle->GetURL().spec(),
- navigation_handle->IsPost() ? "POST" : "GET",
- navigation_handle->IsInPrimaryMainFrame(),
- navigation_handle->HasUserGesture(),
- net::HttpRequestHeaders());
- request.is_renderer_initiated = navigation_handle->IsRendererInitiated();
- client->OnReceivedError(request, error_code, false, false);
- }
- bool AwContents::CanShowInterstitial() {
- JNIEnv* env = AttachCurrentThread();
- const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return false;
- return Java_AwContents_canShowInterstitial(env, obj);
- }
- int AwContents::GetErrorUiType() {
- JNIEnv* env = AttachCurrentThread();
- const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return false;
- return Java_AwContents_getErrorUiType(env, obj);
- }
- VisibilityMetricsLogger::VisibilityInfo AwContents::GetVisibilityInfo() {
- return VisibilityMetricsLogger::VisibilityInfo{
- browser_view_renderer_.attached_to_window(),
- browser_view_renderer_.view_visible(),
- browser_view_renderer_.window_visible(),
- VisibilityMetricsLogger::SchemeStringToEnum(scheme_)};
- }
- void AwContents::RendererUnresponsive(
- content::RenderProcessHost* render_process_host) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- AwRenderProcess* aw_render_process =
- AwRenderProcess::GetInstanceForRenderProcessHost(render_process_host);
- Java_AwContents_onRendererUnresponsive(env, obj,
- aw_render_process->GetJavaObject());
- }
- void AwContents::RendererResponsive(
- content::RenderProcessHost* render_process_host) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return;
- AwRenderProcess* aw_render_process =
- AwRenderProcess::GetInstanceForRenderProcessHost(render_process_host);
- Java_AwContents_onRendererResponsive(env, obj,
- aw_render_process->GetJavaObject());
- }
- AwContents::RenderProcessGoneResult AwContents::OnRenderProcessGone(
- int child_process_id,
- bool crashed) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj)
- return RenderProcessGoneResult::kHandled;
- bool result =
- Java_AwContents_onRenderProcessGone(env, obj, child_process_id, crashed);
- if (HasException(env))
- return RenderProcessGoneResult::kException;
- return result ? RenderProcessGoneResult::kHandled
- : RenderProcessGoneResult::kUnhandled;
- }
- } // namespace android_webview
|