diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java index 6fe3b3f77ae..69011f45367 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java @@ -12,6 +12,8 @@ import android.util.Log; import java.io.IOException; import java.io.InputStream; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; import org.freedesktop.gstreamer.GStreamer; import org.mozilla.servoview.JNIServo.ServoOptions; @@ -21,6 +23,8 @@ public class Servo { private AssetManager mAssetMgr; private JNIServo mJNI = new JNIServo(); private RunCallback mRunCallback; + private boolean mShuttingDown; + private boolean mShutdownComplete; private boolean mSuspended; public Servo( @@ -47,12 +51,33 @@ public class Servo { } } - public void requestShutdown() { - mRunCallback.inGLThread(() -> mJNI.requestShutdown()); - } - - public void deinit() { - mRunCallback.inGLThread(() -> mJNI.deinit()); + public void shutdown() { + mShuttingDown = true; + FutureTask task = new FutureTask(new Callable() { + public Void call() throws Exception { + mJNI.requestShutdown(); + // Wait until Servo gets back to us to finalize shutdown. + while (!mShutdownComplete) { + try { + Thread.sleep(10); + } catch (Exception e) { + mShutdownComplete = true; + e.printStackTrace(); + return null; + } + mJNI.performUpdates(); + } + mJNI.deinit(); + return null; + } + }); + mRunCallback.inGLThread(task); + // Block until task is complete. + try { + task.get(); + } catch (Exception e) { + e.printStackTrace(); + } } public String version() { @@ -161,8 +186,6 @@ public class Servo { void inGLThread(Runnable f); void inUIThread(Runnable f); - - void finalizeShutdown(); } public interface GfxCallbacks { @@ -184,7 +207,7 @@ public class Servo { } public void wakeup() { - if (!mSuspended) { + if (!mSuspended && !mShuttingDown) { mRunCallback.inGLThread(() -> mJNI.performUpdates()); } } @@ -200,7 +223,7 @@ public class Servo { } public void onShutdownComplete() { - mRunCallback.finalizeShutdown(); + mShutdownComplete = true; } public void onAnimatingChanged(boolean animating) { diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java index bc0e04fe898..ba61e4f82d9 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java @@ -70,7 +70,9 @@ public class ServoSurface { public void shutdown() { Log.d(LOGTAG, "shutdown"); - mServo.requestShutdown(); + mServo.shutdown(); + mServo = null; + mGLThread.shutdown(); try { Log.d(LOGTAG, "Waiting for GL thread to shutdown"); mGLThread.join(); @@ -228,9 +230,8 @@ public class ServoSurface { mMainLooperHandler.post(r); } - public void finalizeShutdown() { - Log.d(LOGTAG, "finalizeShutdown"); - mServo.deinit(); + public void shutdown() { + Log.d(LOGTAG, "GLThread::shutdown"); mSurface.destroy(); mGLLooperHandler.getLooper().quitSafely(); } diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoView.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoView.java index b042735d8d8..57bf19f53a1 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoView.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoView.java @@ -69,8 +69,9 @@ public class ServoView extends GLSurfaceView init(context); } - protected void onDetachedFromWindow() { - mServo.requestShutdown(); + public void onDetachedFromWindow() { + mServo.shutdown(); + mServo = null; super.onDetachedFromWindow(); } @@ -140,11 +141,6 @@ public class ServoView extends GLSurfaceView public void makeCurrent() { } - public void finalizeShutdown() { - // shutdown has been requested and completed. - mServo.deinit(); - } - public void inGLThread(Runnable f) { queueEvent(f); }