diff options
author | Chih-Chung Chang <chihchung@google.com> | 2010-04-07 22:10:41 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-04-07 22:10:41 -0700 |
commit | 0820de66481ba2e26c116dfa0a17ac470f11cf22 (patch) | |
tree | 57f74045ecf01d6af71a331ded1c1bdf8f2f5cfa /src/com | |
parent | 37c3e754751deb849f7fe2d59743deac0d7c6392 (diff) | |
parent | 1aaf351f6bbaa0b1dc6c08bd5a590e1930e2ef07 (diff) | |
download | LegacyCamera-0820de66481ba2e26c116dfa0a17ac470f11cf22.zip LegacyCamera-0820de66481ba2e26c116dfa0a17ac470f11cf22.tar.gz LegacyCamera-0820de66481ba2e26c116dfa0a17ac470f11cf22.tar.bz2 |
Merge "Fix the ANR after switching between Camera and Camcorder." into froyo
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/camera/ui/GLRootView.java | 39 | ||||
-rw-r--r-- | src/com/android/camera/ui/HeadUpDisplay.java | 42 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorBar.java | 8 |
3 files changed, 56 insertions, 33 deletions
diff --git a/src/com/android/camera/ui/GLRootView.java b/src/com/android/camera/ui/GLRootView.java index e3c066b..33aa736 100644 --- a/src/com/android/camera/ui/GLRootView.java +++ b/src/com/android/camera/ui/GLRootView.java @@ -1,13 +1,14 @@ package com.android.camera.ui; +import com.android.camera.Util; + import android.app.Activity; import android.content.Context; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; import android.opengl.GLU; -import android.os.Handler; -import android.os.HandlerThread; +import android.os.ConditionVariable; import android.os.Looper; import android.os.Process; import android.os.SystemClock; @@ -18,8 +19,6 @@ import android.view.MotionEvent; import android.view.animation.Animation; import android.view.animation.Transformation; -import com.android.camera.Util; - import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; @@ -75,11 +74,13 @@ public class GLRootView extends GLSurfaceView private Thread mGLThread; + private boolean mIsQueueActive = true; + // TODO: move this part (handler) into GLSurfaceView private final Looper mLooper; public GLRootView(Context context) { - this(context, null); + this(context, null); } public GLRootView(Context context, AttributeSet attrs) { @@ -437,9 +438,11 @@ public class GLRootView extends GLSurfaceView @Override public boolean dispatchTouchEvent(MotionEvent event) { + // If this has been detached from root, we don't need to handle event + if (mIsQueueActive) return false; FutureTask<Boolean> task = new FutureTask<Boolean>( new TouchEventHandler(event)); - queueEvent(task); + queueEventOrThrowException(task); try { return task.get(); } catch (Exception e) { @@ -521,6 +524,30 @@ public class GLRootView extends GLSurfaceView (float) width / newWidth, (float) height / newHeight); } + public synchronized void queueEventOrThrowException(Runnable runnable) { + if (!mIsQueueActive) { + throw new IllegalStateException("GLThread has exit"); + } + super.queueEvent(runnable); + } + + @Override + protected void onDetachedFromWindow() { + final ConditionVariable var = new ConditionVariable(); + synchronized (this) { + mIsQueueActive = false; + queueEvent(new Runnable() { + public void run() { + var.open(); + } + }); + } + + // Make sure all the runnables in the event queue is executed. + var.block(); + super.onDetachedFromWindow(); + } + protected Looper getTimerLooper() { return mLooper; } diff --git a/src/com/android/camera/ui/HeadUpDisplay.java b/src/com/android/camera/ui/HeadUpDisplay.java index 0e43ebe..ac2928f 100644 --- a/src/com/android/camera/ui/HeadUpDisplay.java +++ b/src/com/android/camera/ui/HeadUpDisplay.java @@ -1,6 +1,11 @@ package com.android.camera.ui; import static com.android.camera.ui.GLRootView.dpToPixel; + +import java.util.ArrayList; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; @@ -11,7 +16,6 @@ import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager; import android.util.DisplayMetrics; -import android.util.Log; import android.view.MotionEvent; import android.view.View.MeasureSpec; import android.view.animation.AlphaAnimation; @@ -23,10 +27,6 @@ import com.android.camera.ListPreference; import com.android.camera.PreferenceGroup; import com.android.camera.R; -import java.util.ArrayList; -import java.util.concurrent.Callable; -import java.util.concurrent.FutureTask; - // This is the UI for the on-screen settings. It mainly run in the GLThread. It // will modify the shared-preferences. The concurrency rule is: The shared- // preference will be updated in the GLThread. And an event will be trigger in @@ -88,22 +88,16 @@ public class HeadUpDisplay extends GLView { @Override public void handleMessage(Message msg) { GLRootView root = getGLRootView(); - FutureTask<Void> task = null; + Runnable runnable = null; switch(msg.what) { case DESELECT_INDICATOR: - task = new FutureTask<Void>(mDeselectIndicator); + runnable = mDeselectIndicator; break; case DEACTIVATE_INDICATOR_BAR: - task = new FutureTask<Void>(mDeactivateIndicatorBar); + runnable = mDeactivateIndicatorBar; break; } - if (task == null) return; - try { - root.queueEvent(task); - task.get(); - } catch (Exception e) { - Log.e(TAG, "error in concurrent code", e); - } + if (runnable != null) root.queueEvent(runnable); } }; } @@ -116,17 +110,15 @@ public class HeadUpDisplay extends GLView { sPopupTriangleOffset = dpToPixel(context, POPUP_TRIANGLE_OFFSET); } - private final Callable<Void> mDeselectIndicator = new Callable<Void> () { - public Void call() throws Exception { + private final Runnable mDeselectIndicator = new Runnable () { + public void run() { mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE); - return null; - } + } }; - private final Callable<Void> mDeactivateIndicatorBar = new Callable<Void> () { - public Void call() throws Exception { + private final Runnable mDeactivateIndicatorBar = new Runnable () { + public void run() { if (mIndicatorBar != null) mIndicatorBar.setActivated(false); - return null; } }; @@ -367,9 +359,9 @@ public class HeadUpDisplay extends GLView { private final Callable<Boolean> mCollapse = new Callable<Boolean>() { public Boolean call() { - if (mIndicatorBar.getSelectedIndex() == IndicatorBar.INDEX_NONE) { - return false; - } + if (!mIndicatorBar.isActivated()) return false; + mHandler.removeMessages(DESELECT_INDICATOR); + mHandler.removeMessages(DEACTIVATE_INDICATOR_BAR); mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE); mIndicatorBar.setActivated(false); return true; diff --git a/src/com/android/camera/ui/IndicatorBar.java b/src/com/android/camera/ui/IndicatorBar.java index 28c4eab..e5ee82a 100644 --- a/src/com/android/camera/ui/IndicatorBar.java +++ b/src/com/android/camera/ui/IndicatorBar.java @@ -1,12 +1,12 @@ package com.android.camera.ui; +import javax.microedition.khronos.opengles.GL11; + import android.graphics.Rect; import android.view.MotionEvent; import android.view.View.MeasureSpec; import android.view.animation.AlphaAnimation; -import javax.microedition.khronos.opengles.GL11; - public class IndicatorBar extends GLView { public static final int INDEX_NONE = -1; @@ -148,6 +148,10 @@ public class IndicatorBar extends GLView { } } + public boolean isActivated() { + return mActivated; + } + @Override protected boolean dispatchTouchEvent(MotionEvent event) { // Do not pass motion events to children |