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

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

Issue 1056113004: android_webview: stop leaking Contexts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2311
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 java.util.WeakHashMap;
13
14 /** 12 /**
15 * This class allows us to wrap the application context so that the WebView impl ementation can 13 * This class allows us to wrap the application context so that the WebView impl ementation can
16 * correctly reference both org.chromium.* and application classes which is nece ssary to properly 14 * correctly reference both org.chromium.* and application classes which is nece ssary to properly
17 * inflate UI. We keep a weak map from contexts to wrapped contexts to avoid co nstantly re-wrapping 15 * inflate UI.
18 * or doubly wrapping contexts.
19 */ 16 */
20 public class ResourcesContextWrapperFactory { 17 public class ResourcesContextWrapperFactory {
21 private static WeakHashMap<Context, ContextWrapper> sCtxToWrapper =
22 new WeakHashMap<Context, ContextWrapper>();
23 private static final Object sLock = new Object();
24
25 private ResourcesContextWrapperFactory() {} 18 private ResourcesContextWrapperFactory() {}
26 19
27 public static Context get(Context ctx) { 20 public static Context get(Context ctx) {
28 ContextWrapper wrappedCtx; 21 // Avoid double-wrapping a context.
29 synchronized (sLock) { 22 if (ctx instanceof WebViewContextWrapper) {
30 wrappedCtx = sCtxToWrapper.get(ctx); 23 return ctx;
31 if (wrappedCtx == null) { 24 }
32 wrappedCtx = createWrapper(ctx); 25 return new WebViewContextWrapper(ctx);
33 sCtxToWrapper.put(ctx, wrappedCtx); 26 }
27
28 private static class WebViewContextWrapper extends ContextWrapper {
29 private Context mApplicationContext;
30
31 public WebViewContextWrapper(Context base) {
32 super(base);
33 }
34
35 @Override
36 public ClassLoader getClassLoader() {
37 final ClassLoader appCl = getBaseContext().getClassLoader();
38 final ClassLoader webViewCl = this.getClass().getClassLoader();
39 return new ClassLoader() {
40 @Override
41 protected Class<?> findClass(String name) throws ClassNotFoundEx ception {
42 // First look in the WebViewProvider class loader.
43 try {
44 return webViewCl.loadClass(name);
45 } catch (ClassNotFoundException e) {
46 // Look in the app class loader; allowing it to throw
47 // ClassNotFoundException.
48 return appCl.loadClass(name);
49 }
50 }
51 };
52 }
53
54 @Override
55 public Object getSystemService(String name) {
56 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
57 LayoutInflater i = (LayoutInflater) getBaseContext().getSystemSe rvice(name);
58 return i.cloneInContext(this);
59 } else {
60 return getBaseContext().getSystemService(name);
34 } 61 }
35 } 62 }
36 return wrappedCtx;
37 }
38 63
39 private static ContextWrapper createWrapper(final Context ctx) { 64 @Override
40 return new ContextWrapper(ctx) { 65 public Context getApplicationContext() {
41 private Context mApplicationContext; 66 if (mApplicationContext == null) {
42 67 Context appCtx = getBaseContext().getApplicationContext();
43 @Override 68 if (appCtx == getBaseContext()) {
44 public ClassLoader getClassLoader() { 69 mApplicationContext = this;
45 final ClassLoader appCl = getBaseContext().getClassLoader();
46 final ClassLoader webViewCl = this.getClass().getClassLoader();
47 return new ClassLoader() {
48 @Override
49 protected Class<?> findClass(String name) throws ClassNotFou ndException {
50 // First look in the WebViewProvider class loader.
51 try {
52 return webViewCl.loadClass(name);
53 } catch (ClassNotFoundException e) {
54 // Look in the app class loader; allowing it to thro w
55 // ClassNotFoundException.
56 return appCl.loadClass(name);
57 }
58 }
59 };
60 }
61
62 @Override
63 public Object getSystemService(String name) {
64 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
65 LayoutInflater i = (LayoutInflater) getBaseContext().getSyst emService(name);
66 return i.cloneInContext(this);
67 } else { 70 } else {
68 return getBaseContext().getSystemService(name); 71 mApplicationContext = get(appCtx);
69 } 72 }
70 } 73 }
74 return mApplicationContext;
75 }
71 76
72 @Override 77 @Override
73 public Context getApplicationContext() { 78 public void registerComponentCallbacks(ComponentCallbacks callback) {
74 if (mApplicationContext == null) 79 // We have to override registerComponentCallbacks and unregisterComp onentCallbacks
75 mApplicationContext = get(ctx.getApplicationContext()); 80 // since they call getApplicationContext().[un]registerComponentCall backs()
76 return mApplicationContext; 81 // which causes us to go into a loop.
77 } 82 getBaseContext().registerComponentCallbacks(callback);
83 }
78 84
79 @Override 85 @Override
80 public void registerComponentCallbacks(ComponentCallbacks callback) { 86 public void unregisterComponentCallbacks(ComponentCallbacks callback) {
81 // We have to override registerComponentCallbacks and unregister ComponentCallbacks 87 getBaseContext().unregisterComponentCallbacks(callback);
82 // since they call getApplicationContext().[un]registerComponent Callbacks() 88 }
83 // which causes us to go into a loop.
84 ctx.registerComponentCallbacks(callback);
85 }
86
87 @Override
88 public void unregisterComponentCallbacks(ComponentCallbacks callback ) {
89 ctx.unregisterComponentCallbacks(callback);
90 }
91 };
92 } 89 }
93 } 90 }
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