WebViewChromium.java 92 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. package com.android.webview.chromium;
  5. import android.annotation.SuppressLint;
  6. import android.content.Context;
  7. import android.content.Intent;
  8. import android.content.res.Configuration;
  9. import android.graphics.Bitmap;
  10. import android.graphics.Canvas;
  11. import android.graphics.Paint;
  12. import android.graphics.Picture;
  13. import android.graphics.Rect;
  14. import android.graphics.drawable.Drawable;
  15. import android.net.Uri;
  16. import android.net.http.SslCertificate;
  17. import android.os.Build;
  18. import android.os.Bundle;
  19. import android.os.Handler;
  20. import android.os.Message;
  21. import android.os.SystemClock;
  22. import android.print.PrintDocumentAdapter;
  23. import android.util.Log;
  24. import android.util.SparseArray;
  25. import android.view.DragEvent;
  26. import android.view.KeyEvent;
  27. import android.view.MotionEvent;
  28. import android.view.View;
  29. import android.view.ViewGroup;
  30. import android.view.ViewStructure;
  31. import android.view.accessibility.AccessibilityEvent;
  32. import android.view.accessibility.AccessibilityNodeInfo;
  33. import android.view.accessibility.AccessibilityNodeProvider;
  34. import android.view.autofill.AutofillValue;
  35. import android.view.inputmethod.EditorInfo;
  36. import android.view.inputmethod.InputConnection;
  37. import android.view.textclassifier.TextClassifier;
  38. import android.webkit.DownloadListener;
  39. import android.webkit.FindActionModeCallback;
  40. import android.webkit.ValueCallback;
  41. import android.webkit.WebBackForwardList;
  42. import android.webkit.WebChromeClient;
  43. import android.webkit.WebChromeClient.CustomViewCallback;
  44. import android.webkit.WebMessage;
  45. import android.webkit.WebMessagePort;
  46. import android.webkit.WebSettings;
  47. import android.webkit.WebView;
  48. import android.webkit.WebView.VisualStateCallback;
  49. import android.webkit.WebViewClient;
  50. import android.webkit.WebViewProvider;
  51. import android.webkit.WebViewRenderProcess;
  52. import android.webkit.WebViewRenderProcessClient;
  53. import android.widget.TextView;
  54. import androidx.annotation.IntDef;
  55. import androidx.annotation.RequiresApi;
  56. import org.chromium.android_webview.AwContents;
  57. import org.chromium.android_webview.AwContentsStatics;
  58. import org.chromium.android_webview.AwPrintDocumentAdapter;
  59. import org.chromium.android_webview.AwSettings;
  60. import org.chromium.android_webview.AwThreadUtils;
  61. import org.chromium.android_webview.gfx.AwDrawFnImpl;
  62. import org.chromium.android_webview.renderer_priority.RendererPriority;
  63. import org.chromium.base.ThreadUtils;
  64. import org.chromium.base.metrics.RecordHistogram;
  65. import org.chromium.base.metrics.ScopedSysTraceEvent;
  66. import org.chromium.components.content_capture.ContentCaptureFeatures;
  67. import org.chromium.components.content_capture.OnscreenContentProvider;
  68. import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory;
  69. import org.chromium.content_public.browser.MessagePayload;
  70. import org.chromium.content_public.browser.NavigationHistory;
  71. import org.chromium.content_public.browser.SmartClipProvider;
  72. import org.chromium.url.GURL;
  73. import java.io.BufferedWriter;
  74. import java.io.File;
  75. import java.lang.reflect.Field;
  76. import java.lang.reflect.Method;
  77. import java.util.Map;
  78. import java.util.concurrent.Callable;
  79. import java.util.concurrent.Executor;
  80. /**
  81. * This class is the delegate to which WebViewProxy forwards all API calls.
  82. *
  83. * Most of the actual functionality is implemented by AwContents (or WebContents within
  84. * it). This class also contains WebView-specific APIs that require the creation of other
  85. * adapters (otherwise org.chromium.content would depend on the webview.chromium package)
  86. * and a small set of no-op deprecated APIs.
  87. */
  88. @SuppressWarnings("deprecation")
  89. class WebViewChromium implements WebViewProvider, WebViewProvider.ScrollDelegate,
  90. WebViewProvider.ViewDelegate, SmartClipProvider {
  91. private static final String TAG = WebViewChromium.class.getSimpleName();
  92. // The WebView that this WebViewChromium is the provider for.
  93. WebView mWebView;
  94. // Lets us access protected View-derived methods on the WebView instance we're backing.
  95. WebView.PrivateAccess mWebViewPrivate;
  96. // The client adapter class.
  97. private WebViewContentsClientAdapter mContentsClientAdapter;
  98. // The wrapped Context.
  99. private Context mContext;
  100. // Variables for functionality provided by this adapter ---------------------------------------
  101. private ContentSettingsAdapter mWebSettings;
  102. // The WebView wrapper for WebContents and required browser components.
  103. AwContents mAwContents;
  104. private final WebView.HitTestResult mHitTestResult;
  105. private final int mAppTargetSdkVersion;
  106. protected WebViewChromiumFactoryProvider mFactory;
  107. protected final SharedWebViewChromium mSharedWebViewChromium;
  108. private final boolean mShouldDisableThreadChecking;
  109. private static boolean sRecordWholeDocumentEnabledByApi;
  110. static void enableSlowWholeDocumentDraw() {
  111. sRecordWholeDocumentEnabledByApi = true;
  112. }
  113. // Used to record the UMA histogram WebView.WebViewApiCall. Since these values are persisted to
  114. // logs, they should never be renumbered or reused.
  115. @IntDef({ApiCall.ADD_JAVASCRIPT_INTERFACE, ApiCall.AUTOFILL, ApiCall.CAN_GO_BACK,
  116. ApiCall.CAN_GO_BACK_OR_FORWARD, ApiCall.CAN_GO_FORWARD, ApiCall.CAN_ZOOM_IN,
  117. ApiCall.CAN_ZOOM_OUT, ApiCall.CAPTURE_PICTURE, ApiCall.CLEAR_CACHE,
  118. ApiCall.CLEAR_FORM_DATA, ApiCall.CLEAR_HISTORY, ApiCall.CLEAR_MATCHES,
  119. ApiCall.CLEAR_SSL_PREFERENCES, ApiCall.CLEAR_VIEW, ApiCall.COPY_BACK_FORWARD_LIST,
  120. ApiCall.CREATE_PRINT_DOCUMENT_ADAPTER, ApiCall.CREATE_WEBMESSAGE_CHANNEL,
  121. ApiCall.DOCUMENT_HAS_IMAGES, ApiCall.DOES_SUPPORT_FULLSCREEN,
  122. ApiCall.EVALUATE_JAVASCRIPT, ApiCall.EXTRACT_SMART_CLIP_DATA, ApiCall.FIND_NEXT,
  123. ApiCall.GET_CERTIFICATE, ApiCall.GET_CONTENT_HEIGHT, ApiCall.GET_CONTENT_WIDTH,
  124. ApiCall.GET_FAVICON, ApiCall.GET_HIT_TEST_RESULT,
  125. ApiCall.GET_HTTP_AUTH_USERNAME_PASSWORD, ApiCall.GET_ORIGINAL_URL, ApiCall.GET_PROGRESS,
  126. ApiCall.GET_SCALE, ApiCall.GET_SETTINGS, ApiCall.GET_TEXT_CLASSIFIER, ApiCall.GET_TITLE,
  127. ApiCall.GET_URL, ApiCall.GET_WEBCHROME_CLIENT, ApiCall.GET_WEBVIEW_CLIENT,
  128. ApiCall.GO_BACK, ApiCall.GO_BACK_OR_FORWARD, ApiCall.GO_FORWARD,
  129. ApiCall.INSERT_VISUAL_STATE_CALLBACK, ApiCall.INVOKE_ZOOM_PICKER, ApiCall.IS_PAUSED,
  130. ApiCall.IS_PRIVATE_BROWSING_ENABLED, ApiCall.LOAD_DATA, ApiCall.LOAD_DATA_WITH_BASE_URL,
  131. ApiCall.NOTIFY_FIND_DIALOG_DISMISSED, ApiCall.ON_PAUSE,
  132. ApiCall.ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE, ApiCall.ON_RESUME,
  133. ApiCall.OVERLAY_HORIZONTAL_SCROLLBAR, ApiCall.OVERLAY_VERTICAL_SCROLLBAR,
  134. ApiCall.PAGE_DOWN, ApiCall.PAGE_UP, ApiCall.PAUSE_TIMERS,
  135. ApiCall.POST_MESSAGE_TO_MAIN_FRAME, ApiCall.POST_URL, ApiCall.RELOAD,
  136. ApiCall.REMOVE_JAVASCRIPT_INTERFACE, ApiCall.REQUEST_FOCUS_NODE_HREF,
  137. ApiCall.REQUEST_IMAGE_REF, ApiCall.RESTORE_STATE, ApiCall.RESUME_TIMERS,
  138. ApiCall.SAVE_STATE, ApiCall.SET_DOWNLOAD_LISTENER, ApiCall.SET_FIND_LISTENER,
  139. ApiCall.SET_HORIZONTAL_SCROLLBAR_OVERLAY, ApiCall.SET_HTTP_AUTH_USERNAME_PASSWORD,
  140. ApiCall.SET_INITIAL_SCALE, ApiCall.SET_NETWORK_AVAILABLE, ApiCall.SET_PICTURE_LISTENER,
  141. ApiCall.SET_SMART_CLIP_RESULT_HANDLER, ApiCall.SET_TEXT_CLASSIFIER,
  142. ApiCall.SET_VERTICAL_SCROLLBAR_OVERLAY, ApiCall.SET_WEBCHROME_CLIENT,
  143. ApiCall.SET_WEBVIEW_CLIENT, ApiCall.SHOW_FIND_DIALOG, ApiCall.STOP_LOADING})
  144. @interface ApiCall {
  145. int ADD_JAVASCRIPT_INTERFACE = 0;
  146. int AUTOFILL = 1;
  147. int CAN_GO_BACK = 2;
  148. int CAN_GO_BACK_OR_FORWARD = 3;
  149. int CAN_GO_FORWARD = 4;
  150. int CAN_ZOOM_IN = 5;
  151. int CAN_ZOOM_OUT = 6;
  152. int CAPTURE_PICTURE = 7;
  153. int CLEAR_CACHE = 8;
  154. int CLEAR_FORM_DATA = 9;
  155. int CLEAR_HISTORY = 10;
  156. int CLEAR_MATCHES = 11;
  157. int CLEAR_SSL_PREFERENCES = 12;
  158. int CLEAR_VIEW = 13;
  159. int COPY_BACK_FORWARD_LIST = 14;
  160. int CREATE_PRINT_DOCUMENT_ADAPTER = 15;
  161. int CREATE_WEBMESSAGE_CHANNEL = 16;
  162. int DOCUMENT_HAS_IMAGES = 17;
  163. int DOES_SUPPORT_FULLSCREEN = 18;
  164. int EVALUATE_JAVASCRIPT = 19;
  165. int EXTRACT_SMART_CLIP_DATA = 20;
  166. int FIND_NEXT = 21;
  167. int GET_CERTIFICATE = 22;
  168. int GET_CONTENT_HEIGHT = 23;
  169. int GET_CONTENT_WIDTH = 24;
  170. int GET_FAVICON = 25;
  171. int GET_HIT_TEST_RESULT = 26;
  172. int GET_HTTP_AUTH_USERNAME_PASSWORD = 27;
  173. int GET_ORIGINAL_URL = 28;
  174. int GET_PROGRESS = 29;
  175. int GET_SCALE = 30;
  176. int GET_SETTINGS = 31;
  177. int GET_TEXT_CLASSIFIER = 32;
  178. int GET_TITLE = 33;
  179. int GET_URL = 34;
  180. int GET_WEBCHROME_CLIENT = 35;
  181. int GET_WEBVIEW_CLIENT = 36;
  182. int GO_BACK = 37;
  183. int GO_BACK_OR_FORWARD = 38;
  184. int GO_FORWARD = 39;
  185. int INSERT_VISUAL_STATE_CALLBACK = 40;
  186. int INVOKE_ZOOM_PICKER = 41;
  187. int IS_PAUSED = 42;
  188. int IS_PRIVATE_BROWSING_ENABLED = 43;
  189. int LOAD_DATA = 44;
  190. int LOAD_DATA_WITH_BASE_URL = 45;
  191. int NOTIFY_FIND_DIALOG_DISMISSED = 46;
  192. int ON_PAUSE = 47;
  193. int ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE = 48;
  194. int ON_RESUME = 49;
  195. int OVERLAY_HORIZONTAL_SCROLLBAR = 50;
  196. int OVERLAY_VERTICAL_SCROLLBAR = 51;
  197. int PAGE_DOWN = 52;
  198. int PAGE_UP = 53;
  199. int PAUSE_TIMERS = 54;
  200. int POST_MESSAGE_TO_MAIN_FRAME = 55;
  201. int POST_URL = 56;
  202. int RELOAD = 57;
  203. int REMOVE_JAVASCRIPT_INTERFACE = 58;
  204. int REQUEST_FOCUS_NODE_HREF = 59;
  205. int REQUEST_IMAGE_REF = 60;
  206. int RESTORE_STATE = 61;
  207. int RESUME_TIMERS = 62;
  208. int SAVE_STATE = 63;
  209. int SET_DOWNLOAD_LISTENER = 64;
  210. int SET_FIND_LISTENER = 65;
  211. int SET_HORIZONTAL_SCROLLBAR_OVERLAY = 66;
  212. int SET_HTTP_AUTH_USERNAME_PASSWORD = 67;
  213. int SET_INITIAL_SCALE = 68;
  214. int SET_NETWORK_AVAILABLE = 69;
  215. int SET_PICTURE_LISTENER = 70;
  216. int SET_SMART_CLIP_RESULT_HANDLER = 71;
  217. int SET_TEXT_CLASSIFIER = 72;
  218. int SET_VERTICAL_SCROLLBAR_OVERLAY = 73;
  219. int SET_WEBCHROME_CLIENT = 74;
  220. int SET_WEBVIEW_CLIENT = 75;
  221. int SHOW_FIND_DIALOG = 76;
  222. int STOP_LOADING = 77;
  223. int COUNT = 78;
  224. }
  225. private static void recordWebViewApiCall(@ApiCall int sample) {
  226. RecordHistogram.recordEnumeratedHistogram("Android.WebView.ApiCall", sample, ApiCall.COUNT);
  227. }
  228. // This does not touch any global / non-threadsafe state, but note that
  229. // init is ofter called right after and is NOT threadsafe.
  230. public WebViewChromium(WebViewChromiumFactoryProvider factory, WebView webView,
  231. WebView.PrivateAccess webViewPrivate, boolean shouldDisableThreadChecking) {
  232. try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.constructor")) {
  233. WebViewChromiumFactoryProvider.checkStorageIsNotDeviceProtected(webView.getContext());
  234. mWebView = webView;
  235. mWebViewPrivate = webViewPrivate;
  236. mHitTestResult = new WebView.HitTestResult();
  237. mContext = ClassLoaderContextWrapperFactory.get(mWebView.getContext());
  238. mAppTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
  239. mFactory = factory;
  240. mShouldDisableThreadChecking = shouldDisableThreadChecking;
  241. factory.addWebViewAssetPath(mWebView.getContext());
  242. mSharedWebViewChromium =
  243. new SharedWebViewChromium(mFactory.getRunQueue(), mFactory.getAwInit());
  244. }
  245. }
  246. // See //android_webview/docs/how-does-on-create-window-work.md for more details.
  247. static void completeWindowCreation(WebView parent, WebView child) {
  248. AwContents parentContents = ((WebViewChromium) parent.getWebViewProvider()).mAwContents;
  249. AwContents childContents =
  250. child == null ? null : ((WebViewChromium) child.getWebViewProvider()).mAwContents;
  251. parentContents.supplyContentsForPopup(childContents);
  252. }
  253. // WebViewProvider methods --------------------------------------------------------------------
  254. @Override
  255. // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete DumpRenderTree
  256. // so is ignored. TODO: remove it from WebViewProvider.
  257. public void init(final Map<String, Object> javaScriptInterfaces,
  258. final boolean privateBrowsing) {
  259. long startTime = SystemClock.uptimeMillis();
  260. boolean isFirstWebViewInit = !mFactory.hasStarted();
  261. try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.init")) {
  262. if (privateBrowsing) {
  263. mFactory.startYourEngines(true);
  264. final String msg = "Private browsing is not supported in WebView.";
  265. if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) {
  266. throw new IllegalArgumentException(msg);
  267. } else {
  268. Log.w(TAG, msg);
  269. TextView warningLabel = new TextView(mContext);
  270. warningLabel.setText(mContext.getString(
  271. org.chromium.android_webview.R.string.private_browsing_warning));
  272. mWebView.addView(warningLabel);
  273. }
  274. }
  275. if (mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
  276. // If the app targets >= JB MR2 then we require that WebView is only used from a
  277. // single thread. So, we:
  278. // 1) start Chromium using the current thread as the UI thread (this is a no-op if
  279. // it was already started).
  280. mFactory.startYourEngines(false);
  281. // 2) check that the current thread is the UI thread, which will throw if it was
  282. // already started using a different thread as the UI thread.
  283. checkThread();
  284. } else {
  285. // For older apps, only the view methods that relate to the view hierarchy must come
  286. // from a single thread. Other calls, including the constructor itself, can come
  287. // from any thread, and will be posted to the UI thread if necessary.
  288. //
  289. // We used to defer the decision about which thread is the UI thread for as long as
  290. // possible to allow for the case where an app targeting < JB MR2 used a different
  291. // thread, but this significantly complicated initialization and is virtually never
  292. // encountered in the wild. We can't just use the current thread as the UI thread as
  293. // the normal case does, because it *is* somewhat common for old apps to construct
  294. // WebView on a background thread and then attach it to the view hierarchy on the
  295. // main looper.
  296. //
  297. // So, we just start Chromium using the main looper as the UI thread, which works
  298. // for virtually every old app, and accept that a very tiny number of them will
  299. // break.
  300. mFactory.startYourEngines(true);
  301. }
  302. final boolean isAccessFromFileURLsGrantedByDefault =
  303. mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN;
  304. final boolean areLegacyQuirksEnabled =
  305. mAppTargetSdkVersion < Build.VERSION_CODES.KITKAT;
  306. final boolean allowEmptyDocumentPersistence =
  307. mAppTargetSdkVersion <= Build.VERSION_CODES.M;
  308. final boolean allowGeolocationOnInsecureOrigins =
  309. mAppTargetSdkVersion <= Build.VERSION_CODES.M;
  310. // https://crbug.com/698752
  311. final boolean doNotUpdateSelectionOnMutatingSelectionRange =
  312. mAppTargetSdkVersion <= Build.VERSION_CODES.M;
  313. mContentsClientAdapter =
  314. mFactory.createWebViewContentsClientAdapter(mWebView, mContext);
  315. try (ScopedSysTraceEvent e2 =
  316. ScopedSysTraceEvent.scoped("WebViewChromium.ContentSettingsAdapter")) {
  317. mWebSettings = mFactory.createContentSettingsAdapter(new AwSettings(mContext,
  318. isAccessFromFileURLsGrantedByDefault, areLegacyQuirksEnabled,
  319. allowEmptyDocumentPersistence, allowGeolocationOnInsecureOrigins,
  320. doNotUpdateSelectionOnMutatingSelectionRange));
  321. }
  322. if (mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
  323. // Prior to Lollipop we always allowed third party cookies and mixed content.
  324. mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
  325. mWebSettings.setAcceptThirdPartyCookies(true);
  326. mWebSettings.getAwSettings().setZeroLayoutHeightDisablesViewportQuirk(true);
  327. }
  328. if (mAppTargetSdkVersion >= Build.VERSION_CODES.P) {
  329. mWebSettings.getAwSettings().setCSSHexAlphaColorEnabled(true);
  330. mWebSettings.getAwSettings().setScrollTopLeftInteropEnabled(true);
  331. }
  332. if (mShouldDisableThreadChecking) disableThreadChecking();
  333. mSharedWebViewChromium.init(mContentsClientAdapter);
  334. mFactory.addTask(new Runnable() {
  335. @Override
  336. public void run() {
  337. initForReal();
  338. if (privateBrowsing) {
  339. // Intentionally irreversibly disable the webview instance, so that private
  340. // user data cannot leak through misuse of a non-private-browsing WebView
  341. // instance. Can't just null out mAwContents as we never null-check it
  342. // before use.
  343. destroy();
  344. }
  345. }
  346. });
  347. }
  348. // If initialization hasn't been deferred, record a startup time histogram entry.
  349. if (mFactory.hasStarted()) {
  350. if (isFirstWebViewInit) {
  351. RecordHistogram.recordTimesHistogram(
  352. "Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Cold",
  353. SystemClock.uptimeMillis() - startTime);
  354. } else {
  355. RecordHistogram.recordTimesHistogram(
  356. "Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Warm",
  357. SystemClock.uptimeMillis() - startTime);
  358. }
  359. }
  360. }
  361. // This is a workaround for https://crbug.com/622151.
  362. // In HTC's email app, InputConnection.setComposingText() will call WebView.evaluateJavaScript,
  363. // and thread assertion will occur. We turn off WebView thread assertion for this app.
  364. // SuppressLint rationale: https://crrev.com/c/3439168/comments/d612ae09_b7bfca2b
  365. @SuppressLint("SoonBlockedPrivateApi")
  366. private void disableThreadChecking() {
  367. try {
  368. Class<?> webViewClass = Class.forName("android.webkit.WebView");
  369. Field field = webViewClass.getDeclaredField("sEnforceThreadChecking");
  370. field.setAccessible(true);
  371. field.setBoolean(null, false);
  372. field.setAccessible(false);
  373. } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException
  374. | IllegalArgumentException e) {
  375. Log.w(TAG, "Failed to disable thread checking.");
  376. }
  377. }
  378. private void initForReal() {
  379. try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("WebViewChromium.initForReal")) {
  380. AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi
  381. || mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP);
  382. mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWebView, mContext,
  383. new InternalAccessAdapter(), new WebViewNativeDrawFunctorFactory(),
  384. mContentsClientAdapter, mWebSettings.getAwSettings(),
  385. new AwContents.DependencyFactory());
  386. if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) {
  387. // On KK and above, favicons are automatically downloaded as the method
  388. // old apps use to enable that behavior is deprecated.
  389. AwContents.setShouldDownloadFavicons();
  390. }
  391. if (mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
  392. // Prior to Lollipop, JavaScript objects injected via addJavascriptInterface
  393. // were not inspectable.
  394. mAwContents.disableJavascriptInterfacesInspection();
  395. }
  396. // TODO: This assumes AwContents ignores second Paint param.
  397. mAwContents.setLayerType(mWebView.getLayerType(), null);
  398. mSharedWebViewChromium.initForReal(mAwContents);
  399. }
  400. }
  401. private RuntimeException createThreadException() {
  402. return new IllegalStateException(
  403. "Calling View methods on another thread than the UI thread.");
  404. }
  405. protected boolean checkNeedsPost() {
  406. return mSharedWebViewChromium.checkNeedsPost();
  407. }
  408. // Intentionally not static, as no need to check thread on static methods
  409. private void checkThread() {
  410. if (!ThreadUtils.runningOnUiThread()) {
  411. final RuntimeException threadViolation = createThreadException();
  412. AwThreadUtils.postToUiThreadLooper(() -> { throw threadViolation; });
  413. throw createThreadException();
  414. }
  415. }
  416. @Override
  417. public void setHorizontalScrollbarOverlay(final boolean overlay) {
  418. if (checkNeedsPost()) {
  419. mFactory.addTask(new Runnable() {
  420. @Override
  421. public void run() {
  422. setHorizontalScrollbarOverlay(overlay);
  423. }
  424. });
  425. return;
  426. }
  427. recordWebViewApiCall(ApiCall.SET_HORIZONTAL_SCROLLBAR_OVERLAY);
  428. mAwContents.setHorizontalScrollbarOverlay(overlay);
  429. }
  430. @Override
  431. public void setVerticalScrollbarOverlay(final boolean overlay) {
  432. if (checkNeedsPost()) {
  433. mFactory.addTask(new Runnable() {
  434. @Override
  435. public void run() {
  436. setVerticalScrollbarOverlay(overlay);
  437. }
  438. });
  439. return;
  440. }
  441. recordWebViewApiCall(ApiCall.SET_VERTICAL_SCROLLBAR_OVERLAY);
  442. mAwContents.setVerticalScrollbarOverlay(overlay);
  443. }
  444. @Override
  445. public boolean overlayHorizontalScrollbar() {
  446. mFactory.startYourEngines(false);
  447. if (checkNeedsPost()) {
  448. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  449. @Override
  450. public Boolean call() {
  451. return overlayHorizontalScrollbar();
  452. }
  453. });
  454. return ret;
  455. }
  456. recordWebViewApiCall(ApiCall.OVERLAY_HORIZONTAL_SCROLLBAR);
  457. return mAwContents.overlayHorizontalScrollbar();
  458. }
  459. @Override
  460. public boolean overlayVerticalScrollbar() {
  461. mFactory.startYourEngines(false);
  462. if (checkNeedsPost()) {
  463. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  464. @Override
  465. public Boolean call() {
  466. return overlayVerticalScrollbar();
  467. }
  468. });
  469. return ret;
  470. }
  471. recordWebViewApiCall(ApiCall.OVERLAY_VERTICAL_SCROLLBAR);
  472. return mAwContents.overlayVerticalScrollbar();
  473. }
  474. @Override
  475. public int getVisibleTitleHeight() {
  476. // This is deprecated in WebView and should always return 0.
  477. return 0;
  478. }
  479. @Override
  480. public SslCertificate getCertificate() {
  481. mFactory.startYourEngines(true);
  482. if (checkNeedsPost()) {
  483. SslCertificate ret = mFactory.runOnUiThreadBlocking(new Callable<SslCertificate>() {
  484. @Override
  485. public SslCertificate call() {
  486. return getCertificate();
  487. }
  488. });
  489. return ret;
  490. }
  491. recordWebViewApiCall(ApiCall.GET_CERTIFICATE);
  492. return mAwContents.getCertificate();
  493. }
  494. @Override
  495. public void setCertificate(SslCertificate certificate) {
  496. // intentional no-op
  497. }
  498. @Override
  499. public void savePassword(String host, String username, String password) {
  500. // This is a deprecated API: intentional no-op.
  501. }
  502. @Override
  503. public void setHttpAuthUsernamePassword(
  504. final String host, final String realm, final String username, final String password) {
  505. if (checkNeedsPost()) {
  506. mFactory.addTask(new Runnable() {
  507. @Override
  508. public void run() {
  509. setHttpAuthUsernamePassword(host, realm, username, password);
  510. }
  511. });
  512. return;
  513. }
  514. recordWebViewApiCall(ApiCall.SET_HTTP_AUTH_USERNAME_PASSWORD);
  515. ((WebViewDatabaseAdapter) mFactory.getWebViewDatabase(mContext))
  516. .setHttpAuthUsernamePassword(host, realm, username, password);
  517. }
  518. @Override
  519. public String[] getHttpAuthUsernamePassword(final String host, final String realm) {
  520. mFactory.startYourEngines(true);
  521. if (checkNeedsPost()) {
  522. String[] ret = mFactory.runOnUiThreadBlocking(new Callable<String[]>() {
  523. @Override
  524. public String[] call() {
  525. return getHttpAuthUsernamePassword(host, realm);
  526. }
  527. });
  528. return ret;
  529. }
  530. recordWebViewApiCall(ApiCall.GET_HTTP_AUTH_USERNAME_PASSWORD);
  531. return ((WebViewDatabaseAdapter) mFactory.getWebViewDatabase(mContext))
  532. .getHttpAuthUsernamePassword(host, realm);
  533. }
  534. @Override
  535. public void destroy() {
  536. if (checkNeedsPost()) {
  537. mFactory.addTask(new Runnable() {
  538. @Override
  539. public void run() {
  540. destroy();
  541. }
  542. });
  543. return;
  544. }
  545. // Make sure that we do not trigger any callbacks after destruction
  546. setWebChromeClient(null);
  547. setWebViewClient(null);
  548. mContentsClientAdapter.setPictureListener(null, true);
  549. mContentsClientAdapter.setFindListener(null);
  550. mContentsClientAdapter.setDownloadListener(null);
  551. mAwContents.destroy();
  552. }
  553. @Override
  554. public void setNetworkAvailable(final boolean networkUp) {
  555. // Note that this purely toggles the JS navigator.online property.
  556. // It does not in affect chromium or network stack state in any way.
  557. if (checkNeedsPost()) {
  558. mFactory.addTask(new Runnable() {
  559. @Override
  560. public void run() {
  561. setNetworkAvailable(networkUp);
  562. }
  563. });
  564. return;
  565. }
  566. recordWebViewApiCall(ApiCall.SET_NETWORK_AVAILABLE);
  567. mAwContents.setNetworkAvailable(networkUp);
  568. }
  569. @Override
  570. public WebBackForwardList saveState(final Bundle outState) {
  571. mFactory.startYourEngines(true);
  572. if (checkNeedsPost()) {
  573. WebBackForwardList ret =
  574. mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
  575. @Override
  576. public WebBackForwardList call() {
  577. return saveState(outState);
  578. }
  579. });
  580. return ret;
  581. }
  582. recordWebViewApiCall(ApiCall.SAVE_STATE);
  583. if (outState == null) return null;
  584. if (!mAwContents.saveState(outState)) return null;
  585. return copyBackForwardList();
  586. }
  587. @Override
  588. public boolean savePicture(Bundle b, File dest) {
  589. // Intentional no-op: hidden method on WebView.
  590. return false;
  591. }
  592. @Override
  593. public boolean restorePicture(Bundle b, File src) {
  594. // Intentional no-op: hidden method on WebView.
  595. return false;
  596. }
  597. @Override
  598. public WebBackForwardList restoreState(final Bundle inState) {
  599. mFactory.startYourEngines(true);
  600. if (checkNeedsPost()) {
  601. WebBackForwardList ret =
  602. mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
  603. @Override
  604. public WebBackForwardList call() {
  605. return restoreState(inState);
  606. }
  607. });
  608. return ret;
  609. }
  610. recordWebViewApiCall(ApiCall.RESTORE_STATE);
  611. if (inState == null) return null;
  612. if (!mAwContents.restoreState(inState)) return null;
  613. return copyBackForwardList();
  614. }
  615. @Override
  616. public void loadUrl(final String url, final Map<String, String> additionalHttpHeaders) {
  617. mFactory.startYourEngines(true);
  618. if (checkNeedsPost()) {
  619. // Disallowed in WebView API for apps targeting a new SDK
  620. assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
  621. mFactory.addTask(new Runnable() {
  622. @Override
  623. public void run() {
  624. mAwContents.loadUrl(url, additionalHttpHeaders);
  625. }
  626. });
  627. return;
  628. }
  629. mAwContents.loadUrl(url, additionalHttpHeaders);
  630. }
  631. @Override
  632. public void loadUrl(final String url) {
  633. mFactory.startYourEngines(true);
  634. if (checkNeedsPost()) {
  635. // Disallowed in WebView API for apps targeting a new SDK
  636. assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
  637. mFactory.addTask(new Runnable() {
  638. @Override
  639. public void run() {
  640. mAwContents.loadUrl(url);
  641. }
  642. });
  643. return;
  644. }
  645. mAwContents.loadUrl(url);
  646. }
  647. @Override
  648. public void postUrl(final String url, final byte[] postData) {
  649. mFactory.startYourEngines(true);
  650. if (checkNeedsPost()) {
  651. // Disallowed in WebView API for apps targeting a new SDK
  652. assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
  653. mFactory.addTask(new Runnable() {
  654. @Override
  655. public void run() {
  656. recordWebViewApiCall(ApiCall.POST_URL);
  657. mAwContents.postUrl(url, postData);
  658. }
  659. });
  660. return;
  661. }
  662. recordWebViewApiCall(ApiCall.POST_URL);
  663. mAwContents.postUrl(url, postData);
  664. }
  665. @Override
  666. public void loadData(final String data, final String mimeType, final String encoding) {
  667. mFactory.startYourEngines(true);
  668. if (checkNeedsPost()) {
  669. // Disallowed in WebView API for apps targeting a new SDK
  670. assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
  671. mFactory.addTask(new Runnable() {
  672. @Override
  673. public void run() {
  674. recordWebViewApiCall(ApiCall.LOAD_DATA);
  675. mAwContents.loadData(data, mimeType, encoding);
  676. }
  677. });
  678. return;
  679. }
  680. recordWebViewApiCall(ApiCall.LOAD_DATA);
  681. mAwContents.loadData(data, mimeType, encoding);
  682. }
  683. @Override
  684. public void loadDataWithBaseURL(final String baseUrl, final String data, final String mimeType,
  685. final String encoding, final String historyUrl) {
  686. mFactory.startYourEngines(true);
  687. if (checkNeedsPost()) {
  688. // Disallowed in WebView API for apps targeting a new SDK
  689. assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
  690. mFactory.addTask(new Runnable() {
  691. @Override
  692. public void run() {
  693. recordWebViewApiCall(ApiCall.LOAD_DATA_WITH_BASE_URL);
  694. mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
  695. }
  696. });
  697. return;
  698. }
  699. recordWebViewApiCall(ApiCall.LOAD_DATA_WITH_BASE_URL);
  700. mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
  701. }
  702. @Override
  703. public void evaluateJavaScript(
  704. final String script, final ValueCallback<String> resultCallback) {
  705. if (mShouldDisableThreadChecking && checkNeedsPost()) {
  706. // This is a workaround for https://crbug.com/622151.
  707. mFactory.addTask(new Runnable() {
  708. @Override
  709. public void run() {
  710. recordWebViewApiCall(ApiCall.EVALUATE_JAVASCRIPT);
  711. mAwContents.evaluateJavaScript(
  712. script, CallbackConverter.fromValueCallback(resultCallback));
  713. }
  714. });
  715. } else {
  716. recordWebViewApiCall(ApiCall.EVALUATE_JAVASCRIPT);
  717. checkThread();
  718. mAwContents.evaluateJavaScript(
  719. script, CallbackConverter.fromValueCallback(resultCallback));
  720. }
  721. }
  722. @Override
  723. public void saveWebArchive(String filename) {
  724. saveWebArchive(filename, false, null);
  725. }
  726. @Override
  727. public void saveWebArchive(final String basename, final boolean autoname,
  728. final ValueCallback<String> callback) {
  729. if (checkNeedsPost()) {
  730. mFactory.addTask(new Runnable() {
  731. @Override
  732. public void run() {
  733. saveWebArchive(basename, autoname, callback);
  734. }
  735. });
  736. return;
  737. }
  738. mAwContents.saveWebArchive(
  739. basename, autoname, CallbackConverter.fromValueCallback(callback));
  740. }
  741. @Override
  742. public void stopLoading() {
  743. if (checkNeedsPost()) {
  744. mFactory.addTask(new Runnable() {
  745. @Override
  746. public void run() {
  747. stopLoading();
  748. }
  749. });
  750. return;
  751. }
  752. recordWebViewApiCall(ApiCall.STOP_LOADING);
  753. mAwContents.stopLoading();
  754. }
  755. @Override
  756. public void reload() {
  757. if (checkNeedsPost()) {
  758. mFactory.addTask(new Runnable() {
  759. @Override
  760. public void run() {
  761. reload();
  762. }
  763. });
  764. return;
  765. }
  766. recordWebViewApiCall(ApiCall.RELOAD);
  767. mAwContents.reload();
  768. }
  769. @Override
  770. public boolean canGoBack() {
  771. mFactory.startYourEngines(true);
  772. if (checkNeedsPost()) {
  773. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  774. @Override
  775. public Boolean call() {
  776. return canGoBack();
  777. }
  778. });
  779. return ret;
  780. }
  781. recordWebViewApiCall(ApiCall.CAN_GO_BACK);
  782. return mAwContents.canGoBack();
  783. }
  784. @Override
  785. public void goBack() {
  786. if (checkNeedsPost()) {
  787. mFactory.addTask(new Runnable() {
  788. @Override
  789. public void run() {
  790. goBack();
  791. }
  792. });
  793. return;
  794. }
  795. recordWebViewApiCall(ApiCall.GO_BACK);
  796. mAwContents.goBack();
  797. }
  798. @Override
  799. public boolean canGoForward() {
  800. mFactory.startYourEngines(true);
  801. if (checkNeedsPost()) {
  802. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  803. @Override
  804. public Boolean call() {
  805. return canGoForward();
  806. }
  807. });
  808. return ret;
  809. }
  810. recordWebViewApiCall(ApiCall.CAN_GO_FORWARD);
  811. return mAwContents.canGoForward();
  812. }
  813. @Override
  814. public void goForward() {
  815. if (checkNeedsPost()) {
  816. mFactory.addTask(new Runnable() {
  817. @Override
  818. public void run() {
  819. goForward();
  820. }
  821. });
  822. return;
  823. }
  824. recordWebViewApiCall(ApiCall.GO_FORWARD);
  825. mAwContents.goForward();
  826. }
  827. @Override
  828. public boolean canGoBackOrForward(final int steps) {
  829. mFactory.startYourEngines(true);
  830. if (checkNeedsPost()) {
  831. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  832. @Override
  833. public Boolean call() {
  834. return canGoBackOrForward(steps);
  835. }
  836. });
  837. return ret;
  838. }
  839. recordWebViewApiCall(ApiCall.CAN_GO_BACK_OR_FORWARD);
  840. return mAwContents.canGoBackOrForward(steps);
  841. }
  842. @Override
  843. public void goBackOrForward(final int steps) {
  844. if (checkNeedsPost()) {
  845. mFactory.addTask(new Runnable() {
  846. @Override
  847. public void run() {
  848. goBackOrForward(steps);
  849. }
  850. });
  851. return;
  852. }
  853. recordWebViewApiCall(ApiCall.GO_BACK_OR_FORWARD);
  854. mAwContents.goBackOrForward(steps);
  855. }
  856. @Override
  857. public boolean isPrivateBrowsingEnabled() {
  858. // Not supported in this WebView implementation.
  859. recordWebViewApiCall(ApiCall.IS_PRIVATE_BROWSING_ENABLED);
  860. return false;
  861. }
  862. @Override
  863. public boolean pageUp(final boolean top) {
  864. mFactory.startYourEngines(true);
  865. if (checkNeedsPost()) {
  866. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  867. @Override
  868. public Boolean call() {
  869. return pageUp(top);
  870. }
  871. });
  872. return ret;
  873. }
  874. recordWebViewApiCall(ApiCall.PAGE_UP);
  875. return mAwContents.pageUp(top);
  876. }
  877. @Override
  878. public boolean pageDown(final boolean bottom) {
  879. mFactory.startYourEngines(true);
  880. if (checkNeedsPost()) {
  881. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  882. @Override
  883. public Boolean call() {
  884. return pageDown(bottom);
  885. }
  886. });
  887. return ret;
  888. }
  889. recordWebViewApiCall(ApiCall.PAGE_DOWN);
  890. return mAwContents.pageDown(bottom);
  891. }
  892. @Override
  893. public void insertVisualStateCallback(
  894. final long requestId, final VisualStateCallback callback) {
  895. recordWebViewApiCall(ApiCall.INSERT_VISUAL_STATE_CALLBACK);
  896. mSharedWebViewChromium.insertVisualStateCallback(
  897. requestId, callback == null ? null : new AwContents.VisualStateCallback() {
  898. @Override
  899. public void onComplete(long requestId) {
  900. callback.onComplete(requestId);
  901. }
  902. });
  903. }
  904. @Override
  905. public void clearView() {
  906. if (checkNeedsPost()) {
  907. mFactory.addTask(new Runnable() {
  908. @Override
  909. public void run() {
  910. clearView();
  911. }
  912. });
  913. return;
  914. }
  915. recordWebViewApiCall(ApiCall.CLEAR_VIEW);
  916. mAwContents.clearView();
  917. }
  918. @Override
  919. public Picture capturePicture() {
  920. mFactory.startYourEngines(true);
  921. if (checkNeedsPost()) {
  922. Picture ret = mFactory.runOnUiThreadBlocking(new Callable<Picture>() {
  923. @Override
  924. public Picture call() {
  925. return capturePicture();
  926. }
  927. });
  928. return ret;
  929. }
  930. recordWebViewApiCall(ApiCall.CAPTURE_PICTURE);
  931. return mAwContents.capturePicture();
  932. }
  933. @Override
  934. public float getScale() {
  935. recordWebViewApiCall(ApiCall.GET_SCALE);
  936. // No checkThread() as it is mostly thread safe (workaround for b/10652991).
  937. mFactory.startYourEngines(true);
  938. return mAwContents.getScale();
  939. }
  940. @Override
  941. public void setInitialScale(final int scaleInPercent) {
  942. recordWebViewApiCall(ApiCall.SET_INITIAL_SCALE);
  943. // No checkThread() as it is thread safe
  944. mWebSettings.getAwSettings().setInitialPageScale(scaleInPercent);
  945. }
  946. @Override
  947. public void invokeZoomPicker() {
  948. if (checkNeedsPost()) {
  949. mFactory.addTask(new Runnable() {
  950. @Override
  951. public void run() {
  952. invokeZoomPicker();
  953. }
  954. });
  955. return;
  956. }
  957. recordWebViewApiCall(ApiCall.INVOKE_ZOOM_PICKER);
  958. mAwContents.invokeZoomPicker();
  959. }
  960. @Override
  961. public WebView.HitTestResult getHitTestResult() {
  962. mFactory.startYourEngines(true);
  963. if (checkNeedsPost()) {
  964. WebView.HitTestResult ret =
  965. mFactory.runOnUiThreadBlocking(new Callable<WebView.HitTestResult>() {
  966. @Override
  967. public WebView.HitTestResult call() {
  968. return getHitTestResult();
  969. }
  970. });
  971. return ret;
  972. }
  973. recordWebViewApiCall(ApiCall.GET_HIT_TEST_RESULT);
  974. AwContents.HitTestData data = mAwContents.getLastHitTestResult();
  975. mHitTestResult.setType(data.hitTestResultType);
  976. mHitTestResult.setExtra(data.hitTestResultExtraData);
  977. return mHitTestResult;
  978. }
  979. @Override
  980. public void requestFocusNodeHref(final Message hrefMsg) {
  981. if (checkNeedsPost()) {
  982. mFactory.addTask(new Runnable() {
  983. @Override
  984. public void run() {
  985. requestFocusNodeHref(hrefMsg);
  986. }
  987. });
  988. return;
  989. }
  990. recordWebViewApiCall(ApiCall.REQUEST_FOCUS_NODE_HREF);
  991. mAwContents.requestFocusNodeHref(hrefMsg);
  992. }
  993. @Override
  994. public void requestImageRef(final Message msg) {
  995. if (checkNeedsPost()) {
  996. mFactory.addTask(new Runnable() {
  997. @Override
  998. public void run() {
  999. requestImageRef(msg);
  1000. }
  1001. });
  1002. return;
  1003. }
  1004. recordWebViewApiCall(ApiCall.REQUEST_IMAGE_REF);
  1005. mAwContents.requestImageRef(msg);
  1006. }
  1007. @Override
  1008. public String getUrl() {
  1009. mFactory.startYourEngines(true);
  1010. if (checkNeedsPost()) {
  1011. String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
  1012. @Override
  1013. public String call() {
  1014. return getUrl();
  1015. }
  1016. });
  1017. return ret;
  1018. }
  1019. recordWebViewApiCall(ApiCall.GET_URL);
  1020. GURL url = mAwContents.getUrl();
  1021. return url == null ? null : url.getSpec();
  1022. }
  1023. @Override
  1024. public String getOriginalUrl() {
  1025. mFactory.startYourEngines(true);
  1026. if (checkNeedsPost()) {
  1027. String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
  1028. @Override
  1029. public String call() {
  1030. return getOriginalUrl();
  1031. }
  1032. });
  1033. return ret;
  1034. }
  1035. recordWebViewApiCall(ApiCall.GET_ORIGINAL_URL);
  1036. return mAwContents.getOriginalUrl();
  1037. }
  1038. @Override
  1039. public String getTitle() {
  1040. mFactory.startYourEngines(true);
  1041. if (checkNeedsPost()) {
  1042. String ret = mFactory.runOnUiThreadBlocking(new Callable<String>() {
  1043. @Override
  1044. public String call() {
  1045. return getTitle();
  1046. }
  1047. });
  1048. return ret;
  1049. }
  1050. recordWebViewApiCall(ApiCall.GET_TITLE);
  1051. return mAwContents.getTitle();
  1052. }
  1053. @Override
  1054. public Bitmap getFavicon() {
  1055. mFactory.startYourEngines(true);
  1056. if (checkNeedsPost()) {
  1057. Bitmap ret = mFactory.runOnUiThreadBlocking(new Callable<Bitmap>() {
  1058. @Override
  1059. public Bitmap call() {
  1060. return getFavicon();
  1061. }
  1062. });
  1063. return ret;
  1064. }
  1065. recordWebViewApiCall(ApiCall.GET_FAVICON);
  1066. return mAwContents.getFavicon();
  1067. }
  1068. @Override
  1069. public String getTouchIconUrl() {
  1070. // Intentional no-op: hidden method on WebView.
  1071. return null;
  1072. }
  1073. @Override
  1074. public int getProgress() {
  1075. recordWebViewApiCall(ApiCall.GET_PROGRESS);
  1076. if (mAwContents == null) return 100;
  1077. // No checkThread() because the value is cached java side (workaround for b/10533304).
  1078. return mAwContents.getMostRecentProgress();
  1079. }
  1080. @Override
  1081. public int getContentHeight() {
  1082. recordWebViewApiCall(ApiCall.GET_CONTENT_HEIGHT);
  1083. if (mAwContents == null) return 0;
  1084. // No checkThread() as it is mostly thread safe (workaround for b/10594869).
  1085. return mAwContents.getContentHeightCss();
  1086. }
  1087. @Override
  1088. public int getContentWidth() {
  1089. recordWebViewApiCall(ApiCall.GET_CONTENT_WIDTH);
  1090. if (mAwContents == null) return 0;
  1091. // No checkThread() as it is mostly thread safe (workaround for b/10594869).
  1092. return mAwContents.getContentWidthCss();
  1093. }
  1094. @Override
  1095. public void pauseTimers() {
  1096. if (checkNeedsPost()) {
  1097. mFactory.addTask(new Runnable() {
  1098. @Override
  1099. public void run() {
  1100. pauseTimers();
  1101. }
  1102. });
  1103. return;
  1104. }
  1105. recordWebViewApiCall(ApiCall.PAUSE_TIMERS);
  1106. mAwContents.pauseTimers();
  1107. }
  1108. @Override
  1109. public void resumeTimers() {
  1110. if (checkNeedsPost()) {
  1111. mFactory.addTask(new Runnable() {
  1112. @Override
  1113. public void run() {
  1114. resumeTimers();
  1115. }
  1116. });
  1117. return;
  1118. }
  1119. recordWebViewApiCall(ApiCall.RESUME_TIMERS);
  1120. mAwContents.resumeTimers();
  1121. }
  1122. @Override
  1123. public void onPause() {
  1124. if (checkNeedsPost()) {
  1125. mFactory.addTask(new Runnable() {
  1126. @Override
  1127. public void run() {
  1128. onPause();
  1129. }
  1130. });
  1131. return;
  1132. }
  1133. recordWebViewApiCall(ApiCall.ON_PAUSE);
  1134. mAwContents.onPause();
  1135. }
  1136. @Override
  1137. public void onResume() {
  1138. if (checkNeedsPost()) {
  1139. mFactory.addTask(new Runnable() {
  1140. @Override
  1141. public void run() {
  1142. onResume();
  1143. }
  1144. });
  1145. return;
  1146. }
  1147. recordWebViewApiCall(ApiCall.ON_RESUME);
  1148. mAwContents.onResume();
  1149. }
  1150. @Override
  1151. public boolean isPaused() {
  1152. mFactory.startYourEngines(true);
  1153. if (checkNeedsPost()) {
  1154. Boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1155. @Override
  1156. public Boolean call() {
  1157. return isPaused();
  1158. }
  1159. });
  1160. return ret;
  1161. }
  1162. recordWebViewApiCall(ApiCall.IS_PAUSED);
  1163. return mAwContents.isPaused();
  1164. }
  1165. @Override
  1166. public void freeMemory() {
  1167. // Intentional no-op. Memory is managed automatically by Chromium.
  1168. }
  1169. @Override
  1170. public void clearCache(final boolean includeDiskFiles) {
  1171. if (checkNeedsPost()) {
  1172. mFactory.addTask(new Runnable() {
  1173. @Override
  1174. public void run() {
  1175. clearCache(includeDiskFiles);
  1176. }
  1177. });
  1178. return;
  1179. }
  1180. recordWebViewApiCall(ApiCall.CLEAR_CACHE);
  1181. mAwContents.clearCache(includeDiskFiles);
  1182. }
  1183. /**
  1184. * This is a poorly named method, but we keep it for historical reasons.
  1185. */
  1186. @Override
  1187. public void clearFormData() {
  1188. if (checkNeedsPost()) {
  1189. mFactory.addTask(new Runnable() {
  1190. @Override
  1191. public void run() {
  1192. clearFormData();
  1193. }
  1194. });
  1195. return;
  1196. }
  1197. recordWebViewApiCall(ApiCall.CLEAR_FORM_DATA);
  1198. mAwContents.hideAutofillPopup();
  1199. }
  1200. @Override
  1201. public void clearHistory() {
  1202. if (checkNeedsPost()) {
  1203. mFactory.addTask(new Runnable() {
  1204. @Override
  1205. public void run() {
  1206. clearHistory();
  1207. }
  1208. });
  1209. return;
  1210. }
  1211. recordWebViewApiCall(ApiCall.CLEAR_HISTORY);
  1212. mAwContents.clearHistory();
  1213. }
  1214. @Override
  1215. public void clearSslPreferences() {
  1216. if (checkNeedsPost()) {
  1217. mFactory.addTask(new Runnable() {
  1218. @Override
  1219. public void run() {
  1220. clearSslPreferences();
  1221. }
  1222. });
  1223. return;
  1224. }
  1225. recordWebViewApiCall(ApiCall.CLEAR_SSL_PREFERENCES);
  1226. mAwContents.clearSslPreferences();
  1227. }
  1228. @Override
  1229. public WebBackForwardList copyBackForwardList() {
  1230. mFactory.startYourEngines(true);
  1231. if (checkNeedsPost()) {
  1232. WebBackForwardList ret =
  1233. mFactory.runOnUiThreadBlocking(new Callable<WebBackForwardList>() {
  1234. @Override
  1235. public WebBackForwardList call() {
  1236. return copyBackForwardList();
  1237. }
  1238. });
  1239. return ret;
  1240. }
  1241. recordWebViewApiCall(ApiCall.COPY_BACK_FORWARD_LIST);
  1242. // mAwContents.getNavigationHistory() can be null here if mAwContents has been destroyed,
  1243. // and we do not handle passing null to the WebBackForwardListChromium constructor.
  1244. NavigationHistory navHistory = mAwContents.getNavigationHistory();
  1245. if (navHistory == null) navHistory = new NavigationHistory();
  1246. return new WebBackForwardListChromium(navHistory);
  1247. }
  1248. @Override
  1249. public void setFindListener(WebView.FindListener listener) {
  1250. recordWebViewApiCall(ApiCall.SET_FIND_LISTENER);
  1251. mContentsClientAdapter.setFindListener(listener);
  1252. }
  1253. @Override
  1254. public void findNext(final boolean forwards) {
  1255. if (checkNeedsPost()) {
  1256. mFactory.addTask(new Runnable() {
  1257. @Override
  1258. public void run() {
  1259. findNext(forwards);
  1260. }
  1261. });
  1262. return;
  1263. }
  1264. recordWebViewApiCall(ApiCall.FIND_NEXT);
  1265. mAwContents.findNext(forwards);
  1266. }
  1267. @Override
  1268. public int findAll(final String searchString) {
  1269. findAllAsync(searchString);
  1270. return 0;
  1271. }
  1272. @Override
  1273. public void findAllAsync(final String searchString) {
  1274. if (checkNeedsPost()) {
  1275. mFactory.addTask(new Runnable() {
  1276. @Override
  1277. public void run() {
  1278. findAllAsync(searchString);
  1279. }
  1280. });
  1281. return;
  1282. }
  1283. mAwContents.findAllAsync(searchString);
  1284. }
  1285. @Override
  1286. public boolean showFindDialog(final String text, final boolean showIme) {
  1287. recordWebViewApiCall(ApiCall.SHOW_FIND_DIALOG);
  1288. mFactory.startYourEngines(false);
  1289. if (checkNeedsPost()) {
  1290. return false;
  1291. }
  1292. if (mWebView.getParent() == null) {
  1293. return false;
  1294. }
  1295. FindActionModeCallback findAction = new FindActionModeCallback(mContext);
  1296. if (findAction == null) {
  1297. return false;
  1298. }
  1299. mWebView.startActionMode(findAction);
  1300. findAction.setWebView(mWebView);
  1301. if (showIme) {
  1302. findAction.showSoftInput();
  1303. }
  1304. if (text != null) {
  1305. findAction.setText(text);
  1306. findAction.findAll();
  1307. }
  1308. return true;
  1309. }
  1310. @Override
  1311. public void notifyFindDialogDismissed() {
  1312. if (checkNeedsPost()) {
  1313. mFactory.addTask(new Runnable() {
  1314. @Override
  1315. public void run() {
  1316. notifyFindDialogDismissed();
  1317. }
  1318. });
  1319. return;
  1320. }
  1321. recordWebViewApiCall(ApiCall.NOTIFY_FIND_DIALOG_DISMISSED);
  1322. clearMatches();
  1323. }
  1324. @Override
  1325. public void clearMatches() {
  1326. if (checkNeedsPost()) {
  1327. mFactory.addTask(new Runnable() {
  1328. @Override
  1329. public void run() {
  1330. clearMatches();
  1331. }
  1332. });
  1333. return;
  1334. }
  1335. recordWebViewApiCall(ApiCall.CLEAR_MATCHES);
  1336. mAwContents.clearMatches();
  1337. }
  1338. @Override
  1339. public void documentHasImages(final Message response) {
  1340. if (checkNeedsPost()) {
  1341. mFactory.addTask(new Runnable() {
  1342. @Override
  1343. public void run() {
  1344. documentHasImages(response);
  1345. }
  1346. });
  1347. return;
  1348. }
  1349. recordWebViewApiCall(ApiCall.DOCUMENT_HAS_IMAGES);
  1350. mAwContents.documentHasImages(response);
  1351. }
  1352. @Override
  1353. public void setWebViewClient(WebViewClient client) {
  1354. recordWebViewApiCall(ApiCall.SET_WEBVIEW_CLIENT);
  1355. mSharedWebViewChromium.setWebViewClient(client);
  1356. mContentsClientAdapter.setWebViewClient(mSharedWebViewChromium.getWebViewClient());
  1357. }
  1358. @Override
  1359. public WebViewClient getWebViewClient() {
  1360. recordWebViewApiCall(ApiCall.GET_WEBVIEW_CLIENT);
  1361. return mSharedWebViewChromium.getWebViewClient();
  1362. }
  1363. @RequiresApi(Build.VERSION_CODES.Q)
  1364. @Override
  1365. public WebViewRenderProcess getWebViewRenderProcess() {
  1366. return GlueApiHelperForQ.getWebViewRenderProcess(mSharedWebViewChromium.getRenderProcess());
  1367. }
  1368. @RequiresApi(Build.VERSION_CODES.Q)
  1369. @Override
  1370. public void setWebViewRenderProcessClient(
  1371. Executor executor, WebViewRenderProcessClient webViewRenderProcessClient) {
  1372. if (webViewRenderProcessClient == null) {
  1373. mSharedWebViewChromium.setWebViewRendererClientAdapter(null);
  1374. } else {
  1375. if (executor == null) {
  1376. executor = (Runnable r) -> r.run();
  1377. }
  1378. GlueApiHelperForQ.setWebViewRenderProcessClient(
  1379. mSharedWebViewChromium, executor, webViewRenderProcessClient);
  1380. }
  1381. }
  1382. @RequiresApi(Build.VERSION_CODES.Q)
  1383. @Override
  1384. public WebViewRenderProcessClient getWebViewRenderProcessClient() {
  1385. SharedWebViewRendererClientAdapter adapter =
  1386. mSharedWebViewChromium.getWebViewRendererClientAdapter();
  1387. if (adapter == null || !(adapter instanceof WebViewRenderProcessClientAdapter)) {
  1388. return null;
  1389. }
  1390. return GlueApiHelperForQ.getWebViewRenderProcessClient(adapter);
  1391. }
  1392. @Override
  1393. public void setDownloadListener(DownloadListener listener) {
  1394. recordWebViewApiCall(ApiCall.SET_DOWNLOAD_LISTENER);
  1395. mContentsClientAdapter.setDownloadListener(listener);
  1396. }
  1397. @Override
  1398. public void setWebChromeClient(WebChromeClient client) {
  1399. recordWebViewApiCall(ApiCall.SET_WEBCHROME_CLIENT);
  1400. mWebSettings.getAwSettings().setFullscreenSupported(doesSupportFullscreen(client));
  1401. mSharedWebViewChromium.setWebChromeClient(client);
  1402. mContentsClientAdapter.setWebChromeClient(mSharedWebViewChromium.getWebChromeClient());
  1403. }
  1404. @Override
  1405. public WebChromeClient getWebChromeClient() {
  1406. recordWebViewApiCall(ApiCall.GET_WEBCHROME_CLIENT);
  1407. return mSharedWebViewChromium.getWebChromeClient();
  1408. }
  1409. /**
  1410. * Returns true if the supplied {@link WebChromeClient} supports fullscreen.
  1411. *
  1412. * <p>For fullscreen support, implementations of {@link WebChromeClient#onShowCustomView}
  1413. * and {@link WebChromeClient#onHideCustomView()} are required.
  1414. */
  1415. private boolean doesSupportFullscreen(WebChromeClient client) {
  1416. recordWebViewApiCall(ApiCall.DOES_SUPPORT_FULLSCREEN);
  1417. if (client == null) {
  1418. return false;
  1419. }
  1420. Class<?> clientClass = client.getClass();
  1421. boolean foundShowMethod = false;
  1422. boolean foundHideMethod = false;
  1423. while (clientClass != WebChromeClient.class && (!foundShowMethod || !foundHideMethod)) {
  1424. if (!foundShowMethod) {
  1425. try {
  1426. clientClass.getDeclaredMethod(
  1427. "onShowCustomView", View.class, CustomViewCallback.class);
  1428. foundShowMethod = true;
  1429. } catch (NoSuchMethodException e) {
  1430. // Intentionally empty.
  1431. }
  1432. }
  1433. if (!foundHideMethod) {
  1434. try {
  1435. clientClass.getDeclaredMethod("onHideCustomView");
  1436. foundHideMethod = true;
  1437. } catch (NoSuchMethodException e) {
  1438. // Intentionally empty.
  1439. }
  1440. }
  1441. clientClass = clientClass.getSuperclass();
  1442. }
  1443. return foundShowMethod && foundHideMethod;
  1444. }
  1445. @Override
  1446. @SuppressWarnings("deprecation")
  1447. public void setPictureListener(final WebView.PictureListener listener) {
  1448. if (checkNeedsPost()) {
  1449. mFactory.addTask(new Runnable() {
  1450. @Override
  1451. public void run() {
  1452. setPictureListener(listener);
  1453. }
  1454. });
  1455. return;
  1456. }
  1457. recordWebViewApiCall(ApiCall.SET_PICTURE_LISTENER);
  1458. boolean invalidateOnly = mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2;
  1459. mContentsClientAdapter.setPictureListener(listener, invalidateOnly);
  1460. mAwContents.enableOnNewPicture(listener != null, invalidateOnly);
  1461. }
  1462. @Override
  1463. public void addJavascriptInterface(final Object obj, final String interfaceName) {
  1464. if (checkNeedsPost()) {
  1465. mFactory.addTask(new Runnable() {
  1466. @Override
  1467. public void run() {
  1468. addJavascriptInterface(obj, interfaceName);
  1469. }
  1470. });
  1471. return;
  1472. }
  1473. recordWebViewApiCall(ApiCall.ADD_JAVASCRIPT_INTERFACE);
  1474. mAwContents.addJavascriptInterface(obj, interfaceName);
  1475. }
  1476. @Override
  1477. public void removeJavascriptInterface(final String interfaceName) {
  1478. if (checkNeedsPost()) {
  1479. mFactory.addTask(new Runnable() {
  1480. @Override
  1481. public void run() {
  1482. removeJavascriptInterface(interfaceName);
  1483. }
  1484. });
  1485. return;
  1486. }
  1487. recordWebViewApiCall(ApiCall.REMOVE_JAVASCRIPT_INTERFACE);
  1488. mAwContents.removeJavascriptInterface(interfaceName);
  1489. }
  1490. @Override
  1491. public WebMessagePort[] createWebMessageChannel() {
  1492. recordWebViewApiCall(ApiCall.CREATE_WEBMESSAGE_CHANNEL);
  1493. return WebMessagePortAdapter.fromMessagePorts(
  1494. mSharedWebViewChromium.createWebMessageChannel());
  1495. }
  1496. @Override
  1497. public void postMessageToMainFrame(final WebMessage message, final Uri targetOrigin) {
  1498. recordWebViewApiCall(ApiCall.POST_MESSAGE_TO_MAIN_FRAME);
  1499. // Create MessagePayload from AOSP WebMessage, MessagePayload is not directly supported by
  1500. // AOSP.
  1501. mSharedWebViewChromium.postMessageToMainFrame(new MessagePayload(message.getData()),
  1502. targetOrigin.toString(), WebMessagePortAdapter.toMessagePorts(message.getPorts()));
  1503. }
  1504. @Override
  1505. public WebSettings getSettings() {
  1506. recordWebViewApiCall(ApiCall.GET_SETTINGS);
  1507. return mWebSettings;
  1508. }
  1509. @Override
  1510. public void setMapTrackballToArrowKeys(boolean setMap) {
  1511. // This is a deprecated API: intentional no-op.
  1512. }
  1513. @Override
  1514. public void flingScroll(final int vx, final int vy) {
  1515. if (checkNeedsPost()) {
  1516. mFactory.addTask(new Runnable() {
  1517. @Override
  1518. public void run() {
  1519. flingScroll(vx, vy);
  1520. }
  1521. });
  1522. return;
  1523. }
  1524. mAwContents.flingScroll(vx, vy);
  1525. }
  1526. @Override
  1527. public View getZoomControls() {
  1528. mFactory.startYourEngines(false);
  1529. if (checkNeedsPost()) {
  1530. return null;
  1531. }
  1532. // This was deprecated in 2009 and hidden in JB MR1, so just provide the minimum needed
  1533. // to stop very out-dated applications from crashing.
  1534. Log.w(TAG, "WebView doesn't support getZoomControls");
  1535. return mAwContents.getSettings().supportZoom() ? new View(mContext) : null;
  1536. }
  1537. @Override
  1538. public boolean canZoomIn() {
  1539. recordWebViewApiCall(ApiCall.CAN_ZOOM_IN);
  1540. if (checkNeedsPost()) {
  1541. return false;
  1542. }
  1543. return mAwContents.canZoomIn();
  1544. }
  1545. @Override
  1546. public boolean canZoomOut() {
  1547. recordWebViewApiCall(ApiCall.CAN_ZOOM_OUT);
  1548. if (checkNeedsPost()) {
  1549. return false;
  1550. }
  1551. return mAwContents.canZoomOut();
  1552. }
  1553. @Override
  1554. public boolean zoomIn() {
  1555. mFactory.startYourEngines(true);
  1556. if (checkNeedsPost()) {
  1557. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1558. @Override
  1559. public Boolean call() {
  1560. return zoomIn();
  1561. }
  1562. });
  1563. return ret;
  1564. }
  1565. return mAwContents.zoomIn();
  1566. }
  1567. @Override
  1568. public boolean zoomOut() {
  1569. mFactory.startYourEngines(true);
  1570. if (checkNeedsPost()) {
  1571. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1572. @Override
  1573. public Boolean call() {
  1574. return zoomOut();
  1575. }
  1576. });
  1577. return ret;
  1578. }
  1579. return mAwContents.zoomOut();
  1580. }
  1581. // TODO(paulmiller) Return void for consistency with AwContents.zoomBy and WebView.zoomBy -
  1582. // tricky because frameworks WebViewProvider.zoomBy must change simultaneously
  1583. @Override
  1584. public boolean zoomBy(float factor) {
  1585. mFactory.startYourEngines(true);
  1586. // This is an L API and therefore we can enforce stricter threading constraints.
  1587. checkThread();
  1588. mAwContents.zoomBy(factor);
  1589. return true;
  1590. }
  1591. @Override
  1592. public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
  1593. // Intentional no-op
  1594. }
  1595. @Override
  1596. public View findHierarchyView(String className, int hashCode) {
  1597. // Intentional no-op
  1598. return null;
  1599. }
  1600. @Override
  1601. public void setRendererPriorityPolicy(
  1602. int rendererRequestedPriority, boolean waivedWhenNotVisible) {
  1603. @RendererPriority
  1604. int awRendererRequestedPriority;
  1605. switch (rendererRequestedPriority) {
  1606. case WebView.RENDERER_PRIORITY_WAIVED:
  1607. awRendererRequestedPriority = RendererPriority.WAIVED;
  1608. break;
  1609. case WebView.RENDERER_PRIORITY_BOUND:
  1610. awRendererRequestedPriority = RendererPriority.LOW;
  1611. break;
  1612. default:
  1613. case WebView.RENDERER_PRIORITY_IMPORTANT:
  1614. awRendererRequestedPriority = RendererPriority.HIGH;
  1615. break;
  1616. }
  1617. mAwContents.setRendererPriorityPolicy(awRendererRequestedPriority, waivedWhenNotVisible);
  1618. }
  1619. @Override
  1620. public int getRendererRequestedPriority() {
  1621. @RendererPriority
  1622. final int awRendererRequestedPriority = mAwContents.getRendererRequestedPriority();
  1623. switch (awRendererRequestedPriority) {
  1624. case RendererPriority.WAIVED:
  1625. return WebView.RENDERER_PRIORITY_WAIVED;
  1626. case RendererPriority.LOW:
  1627. return WebView.RENDERER_PRIORITY_BOUND;
  1628. default:
  1629. case RendererPriority.HIGH:
  1630. return WebView.RENDERER_PRIORITY_IMPORTANT;
  1631. }
  1632. }
  1633. @Override
  1634. public boolean getRendererPriorityWaivedWhenNotVisible() {
  1635. return mAwContents.getRendererPriorityWaivedWhenNotVisible();
  1636. }
  1637. @Override
  1638. public void setTextClassifier(TextClassifier textClassifier) {
  1639. recordWebViewApiCall(ApiCall.SET_TEXT_CLASSIFIER);
  1640. mAwContents.setTextClassifier(textClassifier);
  1641. }
  1642. @Override
  1643. public TextClassifier getTextClassifier() {
  1644. recordWebViewApiCall(ApiCall.GET_TEXT_CLASSIFIER);
  1645. return mAwContents.getTextClassifier();
  1646. }
  1647. @Override
  1648. public void autofill(final SparseArray<AutofillValue> values) {
  1649. mFactory.startYourEngines(false);
  1650. if (checkNeedsPost()) {
  1651. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  1652. @Override
  1653. public void run() {
  1654. autofill(values);
  1655. }
  1656. });
  1657. }
  1658. recordWebViewApiCall(ApiCall.AUTOFILL);
  1659. mAwContents.autofill(values);
  1660. }
  1661. @Override
  1662. public void onProvideAutofillVirtualStructure(final ViewStructure structure, final int flags) {
  1663. mFactory.startYourEngines(false);
  1664. if (checkNeedsPost()) {
  1665. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  1666. @Override
  1667. public void run() {
  1668. onProvideAutofillVirtualStructure(structure, flags);
  1669. }
  1670. });
  1671. return;
  1672. }
  1673. recordWebViewApiCall(ApiCall.ON_PROVIDE_AUTOFILL_VIRTUAL_STRUCTURE);
  1674. mAwContents.onProvideAutoFillVirtualStructure(structure, flags);
  1675. }
  1676. @Override
  1677. public void onProvideContentCaptureStructure(ViewStructure structure, int flags) {
  1678. if (ContentCaptureFeatures.isDumpForTestingEnabled()) {
  1679. Log.i("ContentCapture", "onProvideContentCaptureStructure");
  1680. }
  1681. mAwContents.setOnscreenContentProvider(new OnscreenContentProvider(
  1682. ClassLoaderContextWrapperFactory.get(mWebView.getContext()), mWebView, structure,
  1683. mAwContents.getWebContents()));
  1684. }
  1685. // WebViewProvider glue methods ---------------------------------------------------------------
  1686. @Override
  1687. // This needs to be kept thread safe!
  1688. public WebViewProvider.ViewDelegate getViewDelegate() {
  1689. return this;
  1690. }
  1691. @Override
  1692. // This needs to be kept thread safe!
  1693. public WebViewProvider.ScrollDelegate getScrollDelegate() {
  1694. return this;
  1695. }
  1696. // WebViewProvider.ViewDelegate implementation ------------------------------------------------
  1697. // TODO: remove from WebViewProvider and use default implementation from
  1698. // ViewGroup.
  1699. @Override
  1700. public boolean shouldDelayChildPressedState() {
  1701. mFactory.startYourEngines(false);
  1702. if (checkNeedsPost()) {
  1703. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1704. @Override
  1705. public Boolean call() {
  1706. return shouldDelayChildPressedState();
  1707. }
  1708. });
  1709. return ret;
  1710. }
  1711. return true;
  1712. }
  1713. @Override
  1714. public AccessibilityNodeProvider getAccessibilityNodeProvider() {
  1715. mFactory.startYourEngines(false);
  1716. if (checkNeedsPost()) {
  1717. AccessibilityNodeProvider ret =
  1718. mFactory.runOnUiThreadBlocking(new Callable<AccessibilityNodeProvider>() {
  1719. @Override
  1720. public AccessibilityNodeProvider call() {
  1721. return getAccessibilityNodeProvider();
  1722. }
  1723. });
  1724. return ret;
  1725. }
  1726. return mAwContents.getAccessibilityNodeProvider();
  1727. }
  1728. @Override
  1729. public void onProvideVirtualStructure(final ViewStructure structure) {
  1730. mFactory.startYourEngines(false);
  1731. if (checkNeedsPost()) {
  1732. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  1733. @Override
  1734. public void run() {
  1735. onProvideVirtualStructure(structure);
  1736. }
  1737. });
  1738. return;
  1739. }
  1740. mAwContents.onProvideVirtualStructure(structure);
  1741. }
  1742. @Override
  1743. public void onInitializeAccessibilityNodeInfo(final AccessibilityNodeInfo info) {
  1744. // Intentional no-op. Chromium accessibility implementation currently does not need this
  1745. // calls.
  1746. }
  1747. @Override
  1748. public void onInitializeAccessibilityEvent(final AccessibilityEvent event) {
  1749. // Intentional no-op. Chromium accessibility implementation currently does not need this
  1750. // calls.
  1751. }
  1752. @Override
  1753. public boolean performAccessibilityAction(final int action, final Bundle arguments) {
  1754. mFactory.startYourEngines(false);
  1755. if (checkNeedsPost()) {
  1756. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1757. @Override
  1758. public Boolean call() {
  1759. return performAccessibilityAction(action, arguments);
  1760. }
  1761. });
  1762. return ret;
  1763. }
  1764. if (mAwContents.supportsAccessibilityAction(action)) {
  1765. return mAwContents.performAccessibilityAction(action, arguments);
  1766. }
  1767. return mWebViewPrivate.super_performAccessibilityAction(action, arguments);
  1768. }
  1769. @Override
  1770. public void setOverScrollMode(final int mode) {
  1771. // This gets called from the android.view.View c'tor that WebView inherits from. This
  1772. // causes the method to be called when mAwContents == null.
  1773. // It's safe to ignore these calls however since AwContents will read the current value of
  1774. // this setting when it's created.
  1775. if (mAwContents == null) return;
  1776. if (checkNeedsPost()) {
  1777. mFactory.addTask(new Runnable() {
  1778. @Override
  1779. public void run() {
  1780. setOverScrollMode(mode);
  1781. }
  1782. });
  1783. return;
  1784. }
  1785. mAwContents.setOverScrollMode(mode);
  1786. }
  1787. @Override
  1788. public void setScrollBarStyle(final int style) {
  1789. if (checkNeedsPost()) {
  1790. mFactory.addTask(new Runnable() {
  1791. @Override
  1792. public void run() {
  1793. setScrollBarStyle(style);
  1794. }
  1795. });
  1796. return;
  1797. }
  1798. mAwContents.setScrollBarStyle(style);
  1799. }
  1800. @Override
  1801. public void onDrawVerticalScrollBar(final Canvas canvas, final Drawable scrollBar, final int l,
  1802. final int t, final int r, final int b) {
  1803. // WebViewClassic was overriding this method to handle rubberband over-scroll. Since
  1804. // WebViewChromium doesn't support that the vanilla implementation of this method can be
  1805. // used.
  1806. mWebViewPrivate.super_onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
  1807. }
  1808. @Override
  1809. public void onOverScrolled(final int scrollX, final int scrollY,
  1810. final boolean clampedX, final boolean clampedY) {
  1811. if (checkNeedsPost()) {
  1812. mFactory.addTask(new Runnable() {
  1813. @Override
  1814. public void run() {
  1815. onOverScrolled(scrollX, scrollY, clampedX, clampedY);
  1816. }
  1817. });
  1818. return;
  1819. }
  1820. mAwContents.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
  1821. }
  1822. @Override
  1823. public void onWindowVisibilityChanged(final int visibility) {
  1824. if (checkNeedsPost()) {
  1825. mFactory.addTask(new Runnable() {
  1826. @Override
  1827. public void run() {
  1828. onWindowVisibilityChanged(visibility);
  1829. }
  1830. });
  1831. return;
  1832. }
  1833. mAwContents.onWindowVisibilityChanged(visibility);
  1834. }
  1835. @Override
  1836. @SuppressLint("DrawAllocation")
  1837. public void onDraw(final Canvas canvas) {
  1838. mFactory.startYourEngines(true);
  1839. if (checkNeedsPost()) {
  1840. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  1841. @Override
  1842. public void run() {
  1843. onDraw(canvas);
  1844. }
  1845. });
  1846. return;
  1847. }
  1848. mAwContents.onDraw(canvas);
  1849. }
  1850. @Override
  1851. public void setLayoutParams(final ViewGroup.LayoutParams layoutParams) {
  1852. // This API is our strongest signal from the View system that this
  1853. // WebView is going to be bound to a View hierarchy and so at this
  1854. // point we must bind Chromium's UI thread to the current thread.
  1855. mFactory.startYourEngines(false);
  1856. checkThread();
  1857. mWebViewPrivate.super_setLayoutParams(layoutParams);
  1858. if (checkNeedsPost()) {
  1859. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  1860. @Override
  1861. public void run() {
  1862. mAwContents.setLayoutParams(layoutParams);
  1863. }
  1864. });
  1865. return;
  1866. }
  1867. mAwContents.setLayoutParams(layoutParams);
  1868. }
  1869. @Override
  1870. public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
  1871. if (checkNeedsPost()) {
  1872. mFactory.addTask(new Runnable() {
  1873. @Override
  1874. public void run() {
  1875. onActivityResult(requestCode, resultCode, data);
  1876. }
  1877. });
  1878. return;
  1879. }
  1880. mAwContents.onActivityResult(requestCode, resultCode, data);
  1881. }
  1882. @Override
  1883. public boolean performLongClick() {
  1884. // Return false unless the WebView is attached to a View with a parent
  1885. return mWebView.getParent() != null ? mWebViewPrivate.super_performLongClick() : false;
  1886. }
  1887. @Override
  1888. public void onConfigurationChanged(final Configuration newConfig) {
  1889. if (checkNeedsPost()) {
  1890. mFactory.addTask(new Runnable() {
  1891. @Override
  1892. public void run() {
  1893. onConfigurationChanged(newConfig);
  1894. }
  1895. });
  1896. return;
  1897. }
  1898. mAwContents.onConfigurationChanged(newConfig);
  1899. }
  1900. @Override
  1901. public boolean onDragEvent(final DragEvent event) {
  1902. mFactory.startYourEngines(false);
  1903. if (checkNeedsPost()) {
  1904. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1905. @Override
  1906. public Boolean call() {
  1907. return onDragEvent(event);
  1908. }
  1909. });
  1910. return ret;
  1911. }
  1912. return mAwContents.onDragEvent(event);
  1913. }
  1914. @Override
  1915. public InputConnection onCreateInputConnection(final EditorInfo outAttrs) {
  1916. mFactory.startYourEngines(false);
  1917. if (checkNeedsPost()) {
  1918. return null;
  1919. }
  1920. return mAwContents.onCreateInputConnection(outAttrs);
  1921. }
  1922. @Override
  1923. public boolean onKeyMultiple(final int keyCode, final int repeatCount, final KeyEvent event) {
  1924. mFactory.startYourEngines(false);
  1925. if (checkNeedsPost()) {
  1926. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1927. @Override
  1928. public Boolean call() {
  1929. return onKeyMultiple(keyCode, repeatCount, event);
  1930. }
  1931. });
  1932. return ret;
  1933. }
  1934. return false;
  1935. }
  1936. @Override
  1937. public boolean onKeyDown(final int keyCode, final KeyEvent event) {
  1938. mFactory.startYourEngines(false);
  1939. if (checkNeedsPost()) {
  1940. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1941. @Override
  1942. public Boolean call() {
  1943. return onKeyDown(keyCode, event);
  1944. }
  1945. });
  1946. return ret;
  1947. }
  1948. return false;
  1949. }
  1950. @Override
  1951. public boolean onKeyUp(final int keyCode, final KeyEvent event) {
  1952. mFactory.startYourEngines(false);
  1953. if (checkNeedsPost()) {
  1954. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  1955. @Override
  1956. public Boolean call() {
  1957. return onKeyUp(keyCode, event);
  1958. }
  1959. });
  1960. return ret;
  1961. }
  1962. return mAwContents.onKeyUp(keyCode, event);
  1963. }
  1964. @Override
  1965. public void onAttachedToWindow() {
  1966. // This API is our strongest signal from the View system that this
  1967. // WebView is going to be bound to a View hierarchy and so at this
  1968. // point we must bind Chromium's UI thread to the current thread.
  1969. mFactory.startYourEngines(false);
  1970. checkThread();
  1971. mAwContents.onAttachedToWindow();
  1972. }
  1973. @Override
  1974. public void onDetachedFromWindow() {
  1975. if (checkNeedsPost()) {
  1976. mFactory.addTask(new Runnable() {
  1977. @Override
  1978. public void run() {
  1979. onDetachedFromWindow();
  1980. }
  1981. });
  1982. return;
  1983. }
  1984. mAwContents.onDetachedFromWindow();
  1985. }
  1986. @Override
  1987. public void onVisibilityChanged(final View changedView, final int visibility) {
  1988. // The AwContents will find out the container view visibility before the first draw so we
  1989. // can safely ignore onVisibilityChanged callbacks that happen before init().
  1990. if (mAwContents == null) return;
  1991. if (checkNeedsPost()) {
  1992. mFactory.addTask(new Runnable() {
  1993. @Override
  1994. public void run() {
  1995. onVisibilityChanged(changedView, visibility);
  1996. }
  1997. });
  1998. return;
  1999. }
  2000. mAwContents.onVisibilityChanged(changedView, visibility);
  2001. }
  2002. @Override
  2003. public void onWindowFocusChanged(final boolean hasWindowFocus) {
  2004. if (checkNeedsPost()) {
  2005. mFactory.addTask(new Runnable() {
  2006. @Override
  2007. public void run() {
  2008. onWindowFocusChanged(hasWindowFocus);
  2009. }
  2010. });
  2011. return;
  2012. }
  2013. mAwContents.onWindowFocusChanged(hasWindowFocus);
  2014. }
  2015. @Override
  2016. public void onFocusChanged(
  2017. final boolean focused, final int direction, final Rect previouslyFocusedRect) {
  2018. if (checkNeedsPost()) {
  2019. mFactory.addTask(new Runnable() {
  2020. @Override
  2021. public void run() {
  2022. onFocusChanged(focused, direction, previouslyFocusedRect);
  2023. }
  2024. });
  2025. return;
  2026. }
  2027. mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect);
  2028. }
  2029. @Override
  2030. public boolean setFrame(final int left, final int top, final int right, final int bottom) {
  2031. return mWebViewPrivate.super_setFrame(left, top, right, bottom);
  2032. }
  2033. @Override
  2034. public void onSizeChanged(final int w, final int h, final int ow, final int oh) {
  2035. if (checkNeedsPost()) {
  2036. mFactory.addTask(new Runnable() {
  2037. @Override
  2038. public void run() {
  2039. onSizeChanged(w, h, ow, oh);
  2040. }
  2041. });
  2042. return;
  2043. }
  2044. mAwContents.onSizeChanged(w, h, ow, oh);
  2045. }
  2046. @Override
  2047. public void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
  2048. if (checkNeedsPost()) {
  2049. mFactory.addTask(new Runnable() {
  2050. @Override
  2051. public void run() {
  2052. onScrollChanged(l, t, oldl, oldt);
  2053. }
  2054. });
  2055. return;
  2056. }
  2057. mAwContents.onContainerViewScrollChanged(l, t, oldl, oldt);
  2058. }
  2059. @Override
  2060. public boolean dispatchKeyEvent(final KeyEvent event) {
  2061. mFactory.startYourEngines(false);
  2062. if (checkNeedsPost()) {
  2063. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2064. @Override
  2065. public Boolean call() {
  2066. return dispatchKeyEvent(event);
  2067. }
  2068. });
  2069. return ret;
  2070. }
  2071. return mAwContents.dispatchKeyEvent(event);
  2072. }
  2073. @Override
  2074. public boolean onTouchEvent(final MotionEvent ev) {
  2075. mFactory.startYourEngines(false);
  2076. if (checkNeedsPost()) {
  2077. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2078. @Override
  2079. public Boolean call() {
  2080. return onTouchEvent(ev);
  2081. }
  2082. });
  2083. return ret;
  2084. }
  2085. return mAwContents.onTouchEvent(ev);
  2086. }
  2087. @Override
  2088. public boolean onHoverEvent(final MotionEvent event) {
  2089. mFactory.startYourEngines(false);
  2090. if (checkNeedsPost()) {
  2091. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2092. @Override
  2093. public Boolean call() {
  2094. return onHoverEvent(event);
  2095. }
  2096. });
  2097. return ret;
  2098. }
  2099. return mAwContents.onHoverEvent(event);
  2100. }
  2101. @Override
  2102. public boolean onGenericMotionEvent(final MotionEvent event) {
  2103. mFactory.startYourEngines(false);
  2104. if (checkNeedsPost()) {
  2105. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2106. @Override
  2107. public Boolean call() {
  2108. return onGenericMotionEvent(event);
  2109. }
  2110. });
  2111. return ret;
  2112. }
  2113. return mAwContents.onGenericMotionEvent(event);
  2114. }
  2115. @Override
  2116. public boolean onTrackballEvent(MotionEvent ev) {
  2117. // Trackball event not handled, which eventually gets converted to DPAD keyevents
  2118. return false;
  2119. }
  2120. @Override
  2121. public boolean requestFocus(final int direction, final Rect previouslyFocusedRect) {
  2122. mFactory.startYourEngines(false);
  2123. if (checkNeedsPost()) {
  2124. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2125. @Override
  2126. public Boolean call() {
  2127. return requestFocus(direction, previouslyFocusedRect);
  2128. }
  2129. });
  2130. return ret;
  2131. }
  2132. mAwContents.requestFocus();
  2133. return mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
  2134. }
  2135. @Override
  2136. @SuppressLint("DrawAllocation")
  2137. public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
  2138. mFactory.startYourEngines(false);
  2139. if (checkNeedsPost()) {
  2140. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  2141. @Override
  2142. public void run() {
  2143. onMeasure(widthMeasureSpec, heightMeasureSpec);
  2144. }
  2145. });
  2146. return;
  2147. }
  2148. mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
  2149. }
  2150. @Override
  2151. public boolean requestChildRectangleOnScreen(
  2152. final View child, final Rect rect, final boolean immediate) {
  2153. mFactory.startYourEngines(false);
  2154. if (checkNeedsPost()) {
  2155. boolean ret = mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2156. @Override
  2157. public Boolean call() {
  2158. return requestChildRectangleOnScreen(child, rect, immediate);
  2159. }
  2160. });
  2161. return ret;
  2162. }
  2163. return mAwContents.requestChildRectangleOnScreen(child, rect, immediate);
  2164. }
  2165. @Override
  2166. public void setBackgroundColor(final int color) {
  2167. mFactory.startYourEngines(false);
  2168. if (checkNeedsPost()) {
  2169. mFactory.addTask(new Runnable() {
  2170. @Override
  2171. public void run() {
  2172. setBackgroundColor(color);
  2173. }
  2174. });
  2175. return;
  2176. }
  2177. mAwContents.setBackgroundColor(color);
  2178. }
  2179. @Override
  2180. public void setLayerType(final int layerType, final Paint paint) {
  2181. // This can be called from WebView constructor in which case mAwContents
  2182. // is still null. We set the layer type in initForReal in that case.
  2183. if (mAwContents == null) return;
  2184. if (checkNeedsPost()) {
  2185. mFactory.addTask(new Runnable() {
  2186. @Override
  2187. public void run() {
  2188. setLayerType(layerType, paint);
  2189. }
  2190. });
  2191. return;
  2192. }
  2193. mAwContents.setLayerType(layerType, paint);
  2194. }
  2195. // Overrides method added to WebViewProvider.ViewDelegate interface
  2196. // (not called in M and below)
  2197. @Override
  2198. public Handler getHandler(Handler originalHandler) {
  2199. return originalHandler;
  2200. }
  2201. // Overrides method added to WebViewProvider.ViewDelegate interface
  2202. // (not called in M and below)
  2203. @Override
  2204. public View findFocus(View originalFocusedView) {
  2205. return originalFocusedView;
  2206. }
  2207. // Remove from superclass
  2208. @Override
  2209. public void preDispatchDraw(Canvas canvas) {
  2210. // TODO(leandrogracia): remove this method from WebViewProvider if we think
  2211. // we won't need it again.
  2212. }
  2213. @Override
  2214. public void onStartTemporaryDetach() {
  2215. mAwContents.onStartTemporaryDetach();
  2216. }
  2217. @Override
  2218. public void onFinishTemporaryDetach() {
  2219. mAwContents.onFinishTemporaryDetach();
  2220. }
  2221. @Override
  2222. public boolean onCheckIsTextEditor() {
  2223. mFactory.startYourEngines(false);
  2224. if (checkNeedsPost()) {
  2225. return mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
  2226. @Override
  2227. public Boolean call() {
  2228. return onCheckIsTextEditor();
  2229. }
  2230. });
  2231. }
  2232. return mAwContents.onCheckIsTextEditor();
  2233. }
  2234. // WebViewProvider.ScrollDelegate implementation ----------------------------------------------
  2235. @Override
  2236. public int computeHorizontalScrollRange() {
  2237. mFactory.startYourEngines(false);
  2238. if (checkNeedsPost()) {
  2239. int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
  2240. @Override
  2241. public Integer call() {
  2242. return computeHorizontalScrollRange();
  2243. }
  2244. });
  2245. return ret;
  2246. }
  2247. return mAwContents.computeHorizontalScrollRange();
  2248. }
  2249. @Override
  2250. public int computeHorizontalScrollOffset() {
  2251. mFactory.startYourEngines(false);
  2252. if (checkNeedsPost()) {
  2253. int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
  2254. @Override
  2255. public Integer call() {
  2256. return computeHorizontalScrollOffset();
  2257. }
  2258. });
  2259. return ret;
  2260. }
  2261. return mAwContents.computeHorizontalScrollOffset();
  2262. }
  2263. @Override
  2264. public int computeVerticalScrollRange() {
  2265. mFactory.startYourEngines(false);
  2266. if (checkNeedsPost()) {
  2267. int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
  2268. @Override
  2269. public Integer call() {
  2270. return computeVerticalScrollRange();
  2271. }
  2272. });
  2273. return ret;
  2274. }
  2275. return mAwContents.computeVerticalScrollRange();
  2276. }
  2277. @Override
  2278. public int computeVerticalScrollOffset() {
  2279. mFactory.startYourEngines(false);
  2280. if (checkNeedsPost()) {
  2281. int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
  2282. @Override
  2283. public Integer call() {
  2284. return computeVerticalScrollOffset();
  2285. }
  2286. });
  2287. return ret;
  2288. }
  2289. return mAwContents.computeVerticalScrollOffset();
  2290. }
  2291. @Override
  2292. public int computeVerticalScrollExtent() {
  2293. mFactory.startYourEngines(false);
  2294. if (checkNeedsPost()) {
  2295. int ret = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
  2296. @Override
  2297. public Integer call() {
  2298. return computeVerticalScrollExtent();
  2299. }
  2300. });
  2301. return ret;
  2302. }
  2303. return mAwContents.computeVerticalScrollExtent();
  2304. }
  2305. @Override
  2306. public void computeScroll() {
  2307. mFactory.startYourEngines(false);
  2308. if (checkNeedsPost()) {
  2309. mFactory.runVoidTaskOnUiThreadBlocking(new Runnable() {
  2310. @Override
  2311. public void run() {
  2312. computeScroll();
  2313. }
  2314. });
  2315. return;
  2316. }
  2317. mAwContents.computeScroll();
  2318. }
  2319. @Override
  2320. public PrintDocumentAdapter createPrintDocumentAdapter(String documentName) {
  2321. recordWebViewApiCall(ApiCall.CREATE_PRINT_DOCUMENT_ADAPTER);
  2322. checkThread();
  2323. return new AwPrintDocumentAdapter(mAwContents.getPdfExporter(), documentName);
  2324. }
  2325. // AwContents.NativeDrawFunctorFactory implementation ----------------------------------
  2326. private class WebViewNativeDrawFunctorFactory implements AwContents.NativeDrawFunctorFactory {
  2327. @Override
  2328. public AwContents.NativeDrawGLFunctor createGLFunctor(long context) {
  2329. return new DrawGLFunctor(context, mFactory.getWebViewDelegate());
  2330. }
  2331. @Override
  2332. public AwDrawFnImpl.DrawFnAccess getDrawFnAccess() {
  2333. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
  2334. return mFactory.getWebViewDelegate()::drawWebViewFunctor;
  2335. }
  2336. return null;
  2337. }
  2338. }
  2339. // AwContents.InternalAccessDelegate implementation --------------------------------------
  2340. private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
  2341. @Override
  2342. public boolean super_onKeyUp(int arg0, KeyEvent arg1) {
  2343. // Intentional no-op
  2344. return false;
  2345. }
  2346. @Override
  2347. public boolean super_dispatchKeyEvent(KeyEvent event) {
  2348. return mWebViewPrivate.super_dispatchKeyEvent(event);
  2349. }
  2350. @Override
  2351. public boolean super_onGenericMotionEvent(MotionEvent arg0) {
  2352. return mWebViewPrivate.super_onGenericMotionEvent(arg0);
  2353. }
  2354. @Override
  2355. public void super_onConfigurationChanged(Configuration arg0) {
  2356. // Intentional no-op
  2357. }
  2358. @Override
  2359. public int super_getScrollBarStyle() {
  2360. return mWebViewPrivate.super_getScrollBarStyle();
  2361. }
  2362. @Override
  2363. public void super_startActivityForResult(Intent intent, int requestCode) {
  2364. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  2365. GlueApiHelperForN.super_startActivityForResult(
  2366. mWebViewPrivate, intent, requestCode);
  2367. } else {
  2368. try {
  2369. Method startActivityForResultMethod =
  2370. View.class.getMethod("startActivityForResult", Intent.class, int.class);
  2371. startActivityForResultMethod.invoke(mWebView, intent, requestCode);
  2372. } catch (Exception e) {
  2373. throw new RuntimeException("Invalid reflection", e);
  2374. }
  2375. }
  2376. }
  2377. @Override
  2378. public void onScrollChanged(int l, int t, int oldl, int oldt) {
  2379. // Intentional no-op.
  2380. // Chromium calls this directly to trigger accessibility events. That isn't needed
  2381. // for WebView since super_scrollTo invokes onScrollChanged for us.
  2382. }
  2383. @Override
  2384. public void overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
  2385. int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
  2386. mWebViewPrivate.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
  2387. scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
  2388. }
  2389. @Override
  2390. public void super_scrollTo(int scrollX, int scrollY) {
  2391. mWebViewPrivate.super_scrollTo(scrollX, scrollY);
  2392. }
  2393. @Override
  2394. public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
  2395. mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
  2396. }
  2397. // @Override
  2398. public boolean super_onHoverEvent(MotionEvent event) {
  2399. return mWebViewPrivate.super_onHoverEvent(event);
  2400. }
  2401. }
  2402. // Implements SmartClipProvider
  2403. @Override
  2404. public void extractSmartClipData(int x, int y, int width, int height) {
  2405. recordWebViewApiCall(ApiCall.EXTRACT_SMART_CLIP_DATA);
  2406. checkThread();
  2407. mAwContents.extractSmartClipData(x, y, width, height);
  2408. }
  2409. // Implements SmartClipProvider
  2410. @Override
  2411. public void setSmartClipResultHandler(final Handler resultHandler) {
  2412. recordWebViewApiCall(ApiCall.SET_SMART_CLIP_RESULT_HANDLER);
  2413. checkThread();
  2414. mAwContents.setSmartClipResultHandler(resultHandler);
  2415. }
  2416. SharedWebViewChromium getSharedWebViewChromium() {
  2417. return mSharedWebViewChromium;
  2418. }
  2419. }