Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package com.android.webview.chromium; | 5 package com.android.webview.chromium; |
| 6 | 6 |
| 7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.annotation.TargetApi; | 8 import android.annotation.TargetApi; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.content.Intent; | 10 import android.content.Intent; |
| 11 import android.content.pm.PackageInfo; | |
| 11 import android.content.res.Configuration; | 12 import android.content.res.Configuration; |
| 12 import android.graphics.Bitmap; | 13 import android.graphics.Bitmap; |
| 13 import android.graphics.Canvas; | 14 import android.graphics.Canvas; |
| 14 import android.graphics.Paint; | 15 import android.graphics.Paint; |
| 15 import android.graphics.Picture; | 16 import android.graphics.Picture; |
| 16 import android.graphics.Rect; | 17 import android.graphics.Rect; |
| 17 import android.graphics.drawable.Drawable; | 18 import android.graphics.drawable.Drawable; |
| 18 import android.net.Uri; | 19 import android.net.Uri; |
| 19 import android.net.http.SslCertificate; | 20 import android.net.http.SslCertificate; |
| 20 import android.os.Build; | 21 import android.os.Build; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 import org.chromium.android_webview.AwPrintDocumentAdapter; | 56 import org.chromium.android_webview.AwPrintDocumentAdapter; |
| 56 import org.chromium.android_webview.AwSettings; | 57 import org.chromium.android_webview.AwSettings; |
| 57 import org.chromium.android_webview.ResourcesContextWrapperFactory; | 58 import org.chromium.android_webview.ResourcesContextWrapperFactory; |
| 58 import org.chromium.base.ThreadUtils; | 59 import org.chromium.base.ThreadUtils; |
| 59 import org.chromium.base.annotations.SuppressFBWarnings; | 60 import org.chromium.base.annotations.SuppressFBWarnings; |
| 60 import org.chromium.content.browser.SmartClipProvider; | 61 import org.chromium.content.browser.SmartClipProvider; |
| 61 import org.chromium.content_public.browser.NavigationHistory; | 62 import org.chromium.content_public.browser.NavigationHistory; |
| 62 | 63 |
| 63 import java.io.BufferedWriter; | 64 import java.io.BufferedWriter; |
| 64 import java.io.File; | 65 import java.io.File; |
| 66 import java.lang.reflect.Field; | |
| 65 import java.lang.reflect.Method; | 67 import java.lang.reflect.Method; |
| 66 import java.util.Map; | 68 import java.util.Map; |
| 67 import java.util.concurrent.Callable; | 69 import java.util.concurrent.Callable; |
| 70 import java.util.concurrent.atomic.AtomicBoolean; | |
| 68 | 71 |
| 69 /** | 72 /** |
| 70 * This class is the delegate to which WebViewProxy forwards all API calls. | 73 * This class is the delegate to which WebViewProxy forwards all API calls. |
| 71 * | 74 * |
| 72 * Most of the actual functionality is implemented by AwContents (or ContentView Core within | 75 * Most of the actual functionality is implemented by AwContents (or ContentView Core within |
| 73 * it). This class also contains WebView-specific APIs that require the creation of other | 76 * it). This class also contains WebView-specific APIs that require the creation of other |
| 74 * adapters (otherwise org.chromium.content would depend on the webview.chromium package) | 77 * adapters (otherwise org.chromium.content would depend on the webview.chromium package) |
| 75 * and a small set of no-op deprecated APIs. | 78 * and a small set of no-op deprecated APIs. |
| 76 */ | 79 */ |
| 77 @SuppressWarnings("deprecation") | 80 @SuppressWarnings("deprecation") |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 95 private AwContents mAwContents; | 98 private AwContents mAwContents; |
| 96 // Non-null if this webview is using the GL accelerated draw path. | 99 // Non-null if this webview is using the GL accelerated draw path. |
| 97 private DrawGLFunctor mGLfunctor; | 100 private DrawGLFunctor mGLfunctor; |
| 98 | 101 |
| 99 private final WebView.HitTestResult mHitTestResult; | 102 private final WebView.HitTestResult mHitTestResult; |
| 100 | 103 |
| 101 private final int mAppTargetSdkVersion; | 104 private final int mAppTargetSdkVersion; |
| 102 | 105 |
| 103 private WebViewChromiumFactoryProvider mFactory; | 106 private WebViewChromiumFactoryProvider mFactory; |
| 104 | 107 |
| 108 private static volatile AtomicBoolean sIsHtcMail = new AtomicBoolean(false); | |
|
Torne
2016/08/12 09:24:23
For future reference, don't use volatile for this
Changwan Ryu
2016/08/12 11:14:06
Acknowledged.
Torne
2016/08/12 13:25:41
Your new CL still has this as volatile. If we actu
Changwan Ryu
2016/08/16 10:30:24
My bad. Fixed as final.
| |
| 109 | |
| 105 private static boolean sRecordWholeDocumentEnabledByApi = false; | 110 private static boolean sRecordWholeDocumentEnabledByApi = false; |
| 106 static void enableSlowWholeDocumentDraw() { | 111 static void enableSlowWholeDocumentDraw() { |
| 107 sRecordWholeDocumentEnabledByApi = true; | 112 sRecordWholeDocumentEnabledByApi = true; |
| 108 } | 113 } |
| 109 | 114 |
| 110 // This does not touch any global / non-threadsafe state, but note that | 115 // This does not touch any global / non-threadsafe state, but note that |
| 111 // init is ofter called right after and is NOT threadsafe. | 116 // init is ofter called right after and is NOT threadsafe. |
| 112 public WebViewChromium(WebViewChromiumFactoryProvider factory, WebView webVi ew, | 117 public WebViewChromium(WebViewChromiumFactoryProvider factory, WebView webVi ew, |
| 113 WebView.PrivateAccess webViewPrivate) { | 118 WebView.PrivateAccess webViewPrivate) { |
| 114 mWebView = webView; | 119 mWebView = webView; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 128 } | 133 } |
| 129 | 134 |
| 130 // WebViewProvider methods ------------------------------------------------- ------------------- | 135 // WebViewProvider methods ------------------------------------------------- ------------------- |
| 131 | 136 |
| 132 @Override | 137 @Override |
| 133 // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete Dum pRenderTree | 138 // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete Dum pRenderTree |
| 134 // so is ignored. TODO: remove it from WebViewProvider. | 139 // so is ignored. TODO: remove it from WebViewProvider. |
| 135 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 140 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
| 136 public void init(final Map<String, Object> javaScriptInterfaces, | 141 public void init(final Map<String, Object> javaScriptInterfaces, |
| 137 final boolean privateBrowsing) { | 142 final boolean privateBrowsing) { |
| 143 sIsHtcMail.set(isHtcMail(mWebView)); | |
|
Torne
2016/08/12 09:24:23
There's no need to do this in WebViewChromium and
Changwan Ryu
2016/08/12 11:14:06
Unfortunately, disableThreadChecking should be cal
Torne
2016/08/12 13:25:41
Ah, I didn't realise it was reset in the construct
Changwan Ryu
2016/08/16 10:30:24
Moved the checking logic to factory and replaced a
| |
| 144 if (sIsHtcMail.get()) disableThreadChecking(mWebView); | |
| 138 if (privateBrowsing) { | 145 if (privateBrowsing) { |
| 139 mFactory.startYourEngines(true); | 146 mFactory.startYourEngines(true); |
| 140 final String msg = "Private browsing is not supported in WebView."; | 147 final String msg = "Private browsing is not supported in WebView."; |
| 141 if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) { | 148 if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) { |
| 142 throw new IllegalArgumentException(msg); | 149 throw new IllegalArgumentException(msg); |
| 143 } else { | 150 } else { |
| 144 Log.w(TAG, msg); | 151 Log.w(TAG, msg); |
| 145 TextView warningLabel = new TextView(mContext); | 152 TextView warningLabel = new TextView(mContext); |
| 146 warningLabel.setText(mContext.getString( | 153 warningLabel.setText(mContext.getString( |
| 147 org.chromium.android_webview.R.string.private_browsing_w arning)); | 154 org.chromium.android_webview.R.string.private_browsing_w arning)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 // Intentionally irreversibly disable the webview instance, so that private | 198 // Intentionally irreversibly disable the webview instance, so that private |
| 192 // user data cannot leak through misuse of a non-privateBrow ing WebView | 199 // user data cannot leak through misuse of a non-privateBrow ing WebView |
| 193 // instance. Can't just null out mAwContents as we never nul l-check it | 200 // instance. Can't just null out mAwContents as we never nul l-check it |
| 194 // before use. | 201 // before use. |
| 195 destroy(); | 202 destroy(); |
| 196 } | 203 } |
| 197 } | 204 } |
| 198 }); | 205 }); |
| 199 } | 206 } |
| 200 | 207 |
| 208 private boolean isHtcMail(View view) { | |
| 209 if (mAppTargetSdkVersion > Build.VERSION_CODES.M) return false; | |
| 210 final String htcMailPackageId = "com.htc.android.mail"; | |
| 211 if (view.getClass().getName() == null | |
|
Torne
2016/08/12 09:24:23
Instead of checking the class name of a view, just
Changwan Ryu
2016/08/12 11:14:06
Done.
| |
| 212 || !view.getClass().getName().startsWith(htcMailPackageId)) { | |
| 213 return false; | |
| 214 } | |
| 215 | |
| 216 try { | |
| 217 PackageInfo packageInfo = | |
| 218 view.getContext().getPackageManager().getPackageInfo(htcMail PackageId, 0); | |
| 219 // These values are provided by HTC. | |
| 220 if ((mAppTargetSdkVersion < Build.VERSION_CODES.M | |
| 221 && packageInfo.versionCode < 864021756) | |
| 222 || packageInfo.versionCode < 866001861) { | |
| 223 Log.w(TAG, "Disabling thread check in WebView (http://crbug.com/ 622151). " | |
| 224 + "APK name: " + htcMailPackageId + ", versionCode: " | |
| 225 + packageInfo.versionCode); | |
| 226 return true; | |
| 227 } | |
| 228 } catch (Exception e) { | |
| 229 e.printStackTrace(); | |
|
Torne
2016/08/12 09:24:23
Printing a stack trace and throwing the exception
Changwan Ryu
2016/08/12 11:14:06
Changed not to print stack trace.
| |
| 230 } | |
| 231 return false; | |
| 232 } | |
| 233 | |
| 234 // This is a workaround for https://crbug.com/622151. | |
| 235 // In HTC's email app, InputConnection.setComposingText() will call WebView. evaluateJavaScript, | |
| 236 // and thread assertion will occur. We turn off WebView thread assertion for this app. | |
| 237 private void disableThreadChecking(View view) { | |
| 238 for (Class<?> webViewClass = view.getClass(); | |
|
Torne
2016/08/12 09:24:23
No need to search the class hierarchy here (and th
Changwan Ryu
2016/08/12 11:14:06
Done. BTW, this should be done for each WebView.in
| |
| 239 webViewClass != null; | |
| 240 webViewClass = webViewClass.getSuperclass()) { | |
| 241 String name = webViewClass.getName(); | |
| 242 if (name != null && name.contains("WebView")) { | |
| 243 try { | |
| 244 Field field = webViewClass.getDeclaredField("sEnforceThreadC hecking"); | |
| 245 field.setAccessible(true); | |
| 246 field.setBoolean(null, false); | |
| 247 field.setAccessible(false); | |
| 248 } catch (NoSuchFieldException | IllegalAccessException | |
| 249 | IllegalArgumentException e) { | |
| 250 e.printStackTrace(); | |
|
Torne
2016/08/12 09:24:23
If we failed here, probably just print a single-li
Changwan Ryu
2016/08/12 11:14:06
Done.
| |
| 251 } | |
| 252 return; | |
| 253 } | |
| 254 } | |
| 255 } | |
| 256 | |
| 201 private void initForReal() { | 257 private void initForReal() { |
| 202 AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi | 258 AwContentsStatics.setRecordFullDocument(sRecordWholeDocumentEnabledByApi |
| 203 || mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP); | 259 || mAppTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP); |
| 204 | 260 |
| 205 mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWe bView, mContext, | 261 mAwContents = new AwContents(mFactory.getBrowserContextOnUiThread(), mWe bView, mContext, |
| 206 new InternalAccessAdapter(), new WebViewNativeDrawGLFunctorFacto ry(), | 262 new InternalAccessAdapter(), new WebViewNativeDrawGLFunctorFacto ry(), |
| 207 mContentsClientAdapter, mWebSettings.getAwSettings()); | 263 mContentsClientAdapter, mWebSettings.getAwSettings()); |
| 208 | 264 |
| 209 if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) { | 265 if (mAppTargetSdkVersion >= Build.VERSION_CODES.KITKAT) { |
| 210 // On KK and above, favicons are automatically downloaded as the met hod | 266 // On KK and above, favicons are automatically downloaded as the met hod |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 @Override | 589 @Override |
| 534 public void run() { | 590 public void run() { |
| 535 mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, enc oding, historyUrl); | 591 mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, enc oding, historyUrl); |
| 536 } | 592 } |
| 537 }); | 593 }); |
| 538 return; | 594 return; |
| 539 } | 595 } |
| 540 mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, histo ryUrl); | 596 mAwContents.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, histo ryUrl); |
| 541 } | 597 } |
| 542 | 598 |
| 543 public void evaluateJavaScript(String script, ValueCallback<String> resultCa llback) { | 599 public void evaluateJavaScript( |
| 600 final String script, final ValueCallback<String> resultCallback) { | |
| 601 if (sIsHtcMail.get()) { | |
| 602 // This is a workaround for https://crbug.com/622151. | |
| 603 ThreadUtils.postOnUiThread(new Runnable() { | |
|
Torne
2016/08/12 09:24:23
Use checkNeedsPost() instead of doing it unconditi
Changwan Ryu
2016/08/12 11:14:06
Changed to runOnUiThread and removed extra method.
| |
| 604 @Override | |
| 605 public void run() { | |
| 606 evaluateJavaScriptInternal(script, resultCallback); | |
| 607 } | |
| 608 }); | |
| 609 } else { | |
| 610 evaluateJavaScriptInternal(script, resultCallback); | |
| 611 } | |
| 612 } | |
| 613 | |
| 614 private void evaluateJavaScriptInternal(String script, ValueCallback<String> resultCallback) { | |
| 544 checkThread(); | 615 checkThread(); |
| 545 mAwContents.evaluateJavaScript(script, resultCallback); | 616 mAwContents.evaluateJavaScript(script, resultCallback); |
| 546 } | 617 } |
| 547 | 618 |
| 548 @Override | 619 @Override |
| 549 public void saveWebArchive(String filename) { | 620 public void saveWebArchive(String filename) { |
| 550 saveWebArchive(filename, false, null); | 621 saveWebArchive(filename, false, null); |
| 551 } | 622 } |
| 552 | 623 |
| 553 @Override | 624 @Override |
| (...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2227 mAwContents.extractSmartClipData(x, y, width, height); | 2298 mAwContents.extractSmartClipData(x, y, width, height); |
| 2228 } | 2299 } |
| 2229 | 2300 |
| 2230 // Implements SmartClipProvider | 2301 // Implements SmartClipProvider |
| 2231 @Override | 2302 @Override |
| 2232 public void setSmartClipResultHandler(final Handler resultHandler) { | 2303 public void setSmartClipResultHandler(final Handler resultHandler) { |
| 2233 checkThread(); | 2304 checkThread(); |
| 2234 mAwContents.setSmartClipResultHandler(resultHandler); | 2305 mAwContents.setSmartClipResultHandler(resultHandler); |
| 2235 } | 2306 } |
| 2236 } | 2307 } |
| OLD | NEW |