summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/BrowserFrame.java
diff options
context:
space:
mode:
authorPatrick Scott <phanna@android.com>2010-03-25 11:18:59 -0400
committerPatrick Scott <phanna@android.com>2010-03-25 11:51:37 -0400
commit11f5738424023ab0d2e90a41293685e71ac7e63a (patch)
tree65de03cdf5638e92c877d11bdf7684aa656957b8 /core/java/android/webkit/BrowserFrame.java
parent9c4750a6763ac0833f0d2d22bdeaa86561bbbebb (diff)
downloadframeworks_base-11f5738424023ab0d2e90a41293685e71ac7e63a.zip
frameworks_base-11f5738424023ab0d2e90a41293685e71ac7e63a.tar.gz
frameworks_base-11f5738424023ab0d2e90a41293685e71ac7e63a.tar.bz2
Use ViewRoot.addConfigCallback instead of a BroadcastReceiver.
Store a list of Handlers in a global ComponentCallbacks instance. Use WeakReference to avoid leaking BrowserFrame objects. Bug: 2542935 Change-Id: I67b102288f47f9fa6e855ba6558f2b1d611e8427
Diffstat (limited to 'core/java/android/webkit/BrowserFrame.java')
-rw-r--r--core/java/android/webkit/BrowserFrame.java121
1 files changed, 78 insertions, 43 deletions
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 7e871d0..beac0b8 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -17,11 +17,10 @@
package android.webkit;
import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
+import android.content.ComponentCallbacks;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.AssetManager;
+import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.ParseException;
@@ -34,12 +33,15 @@ import android.provider.OpenableColumns;
import android.util.Log;
import android.util.TypedValue;
import android.view.Surface;
+import android.view.ViewRoot;
import android.view.WindowManager;
import junit.framework.Assert;
import java.io.InputStream;
+import java.lang.ref.WeakReference;
import java.net.URLEncoder;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
@@ -76,11 +78,6 @@ class BrowserFrame extends Handler {
// Attached Javascript interfaces
private Map<String, Object> mJSInterfaceMap;
- // WindowManager to obtain the Display configuration.
- private WindowManager mWindowManager;
- // Orientation listener
- private BroadcastReceiver mOrientationListener;
-
// message ids
// a message posted when a frame loading is completed
static final int FRAME_COMPLETED = 1001;
@@ -110,6 +107,70 @@ class BrowserFrame extends Handler {
// requests from WebCore.
static JWebCoreJavaBridge sJavaBridge;
+ private static class ConfigCallback implements ComponentCallbacks {
+ private final ArrayList<WeakReference<Handler>> mHandlers =
+ new ArrayList<WeakReference<Handler>>();
+ private final WindowManager mWindowManager;
+
+ ConfigCallback(WindowManager wm) {
+ mWindowManager = wm;
+ }
+
+ public synchronized void addHandler(Handler h) {
+ // No need to ever remove a Handler. If the BrowserFrame is
+ // destroyed, it will be collected and the WeakReference set to
+ // null. If it happens to still be around during a configuration
+ // change, the message will be ignored.
+ mHandlers.add(new WeakReference<Handler>(h));
+ }
+
+ public void onConfigurationChanged(Configuration newConfig) {
+ if (mHandlers.size() == 0) {
+ return;
+ }
+ int orientation =
+ mWindowManager.getDefaultDisplay().getOrientation();
+ switch (orientation) {
+ case Surface.ROTATION_90:
+ orientation = 90;
+ break;
+ case Surface.ROTATION_180:
+ orientation = 180;
+ break;
+ case Surface.ROTATION_270:
+ orientation = -90;
+ break;
+ case Surface.ROTATION_0:
+ orientation = 0;
+ break;
+ default:
+ break;
+ }
+ synchronized (this) {
+ // Create a list of handlers to remove. Go ahead and make it
+ // the same size to avoid resizing.
+ ArrayList<WeakReference> handlersToRemove =
+ new ArrayList<WeakReference>(mHandlers.size());
+ for (WeakReference<Handler> wh : mHandlers) {
+ Handler h = wh.get();
+ if (h != null) {
+ h.sendMessage(h.obtainMessage(ORIENTATION_CHANGED,
+ orientation, 0));
+ } else {
+ handlersToRemove.add(wh);
+ }
+ }
+ // Now remove all the null references.
+ for (WeakReference weak : handlersToRemove) {
+ mHandlers.remove(weak);
+ }
+ }
+ }
+
+ public void onLowMemory() {}
+ }
+ static ConfigCallback sConfigCallback;
+
/**
* Create a new BrowserFrame to be used in an application.
* @param context An application context to use when retrieving assets.
@@ -143,6 +204,15 @@ class BrowserFrame extends Handler {
// create PluginManager with current Context
PluginManager.getInstance(appContext);
}
+
+ if (sConfigCallback == null) {
+ sConfigCallback = new ConfigCallback(
+ (WindowManager) context.getSystemService(
+ Context.WINDOW_SERVICE));
+ ViewRoot.addConfigCallback(sConfigCallback);
+ }
+ sConfigCallback.addHandler(this);
+
mJSInterfaceMap = javascriptInterfaces;
mSettings = settings;
@@ -157,40 +227,6 @@ class BrowserFrame extends Handler {
if (DebugFlags.BROWSER_FRAME) {
Log.v(LOGTAG, "BrowserFrame constructor: this=" + this);
}
-
- mWindowManager = (WindowManager) context.getSystemService(
- Context.WINDOW_SERVICE);
- mOrientationListener = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_CONFIGURATION_CHANGED.equals(
- intent.getAction())) {
- int orientation =
- mWindowManager.getDefaultDisplay().getOrientation();
- switch (orientation) {
- case Surface.ROTATION_90:
- orientation = 90;
- break;
- case Surface.ROTATION_180:
- orientation = 180;
- break;
- case Surface.ROTATION_270:
- orientation = -90;
- break;
- case Surface.ROTATION_0:
- orientation = 0;
- break;
- default:
- break;
- }
- sendMessage(
- obtainMessage(ORIENTATION_CHANGED, orientation, 0));
-
- }
- }
- };
- context.registerReceiver(mOrientationListener,
- new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
/**
@@ -397,7 +433,6 @@ class BrowserFrame extends Handler {
* Destroy all native components of the BrowserFrame.
*/
public void destroy() {
- mContext.unregisterReceiver(mOrientationListener);
nativeDestroyFrame();
mBlockMessages = true;
removeCallbacksAndMessages(null);