Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(812)

Side by Side Diff: android_webview/glue/java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java

Issue 1078693003: android_webview: stop leaking Contexts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.content.ComponentCallbacks; 7 import android.content.ComponentCallbacks;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.ContextWrapper; 9 import android.content.ContextWrapper;
10 import android.view.LayoutInflater; 10 import android.view.LayoutInflater;
11 11
12 import org.chromium.base.annotations.SuppressFBWarnings; 12 import org.chromium.base.annotations.SuppressFBWarnings;
13 13
14 import java.util.WeakHashMap;
15
16 /** 14 /**
17 * This class allows us to wrap the application context so that the WebView impl ementation can 15 * This class allows us to wrap the application context so that the WebView impl ementation can
18 * correctly reference both org.chromium.* and application classes which is nece ssary to properly 16 * correctly reference both org.chromium.* and application classes which is nece ssary to properly
19 * inflate UI. We keep a weak map from contexts to wrapped contexts to avoid co nstantly re-wrapping 17 * inflate UI.
20 * or doubly wrapping contexts.
21 */ 18 */
22 public class ResourcesContextWrapperFactory { 19 public class ResourcesContextWrapperFactory {
23 private static WeakHashMap<Context, ContextWrapper> sCtxToWrapper =
24 new WeakHashMap<Context, ContextWrapper>();
25 private static final Object sLock = new Object();
26
27 private ResourcesContextWrapperFactory() {} 20 private ResourcesContextWrapperFactory() {}
28 21
29 public static Context get(Context ctx) { 22 public static Context get(Context ctx) {
30 ContextWrapper wrappedCtx; 23 // Avoid double-wrapping a context.
31 synchronized (sLock) { 24 if (ctx instanceof WebViewContextWrapper) {
32 wrappedCtx = sCtxToWrapper.get(ctx); 25 return ctx;
33 if (wrappedCtx == null) { 26 }
34 wrappedCtx = createWrapper(ctx); 27 return new WebViewContextWrapper(ctx);
35 sCtxToWrapper.put(ctx, wrappedCtx); 28 }
29
30 private static class WebViewContextWrapper extends ContextWrapper {
31 private Context mApplicationContext;
32
33 public WebViewContextWrapper(Context base) {
34 super(base);
35 }
36
37 @SuppressFBWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
38 @Override
39 public ClassLoader getClassLoader() {
40 final ClassLoader appCl = getBaseContext().getClassLoader();
41 final ClassLoader webViewCl = this.getClass().getClassLoader();
42 return new ClassLoader() {
43 @Override
44 protected Class<?> findClass(String name) throws ClassNotFoundEx ception {
45 // First look in the WebViewProvider class loader.
46 try {
47 return webViewCl.loadClass(name);
48 } catch (ClassNotFoundException e) {
49 // Look in the app class loader; allowing it to throw
50 // ClassNotFoundException.
51 return appCl.loadClass(name);
52 }
53 }
54 };
55 }
56
57 @Override
58 public Object getSystemService(String name) {
59 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
60 LayoutInflater i = (LayoutInflater) getBaseContext().getSystemSe rvice(name);
61 return i.cloneInContext(this);
62 } else {
63 return getBaseContext().getSystemService(name);
36 } 64 }
37 } 65 }
38 return wrappedCtx;
39 }
40 66
41 private static ContextWrapper createWrapper(final Context ctx) { 67 @Override
42 return new ContextWrapper(ctx) { 68 public Context getApplicationContext() {
43 private Context mApplicationContext; 69 if (mApplicationContext == null) {
44 70 Context appCtx = getBaseContext().getApplicationContext();
45 @SuppressFBWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED") 71 if (appCtx == getBaseContext()) {
46 @Override 72 mApplicationContext = this;
47 public ClassLoader getClassLoader() {
48 final ClassLoader appCl = getBaseContext().getClassLoader();
49 final ClassLoader webViewCl = this.getClass().getClassLoader();
50 return new ClassLoader() {
51 @Override
52 protected Class<?> findClass(String name) throws ClassNotFou ndException {
53 // First look in the WebViewProvider class loader.
54 try {
55 return webViewCl.loadClass(name);
56 } catch (ClassNotFoundException e) {
57 // Look in the app class loader; allowing it to thro w
58 // ClassNotFoundException.
59 return appCl.loadClass(name);
60 }
61 }
62 };
63 }
64
65 @Override
66 public Object getSystemService(String name) {
67 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
68 LayoutInflater i = (LayoutInflater) getBaseContext().getSyst emService(name);
69 return i.cloneInContext(this);
70 } else { 73 } else {
71 return getBaseContext().getSystemService(name); 74 mApplicationContext = get(appCtx);
72 } 75 }
73 } 76 }
77 return mApplicationContext;
78 }
74 79
75 @Override 80 @Override
76 public Context getApplicationContext() { 81 public void registerComponentCallbacks(ComponentCallbacks callback) {
77 if (mApplicationContext == null) { 82 // We have to override registerComponentCallbacks and unregisterComp onentCallbacks
78 mApplicationContext = get(ctx.getApplicationContext()); 83 // since they call getApplicationContext().[un]registerComponentCall backs()
79 } 84 // which causes us to go into a loop.
80 return mApplicationContext; 85 getBaseContext().registerComponentCallbacks(callback);
81 } 86 }
82 87
83 @Override 88 @Override
84 public void registerComponentCallbacks(ComponentCallbacks callback) { 89 public void unregisterComponentCallbacks(ComponentCallbacks callback) {
85 // We have to override registerComponentCallbacks and unregister ComponentCallbacks 90 getBaseContext().unregisterComponentCallbacks(callback);
86 // since they call getApplicationContext().[un]registerComponent Callbacks() 91 }
87 // which causes us to go into a loop.
88 ctx.registerComponentCallbacks(callback);
89 }
90
91 @Override
92 public void unregisterComponentCallbacks(ComponentCallbacks callback ) {
93 ctx.unregisterComponentCallbacks(callback);
94 }
95 };
96 } 92 }
97 } 93 }
OLDNEW
« no previous file with comments | « no previous file | android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698