Bug 802130 - Move mMainHandler into ThreadUtils. r=mfinkle

This commit is contained in:
Kartikaya Gupta 2013-03-15 11:52:53 +01:00
parent 48ba402f28
commit 1424e8b030
17 changed files with 80 additions and 70 deletions

View File

@ -6,6 +6,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.ActivityResultHandlerMap;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONException;
import org.json.JSONObject;
@ -152,7 +153,7 @@ class ActivityHandlerHelper {
}
Runnable filePicker = new FilePickerPromptRunnable(getFilePickerTitle(context, aMimeType), items);
GeckoAppShell.getMainHandler().post(filePicker);
ThreadUtils.postToUiThread(filePicker);
String promptServiceResult = "";
try {

View File

@ -7,8 +7,9 @@ package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.BrowserContract.Combined;
import org.mozilla.gecko.util.UiAsyncTask;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import android.app.Activity;
import android.app.AlertDialog;
@ -100,7 +101,7 @@ public class AwesomeBar extends GeckoActivity {
@Override
public void onEditSuggestion(final String text) {
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mText.setText(text);

View File

@ -11,6 +11,7 @@ import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.util.UiAsyncTask;
import org.mozilla.gecko.util.GeckoBackgroundThread;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONArray;
import org.json.JSONException;
@ -137,7 +138,7 @@ abstract public class BrowserApp extends GeckoApp
: TabsPanel.Panel.NORMAL_TABS;
// Delay calling showTabs so that it does not modify the mTabsChangedListeners
// array while we are still iterating through the array.
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (areTabsShown() && mTabsPanel.getCurrentPanel() != panel)
@ -397,7 +398,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
void onStatePurged() {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (mAboutHomeContent != null)
@ -469,7 +470,7 @@ abstract public class BrowserApp extends GeckoApp
}
mDynamicToolbarEnabled = value;
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (mDynamicToolbarEnabled) {
@ -603,7 +604,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
void toggleChrome(final boolean aShow) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (aShow) {
@ -622,7 +623,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
void focusChrome() {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mBrowserToolbar.show();
@ -751,7 +752,7 @@ abstract public class BrowserApp extends GeckoApp
info.parent = message.getInt("parent") + ADDON_MENU_OFFSET;
} catch (Exception ex) { }
final MenuItemInfo menuItemInfo = info;
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
addAddonMenuItem(menuItemInfo);
@ -759,7 +760,7 @@ abstract public class BrowserApp extends GeckoApp
});
} else if (event.equals("Menu:Remove")) {
final int id = message.getInt("id") + ADDON_MENU_OFFSET;
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
removeAddonMenuItem(id);
@ -768,7 +769,7 @@ abstract public class BrowserApp extends GeckoApp
} else if (event.equals("Menu:Update")) {
final int id = message.getInt("id") + ADDON_MENU_OFFSET;
final JSONObject options = message.getJSONObject("options");
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
updateAddonMenuItem(id, options);
@ -804,7 +805,7 @@ abstract public class BrowserApp extends GeckoApp
dialog.dismiss();
}
});
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
dialogBuilder.show();
@ -814,7 +815,7 @@ abstract public class BrowserApp extends GeckoApp
final boolean visible = message.getString("visible").equals("true");
GeckoPreferences.setCharEncodingState(visible);
final Menu menu = mMenu;
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (menu != null)
@ -834,7 +835,7 @@ abstract public class BrowserApp extends GeckoApp
// menuitem, which is specific to BrowserApp.
super.handleMessage(event, message);
final Menu menu = mMenu;
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (menu != null)
@ -1054,7 +1055,7 @@ abstract public class BrowserApp extends GeckoApp
mAboutHomeShowing = true;
Runnable r = new AboutHomeRunnable(true);
mMainHandler.postAtFrontOfQueue(r);
ThreadUtils.getUiHandler().postAtFrontOfQueue(r);
}
private void hideAboutHome() {
@ -1066,7 +1067,7 @@ abstract public class BrowserApp extends GeckoApp
mBrowserToolbar.setShadowVisibility(true);
mAboutHomeShowing = false;
Runnable r = new AboutHomeRunnable(false);
mMainHandler.postAtFrontOfQueue(r);
ThreadUtils.getUiHandler().postAtFrontOfQueue(r);
}
private class AboutHomeRunnable implements Runnable {
@ -1339,7 +1340,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
public void setFullScreen(final boolean fullscreen) {
super.setFullScreen(fullscreen);
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (fullscreen)

View File

@ -6,8 +6,9 @@
package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.util.UiAsyncTask;
import org.mozilla.gecko.util.GeckoJarReader;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
@ -82,7 +83,7 @@ public class Favicons {
putFaviconInMemCache(pageUrl, image);
// We want to always run the listener on UI thread
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (listener != null)

View File

@ -8,6 +8,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONArray;
import org.json.JSONException;
@ -101,7 +102,7 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
private void handleAutoCompleteMessage(JSONObject message) throws JSONException {
final JSONArray suggestions = message.getJSONArray("suggestions");
final JSONObject rect = message.getJSONObject("rect");
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
showAutoCompleteSuggestions(suggestions, rect);
@ -112,7 +113,7 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
private void handleValidationMessage(JSONObject message) throws JSONException {
final String validationMessage = message.getString("validationMessage");
final JSONObject rect = message.getJSONObject("rect");
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
showValidationMessage(validationMessage, rect);
@ -121,7 +122,7 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
}
private void handleHideMessage(JSONObject message) {
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
hide();

View File

@ -6,6 +6,7 @@
package org.mozilla.gecko;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.util.ThreadUtils;
import android.view.accessibility.*;
import android.view.View;
@ -161,7 +162,7 @@ public class GeckoAccessibility {
// Store the JSON message and use it to populate the event later in the code path.
sEventMessage = message;
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
// If this is an accessibility focus, a lot of internal voodoo happens so we perform an

View File

@ -157,7 +157,6 @@ abstract public class GeckoApp
protected MenuPanel mMenuPanel;
protected Menu mMenu;
private static GeckoThread sGeckoThread;
public Handler mMainHandler;
private GeckoProfile mProfile;
public static int mOrientation;
protected boolean mIsRestoringActivity;
@ -799,7 +798,7 @@ abstract public class GeckoApp
} else if (event.equals("Bookmark:Insert")) {
final String url = message.getString("url");
final String title = message.getString("title");
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GeckoApp.mAppContext, R.string.bookmark_added, Toast.LENGTH_SHORT).show();
@ -949,7 +948,7 @@ abstract public class GeckoApp
}
});
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Dialog dialog = builder.create();
@ -967,7 +966,7 @@ abstract public class GeckoApp
}
public void showToast(final int resId, final int duration) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mAppContext, resId, duration).show();
@ -976,7 +975,7 @@ abstract public class GeckoApp
}
void handleShowToast(final String message, final String duration) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Toast toast;
@ -1018,7 +1017,7 @@ abstract public class GeckoApp
}
void addPluginView(final View view, final Rect rect, final boolean isFullScreen) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Tabs tabs = Tabs.getInstance();
@ -1058,7 +1057,7 @@ abstract public class GeckoApp
// We need do do this on the next iteration in order to avoid
// a deadlock, see comment below in FullScreenHolder
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mLayerView.show();
@ -1075,7 +1074,7 @@ abstract public class GeckoApp
}
void removePluginView(final View view, final boolean isFullScreen) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Tabs tabs = Tabs.getInstance();
@ -1299,7 +1298,7 @@ abstract public class GeckoApp
}
public void setFullScreen(final boolean fullscreen) {
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
// Hide/show the system notification bar
@ -1373,7 +1372,7 @@ abstract public class GeckoApp
((GeckoApplication)getApplication()).initialize();
mAppContext = this;
ThreadUtils.setUiThread(Thread.currentThread());
ThreadUtils.setUiThread(Thread.currentThread(), new Handler());
Tabs.getInstance().attachToActivity(this);
Favicons.getInstance().attachToContext(this);
@ -1393,8 +1392,6 @@ abstract public class GeckoApp
Telemetry.HistogramAdd("FENNEC_RESTORING_ACTIVITY", 1);
}
mMainHandler = new Handler();
// Fix for bug 830557 on Tegra boards running Froyo.
// This fix must be done before doing layout.
// Assume the bug is fixed in Gingerbread and up.
@ -1642,7 +1639,7 @@ abstract public class GeckoApp
sGeckoThread.start();
} else if (ACTION_DEBUG.equals(action) &&
GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.WaitForDebugger)) {
mMainHandler.postDelayed(new Runnable() {
ThreadUtils.getUiHandler().postDelayed(new Runnable() {
@Override
public void run() {
GeckoThread.setLaunchState(GeckoThread.LaunchState.Launching);
@ -2547,7 +2544,7 @@ abstract public class GeckoApp
*/
super.addView(view, index);
mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mLayerView.hide();

View File

@ -14,6 +14,7 @@ import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.GeckoBackgroundThread;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.ActivityManager;
import android.app.PendingIntent;
@ -147,8 +148,6 @@ public class GeckoAppShell
private static boolean mLocationHighAccuracy = false;
private static Handler sGeckoHandler;
static ActivityHandlerHelper sActivityHelper = new ActivityHandlerHelper();
static NotificationServiceClient sNotificationClient;
@ -257,22 +256,12 @@ public class GeckoAppShell
}
}
// Get a Handler for the main java thread
public static Handler getMainHandler() {
return GeckoApp.mAppContext.mMainHandler;
}
public static Handler getGeckoHandler() {
return sGeckoHandler;
}
public static Handler getHandler() {
return GeckoBackgroundThread.getHandler();
}
public static void runGecko(String apkPath, String args, String url, String type) {
Looper.prepare();
sGeckoHandler = new Handler();
// run gecko -- it will spawn its own thread
GeckoAppShell.nativeInit();
@ -409,7 +398,7 @@ public class GeckoAppShell
}
public static void enableLocation(final boolean enable) {
getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
LocationManager lm = (LocationManager)
@ -1346,7 +1335,7 @@ public class GeckoAppShell
}
public static void notifyDefaultPrevented(final boolean defaultPrevented) {
getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
LayerView view = GeckoApp.mAppContext.getLayerView();
@ -1701,7 +1690,7 @@ public class GeckoAppShell
static byte[] sCameraBuffer = null;
static int[] initCamera(String aContentType, int aCamera, int aWidth, int aHeight) {
getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
try {
@ -1793,7 +1782,7 @@ public class GeckoAppShell
}
static synchronized void closeCamera() {
getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
try {

View File

@ -297,7 +297,7 @@ final class GeckoEditable
LayerView v = GeckoApp.mAppContext.getLayerView();
mListener = GeckoInputConnection.create(v, this);
mIcRunHandler = mIcPostHandler = GeckoApp.mAppContext.mMainHandler;
mIcRunHandler = mIcPostHandler = ThreadUtils.getUiHandler();
}
private boolean onIcThread() {

View File

@ -7,6 +7,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.background.announcements.AnnouncementsConstants;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONArray;
import org.json.JSONObject;
@ -110,7 +111,7 @@ public class GeckoPreferences
boolean success = message.getBoolean("success");
final int stringRes = success ? R.string.private_data_success : R.string.private_data_fail;
final Context context = this;
GeckoAppShell.getMainHandler().post(new Runnable () {
ThreadUtils.postToUiThread(new Runnable () {
@Override
public void run() {
Toast.makeText(context, stringRes, Toast.LENGTH_SHORT).show();
@ -423,7 +424,7 @@ public class GeckoPreferences
@Override public void prefValue(String prefName, final boolean value) {
final Preference pref = getField(prefName);
if (pref instanceof CheckBoxPreference) {
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (((CheckBoxPreference)pref).isChecked() != value)
@ -436,14 +437,14 @@ public class GeckoPreferences
@Override public void prefValue(String prefName, final String value) {
final Preference pref = getField(prefName);
if (pref instanceof EditTextPreference) {
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
((EditTextPreference)pref).setText(value);
}
});
} else if (pref instanceof ListPreference) {
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
((ListPreference)pref).setValue(value);
@ -456,7 +457,7 @@ public class GeckoPreferences
final FontSizePreference fontSizePref = (FontSizePreference) pref;
fontSizePref.setSavedFontSize(value);
final String fontSizeName = fontSizePref.getSavedFontSizeName();
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
fontSizePref.setSummary(fontSizeName); // Ex: "Small".
@ -467,7 +468,7 @@ public class GeckoPreferences
@Override public void finish() {
// enable all preferences once we have them from gecko
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mPreferenceScreen.setEnabled(true);

View File

@ -273,7 +273,7 @@ public class PromptService implements OnClickListener, OnCancelListener, OnItemC
@Override
public void handleMessage(String event, final JSONObject message) {
// The dialog must be created on the UI thread.
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
processMessage(message);

View File

@ -13,6 +13,7 @@ import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONArray;
import org.json.JSONException;
@ -718,7 +719,7 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
@Override
public void handleMessage(String event, final JSONObject message) {
if (event.equals("SearchEngines:Data")) {
GeckoAppShell.getMainHandler().post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
setSearchEngines(message);

View File

@ -10,6 +10,7 @@ import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.db.BrowserContract.Combined;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.BrowserDB.URLColumns;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.Activity;
import android.content.Context;
@ -368,7 +369,7 @@ public class BookmarksTab extends AwesomeBarTab {
@Override
protected void onPostExecute(final Cursor cursor) {
// Hack: force this to the main thread, even though it should already be on it
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
// this will update the cursorAdapter to use the new one if it already exists

View File

@ -9,6 +9,7 @@ import org.mozilla.gecko.AwesomeBar.ContextMenuSubject;
import org.mozilla.gecko.db.BrowserContract.Combined;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.BrowserDB.URLColumns;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.Activity;
import android.content.ContentResolver;
@ -368,7 +369,7 @@ public class HistoryTab extends AwesomeBarTab {
final ExpandableListView historyList = (ExpandableListView)getView();
// Hack: force this to the main thread, even though it should already be on it
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
historyList.setAdapter(mCursorAdapter);

View File

@ -8,12 +8,12 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.content.Context;
import android.graphics.PointF;
@ -735,7 +735,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
}
private void setShadowVisibility() {
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (BrowserApp.mBrowserToolbar == null) {

View File

@ -6,6 +6,7 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.graphics.Rect;
import android.graphics.RectF;
@ -60,7 +61,7 @@ public class PluginLayer extends TileLayer {
private void hideView() {
if (mViewVisible) {
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mView.setVisibility(View.GONE);
@ -71,7 +72,7 @@ public class PluginLayer extends TileLayer {
}
public void showView() {
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (mContainer.indexOfChild(mView) < 0) {

View File

@ -5,13 +5,18 @@
package org.mozilla.gecko.util;
import android.os.Handler;
public final class ThreadUtils {
private static Thread sUiThread;
private static Thread sGeckoThread;
private static Thread sBackgroundThread;
public static void setUiThread(Thread thread) {
private static Handler sUiHandler;
public static void setUiThread(Thread thread, Handler handler) {
sUiThread = thread;
sUiHandler = handler;
}
public static void setGeckoThread(Thread thread) {
@ -26,6 +31,14 @@ public final class ThreadUtils {
return sUiThread;
}
public static Handler getUiHandler() {
return sUiHandler;
}
public static void postToUiThread(Runnable runnable) {
sUiHandler.post(runnable);
}
public static Thread getGeckoThread() {
return sGeckoThread;
}