Commit 3680ea1e authored by wnwen's avatar wnwen Committed by Commit bot

Fix and clean up application context in webview.

- Move responsibility of application context initialization in
  AwBrowserProcess to caller to prevent double initialization.

- Switch to using ContextUtils.getApplicationContext for methods that
  only need the application context. Ensures the wrapped context is
  always used.

- Move away from using mWebViewDelegate.getApplication as that
  returns the raw unwrapped application object.

BUG=620790

Review-Url: https://codereview.chromium.org/2076623002
Cr-Commit-Position: refs/heads/master@{#400664}
parent 620327db
...@@ -118,10 +118,11 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -118,10 +118,11 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
// WebView needs to make sure to always use the wrapped application context. // WebView needs to make sure to always use the wrapped application context.
ContextUtils.initApplicationContext( ContextUtils.initApplicationContext(
ResourcesContextWrapperFactory.get(mWebViewDelegate.getApplication())); ResourcesContextWrapperFactory.get(
mWebViewDelegate.getApplication().getApplicationContext()));
if (isBuildDebuggable()) { if (isBuildDebuggable()) {
// Suppress the StrictMode violation as this codepath is only hit on debugglable builds. // Suppress the StrictMode violation as this codepath is only hit on debuggable builds.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
CommandLine.initFromFile(COMMAND_LINE_FILE); CommandLine.initFromFile(COMMAND_LINE_FILE);
StrictMode.setThreadPolicy(oldPolicy); StrictMode.setThreadPolicy(oldPolicy);
...@@ -131,7 +132,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -131,7 +132,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
ThreadUtils.setWillOverrideUiThread(); ThreadUtils.setWillOverrideUiThread();
// Load chromium library. // Load chromium library.
AwBrowserProcess.loadLibrary(ContextUtils.getApplicationContext()); AwBrowserProcess.loadLibrary();
final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo(); final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo();
...@@ -139,14 +140,14 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -139,14 +140,14 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
System.loadLibrary("webviewchromium_plat_support"); System.loadLibrary("webviewchromium_plat_support");
// Use shared preference to check for package downgrade. // Use shared preference to check for package downgrade.
mWebViewPrefs = mWebViewDelegate.getApplication().getSharedPreferences( mWebViewPrefs = ContextUtils.getApplicationContext().getSharedPreferences(
CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE); CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE);
int lastVersion = mWebViewPrefs.getInt(VERSION_CODE_PREF, 0); int lastVersion = mWebViewPrefs.getInt(VERSION_CODE_PREF, 0);
int currentVersion = packageInfo.versionCode; int currentVersion = packageInfo.versionCode;
if (!versionCodeGE(currentVersion, lastVersion)) { if (!versionCodeGE(currentVersion, lastVersion)) {
// The WebView package has been downgraded since we last ran in this application. // The WebView package has been downgraded since we last ran in this application.
// Delete the WebView data directory's contents. // Delete the WebView data directory's contents.
String dataDir = PathUtils.getDataDirectory(mWebViewDelegate.getApplication()); String dataDir = PathUtils.getDataDirectory(ContextUtils.getApplicationContext());
Log.i(TAG, "WebView package downgraded from " + lastVersion + " to " + currentVersion Log.i(TAG, "WebView package downgraded from " + lastVersion + " to " + currentVersion
+ "; deleting contents of " + dataDir); + "; deleting contents of " + dataDir);
deleteContents(new File(dataDir)); deleteContents(new File(dataDir));
...@@ -286,7 +287,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -286,7 +287,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
initNetworkChangeNotifier(context); initNetworkChangeNotifier(context);
final int extraBindFlags = 0; final int extraBindFlags = 0;
AwBrowserProcess.configureChildProcessLauncher(webViewPackageName, extraBindFlags); AwBrowserProcess.configureChildProcessLauncher(webViewPackageName, extraBindFlags);
AwBrowserProcess.start(context); AwBrowserProcess.start();
if (isBuildDebuggable()) { if (isBuildDebuggable()) {
setWebContentsDebuggingEnabled(true); setWebContentsDebuggingEnabled(true);
...@@ -313,7 +314,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -313,7 +314,7 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
// Start listening for data reduction proxy setting changes. // Start listening for data reduction proxy setting changes.
mProxyManager = new AwDataReductionProxyManager(); mProxyManager = new AwDataReductionProxyManager();
mProxyManager.start(mWebViewDelegate.getApplication()); mProxyManager.start(ContextUtils.getApplicationContext());
} }
boolean hasStarted() { boolean hasStarted() {
......
...@@ -40,12 +40,12 @@ public abstract class AwBrowserProcess { ...@@ -40,12 +40,12 @@ public abstract class AwBrowserProcess {
* to run webview in this process. Does not create threads; safe to call from zygote. * to run webview in this process. Does not create threads; safe to call from zygote.
* Note: it is up to the caller to ensure this is only called once. * Note: it is up to the caller to ensure this is only called once.
*/ */
public static void loadLibrary(Context context) { public static void loadLibrary() {
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context); Context appContext = ContextUtils.getApplicationContext();
ContextUtils.initApplicationContext(context.getApplicationContext()); PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, appContext);
try { try {
LibraryLoader libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW); LibraryLoader libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW);
libraryLoader.loadNow(context); libraryLoader.loadNow(appContext);
// Switch the command line implementation from Java to native. // Switch the command line implementation from Java to native.
// It's okay for the WebView to do this before initialization because we have // It's okay for the WebView to do this before initialization because we have
// setup the JNI bindings by this point. // setup the JNI bindings by this point.
...@@ -69,23 +69,23 @@ public abstract class AwBrowserProcess { ...@@ -69,23 +69,23 @@ public abstract class AwBrowserProcess {
* Starts the chromium browser process running within this process. Creates threads * Starts the chromium browser process running within this process. Creates threads
* and performs other per-app resource allocations; must not be called from zygote. * and performs other per-app resource allocations; must not be called from zygote.
* Note: it is up to the caller to ensure this is only called once. * Note: it is up to the caller to ensure this is only called once.
* @param context The Android application context
*/ */
public static void start(final Context context) { public static void start() {
tryObtainingDataDirLockOrDie(context); tryObtainingDataDirLockOrDie();
// We must post to the UI thread to cover the case that the user // We must post to the UI thread to cover the case that the user
// has invoked Chromium startup by using the (thread-safe) // has invoked Chromium startup by using the (thread-safe)
// CookieManager rather than creating a WebView. // CookieManager rather than creating a WebView.
ThreadUtils.runOnUiThreadBlocking(new Runnable() { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override @Override
public void run() { public void run() {
Context appContext = ContextUtils.getApplicationContext();
// The policies are used by browser startup, so we need to register the policy // The policies are used by browser startup, so we need to register the policy
// providers before starting the browser process. This only registers java objects // providers before starting the browser process. This only registers java objects
// and doesn't need the native library. // and doesn't need the native library.
CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(context)); CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(appContext));
try { try {
BrowserStartupController.get(context, LibraryProcessType.PROCESS_WEBVIEW) BrowserStartupController.get(appContext, LibraryProcessType.PROCESS_WEBVIEW)
.startBrowserProcessesSync(!CommandLine.getInstance().hasSwitch( .startBrowserProcessesSync(!CommandLine.getInstance().hasSwitch(
AwSwitches.WEBVIEW_SANDBOXED_RENDERER)); AwSwitches.WEBVIEW_SANDBOXED_RENDERER));
} catch (ProcessInitException e) { } catch (ProcessInitException e) {
...@@ -95,11 +95,11 @@ public abstract class AwBrowserProcess { ...@@ -95,11 +95,11 @@ public abstract class AwBrowserProcess {
}); });
} }
private static void tryObtainingDataDirLockOrDie(Context context) { private static void tryObtainingDataDirLockOrDie() {
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
StrictMode.allowThreadDiskWrites(); StrictMode.allowThreadDiskWrites();
try { try {
String dataPath = PathUtils.getDataDirectory(context); String dataPath = PathUtils.getDataDirectory(ContextUtils.getApplicationContext());
File lockFile = new File(dataPath, EXCLUSIVE_LOCK_FILE); File lockFile = new File(dataPath, EXCLUSIVE_LOCK_FILE);
boolean success = false; boolean success = false;
try { try {
......
...@@ -117,14 +117,15 @@ public class AwSecondBrowserProcessTest extends AwTestBase { ...@@ -117,14 +117,15 @@ public class AwSecondBrowserProcessTest extends AwTestBase {
} }
private boolean tryStartingBrowserProcess() { private boolean tryStartingBrowserProcess() {
final Context context = getActivity();
final Boolean success[] = new Boolean[1]; final Boolean success[] = new Boolean[1];
// The activity must be launched in order for proper webview statics to be setup.
getActivity();
// runOnMainSync does not catch RuntimeExceptions, they just terminate the test. // runOnMainSync does not catch RuntimeExceptions, they just terminate the test.
getInstrumentation().runOnMainSync(new Runnable() { getInstrumentation().runOnMainSync(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
AwBrowserProcess.start(context); AwBrowserProcess.start();
success[0] = true; success[0] = true;
} catch (RuntimeException e) { } catch (RuntimeException e) {
success[0] = false; success[0] = false;
......
...@@ -90,11 +90,12 @@ public class AwTestBase ...@@ -90,11 +90,12 @@ public class AwTestBase
} }
protected void startBrowserProcess() throws Exception { protected void startBrowserProcess() throws Exception {
final Context context = getActivity(); // The activity must be launched in order for proper webview statics to be setup.
getActivity();
getInstrumentation().runOnMainSync(new Runnable() { getInstrumentation().runOnMainSync(new Runnable() {
@Override @Override
public void run() { public void run() {
AwBrowserProcess.start(context); AwBrowserProcess.start();
} }
}); });
} }
......
...@@ -14,6 +14,7 @@ import org.chromium.android_webview.AwCookieManager; ...@@ -14,6 +14,7 @@ import org.chromium.android_webview.AwCookieManager;
import org.chromium.android_webview.AwWebResourceResponse; import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.CookieUtils; import org.chromium.android_webview.test.util.CookieUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.net.test.util.TestWebServer; import org.chromium.net.test.util.TestWebServer;
...@@ -29,10 +30,11 @@ public class CookieManagerStartupTest extends AwTestBase { ...@@ -29,10 +30,11 @@ public class CookieManagerStartupTest extends AwTestBase {
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
// CookeManager assumes that native is loaded, but webview browser should not be loaded for // CookieManager assumes that native is loaded, but webview browser should not be loaded for
// these tests as webview is not necessarily loaded when CookieManager is called. // these tests as webview is not necessarily loaded when CookieManager is called.
AwBrowserProcess.loadLibrary( Context appContext = getInstrumentation().getTargetContext().getApplicationContext();
getInstrumentation().getTargetContext().getApplicationContext()); ContextUtils.initApplicationContext(appContext);
AwBrowserProcess.loadLibrary();
} }
@Override @Override
...@@ -45,11 +47,12 @@ public class CookieManagerStartupTest extends AwTestBase { ...@@ -45,11 +47,12 @@ public class CookieManagerStartupTest extends AwTestBase {
} }
private void startChromiumWithClient(TestAwContentsClient contentsClient) throws Exception { private void startChromiumWithClient(TestAwContentsClient contentsClient) throws Exception {
final Context context = getActivity(); // The activity must be launched in order for proper webview statics to be setup.
getActivity();
getInstrumentation().runOnMainSync(new Runnable() { getInstrumentation().runOnMainSync(new Runnable() {
@Override @Override
public void run() { public void run() {
AwBrowserProcess.start(context); AwBrowserProcess.start();
} }
}); });
......
...@@ -70,11 +70,10 @@ public class HttpCacheTest extends AwTestBase { ...@@ -70,11 +70,10 @@ public class HttpCacheTest extends AwTestBase {
@SmallTest @SmallTest
@Feature({"AndroidWebView"}) @Feature({"AndroidWebView"})
public void testLegacyHttpCacheDirIsRemovedOnStartup() throws Exception { public void testLegacyHttpCacheDirIsRemovedOnStartup() throws Exception {
Context targetContext = getInstrumentation().getTargetContext(); Context appContext = getInstrumentation().getTargetContext().getApplicationContext();
PathUtils.setPrivateDataDirectorySuffix( PathUtils.setPrivateDataDirectorySuffix(
AwBrowserProcess.PRIVATE_DATA_DIRECTORY_SUFFIX, targetContext); AwBrowserProcess.PRIVATE_DATA_DIRECTORY_SUFFIX, appContext);
File webViewLegacyCacheDir = new File( File webViewLegacyCacheDir = new File(PathUtils.getDataDirectory(appContext), "Cache");
PathUtils.getDataDirectory(targetContext), "Cache");
if (!webViewLegacyCacheDir.isDirectory()) { if (!webViewLegacyCacheDir.isDirectory()) {
assertTrue(webViewLegacyCacheDir.mkdir()); assertTrue(webViewLegacyCacheDir.mkdir());
assertTrue(webViewLegacyCacheDir.isDirectory()); assertTrue(webViewLegacyCacheDir.isDirectory());
...@@ -83,8 +82,8 @@ public class HttpCacheTest extends AwTestBase { ...@@ -83,8 +82,8 @@ public class HttpCacheTest extends AwTestBase {
assertTrue(dummyCacheFile.exists()); assertTrue(dummyCacheFile.exists());
// Set up JNI bindings. // Set up JNI bindings.
ContextUtils.initApplicationContext(targetContext.getApplicationContext()); ContextUtils.initApplicationContext(appContext);
AwBrowserProcess.loadLibrary(targetContext); AwBrowserProcess.loadLibrary();
// No delay before removing the legacy cache files. // No delay before removing the legacy cache files.
AwContentsStatics.setLegacyCacheRemovalDelayForTest(0); AwContentsStatics.setLegacyCacheRemovalDelayForTest(0);
......
...@@ -40,6 +40,7 @@ import org.chromium.android_webview.test.AwTestContainerView; ...@@ -40,6 +40,7 @@ import org.chromium.android_webview.test.AwTestContainerView;
import org.chromium.android_webview.test.NullContentsClient; import org.chromium.android_webview.test.NullContentsClient;
import org.chromium.base.BaseSwitches; import org.chromium.base.BaseSwitches;
import org.chromium.base.CommandLine; import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.base.TraceEvent; import org.chromium.base.TraceEvent;
import org.chromium.content.app.ContentApplication; import org.chromium.content.app.ContentApplication;
...@@ -79,7 +80,8 @@ public class AwShellActivity extends Activity { ...@@ -79,7 +80,8 @@ public class AwShellActivity extends Activity {
ContentApplication.initCommandLine(this); ContentApplication.initCommandLine(this);
waitForDebuggerIfNeeded(); waitForDebuggerIfNeeded();
AwBrowserProcess.loadLibrary(this); ContextUtils.initApplicationContext(getApplicationContext());
AwBrowserProcess.loadLibrary();
if (CommandLine.getInstance().hasSwitch(AwShellSwitches.ENABLE_ATRACE)) { if (CommandLine.getInstance().hasSwitch(AwShellSwitches.ENABLE_ATRACE)) {
Log.e(TAG, "Enabling Android trace."); Log.e(TAG, "Enabling Android trace.");
...@@ -129,7 +131,7 @@ public class AwShellActivity extends Activity { ...@@ -129,7 +131,7 @@ public class AwShellActivity extends Activity {
} }
private AwTestContainerView createAwTestContainerView() { private AwTestContainerView createAwTestContainerView() {
AwBrowserProcess.start(this); AwBrowserProcess.start();
AwTestContainerView testContainerView = new AwTestContainerView(this, true); AwTestContainerView testContainerView = new AwTestContainerView(this, true);
AwContentsClient awContentsClient = new NullContentsClient() { AwContentsClient awContentsClient = new NullContentsClient() {
private View mCustomView; private View mCustomView;
......
...@@ -30,7 +30,7 @@ public class AwTestRunnerActivity extends Activity { ...@@ -30,7 +30,7 @@ public class AwTestRunnerActivity extends Activity {
AwShellResourceProvider.registerResources(this); AwShellResourceProvider.registerResources(this);
ContextUtils.initApplicationContext(getApplicationContext()); ContextUtils.initApplicationContext(getApplicationContext());
AwBrowserProcess.loadLibrary(this); AwBrowserProcess.loadLibrary();
mLinearLayout = new LinearLayout(this); mLinearLayout = new LinearLayout(this);
mLinearLayout.setOrientation(LinearLayout.VERTICAL); mLinearLayout.setOrientation(LinearLayout.VERTICAL);
......
...@@ -15,6 +15,7 @@ import org.chromium.android_webview.AwBrowserProcess; ...@@ -15,6 +15,7 @@ import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.android_webview.AwResource; import org.chromium.android_webview.AwResource;
import org.chromium.android_webview.shell.R; import org.chromium.android_webview.shell.R;
import org.chromium.base.CommandLine; import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.annotations.SuppressFBWarnings;
/** /**
...@@ -56,7 +57,8 @@ public class SecondBrowserProcess extends Service { ...@@ -56,7 +57,8 @@ public class SecondBrowserProcess extends Service {
CommandLine.initFromFile("/data/local/tmp/android-webview-command-line"); CommandLine.initFromFile("/data/local/tmp/android-webview-command-line");
AwResource.setResources(this.getResources()); AwResource.setResources(this.getResources());
AwResource.setConfigKeySystemUuidMapping(R.array.config_key_system_uuid_mapping); AwResource.setConfigKeySystemUuidMapping(R.array.config_key_system_uuid_mapping);
AwBrowserProcess.loadLibrary(this); ContextUtils.initApplicationContext(getApplicationContext());
AwBrowserProcess.start(this); AwBrowserProcess.loadLibrary();
AwBrowserProcess.start();
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment