1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647 |
- // Copyright 2014 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.
- package com.android.webview.chromium;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.content.Intent;
- import android.content.res.Configuration;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.graphics.Picture;
- import android.graphics.Rect;
- import android.graphics.drawable.Drawable;
- import android.net.Uri;
- import android.net.http.SslCertificate;
- import android.os.Build;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.os.SystemClock;
- import android.print.PrintDocumentAdapter;
- import android.util.Log;
- import android.util.SparseArray;
- import android.view.DragEvent;
- import android.view.KeyEvent;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.ViewStructure;
- import android.view.accessibility.AccessibilityEvent;
- import android.view.accessibility.AccessibilityNodeInfo;
- import android.view.accessibility.AccessibilityNodeProvider;
- import android.view.autofill.AutofillValue;
- import android.view.inputmethod.EditorInfo;
- import android.view.inputmethod.InputConnection;
- import android.view.textclassifier.TextClassifier;
- import android.webkit.DownloadListener;
- import android.webkit.FindActionModeCallback;
- import android.webkit.ValueCallback;
- import android.webkit.WebBackForwardList;
- import android.webkit.WebChromeClient;
- import android.webkit.WebChromeClient.CustomViewCallback;
- import android.webkit.WebMessage;
- import android.webkit.WebMessagePort;
- import android.webkit.WebSettings;
- import android.webkit.WebView;
- import android.webkit.WebView.VisualStateCallback;
- import android.webkit.WebViewClient;
- import android.webkit.WebViewProvider;
- import android.webkit.WebViewRenderProcess;
- import android.webkit.WebViewRenderProcessClient;
- import android.widget.TextView;
- import androidx.annotation.IntDef;
- import androidx.annotation.RequiresApi;
- import org.chromium.android_webview.AwContents;
- import org.chromium.android_webview.AwContentsStatics;
- import org.chromium.android_webview.AwPrintDocumentAdapter;
- import org.chromium.android_webview.AwSettings;
- import org.chromium.android_webview.AwThreadUtils;
- import org.chromium.android_webview.gfx.AwDrawFnImpl;
- import org.chromium.android_webview.renderer_priority.RendererPriority;
- import org.chromium.base.ThreadUtils;
- import org.chromium.base.metrics.RecordHistogram;
- import org.chromium.base.metrics.ScopedSysTraceEvent;
- import org.chromium.components.content_capture.ContentCaptureFeatures;
- import org.chromium.components.content_capture.OnscreenContentProvider;
- import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory;
- import org.chromium.content_public.browser.MessagePayload;
- import org.chromium.content_public.browser.NavigationHistory;
- import org.chromium.content_public.browser.SmartClipProvider;
- import org.chromium.url.GURL;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Map;
- import java.util.concurrent.Callable;
- import java.util.concurrent.Executor;
- /**
- * This class is the delegate to which WebViewProxy forwards all API calls.
- *
- * Most of the actual functionality is implemented by AwContents (or WebContents within
- * it). This class also contains WebView-specific APIs that require the creation of other
- * adapters (otherwise org.chromium.content would depend on the webview.chromium package)
- * and a small set of no-op deprecated APIs.
- */
- @SuppressWarnings("deprecation")
- class WebViewChromium implements WebViewProvider, WebViewProvider.ScrollDelegate,
- WebViewProvider.ViewDelegate, SmartClipProvider {
- private static final String TAG = WebViewChromium.class.getSimpleName();
- // The WebView that this WebViewChromium is the provider for.
- WebView mWebView;
- // Lets us access protected View-derived methods on the WebView instance we're backing.
- WebView.PrivateAccess mWebViewPrivate;
- // The client adapter class.
- private WebViewContentsClientAdapter mContentsClientAdapter;
- // The wrapped Context.
- private Context mContext;
- // Variables for functionality provided by this adapter ---------------------------------------
- private ContentSettingsAdapter mWebSettings;
- // The WebView wrapper for WebContents and required browser components.
- AwContents mAwContents;
- private final WebView.HitTestResult mHitTestResult;
- private final int mAppTargetSdkVersion;
- protected WebViewChromiumFactoryProvider mFactory;
- protected final SharedWebViewChromium mSharedWebViewChromium;
- private final boolean mShouldDisableThreadChecking;
- private static boolean sRecordWholeDocumentEnabledByApi;
- static void enableSlowWholeDocumentDraw() {
- sRecordWholeDocumentEnabledByApi = true;
- }
- // Used to record the UMA histogram WebView.WebViewApiCall. Since these values are persisted to
- // logs, they should never be renumbered or reused.
- @IntDef({ApiCall.ADD_JAVASCRIPT_INTERFACE, ApiCall.AUTOFILL, ApiCall.CAN_GO_BACK,
- ApiCall.CAN_GO_BACK_OR_FORWARD, ApiCall.CAN_GO_FORWARD, ApiCall.CAN_ZOOM_IN,
- ApiCall.CAN_ZOOM_OUT, ApiCall.CAPTURE_PICTURE, ApiCall.CLEAR_CACHE,
- ApiCall.CLEAR_FORM_DATA, ApiCall.CLEAR_HISTORY, ApiCall.CLEAR_MATCHES,
- ApiCall.CLEAR_SSL_PREFERENCES, ApiCall.CLEAR_VIEW, ApiCall.COPY_BACK_FORWARD_LIST,
- ApiCall.CREATE_PRINT_DOCUMENT_ADAPTER, ApiCall.CREATE_WEBMESSAGE_CHANNEL,
- ApiCall.DOCUMENT_HAS_IMAGES, ApiCall.DOES_SUPPORT_FULLSCREEN,
- ApiCall.EVALUATE_JAVASCRIPT, ApiCall.EXTRACT_SMART_CLIP_DATA, ApiCall.FIND_NEXT,
- ApiCall.GET_CERTIFICATE, ApiCall.GET_CONTENT_HEIGHT, ApiCall.GET_CONTENT_WIDTH,
- ApiCall.GET_FAVICON, ApiCall.GET_HIT_TEST_RESULT,
- ApiCall.GET_HTTP_AUTH_USERNAME_PASSWORD, ApiCall.GET_ORIGINAL_URL, ApiCall.GET_PROGRESS,
- ApiCall.GET_SCALE, ApiCall.GET_SETTINGS, ApiCall.GET_TEXT_CLASSIFIER, ApiCall.GET_TITLE,
- ApiCall.GET_URL, ApiCall.GET_WEBCHROME_CLIENT, ApiCall.GET_WEBVIEW_CLIENT,
- ApiCall.GO_BACK, ApiCall.GO_BACK_OR_FORWARD, ApiCall.GO_FORWARD,
- ApiCall.INSERT_VISUAL_STATE_CALLBACK, ApiCall.INVOKE_ZOOM_PICKER, ApiCall.IS_PAUSED,
- ApiCall.IS_PRIVATE_BROWSING_ENABLED, ApiCall.LOAD_DATA, ApiCall.LOAD_DATA_WITH_BASE_URL,
- ApiCall.NOTIFY_FIND_DIALOG_DISMISSED, ApiCall.ON_PAUSE,
- ApiCall.ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE, ApiCall.ON_RESUME,
- ApiCall.OVERLAY_HORIZONTAL_SCROLLBAR, ApiCall.OVERLAY_VERTICAL_SCROLLBAR,
- ApiCall.PAGE_DOWN, ApiCall.PAGE_UP, ApiCall.PAUSE_TIMERS,
- ApiCall.POST_MESSAGE_TO_MAIN_FRAME, ApiCall.POST_URL, ApiCall.RELOAD,
- ApiCall.REMOVE_JAVASCRIPT_INTERFACE, ApiCall.REQUEST_FOCUS_NODE_HREF,
- ApiCall.REQUEST_IMAGE_REF, ApiCall.RESTORE_STATE, ApiCall.RESUME_TIMERS,
- ApiCall.SAVE_STATE, ApiCall.SET_DOWNLOAD_LISTENER, ApiCall.SET_FIND_LISTENER,
- ApiCall.SET_HORIZONTAL_SCROLLBAR_OVERLAY, ApiCall.SET_HTTP_AUTH_USERNAME_PASSWORD,
- ApiCall.SET_INITIAL_SCALE, ApiCall.SET_NETWORK_AVAILABLE, ApiCall.SET_PICTURE_LISTENER,
- ApiCall.SET_SMART_CLIP_RESULT_HANDLER, ApiCall.SET_TEXT_CLASSIFIER,
- ApiCall.SET_VERTICAL_SCROLLBAR_OVERLAY, ApiCall.SET_WEBCHROME_CLIENT,
- ApiCall.SET_WEBVIEW_CLIENT, ApiCall.SHOW_FIND_DIALOG, ApiCall.STOP_LOADING})
- @interface ApiCall {
- int ADD_JAVASCRIPT_INTERFACE = 0;
- int AUTOFILL = 1;
- int CAN_GO_BACK = 2;
- int CAN_GO_BACK_OR_FORWARD = 3;
- int CAN_GO_FORWARD = 4;
- int CAN_ZOOM_IN = 5;
- int CAN_ZOOM_OUT = 6;
- int CAPTURE_PICTURE = 7;
- int CLEAR_CACHE = 8;
- int CLEAR_FORM_DATA = 9;
- int CLEAR_HISTORY = 10;
- int CLEAR_MATCHES = 11;
- int CLEAR_SSL_PREFERENCES = 12;
- int CLEAR_VIEW = 13;
- int COPY_BACK_FORWARD_LIST = 14;
- int CREATE_PRINT_DOCUMENT_ADAPTER = 15;
- int CREATE_WEBMESSAGE_CHANNEL = 16;
- int DOCUMENT_HAS_IMAGES = 17;
- int DOES_SUPPORT_FULLSCREEN = 18;
- int EVALUATE_JAVASCRIPT = 19;
- int EXTRACT_SMART_CLIP_DATA = 20;
- int FIND_NEXT = 21;
- int GET_CERTIFICATE = 22;
- int GET_CONTENT_HEIGHT = 23;
- int GET_CONTENT_WIDTH = 24;
- int GET_FAVICON = 25;
- int GET_HIT_TEST_RESULT = 26;
- int GET_HTTP_AUTH_USERNAME_PASSWORD = 27;
- int GET_ORIGINAL_URL = 28;
- int GET_PROGRESS = 29;
- int GET_SCALE = 30;
- int GET_SETTINGS = 31;
- int GET_TEXT_CLASSIFIER = 32;
- int GET_TITLE = 33;
- int GET_URL = 34;
- int GET_WEBCHROME_CLIENT = 35;
- int GET_WEBVIEW_CLIENT = 36;
- int GO_BACK = 37;
- int GO_BACK_OR_FORWARD = 38;
- int GO_FORWARD = 39;
- int INSERT_VISUAL_STATE_CALLBACK = 40;
- int INVOKE_ZOOM_PICKER = 41;
- int IS_PAUSED = 42;
- int IS_PRIVATE_BROWSING_ENABLED = 43;
- int LOAD_DATA = 44;
- int LOAD_DATA_WITH_BASE_URL = 45;
- int NOTIFY_FIND_DIALOG_DISMISSED = 46;
- int ON_PAUSE = 47;
- int ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE = 48;
- int ON_RESUME = 49;
- int OVERLAY_HORIZONTAL_SCROLLBAR = 50;
- int OVERLAY_VERTICAL_SCROLLBAR = 51;
- int PAGE_DOWN = 52;
- int PAGE_UP = 53;
- int PAUSE_TIMERS = 54;
- int POST_MESSAGE_TO_MAIN_FRAME = 55;
- int POST_URL = 56;
- int RELOAD = 57;
- int REMOVE_JAVASCRIPT_INTERFACE = 58;
- int REQUEST_FOCUS_NODE_HREF = 59;
- int REQUEST_IMAGE_REF = 60;
- int RESTORE_STATE = 61;
- int RESUME_TIMERS = 62;
- int SAVE_STATE = 63;
- int SET_DOWNLOAD_LISTENER = 64;
- int SET_FIND_LISTENER = 65;
- int SET_HORIZONTAL_SCROLLBAR_OVERLAY = 66;
- int SET_HTTP_AUTH_USERNAME_PASSWORD = 67;
- int SET_INITIAL_SCALE = 68;
- int SET_NETWORK_AVAILABLE = 69;
- int SET_PICTURE_LISTENER = 70;
- int SET_SMART_CLIP_RESULT_HANDLER = 71;
- int SET_TEXT_CLASSIFIER = 72;
- int SET_VERTICAL_SCROLLBAR_OVERLAY = 73;
- int SET_WEBCHROME_CLIENT = 74;
- int SET_WEBVIEW_CLIENT = 75;
- int SHOW_FIND_DIALOG = 76;
- int STOP_LOADING = 77;
- int COUNT = 78;
- }
- private static void recordWebViewApiCall(@ApiCall int sample) {
- RecordHistogram.recordEnumeratedHistogram("Android.WebView.ApiCall", sample, ApiCall.COUNT);
- }
- // This does not touch any global / non-threadsafe state, but note that
- // init is ofter called right after and is NOT threadsafe.
- public WebViewChromium(WebViewChromiumFactoryProvider factory, WebView webView,
- WebView.PrivateAccess webViewPrivate, boolean shouldDisableThreadChecking) {
- try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.constructor")) {
- WebViewChromiumFactoryProvider.checkStorageIsNotDeviceProtected(webView.getContext());
- mWebView = webView;
- mWebViewPrivate = webViewPrivate;
- mHitTestResult = new WebView.HitTestResult();
- mContext = ClassLoaderContextWrapperFactory.get(mWebView.getContext());
- mAppTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
- mFactory = factory;
- mShouldDisableThreadChecking = shouldDisableThreadChecking;
- factory.addWebViewAssetPath(mWebView.getContext());
- mSharedWebViewChromium =
- new SharedWebViewChromium(mFactory.getRunQueue(), mFactory.getAwInit());
- }
- }
- // See //android_webview/docs/how-does-on-create-window-work.md for more details.
- static void completeWindowCreation(WebView parent, WebView child) {
- AwContents parentContents = ((WebViewChromium) parent.getWebViewProvider()).mAwContents;
- AwContents childContents =
- child == null ? null : ((WebViewChromium) child.getWebViewProvider()).mAwContents;
- parentContents.supplyContentsForPopup(childContents);
- }
- // WebViewProvider methods --------------------------------------------------------------------
- @Override
- // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete DumpRenderTree
- // so is ignored. TODO: remove it from WebViewProvider.
- public void init(final Map<String, Object> javaScriptInterfaces,
- final boolean privateBrowsing) {
- long startTime = SystemClock.uptimeMillis();
- boolean isFirstWebViewInit = !mFactory.hasStarted();
- try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.init")) {
- if (privateBrowsing) {
- mFactory.startYourEngines(true);
- final String msg = "Private browsing is not supported in WebView.";
- if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) {
- throw new IllegalArgumentException(msg);
- } else {
- Log.w(TAG, msg);
- TextView warningLabel = new TextView(mContext);
- warningLabel.setText(mContext.getString(
- org.chromium.android_webview.R.string.private_browsing_warning));
- mWebView.addView(warningLabel);
- }
- }
- if (mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- // If the app targets >= JB MR2 then we require that WebView is only used from a
- // single thread. So, we:
- // 1) start Chromium using the current thread as the UI thread (this is a no-op if
- // it was already started).
- mFactory.startYourEngines(false);
- // 2) check that the current thread is the UI thread, which will throw if it was
- // already started using a different thread as the UI thread.
- checkThread();
- } else {
- // For older apps, only the view methods that relate to the view hierarchy must come
- // from a single thread. Other calls, including the constructor itself, can come
- // from any thread, and will be posted to the UI thread if necessary.
- //
- // We used to defer the decision about which thread is the UI thread for as long as
- // possible to allow for the case where an app targeting < JB MR2 used a different
- // thread, but this significantly complicated initialization and is virtually never
- // encountered in the wild. We can't just use the current thread as the UI thread as
- // the normal case does, because it *is* somewhat common for old apps to construct
- // WebView on a background thread and then attach it to the view hierarchy on the
- // main looper.
- //
- // So, we just start Chromium using the main looper as the UI thread, which works
- // for virtually every old app, and accept that a very tiny number of them will
- // break.
- mFactory.startYourEngines(true);
- }
- final boolean isAccessFromFileURLsGrantedByDefault =
- mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN;
- final boolean areLegacyQuirksEnabled =
- mAppTargetSdkVersion < Build.VERSION_CODES.KITKAT;
- final boolean allowEmptyDocumentPersistence =
- mAppTargetSdkVersion <= Build.VERSION_CODES.M;
- final boolean allowGeolocationOnInsecureOrigins =
- mAppTargetSdkVersion <= Build.VERSION_CODES.M;
- // https://crbug.com/698752
- final boolean doNotUpdateSelectionOnMutatingSelectionRange =
- mAppTargetSdkVersion <= Build.VERSION_CODES.M;
- mContentsClientAdapter =
- mFactory.createWebViewContentsClientAdapter(mWebView, mContext);
- try (ScopedSysTraceEvent e2 =
- ScopedSysTraceEvent.scoped("WebViewChromium.ContentSettingsAdapter")) {
- mWebSettings = mFactory.createContentSettingsAdapter(new AwSettings(mContext,
- isAccessFromFileURLsGrantedByDefault, areLegacyQuirksEnabled,
- allowEmptyDocumentPersistence, allowGeolocationOnInsecureOrigins,
- doNotUpdateSelectionOnMutatingSelectionRange));
- }
- if (mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
- // Prior to Lollipop we always allowed third party cookies and mixed content.
- mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
- mWebSettings.setAcceptThirdPartyCookies(true);
- mWebSettings.getAwSettings().setZeroLayoutHeightDisablesViewportQuirk(true);
- }
- if (mAppTargetSdkVersion >= Build.VERSION_CODES.P) {
- mWebSettings.getAwSettings().setCSSHexAlphaColorEnabled(true);
- mWebSettings.getAwSettings().setScrollTopLeftInteropEnabled(true);
- }
- if (mShouldDisableThreadChecking) disableThreadChecking();
- mSharedWebViewChromium.init(mContentsClientAdapter);
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- initForReal();
- if (privateBrowsing) {
- // Intentionally irreversibly disable the webview instance, so that private
- // user data cannot leak through misuse of a non-private-browsing WebView
- // instance. Can't just null out mAwContents as we never null-check it
- // before use.
- destroy();
- }
- }
- });
- }
- // If initialization hasn't been deferred, record a startup time histogram entry.
- if (mFactory.hasStarted()) {
- if (isFirstWebViewInit) {
- RecordHistogram.recordTimesHistogram(
- "Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Cold",
- SystemClock.uptimeMillis() - startTime);
- } else {
- RecordHistogram.recordTimesHistogram(
- "Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Warm",
- SystemClock.uptimeMillis() - startTime);
- }
- }
- }
- // This is a workaround for https://crbug.com/622151.
- // In HTC's email app, InputConnection.setComposingText() will call WebView.evaluateJavaScript,
- // and thread assertion will occur. We turn off WebView thread assertion for this app.
- // SuppressLint rationale: https://crrev.com/c/3439168/comments/d612ae09_b7bfca2b
- @SuppressLint("SoonBlockedPrivateApi")
- private void disableThreadChecking() {
- try {
- Class<?> webViewClass = Class.forName("android.webkit.WebView");
- Field field = webViewClass.getDeclaredField("sEnforceThreadChecking");
- field.setAccessible(true);
- field.setBoolean(null, false);
- field.setAccessible(false);
- } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException
- | IllegalArgumentException e) {
- Log.w(TAG, "Failed to disable thread checking.");
- }
- }
- private void initForReal() {
- try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.initForReal")) {
- AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi
- || mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP);
- mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWebView, mContext,
- new InternalAccessAdapter(), new WebViewNativeDrawFunctorFactory(),
- mContentsClientAdapter, mWebSettings.getAwSettings(),
- new AwContents.DependencyFactory());
- if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) {
- // On KK and above, favicons are automatically downloaded as the method
- // old apps use to enable that behavior is deprecated.
- AwContents.setShouldDownloadFavicons();
- }
- if (mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
- // Prior to Lollipop, JavaScript objects injected via addJavascriptInterface
- // were not inspectable.
- mAwContents.disableJavascriptInterfacesInspection();
- }
- // TODO: This assumes AwContents ignores second Paint param.
- mAwContents.setLayerType(mWebView.getLayerType(), null);
- mSharedWebViewChromium.initForReal(mAwContents);
- }
- }
- private RuntimeException createThreadException() {
- return new IllegalStateException(
- "Calling View methods on another thread than the UI thread.");
- }
- protected boolean checkNeedsPost() {
- return mSharedWebViewChromium.checkNeedsPost();
- }
- // Intentionally not static, as no need to check thread on static methods
- private void checkThread() {
- if (!ThreadUtils.runningOnUiThread()) {
- final RuntimeException threadViolation = createThreadException();
- AwThreadUtils.postToUiThreadLooper(() -> { throw threadViolation; });
- throw createThreadException();
- }
- }
- @Override
- public void setHorizontalScrollbarOverlay(final boolean overlay) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setHorizontalScrollbarOverlay(overlay);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.SET_HORIZONTAL_SCROLLBAR_OVERLAY);
- mAwContents.setHorizontalScrollbarOverlay(overlay);
- }
- @Override
- public void setVerticalScrollbarOverlay(final boolean overlay) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setVerticalScrollbarOverlay(overlay);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.SET_VERTICAL_SCROLLBAR_OVERLAY);
- mAwContents.setVerticalScrollbarOverlay(overlay);
- }
- @Override
- public boolean overlayHorizontalScrollbar() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return overlayHorizontalScrollbar();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.OVERLAY_HORIZONTAL_SCROLLBAR);
- return mAwContents.overlayHorizontalScrollbar();
- }
- @Override
- public boolean overlayVerticalScrollbar() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return overlayVerticalScrollbar();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.OVERLAY_VERTICAL_SCROLLBAR);
- return mAwContents.overlayVerticalScrollbar();
- }
- @Override
- public int getVisibleTitleHeight() {
- // This is deprecated in WebView and should always return 0.
- return 0;
- }
- @Override
- public SslCertificate getCertificate() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- SslCertificate ret = mFactory.runOnUiThreadBlocking(new Callable<SslCertificate>() {
- @Override
- public SslCertificate call() {
- return getCertificate();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_CERTIFICATE);
- return mAwContents.getCertificate();
- }
- @Override
- public void setCertificate(SslCertificate certificate) {
- // intentional no-op
- }
- @Override
- public void savePassword(String host, String username, String password) {
- // This is a deprecated API: intentional no-op.
- }
- @Override
- public void setHttpAuthUsernamePassword(
- final String host, final String realm, final String username, final String password) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setHttpAuthUsernamePassword(host, realm, username, password);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.SET_HTTP_AUTH_USERNAME_PASSWORD);
- ((WebViewDatabaseAdapter) mFactory.getWebViewDatabase(mContext))
- .setHttpAuthUsernamePassword(host, realm, username, password);
- }
- @Override
- public String[] getHttpAuthUsernamePassword(final String host, final String realm) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- String[] ret = mFactory.runOnUiThreadBlocking(new Callable<String[]>() {
- @Override
- public String[] call() {
- return getHttpAuthUsernamePassword(host, realm);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_HTTP_AUTH_USERNAME_PASSWORD);
- return ((WebViewDatabaseAdapter) mFactory.getWebViewDatabase(mContext))
- .getHttpAuthUsernamePassword(host, realm);
- }
- @Override
- public void destroy() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- destroy();
- }
- });
- return;
- }
- // Make sure that we do not trigger any callbacks after destruction
- setWebChromeClient(null);
- setWebViewClient(null);
- mContentsClientAdapter.setPictureListener(null, true);
- mContentsClientAdapter.setFindListener(null);
- mContentsClientAdapter.setDownloadListener(null);
- mAwContents.destroy();
- }
- @Override
- public void setNetworkAvailable(final boolean networkUp) {
- // Note that this purely toggles the JS navigator.online property.
- // It does not in affect chromium or network stack state in any way.
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setNetworkAvailable(networkUp);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.SET_NETWORK_AVAILABLE);
- mAwContents.setNetworkAvailable(networkUp);
- }
- @Override
- public WebBackForwardList saveState(final Bundle outState) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- WebBackForwardList ret =
- mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
- @Override
- public WebBackForwardList call() {
- return saveState(outState);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.SAVE_STATE);
- if (outState == null) return null;
- if (!mAwContents.saveState(outState)) return null;
- return copyBackForwardList();
- }
- @Override
- public boolean savePicture(Bundle b, File dest) {
- // Intentional no-op: hidden method on WebView.
- return false;
- }
- @Override
- public boolean restorePicture(Bundle b, File src) {
- // Intentional no-op: hidden method on WebView.
- return false;
- }
- @Override
- public WebBackForwardList restoreState(final Bundle inState) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- WebBackForwardList ret =
- mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
- @Override
- public WebBackForwardList call() {
- return restoreState(inState);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.RESTORE_STATE);
- if (inState == null) return null;
- if (!mAwContents.restoreState(inState)) return null;
- return copyBackForwardList();
- }
- @Override
- public void loadUrl(final String url, final Map<String, String> additionalHttpHeaders) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- // Disallowed in WebView API for apps targeting a new SDK
- assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- mAwContents.loadUrl(url, additionalHttpHeaders);
- }
- });
- return;
- }
- mAwContents.loadUrl(url, additionalHttpHeaders);
- }
- @Override
- public void loadUrl(final String url) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- // Disallowed in WebView API for apps targeting a new SDK
- assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- mAwContents.loadUrl(url);
- }
- });
- return;
- }
- mAwContents.loadUrl(url);
- }
- @Override
- public void postUrl(final String url, final byte[] postData) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- // Disallowed in WebView API for apps targeting a new SDK
- assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- recordWebViewApiCall(ApiCall.POST_URL);
- mAwContents.postUrl(url, postData);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.POST_URL);
- mAwContents.postUrl(url, postData);
- }
- @Override
- public void loadData(final String data, final String mimeType, final String encoding) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- // Disallowed in WebView API for apps targeting a new SDK
- assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- recordWebViewApiCall(ApiCall.LOAD_DATA);
- mAwContents.loadData(data, mimeType, encoding);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.LOAD_DATA);
- mAwContents.loadData(data, mimeType, encoding);
- }
- @Override
- public void loadDataWithBaseURL(final String baseUrl, final String data, final String mimeType,
- final String encoding, final String historyUrl) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- // Disallowed in WebView API for apps targeting a new SDK
- assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- recordWebViewApiCall(ApiCall.LOAD_DATA_WITH_BASE_URL);
- mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.LOAD_DATA_WITH_BASE_URL);
- mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
- }
- @Override
- public void evaluateJavaScript(
- final String script, final ValueCallback<String> resultCallback) {
- if (mShouldDisableThreadChecking && checkNeedsPost()) {
- // This is a workaround for https://crbug.com/622151.
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- recordWebViewApiCall(ApiCall.EVALUATE_JAVASCRIPT);
- mAwContents.evaluateJavaScript(
- script, CallbackConverter.fromValueCallback(resultCallback));
- }
- });
- } else {
- recordWebViewApiCall(ApiCall.EVALUATE_JAVASCRIPT);
- checkThread();
- mAwContents.evaluateJavaScript(
- script, CallbackConverter.fromValueCallback(resultCallback));
- }
- }
- @Override
- public void saveWebArchive(String filename) {
- saveWebArchive(filename, false, null);
- }
- @Override
- public void saveWebArchive(final String basename, final boolean autoname,
- final ValueCallback<String> callback) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- saveWebArchive(basename, autoname, callback);
- }
- });
- return;
- }
- mAwContents.saveWebArchive(
- basename, autoname, CallbackConverter.fromValueCallback(callback));
- }
- @Override
- public void stopLoading() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- stopLoading();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.STOP_LOADING);
- mAwContents.stopLoading();
- }
- @Override
- public void reload() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- reload();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.RELOAD);
- mAwContents.reload();
- }
- @Override
- public boolean canGoBack() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return canGoBack();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.CAN_GO_BACK);
- return mAwContents.canGoBack();
- }
- @Override
- public void goBack() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- goBack();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.GO_BACK);
- mAwContents.goBack();
- }
- @Override
- public boolean canGoForward() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return canGoForward();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.CAN_GO_FORWARD);
- return mAwContents.canGoForward();
- }
- @Override
- public void goForward() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- goForward();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.GO_FORWARD);
- mAwContents.goForward();
- }
- @Override
- public boolean canGoBackOrForward(final int steps) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return canGoBackOrForward(steps);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.CAN_GO_BACK_OR_FORWARD);
- return mAwContents.canGoBackOrForward(steps);
- }
- @Override
- public void goBackOrForward(final int steps) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- goBackOrForward(steps);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.GO_BACK_OR_FORWARD);
- mAwContents.goBackOrForward(steps);
- }
- @Override
- public boolean isPrivateBrowsingEnabled() {
- // Not supported in this WebView implementation.
- recordWebViewApiCall(ApiCall.IS_PRIVATE_BROWSING_ENABLED);
- return false;
- }
- @Override
- public boolean pageUp(final boolean top) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return pageUp(top);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.PAGE_UP);
- return mAwContents.pageUp(top);
- }
- @Override
- public boolean pageDown(final boolean bottom) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return pageDown(bottom);
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.PAGE_DOWN);
- return mAwContents.pageDown(bottom);
- }
- @Override
- public void insertVisualStateCallback(
- final long requestId, final VisualStateCallback callback) {
- recordWebViewApiCall(ApiCall.INSERT_VISUAL_STATE_CALLBACK);
- mSharedWebViewChromium.insertVisualStateCallback(
- requestId, callback == null ? null : new AwContents.VisualStateCallback() {
- @Override
- public void onComplete(long requestId) {
- callback.onComplete(requestId);
- }
- });
- }
- @Override
- public void clearView() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearView();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_VIEW);
- mAwContents.clearView();
- }
- @Override
- public Picture capturePicture() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Picture ret = mFactory.runOnUiThreadBlocking(new Callable<Picture>() {
- @Override
- public Picture call() {
- return capturePicture();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.CAPTURE_PICTURE);
- return mAwContents.capturePicture();
- }
- @Override
- public float getScale() {
- recordWebViewApiCall(ApiCall.GET_SCALE);
- // No checkThread() as it is mostly thread safe (workaround for b/10652991).
- mFactory.startYourEngines(true);
- return mAwContents.getScale();
- }
- @Override
- public void setInitialScale(final int scaleInPercent) {
- recordWebViewApiCall(ApiCall.SET_INITIAL_SCALE);
- // No checkThread() as it is thread safe
- mWebSettings.getAwSettings().setInitialPageScale(scaleInPercent);
- }
- @Override
- public void invokeZoomPicker() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- invokeZoomPicker();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.INVOKE_ZOOM_PICKER);
- mAwContents.invokeZoomPicker();
- }
- @Override
- public WebView.HitTestResult getHitTestResult() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- WebView.HitTestResult ret =
- mFactory.runOnUiThreadBlocking(new Callable<WebView.HitTestResult>() {
- @Override
- public WebView.HitTestResult call() {
- return getHitTestResult();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_HIT_TEST_RESULT);
- AwContents.HitTestData data = mAwContents.getLastHitTestResult();
- mHitTestResult.setType(data.hitTestResultType);
- mHitTestResult.setExtra(data.hitTestResultExtraData);
- return mHitTestResult;
- }
- @Override
- public void requestFocusNodeHref(final Message hrefMsg) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- requestFocusNodeHref(hrefMsg);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.REQUEST_FOCUS_NODE_HREF);
- mAwContents.requestFocusNodeHref(hrefMsg);
- }
- @Override
- public void requestImageRef(final Message msg) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- requestImageRef(msg);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.REQUEST_IMAGE_REF);
- mAwContents.requestImageRef(msg);
- }
- @Override
- public String getUrl() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
- @Override
- public String call() {
- return getUrl();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_URL);
- GURL url = mAwContents.getUrl();
- return url == null ? null : url.getSpec();
- }
- @Override
- public String getOriginalUrl() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
- @Override
- public String call() {
- return getOriginalUrl();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_ORIGINAL_URL);
- return mAwContents.getOriginalUrl();
- }
- @Override
- public String getTitle() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
- @Override
- public String call() {
- return getTitle();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_TITLE);
- return mAwContents.getTitle();
- }
- @Override
- public Bitmap getFavicon() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Bitmap ret = mFactory.runOnUiThreadBlocking(new Callable<Bitmap>() {
- @Override
- public Bitmap call() {
- return getFavicon();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.GET_FAVICON);
- return mAwContents.getFavicon();
- }
- @Override
- public String getTouchIconUrl() {
- // Intentional no-op: hidden method on WebView.
- return null;
- }
- @Override
- public int getProgress() {
- recordWebViewApiCall(ApiCall.GET_PROGRESS);
- if (mAwContents == null) return 100;
- // No checkThread() because the value is cached java side (workaround for b/10533304).
- return mAwContents.getMostRecentProgress();
- }
- @Override
- public int getContentHeight() {
- recordWebViewApiCall(ApiCall.GET_CONTENT_HEIGHT);
- if (mAwContents == null) return 0;
- // No checkThread() as it is mostly thread safe (workaround for b/10594869).
- return mAwContents.getContentHeightCss();
- }
- @Override
- public int getContentWidth() {
- recordWebViewApiCall(ApiCall.GET_CONTENT_WIDTH);
- if (mAwContents == null) return 0;
- // No checkThread() as it is mostly thread safe (workaround for b/10594869).
- return mAwContents.getContentWidthCss();
- }
- @Override
- public void pauseTimers() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- pauseTimers();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.PAUSE_TIMERS);
- mAwContents.pauseTimers();
- }
- @Override
- public void resumeTimers() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- resumeTimers();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.RESUME_TIMERS);
- mAwContents.resumeTimers();
- }
- @Override
- public void onPause() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onPause();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.ON_PAUSE);
- mAwContents.onPause();
- }
- @Override
- public void onResume() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onResume();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.ON_RESUME);
- mAwContents.onResume();
- }
- @Override
- public boolean isPaused() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return isPaused();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.IS_PAUSED);
- return mAwContents.isPaused();
- }
- @Override
- public void freeMemory() {
- // Intentional no-op. Memory is managed automatically by Chromium.
- }
- @Override
- public void clearCache(final boolean includeDiskFiles) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearCache(includeDiskFiles);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_CACHE);
- mAwContents.clearCache(includeDiskFiles);
- }
- /**
- * This is a poorly named method, but we keep it for historical reasons.
- */
- @Override
- public void clearFormData() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearFormData();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_FORM_DATA);
- mAwContents.hideAutofillPopup();
- }
- @Override
- public void clearHistory() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearHistory();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_HISTORY);
- mAwContents.clearHistory();
- }
- @Override
- public void clearSslPreferences() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearSslPreferences();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_SSL_PREFERENCES);
- mAwContents.clearSslPreferences();
- }
- @Override
- public WebBackForwardList copyBackForwardList() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- WebBackForwardList ret =
- mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
- @Override
- public WebBackForwardList call() {
- return copyBackForwardList();
- }
- });
- return ret;
- }
- recordWebViewApiCall(ApiCall.COPY_BACK_FORWARD_LIST);
- // mAwContents.getNavigationHistory() can be null here if mAwContents has been destroyed,
- // and we do not handle passing null to the WebBackForwardListChromium constructor.
- NavigationHistory navHistory = mAwContents.getNavigationHistory();
- if (navHistory == null) navHistory = new NavigationHistory();
- return new WebBackForwardListChromium(navHistory);
- }
- @Override
- public void setFindListener(WebView.FindListener listener) {
- recordWebViewApiCall(ApiCall.SET_FIND_LISTENER);
- mContentsClientAdapter.setFindListener(listener);
- }
- @Override
- public void findNext(final boolean forwards) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- findNext(forwards);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.FIND_NEXT);
- mAwContents.findNext(forwards);
- }
- @Override
- public int findAll(final String searchString) {
- findAllAsync(searchString);
- return 0;
- }
- @Override
- public void findAllAsync(final String searchString) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- findAllAsync(searchString);
- }
- });
- return;
- }
- mAwContents.findAllAsync(searchString);
- }
- @Override
- public boolean showFindDialog(final String text, final boolean showIme) {
- recordWebViewApiCall(ApiCall.SHOW_FIND_DIALOG);
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- return false;
- }
- if (mWebView.getParent() == null) {
- return false;
- }
- FindActionModeCallback findAction = new FindActionModeCallback(mContext);
- if (findAction == null) {
- return false;
- }
- mWebView.startActionMode(findAction);
- findAction.setWebView(mWebView);
- if (showIme) {
- findAction.showSoftInput();
- }
- if (text != null) {
- findAction.setText(text);
- findAction.findAll();
- }
- return true;
- }
- @Override
- public void notifyFindDialogDismissed() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- notifyFindDialogDismissed();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.NOTIFY_FIND_DIALOG_DISMISSED);
- clearMatches();
- }
- @Override
- public void clearMatches() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- clearMatches();
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.CLEAR_MATCHES);
- mAwContents.clearMatches();
- }
- @Override
- public void documentHasImages(final Message response) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- documentHasImages(response);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.DOCUMENT_HAS_IMAGES);
- mAwContents.documentHasImages(response);
- }
- @Override
- public void setWebViewClient(WebViewClient client) {
- recordWebViewApiCall(ApiCall.SET_WEBVIEW_CLIENT);
- mSharedWebViewChromium.setWebViewClient(client);
- mContentsClientAdapter.setWebViewClient(mSharedWebViewChromium.getWebViewClient());
- }
- @Override
- public WebViewClient getWebViewClient() {
- recordWebViewApiCall(ApiCall.GET_WEBVIEW_CLIENT);
- return mSharedWebViewChromium.getWebViewClient();
- }
- @RequiresApi(Build.VERSION_CODES.Q)
- @Override
- public WebViewRenderProcess getWebViewRenderProcess() {
- return GlueApiHelperForQ.getWebViewRenderProcess(mSharedWebViewChromium.getRenderProcess());
- }
- @RequiresApi(Build.VERSION_CODES.Q)
- @Override
- public void setWebViewRenderProcessClient(
- Executor executor, WebViewRenderProcessClient webViewRenderProcessClient) {
- if (webViewRenderProcessClient == null) {
- mSharedWebViewChromium.setWebViewRendererClientAdapter(null);
- } else {
- if (executor == null) {
- executor = (Runnable r) -> r.run();
- }
- GlueApiHelperForQ.setWebViewRenderProcessClient(
- mSharedWebViewChromium, executor, webViewRenderProcessClient);
- }
- }
- @RequiresApi(Build.VERSION_CODES.Q)
- @Override
- public WebViewRenderProcessClient getWebViewRenderProcessClient() {
- SharedWebViewRendererClientAdapter adapter =
- mSharedWebViewChromium.getWebViewRendererClientAdapter();
- if (adapter == null || !(adapter instanceof WebViewRenderProcessClientAdapter)) {
- return null;
- }
- return GlueApiHelperForQ.getWebViewRenderProcessClient(adapter);
- }
- @Override
- public void setDownloadListener(DownloadListener listener) {
- recordWebViewApiCall(ApiCall.SET_DOWNLOAD_LISTENER);
- mContentsClientAdapter.setDownloadListener(listener);
- }
- @Override
- public void setWebChromeClient(WebChromeClient client) {
- recordWebViewApiCall(ApiCall.SET_WEBCHROME_CLIENT);
- mWebSettings.getAwSettings().setFullscreenSupported(doesSupportFullscreen(client));
- mSharedWebViewChromium.setWebChromeClient(client);
- mContentsClientAdapter.setWebChromeClient(mSharedWebViewChromium.getWebChromeClient());
- }
- @Override
- public WebChromeClient getWebChromeClient() {
- recordWebViewApiCall(ApiCall.GET_WEBCHROME_CLIENT);
- return mSharedWebViewChromium.getWebChromeClient();
- }
- /**
- * Returns true if the supplied {@link WebChromeClient} supports fullscreen.
- *
- * <p>For fullscreen support, implementations of {@link WebChromeClient#onShowCustomView}
- * and {@link WebChromeClient#onHideCustomView()} are required.
- */
- private boolean doesSupportFullscreen(WebChromeClient client) {
- recordWebViewApiCall(ApiCall.DOES_SUPPORT_FULLSCREEN);
- if (client == null) {
- return false;
- }
- Class<?> clientClass = client.getClass();
- boolean foundShowMethod = false;
- boolean foundHideMethod = false;
- while (clientClass != WebChromeClient.class && (!foundShowMethod || !foundHideMethod)) {
- if (!foundShowMethod) {
- try {
- clientClass.getDeclaredMethod(
- "onShowCustomView", View.class, CustomViewCallback.class);
- foundShowMethod = true;
- } catch (NoSuchMethodException e) {
- // Intentionally empty.
- }
- }
- if (!foundHideMethod) {
- try {
- clientClass.getDeclaredMethod("onHideCustomView");
- foundHideMethod = true;
- } catch (NoSuchMethodException e) {
- // Intentionally empty.
- }
- }
- clientClass = clientClass.getSuperclass();
- }
- return foundShowMethod && foundHideMethod;
- }
- @Override
- @SuppressWarnings("deprecation")
- public void setPictureListener(final WebView.PictureListener listener) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setPictureListener(listener);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.SET_PICTURE_LISTENER);
- boolean invalidateOnly = mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2;
- mContentsClientAdapter.setPictureListener(listener, invalidateOnly);
- mAwContents.enableOnNewPicture(listener != null, invalidateOnly);
- }
- @Override
- public void addJavascriptInterface(final Object obj, final String interfaceName) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- addJavascriptInterface(obj, interfaceName);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.ADD_JAVASCRIPT_INTERFACE);
- mAwContents.addJavascriptInterface(obj, interfaceName);
- }
- @Override
- public void removeJavascriptInterface(final String interfaceName) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- removeJavascriptInterface(interfaceName);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.REMOVE_JAVASCRIPT_INTERFACE);
- mAwContents.removeJavascriptInterface(interfaceName);
- }
- @Override
- public WebMessagePort[] createWebMessageChannel() {
- recordWebViewApiCall(ApiCall.CREATE_WEBMESSAGE_CHANNEL);
- return WebMessagePortAdapter.fromMessagePorts(
- mSharedWebViewChromium.createWebMessageChannel());
- }
- @Override
- public void postMessageToMainFrame(final WebMessage message, final Uri targetOrigin) {
- recordWebViewApiCall(ApiCall.POST_MESSAGE_TO_MAIN_FRAME);
- // Create MessagePayload from AOSP WebMessage, MessagePayload is not directly supported by
- // AOSP.
- mSharedWebViewChromium.postMessageToMainFrame(new MessagePayload(message.getData()),
- targetOrigin.toString(), WebMessagePortAdapter.toMessagePorts(message.getPorts()));
- }
- @Override
- public WebSettings getSettings() {
- recordWebViewApiCall(ApiCall.GET_SETTINGS);
- return mWebSettings;
- }
- @Override
- public void setMapTrackballToArrowKeys(boolean setMap) {
- // This is a deprecated API: intentional no-op.
- }
- @Override
- public void flingScroll(final int vx, final int vy) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- flingScroll(vx, vy);
- }
- });
- return;
- }
- mAwContents.flingScroll(vx, vy);
- }
- @Override
- public View getZoomControls() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- return null;
- }
- // This was deprecated in 2009 and hidden in JB MR1, so just provide the minimum needed
- // to stop very out-dated applications from crashing.
- Log.w(TAG, "WebView doesn't support getZoomControls");
- return mAwContents.getSettings().supportZoom() ? new View(mContext) : null;
- }
- @Override
- public boolean canZoomIn() {
- recordWebViewApiCall(ApiCall.CAN_ZOOM_IN);
- if (checkNeedsPost()) {
- return false;
- }
- return mAwContents.canZoomIn();
- }
- @Override
- public boolean canZoomOut() {
- recordWebViewApiCall(ApiCall.CAN_ZOOM_OUT);
- if (checkNeedsPost()) {
- return false;
- }
- return mAwContents.canZoomOut();
- }
- @Override
- public boolean zoomIn() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return zoomIn();
- }
- });
- return ret;
- }
- return mAwContents.zoomIn();
- }
- @Override
- public boolean zoomOut() {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return zoomOut();
- }
- });
- return ret;
- }
- return mAwContents.zoomOut();
- }
- // TODO(paulmiller) Return void for consistency with AwContents.zoomBy and WebView.zoomBy -
- // tricky because frameworks WebViewProvider.zoomBy must change simultaneously
- @Override
- public boolean zoomBy(float factor) {
- mFactory.startYourEngines(true);
- // This is an L API and therefore we can enforce stricter threading constraints.
- checkThread();
- mAwContents.zoomBy(factor);
- return true;
- }
- @Override
- public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
- // Intentional no-op
- }
- @Override
- public View findHierarchyView(String className, int hashCode) {
- // Intentional no-op
- return null;
- }
- @Override
- public void setRendererPriorityPolicy(
- int rendererRequestedPriority, boolean waivedWhenNotVisible) {
- @RendererPriority
- int awRendererRequestedPriority;
- switch (rendererRequestedPriority) {
- case WebView.RENDERER_PRIORITY_WAIVED:
- awRendererRequestedPriority = RendererPriority.WAIVED;
- break;
- case WebView.RENDERER_PRIORITY_BOUND:
- awRendererRequestedPriority = RendererPriority.LOW;
- break;
- default:
- case WebView.RENDERER_PRIORITY_IMPORTANT:
- awRendererRequestedPriority = RendererPriority.HIGH;
- break;
- }
- mAwContents.setRendererPriorityPolicy(awRendererRequestedPriority, waivedWhenNotVisible);
- }
- @Override
- public int getRendererRequestedPriority() {
- @RendererPriority
- final int awRendererRequestedPriority = mAwContents.getRendererRequestedPriority();
- switch (awRendererRequestedPriority) {
- case RendererPriority.WAIVED:
- return WebView.RENDERER_PRIORITY_WAIVED;
- case RendererPriority.LOW:
- return WebView.RENDERER_PRIORITY_BOUND;
- default:
- case RendererPriority.HIGH:
- return WebView.RENDERER_PRIORITY_IMPORTANT;
- }
- }
- @Override
- public boolean getRendererPriorityWaivedWhenNotVisible() {
- return mAwContents.getRendererPriorityWaivedWhenNotVisible();
- }
- @Override
- public void setTextClassifier(TextClassifier textClassifier) {
- recordWebViewApiCall(ApiCall.SET_TEXT_CLASSIFIER);
- mAwContents.setTextClassifier(textClassifier);
- }
- @Override
- public TextClassifier getTextClassifier() {
- recordWebViewApiCall(ApiCall.GET_TEXT_CLASSIFIER);
- return mAwContents.getTextClassifier();
- }
- @Override
- public void autofill(final SparseArray<AutofillValue> values) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- autofill(values);
- }
- });
- }
- recordWebViewApiCall(ApiCall.AUTOFILL);
- mAwContents.autofill(values);
- }
- @Override
- public void onProvideAutofillVirtualStructure(final ViewStructure structure, final int flags) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- onProvideAutofillVirtualStructure(structure, flags);
- }
- });
- return;
- }
- recordWebViewApiCall(ApiCall.ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE);
- mAwContents.onProvideAutoFillVirtualStructure(structure, flags);
- }
- @Override
- public void onProvideContentCaptureStructure(ViewStructure structure, int flags) {
- if (ContentCaptureFeatures.isDumpForTestingEnabled()) {
- Log.i("ContentCapture", "onProvideContentCaptureStructure");
- }
- mAwContents.setOnscreenContentProvider(new OnscreenContentProvider(
- ClassLoaderContextWrapperFactory.get(mWebView.getContext()), mWebView, structure,
- mAwContents.getWebContents()));
- }
- // WebViewProvider glue methods ---------------------------------------------------------------
- @Override
- // This needs to be kept thread safe!
- public WebViewProvider.ViewDelegate getViewDelegate() {
- return this;
- }
- @Override
- // This needs to be kept thread safe!
- public WebViewProvider.ScrollDelegate getScrollDelegate() {
- return this;
- }
- // WebViewProvider.ViewDelegate implementation ------------------------------------------------
- // TODO: remove from WebViewProvider and use default implementation from
- // ViewGroup.
- @Override
- public boolean shouldDelayChildPressedState() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return shouldDelayChildPressedState();
- }
- });
- return ret;
- }
- return true;
- }
- @Override
- public AccessibilityNodeProvider getAccessibilityNodeProvider() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- AccessibilityNodeProvider ret =
- mFactory.runOnUiThreadBlocking(new Callable<AccessibilityNodeProvider>() {
- @Override
- public AccessibilityNodeProvider call() {
- return getAccessibilityNodeProvider();
- }
- });
- return ret;
- }
- return mAwContents.getAccessibilityNodeProvider();
- }
- @Override
- public void onProvideVirtualStructure(final ViewStructure structure) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- onProvideVirtualStructure(structure);
- }
- });
- return;
- }
- mAwContents.onProvideVirtualStructure(structure);
- }
- @Override
- public void onInitializeAccessibilityNodeInfo(final AccessibilityNodeInfo info) {
- // Intentional no-op. Chromium accessibility implementation currently does not need this
- // calls.
- }
- @Override
- public void onInitializeAccessibilityEvent(final AccessibilityEvent event) {
- // Intentional no-op. Chromium accessibility implementation currently does not need this
- // calls.
- }
- @Override
- public boolean performAccessibilityAction(final int action, final Bundle arguments) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return performAccessibilityAction(action, arguments);
- }
- });
- return ret;
- }
- if (mAwContents.supportsAccessibilityAction(action)) {
- return mAwContents.performAccessibilityAction(action, arguments);
- }
- return mWebViewPrivate.super_performAccessibilityAction(action, arguments);
- }
- @Override
- public void setOverScrollMode(final int mode) {
- // This gets called from the android.view.View c'tor that WebView inherits from. This
- // causes the method to be called when mAwContents == null.
- // It's safe to ignore these calls however since AwContents will read the current value of
- // this setting when it's created.
- if (mAwContents == null) return;
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setOverScrollMode(mode);
- }
- });
- return;
- }
- mAwContents.setOverScrollMode(mode);
- }
- @Override
- public void setScrollBarStyle(final int style) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setScrollBarStyle(style);
- }
- });
- return;
- }
- mAwContents.setScrollBarStyle(style);
- }
- @Override
- public void onDrawVerticalScrollBar(final Canvas canvas, final Drawable scrollBar, final int l,
- final int t, final int r, final int b) {
- // WebViewClassic was overriding this method to handle rubberband over-scroll. Since
- // WebViewChromium doesn't support that the vanilla implementation of this method can be
- // used.
- mWebViewPrivate.super_onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
- }
- @Override
- public void onOverScrolled(final int scrollX, final int scrollY,
- final boolean clampedX, final boolean clampedY) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onOverScrolled(scrollX, scrollY, clampedX, clampedY);
- }
- });
- return;
- }
- mAwContents.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
- }
- @Override
- public void onWindowVisibilityChanged(final int visibility) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onWindowVisibilityChanged(visibility);
- }
- });
- return;
- }
- mAwContents.onWindowVisibilityChanged(visibility);
- }
- @Override
- @SuppressLint("DrawAllocation")
- public void onDraw(final Canvas canvas) {
- mFactory.startYourEngines(true);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- onDraw(canvas);
- }
- });
- return;
- }
- mAwContents.onDraw(canvas);
- }
- @Override
- public void setLayoutParams(final ViewGroup.LayoutParams layoutParams) {
- // This API is our strongest signal from the View system that this
- // WebView is going to be bound to a View hierarchy and so at this
- // point we must bind Chromium's UI thread to the current thread.
- mFactory.startYourEngines(false);
- checkThread();
- mWebViewPrivate.super_setLayoutParams(layoutParams);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- mAwContents.setLayoutParams(layoutParams);
- }
- });
- return;
- }
- mAwContents.setLayoutParams(layoutParams);
- }
- @Override
- public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onActivityResult(requestCode, resultCode, data);
- }
- });
- return;
- }
- mAwContents.onActivityResult(requestCode, resultCode, data);
- }
- @Override
- public boolean performLongClick() {
- // Return false unless the WebView is attached to a View with a parent
- return mWebView.getParent() != null ? mWebViewPrivate.super_performLongClick() : false;
- }
- @Override
- public void onConfigurationChanged(final Configuration newConfig) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onConfigurationChanged(newConfig);
- }
- });
- return;
- }
- mAwContents.onConfigurationChanged(newConfig);
- }
- @Override
- public boolean onDragEvent(final DragEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onDragEvent(event);
- }
- });
- return ret;
- }
- return mAwContents.onDragEvent(event);
- }
- @Override
- public InputConnection onCreateInputConnection(final EditorInfo outAttrs) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- return null;
- }
- return mAwContents.onCreateInputConnection(outAttrs);
- }
- @Override
- public boolean onKeyMultiple(final int keyCode, final int repeatCount, final KeyEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onKeyMultiple(keyCode, repeatCount, event);
- }
- });
- return ret;
- }
- return false;
- }
- @Override
- public boolean onKeyDown(final int keyCode, final KeyEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onKeyDown(keyCode, event);
- }
- });
- return ret;
- }
- return false;
- }
- @Override
- public boolean onKeyUp(final int keyCode, final KeyEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onKeyUp(keyCode, event);
- }
- });
- return ret;
- }
- return mAwContents.onKeyUp(keyCode, event);
- }
- @Override
- public void onAttachedToWindow() {
- // This API is our strongest signal from the View system that this
- // WebView is going to be bound to a View hierarchy and so at this
- // point we must bind Chromium's UI thread to the current thread.
- mFactory.startYourEngines(false);
- checkThread();
- mAwContents.onAttachedToWindow();
- }
- @Override
- public void onDetachedFromWindow() {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onDetachedFromWindow();
- }
- });
- return;
- }
- mAwContents.onDetachedFromWindow();
- }
- @Override
- public void onVisibilityChanged(final View changedView, final int visibility) {
- // The AwContents will find out the container view visibility before the first draw so we
- // can safely ignore onVisibilityChanged callbacks that happen before init().
- if (mAwContents == null) return;
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onVisibilityChanged(changedView, visibility);
- }
- });
- return;
- }
- mAwContents.onVisibilityChanged(changedView, visibility);
- }
- @Override
- public void onWindowFocusChanged(final boolean hasWindowFocus) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onWindowFocusChanged(hasWindowFocus);
- }
- });
- return;
- }
- mAwContents.onWindowFocusChanged(hasWindowFocus);
- }
- @Override
- public void onFocusChanged(
- final boolean focused, final int direction, final Rect previouslyFocusedRect) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onFocusChanged(focused, direction, previouslyFocusedRect);
- }
- });
- return;
- }
- mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect);
- }
- @Override
- public boolean setFrame(final int left, final int top, final int right, final int bottom) {
- return mWebViewPrivate.super_setFrame(left, top, right, bottom);
- }
- @Override
- public void onSizeChanged(final int w, final int h, final int ow, final int oh) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onSizeChanged(w, h, ow, oh);
- }
- });
- return;
- }
- mAwContents.onSizeChanged(w, h, ow, oh);
- }
- @Override
- public void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- onScrollChanged(l, t, oldl, oldt);
- }
- });
- return;
- }
- mAwContents.onContainerViewScrollChanged(l, t, oldl, oldt);
- }
- @Override
- public boolean dispatchKeyEvent(final KeyEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return dispatchKeyEvent(event);
- }
- });
- return ret;
- }
- return mAwContents.dispatchKeyEvent(event);
- }
- @Override
- public boolean onTouchEvent(final MotionEvent ev) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onTouchEvent(ev);
- }
- });
- return ret;
- }
- return mAwContents.onTouchEvent(ev);
- }
- @Override
- public boolean onHoverEvent(final MotionEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onHoverEvent(event);
- }
- });
- return ret;
- }
- return mAwContents.onHoverEvent(event);
- }
- @Override
- public boolean onGenericMotionEvent(final MotionEvent event) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onGenericMotionEvent(event);
- }
- });
- return ret;
- }
- return mAwContents.onGenericMotionEvent(event);
- }
- @Override
- public boolean onTrackballEvent(MotionEvent ev) {
- // Trackball event not handled, which eventually gets converted to DPAD keyevents
- return false;
- }
- @Override
- public boolean requestFocus(final int direction, final Rect previouslyFocusedRect) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return requestFocus(direction, previouslyFocusedRect);
- }
- });
- return ret;
- }
- mAwContents.requestFocus();
- return mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
- }
- @Override
- @SuppressLint("DrawAllocation")
- public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- });
- return;
- }
- mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- @Override
- public boolean requestChildRectangleOnScreen(
- final View child, final Rect rect, final boolean immediate) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return requestChildRectangleOnScreen(child, rect, immediate);
- }
- });
- return ret;
- }
- return mAwContents.requestChildRectangleOnScreen(child, rect, immediate);
- }
- @Override
- public void setBackgroundColor(final int color) {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setBackgroundColor(color);
- }
- });
- return;
- }
- mAwContents.setBackgroundColor(color);
- }
- @Override
- public void setLayerType(final int layerType, final Paint paint) {
- // This can be called from WebView constructor in which case mAwContents
- // is still null. We set the layer type in initForReal in that case.
- if (mAwContents == null) return;
- if (checkNeedsPost()) {
- mFactory.addTask(new Runnable() {
- @Override
- public void run() {
- setLayerType(layerType, paint);
- }
- });
- return;
- }
- mAwContents.setLayerType(layerType, paint);
- }
- // Overrides method added to WebViewProvider.ViewDelegate interface
- // (not called in M and below)
- @Override
- public Handler getHandler(Handler originalHandler) {
- return originalHandler;
- }
- // Overrides method added to WebViewProvider.ViewDelegate interface
- // (not called in M and below)
- @Override
- public View findFocus(View originalFocusedView) {
- return originalFocusedView;
- }
- // Remove from superclass
- @Override
- public void preDispatchDraw(Canvas canvas) {
- // TODO(leandrogracia): remove this method from WebViewProvider if we think
- // we won't need it again.
- }
- @Override
- public void onStartTemporaryDetach() {
- mAwContents.onStartTemporaryDetach();
- }
- @Override
- public void onFinishTemporaryDetach() {
- mAwContents.onFinishTemporaryDetach();
- }
- @Override
- public boolean onCheckIsTextEditor() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- return mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return onCheckIsTextEditor();
- }
- });
- }
- return mAwContents.onCheckIsTextEditor();
- }
- // WebViewProvider.ScrollDelegate implementation ----------------------------------------------
- @Override
- public int computeHorizontalScrollRange() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
- @Override
- public Integer call() {
- return computeHorizontalScrollRange();
- }
- });
- return ret;
- }
- return mAwContents.computeHorizontalScrollRange();
- }
- @Override
- public int computeHorizontalScrollOffset() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
- @Override
- public Integer call() {
- return computeHorizontalScrollOffset();
- }
- });
- return ret;
- }
- return mAwContents.computeHorizontalScrollOffset();
- }
- @Override
- public int computeVerticalScrollRange() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
- @Override
- public Integer call() {
- return computeVerticalScrollRange();
- }
- });
- return ret;
- }
- return mAwContents.computeVerticalScrollRange();
- }
- @Override
- public int computeVerticalScrollOffset() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
- @Override
- public Integer call() {
- return computeVerticalScrollOffset();
- }
- });
- return ret;
- }
- return mAwContents.computeVerticalScrollOffset();
- }
- @Override
- public int computeVerticalScrollExtent() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
- @Override
- public Integer call() {
- return computeVerticalScrollExtent();
- }
- });
- return ret;
- }
- return mAwContents.computeVerticalScrollExtent();
- }
- @Override
- public void computeScroll() {
- mFactory.startYourEngines(false);
- if (checkNeedsPost()) {
- mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- computeScroll();
- }
- });
- return;
- }
- mAwContents.computeScroll();
- }
- @Override
- public PrintDocumentAdapter createPrintDocumentAdapter(String documentName) {
- recordWebViewApiCall(ApiCall.CREATE_PRINT_DOCUMENT_ADAPTER);
- checkThread();
- return new AwPrintDocumentAdapter(mAwContents.getPdfExporter(), documentName);
- }
- // AwContents.NativeDrawFunctorFactory implementation ----------------------------------
- private class WebViewNativeDrawFunctorFactory implements AwContents.NativeDrawFunctorFactory {
- @Override
- public AwContents.NativeDrawGLFunctor createGLFunctor(long context) {
- return new DrawGLFunctor(context, mFactory.getWebViewDelegate());
- }
- @Override
- public AwDrawFnImpl.DrawFnAccess getDrawFnAccess() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return mFactory.getWebViewDelegate()::drawWebViewFunctor;
- }
- return null;
- }
- }
- // AwContents.InternalAccessDelegate implementation --------------------------------------
- private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
- @Override
- public boolean super_onKeyUp(int arg0, KeyEvent arg1) {
- // Intentional no-op
- return false;
- }
- @Override
- public boolean super_dispatchKeyEvent(KeyEvent event) {
- return mWebViewPrivate.super_dispatchKeyEvent(event);
- }
- @Override
- public boolean super_onGenericMotionEvent(MotionEvent arg0) {
- return mWebViewPrivate.super_onGenericMotionEvent(arg0);
- }
- @Override
- public void super_onConfigurationChanged(Configuration arg0) {
- // Intentional no-op
- }
- @Override
- public int super_getScrollBarStyle() {
- return mWebViewPrivate.super_getScrollBarStyle();
- }
- @Override
- public void super_startActivityForResult(Intent intent, int requestCode) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- GlueApiHelperForN.super_startActivityForResult(
- mWebViewPrivate, intent, requestCode);
- } else {
- try {
- Method startActivityForResultMethod =
- View.class.getMethod("startActivityForResult", Intent.class, int.class);
- startActivityForResultMethod.invoke(mWebView, intent, requestCode);
- } catch (Exception e) {
- throw new RuntimeException("Invalid reflection", e);
- }
- }
- }
- @Override
- public void onScrollChanged(int l, int t, int oldl, int oldt) {
- // Intentional no-op.
- // Chromium calls this directly to trigger accessibility events. That isn't needed
- // for WebView since super_scrollTo invokes onScrollChanged for us.
- }
- @Override
- public void overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
- int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
- mWebViewPrivate.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
- scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
- }
- @Override
- public void super_scrollTo(int scrollX, int scrollY) {
- mWebViewPrivate.super_scrollTo(scrollX, scrollY);
- }
- @Override
- public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
- mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
- }
- // @Override
- public boolean super_onHoverEvent(MotionEvent event) {
- return mWebViewPrivate.super_onHoverEvent(event);
- }
- }
- // Implements SmartClipProvider
- @Override
- public void extractSmartClipData(int x, int y, int width, int height) {
- recordWebViewApiCall(ApiCall.EXTRACT_SMART_CLIP_DATA);
- checkThread();
- mAwContents.extractSmartClipData(x, y, width, height);
- }
- // Implements SmartClipProvider
- @Override
- public void setSmartClipResultHandler(final Handler resultHandler) {
- recordWebViewApiCall(ApiCall.SET_SMART_CLIP_RESULT_HANDLER);
- checkThread();
- mAwContents.setSmartClipResultHandler(resultHandler);
- }
- SharedWebViewChromium getSharedWebViewChromium() {
- return mSharedWebViewChromium;
- }
- }
|