bug 607939 - fail to opened a URL / link from another application after launching r=dougt a=blocking-fennec

This commit is contained in:
Michael Wu 2010-11-24 17:51:41 -05:00
parent 8cb51d707e
commit ddcce1744b
3 changed files with 128 additions and 85 deletions

View File

@ -71,6 +71,34 @@ abstract public class GeckoApp
public static boolean mFullscreen = false;
ProgressDialog mProgressDialog;
enum LaunchState {PreLaunch, Launching, WaitButton,
Launched, GeckoRunning, GeckoExiting};
private static LaunchState sLaunchState = LaunchState.PreLaunch;
static boolean checkLaunchState(LaunchState checkState) {
synchronized(sLaunchState) {
return sLaunchState == checkState;
}
}
static void setLaunchState(LaunchState setState) {
synchronized(sLaunchState) {
sLaunchState = setState;
}
}
// if mLaunchState is equal to checkState this sets mLaunchState to setState
// and return true. Otherwise we return false.
static boolean checkAndSetLaunchState(LaunchState checkState, LaunchState setState) {
synchronized(sLaunchState) {
if (sLaunchState != checkState)
return false;
sLaunchState = setState;
return true;
}
}
void showErrorDialog(String message)
{
new AlertDialog.Builder(this)
@ -86,28 +114,40 @@ abstract public class GeckoApp
}).show();
}
void launch()
// Returns true when the intent is going to be handled by gecko launch
boolean launch(Intent i)
{
if (!checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched))
return false;
// unpack files in the components directory
try {
unpackComponents();
} catch (FileNotFoundException fnfe) {
showErrorDialog(getString(R.string.error_loading_file));
return;
return false;
} catch (IOException ie) {
String msg = ie.getMessage();
if (msg.equalsIgnoreCase("No space left on device"))
showErrorDialog(getString(R.string.no_space_to_start_error));
else
showErrorDialog(getString(R.string.error_loading_file));
return;
return false;
}
mProgressDialog =
ProgressDialog.show(GeckoApp.this, "",
getString(R.string.splash_screen_label),
true);
// and then fire us up
Intent i = getIntent();
if (i == null)
i = getIntent();
String env = i.getStringExtra("env0");
GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
i.getStringExtra("args"),
i.getDataString());
return true;
}
/** Called when the activity is first created. */
@ -136,11 +176,81 @@ abstract public class GeckoApp
setContentView(mainLayout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
if (!checkAndSetLaunchState(LaunchState.PreLaunch,
LaunchState.Launching))
return;
checkAndLaunchUpdate();
if (!checkCPUCompatability())
return;
// Load our JNI libs
GeckoAppShell.loadGeckoLibs(getApplication().getPackageResourcePath());
}
boolean checkCPUCompatability() {
try {
BufferedReader reader =
new BufferedReader(new FileReader("/proc/cpuinfo"));
String line;
while ((line = reader.readLine()) != null) {
int index = line.indexOf("Processor");
if (index == -1)
continue;
int version = 5;
if (line.indexOf("(v8l)") != -1)
version = 8;
if (line.indexOf("(v7l)") != -1)
version = 7;
if (line.indexOf("(v6l)") != -1)
version = 6;
if (version < getMinCPUVersion()) {
showErrorDialog(
getString(R.string.incompatable_cpu_error));
return false;
}
else {
break;
}
}
} catch (Exception ex) {
// Not much we can do here, just continue assuming we're okay
Log.i("GeckoApp", "exception: " + ex);
}
return true;
}
@Override
protected void onNewIntent(Intent intent) {
if (checkLaunchState(LaunchState.GeckoExiting)) {
// We're exiting and shouldn't try to do anything else just incase
// we're hung for some reason we'll force the process to exit
System.exit(0);
return;
}
final String action = intent.getAction();
if (action.equals("org.mozilla.gecko.DEBUG") &&
checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitButton)) {
final Button launchButton = new Button(this);
launchButton.setText("Launch"); // don't need to localize
launchButton.setOnClickListener(new Button.OnClickListener() {
public void onClick (View v) {
// hide the button so we can't be launched again
mainLayout.removeView(launchButton);
setLaunchState(LaunchState.Launching);
launch(null);
}
});
mainLayout.addView(launchButton, 300, 200);
return;
}
if (checkLaunchState(LaunchState.WaitButton) || launch(intent))
return;
if (Intent.ACTION_VIEW.equals(action)) {
String uri = intent.getDataString();
GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
@ -177,11 +287,16 @@ abstract public class GeckoApp
public void onResume()
{
Log.i("GeckoApp", "resume");
if (GeckoAppShell.sGeckoRunning)
if (checkLaunchState(LaunchState.GeckoRunning))
GeckoAppShell.onResume();
// After an onPause, the activity is back in the foreground.
// Undo whatever we did in onPause.
super.onResume();
// Just in case. Normally we start in onNewIntent
if (checkLaunchState(LaunchState.PreLaunch) ||
checkLaunchState(LaunchState.Launching))
onNewIntent(getIntent());
}
@Override
@ -216,75 +331,6 @@ abstract public class GeckoApp
{
Log.i("GeckoApp", "start");
super.onStart();
boolean useLaunchButton = false;
String intentAction = getIntent().getAction();
if (intentAction != null && intentAction.equals("org.mozilla.gecko.DEBUG"))
useLaunchButton = true;
if (!GeckoAppShell.sGeckoRunning) {
checkAndLaunchUpdate();
try {
BufferedReader reader =
new BufferedReader(new FileReader("/proc/cpuinfo"));
String line;
while ((line = reader.readLine()) != null) {
int index = line.indexOf("Processor");
if (index == -1)
continue;
int version = 5;
if (line.indexOf("(v8l)") != -1)
version = 8;
if (line.indexOf("(v7l)") != -1)
version = 7;
if (line.indexOf("(v6l)") != -1)
version = 6;
if (version < getMinCPUVersion()) {
showErrorDialog(
getString(R.string.incompatable_cpu_error));
return;
}
else {
break;
}
}
} catch (Exception ex) {
// Not much we can do here, just continue assuming we're okay
Log.i("GeckoApp", "exception: " + ex);
}
if (!useLaunchButton) {
mProgressDialog =
ProgressDialog.show(GeckoApp.this, "",
getString(R.string.splash_screen_label),
true);
}
// Load our JNI libs; we need to do this before launch() because
// setInitialSize will be called even before Gecko is actually up
// and running.
GeckoAppShell.loadGeckoLibs(getApplication().getPackageResourcePath());
if (useLaunchButton) {
final Button b = new Button(this);
b.setText("Launch"); // don't need to localize
b.setOnClickListener(new Button.OnClickListener() {
public void onClick (View v) {
// hide the button so we can't be launched again
mainLayout.removeView(b);
launch();
}
});
mainLayout.addView(b, 300, 200);
} else {
launch();
}
}
}
@Override
@ -311,7 +357,7 @@ abstract public class GeckoApp
public void onLowMemory()
{
Log.i("GeckoApp", "low memory");
if (GeckoAppShell.sGeckoRunning)
if (checkLaunchState(LaunchState.GeckoRunning))
GeckoAppShell.onLowMemory();
super.onLowMemory();
}

View File

@ -61,14 +61,9 @@ import android.net.Uri;
class GeckoAppShell
{
static {
sGeckoRunning = false;
}
// static members only
private GeckoAppShell() { }
static boolean sGeckoRunning;
static private GeckoEvent gPendingResize = null;
static private boolean gRestartScheduled = false;
@ -149,7 +144,7 @@ class GeckoAppShell
private static GeckoEvent mLastDrawEvent;
public static void sendEventToGecko(GeckoEvent e) {
if (sGeckoRunning) {
if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) {
if (gPendingResize != null) {
notifyGeckoOfEvent(gPendingResize);
gPendingResize = null;
@ -338,7 +333,8 @@ class GeckoAppShell
static void onAppShellReady()
{
sGeckoRunning = true;
// mLaunchState can only be Launched at this point
GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoRunning);
if (gPendingResize != null) {
notifyGeckoOfEvent(gPendingResize);
gPendingResize = null;
@ -346,7 +342,8 @@ class GeckoAppShell
}
static void onXreExit() {
sGeckoRunning = false;
// mLaunchState can only be Launched or GeckoRunning at this point
GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoExiting);
Log.i("GeckoAppJava", "XRE exited");
if (gRestartScheduled) {
GeckoApp.mAppContext.doRestart();

View File

@ -113,8 +113,8 @@ class GeckoSurfaceView
mSoftwareBuffer.capacity() < (width * height * 2) ||
mWidth != width || mHeight != height)
mSoftwareBuffer = ByteBuffer.allocateDirect(width * height * 2);
boolean doSyncDraw = GeckoAppShell.sGeckoRunning && m2DMode &&
mSoftwareBuffer != null;
boolean doSyncDraw = m2DMode && mSoftwareBuffer != null &&
GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
mSyncDraw = doSyncDraw;
mFormat = format;