| 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.Manifest; | 7 import android.Manifest; |
| 8 import android.app.ActivityManager; | 8 import android.app.ActivityManager; |
| 9 import android.content.ComponentCallbacks2; | 9 import android.content.ComponentCallbacks2; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 import org.chromium.base.TraceEvent; | 51 import org.chromium.base.TraceEvent; |
| 52 import org.chromium.base.annotations.SuppressFBWarnings; | 52 import org.chromium.base.annotations.SuppressFBWarnings; |
| 53 import org.chromium.base.library_loader.LibraryLoader; | 53 import org.chromium.base.library_loader.LibraryLoader; |
| 54 import org.chromium.base.library_loader.LibraryProcessType; | 54 import org.chromium.base.library_loader.LibraryProcessType; |
| 55 import org.chromium.base.library_loader.ProcessInitException; | 55 import org.chromium.base.library_loader.ProcessInitException; |
| 56 import org.chromium.content.browser.ContentViewStatics; | 56 import org.chromium.content.browser.ContentViewStatics; |
| 57 import org.chromium.net.NetworkChangeNotifier; | 57 import org.chromium.net.NetworkChangeNotifier; |
| 58 import org.chromium.ui.base.ResourceBundle; | 58 import org.chromium.ui.base.ResourceBundle; |
| 59 | 59 |
| 60 import java.io.File; | 60 import java.io.File; |
| 61 import java.lang.ref.WeakReference; | 61 import java.util.Queue; |
| 62 import java.util.ArrayList; | 62 import java.util.concurrent.Callable; |
| 63 import java.util.concurrent.ConcurrentLinkedQueue; |
| 64 import java.util.concurrent.FutureTask; |
| 65 import java.util.concurrent.TimeUnit; |
| 63 | 66 |
| 64 /** | 67 /** |
| 65 * Entry point to the WebView. The system framework talks to this class to get i
nstances of the | 68 * Entry point to the WebView. The system framework talks to this class to get i
nstances of the |
| 66 * implementation classes. | 69 * implementation classes. |
| 67 */ | 70 */ |
| 68 @SuppressWarnings("deprecation") | 71 @SuppressWarnings("deprecation") |
| 69 public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { | 72 public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { |
| 70 private static final String TAG = "WebViewChromiumFactoryProvider"; | 73 private static final String TAG = "WebViewChromiumFactoryProvider"; |
| 71 | 74 |
| 72 private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs"; | 75 private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs"; |
| 73 private static final String VERSION_CODE_PREF = "lastVersionCodeUsed"; | 76 private static final String VERSION_CODE_PREF = "lastVersionCodeUsed"; |
| 74 private static final String COMMAND_LINE_FILE = "/data/local/tmp/webview-com
mand-line"; | 77 private static final String COMMAND_LINE_FILE = "/data/local/tmp/webview-com
mand-line"; |
| 75 | 78 |
| 79 private class WebViewChromiumRunQueue { |
| 80 public WebViewChromiumRunQueue() { |
| 81 mQueue = new ConcurrentLinkedQueue<Runnable>(); |
| 82 } |
| 83 |
| 84 public void addTask(Runnable task) { |
| 85 mQueue.add(task); |
| 86 if (WebViewChromiumFactoryProvider.this.hasStarted()) { |
| 87 ThreadUtils.runOnUiThread(new Runnable() { |
| 88 @Override |
| 89 public void run() { |
| 90 drainQueue(); |
| 91 } |
| 92 }); |
| 93 } |
| 94 } |
| 95 |
| 96 public void drainQueue() { |
| 97 if (mQueue == null || mQueue.isEmpty()) { |
| 98 return; |
| 99 } |
| 100 |
| 101 Runnable task = mQueue.poll(); |
| 102 while (task != null) { |
| 103 task.run(); |
| 104 task = mQueue.poll(); |
| 105 } |
| 106 } |
| 107 |
| 108 private Queue<Runnable> mQueue; |
| 109 } |
| 110 |
| 111 private final WebViewChromiumRunQueue mRunQueue = new WebViewChromiumRunQueu
e(); |
| 112 |
| 113 private <T> T runBlockingFuture(FutureTask<T> task) { |
| 114 if (!hasStarted()) throw new RuntimeException("Must be started before we
block!"); |
| 115 if (ThreadUtils.runningOnUiThread()) { |
| 116 throw new IllegalStateException("This method should only be called o
ff the UI thread"); |
| 117 } |
| 118 mRunQueue.addTask(task); |
| 119 try { |
| 120 return task.get(4, TimeUnit.SECONDS); |
| 121 } catch (java.util.concurrent.TimeoutException e) { |
| 122 throw new RuntimeException("Probable deadlock detected due to WebVie
w API being called " |
| 123 + "on incorrect thread while the UI thread is blocke
d.", e); |
| 124 } catch (Exception e) { |
| 125 throw new RuntimeException(e); |
| 126 } |
| 127 } |
| 128 |
| 129 // We have a 4 second timeout to try to detect deadlocks to detect and aid i
n debuggin |
| 130 // deadlocks. |
| 131 // Do not call this method while on the UI thread! |
| 132 /* package */ void runVoidTaskOnUiThreadBlocking(Runnable r) { |
| 133 FutureTask<Void> task = new FutureTask<Void>(r, null); |
| 134 runBlockingFuture(task); |
| 135 } |
| 136 |
| 137 /* package */ <T> T runOnUiThreadBlocking(Callable<T> c) { |
| 138 return runBlockingFuture(new FutureTask<T>(c)); |
| 139 } |
| 140 |
| 141 /* package */ void addTask(Runnable task) { |
| 142 mRunQueue.addTask(task); |
| 143 } |
| 144 |
| 76 // Guards accees to the other members, and is notifyAll() signalled on the U
I thread | 145 // Guards accees to the other members, and is notifyAll() signalled on the U
I thread |
| 77 // when the chromium process has been started. | 146 // when the chromium process has been started. |
| 78 private final Object mLock = new Object(); | 147 private final Object mLock = new Object(); |
| 79 | 148 |
| 80 // Initialization guarded by mLock. | 149 // Initialization guarded by mLock. |
| 81 private AwBrowserContext mBrowserContext; | 150 private AwBrowserContext mBrowserContext; |
| 82 private Statics mStaticMethods; | 151 private Statics mStaticMethods; |
| 83 private GeolocationPermissionsAdapter mGeolocationPermissions; | 152 private GeolocationPermissionsAdapter mGeolocationPermissions; |
| 84 private CookieManagerAdapter mCookieManager; | 153 private CookieManagerAdapter mCookieManager; |
| 85 private WebIconDatabaseAdapter mWebIconDatabase; | 154 private WebIconDatabaseAdapter mWebIconDatabase; |
| 86 private WebStorageAdapter mWebStorage; | 155 private WebStorageAdapter mWebStorage; |
| 87 private WebViewDatabaseAdapter mWebViewDatabase; | 156 private WebViewDatabaseAdapter mWebViewDatabase; |
| 88 private AwDevToolsServer mDevToolsServer; | 157 private AwDevToolsServer mDevToolsServer; |
| 89 | 158 |
| 90 private ArrayList<WeakReference<WebViewChromium>> mWebViewsToStart = | |
| 91 new ArrayList<WeakReference<WebViewChromium>>(); | |
| 92 | |
| 93 // Read/write protected by mLock. | 159 // Read/write protected by mLock. |
| 94 private boolean mStarted; | 160 private boolean mStarted; |
| 95 | 161 |
| 96 private SharedPreferences mWebViewPrefs; | 162 private SharedPreferences mWebViewPrefs; |
| 97 private WebViewDelegate mWebViewDelegate; | 163 private WebViewDelegate mWebViewDelegate; |
| 98 | 164 |
| 99 /** | 165 /** |
| 100 * Constructor called by the API 21 version of {@link WebViewFactory} and ea
rlier. | 166 * Constructor called by the API 21 version of {@link WebViewFactory} and ea
rlier. |
| 101 */ | 167 */ |
| 102 public WebViewChromiumFactoryProvider() { | 168 public WebViewChromiumFactoryProvider() { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 | 359 |
| 294 TraceEvent.setATraceEnabled(mWebViewDelegate.isTraceTagEnabled()); | 360 TraceEvent.setATraceEnabled(mWebViewDelegate.isTraceTagEnabled()); |
| 295 mWebViewDelegate.setOnTraceEnabledChangeListener( | 361 mWebViewDelegate.setOnTraceEnabledChangeListener( |
| 296 new WebViewDelegate.OnTraceEnabledChangeListener() { | 362 new WebViewDelegate.OnTraceEnabledChangeListener() { |
| 297 @Override | 363 @Override |
| 298 public void onTraceEnabledChange(boolean enabled) { | 364 public void onTraceEnabledChange(boolean enabled) { |
| 299 TraceEvent.setATraceEnabled(enabled); | 365 TraceEvent.setATraceEnabled(enabled); |
| 300 } | 366 } |
| 301 }); | 367 }); |
| 302 mStarted = true; | 368 mStarted = true; |
| 303 | 369 mRunQueue.drainQueue(); |
| 304 for (WeakReference<WebViewChromium> wvc : mWebViewsToStart) { | |
| 305 WebViewChromium w = wvc.get(); | |
| 306 if (w != null) { | |
| 307 w.startYourEngine(); | |
| 308 } | |
| 309 } | |
| 310 mWebViewsToStart.clear(); | |
| 311 mWebViewsToStart = null; | |
| 312 } | 370 } |
| 313 | 371 |
| 314 boolean hasStarted() { | 372 boolean hasStarted() { |
| 315 return mStarted; | 373 return mStarted; |
| 316 } | 374 } |
| 317 | 375 |
| 318 void startYourEngines(boolean onMainThread) { | 376 void startYourEngines(boolean onMainThread) { |
| 319 synchronized (mLock) { | 377 synchronized (mLock) { |
| 320 ensureChromiumStartedLocked(onMainThread); | 378 ensureChromiumStartedLocked(onMainThread); |
| 321 } | 379 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 return AwContentsClient.parseFileChooserResult(resultCod
e, intent); | 466 return AwContentsClient.parseFileChooserResult(resultCod
e, intent); |
| 409 } | 467 } |
| 410 }; | 468 }; |
| 411 } | 469 } |
| 412 } | 470 } |
| 413 return mStaticMethods; | 471 return mStaticMethods; |
| 414 } | 472 } |
| 415 | 473 |
| 416 @Override | 474 @Override |
| 417 public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess
privateAccess) { | 475 public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess
privateAccess) { |
| 418 WebViewChromium wvc = new WebViewChromium(this, webView, privateAccess); | 476 return new WebViewChromium(this, webView, privateAccess); |
| 419 | |
| 420 synchronized (mLock) { | |
| 421 if (mWebViewsToStart != null) { | |
| 422 mWebViewsToStart.add(new WeakReference<WebViewChromium>(wvc)); | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 return wvc; | |
| 427 } | 477 } |
| 428 | 478 |
| 429 @Override | 479 @Override |
| 430 public GeolocationPermissions getGeolocationPermissions() { | 480 public GeolocationPermissions getGeolocationPermissions() { |
| 431 synchronized (mLock) { | 481 synchronized (mLock) { |
| 432 if (mGeolocationPermissions == null) { | 482 if (mGeolocationPermissions == null) { |
| 433 ensureChromiumStartedLocked(true); | 483 ensureChromiumStartedLocked(true); |
| 434 mGeolocationPermissions = new GeolocationPermissionsAdapter( | 484 mGeolocationPermissions = new GeolocationPermissionsAdapter( |
| 435 getBrowserContextLocked().getGeolocationPermissions()); | 485 getBrowserContextLocked().getGeolocationPermissions()); |
| 436 } | 486 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 browserContext.getHttpAuthDatabase(context)); | 530 browserContext.getHttpAuthDatabase(context)); |
| 481 } | 531 } |
| 482 } | 532 } |
| 483 return mWebViewDatabase; | 533 return mWebViewDatabase; |
| 484 } | 534 } |
| 485 | 535 |
| 486 WebViewDelegate getWebViewDelegate() { | 536 WebViewDelegate getWebViewDelegate() { |
| 487 return mWebViewDelegate; | 537 return mWebViewDelegate; |
| 488 } | 538 } |
| 489 } | 539 } |
| OLD | NEW |