summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2010-04-07 22:10:41 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-04-07 22:10:41 -0700
commit0820de66481ba2e26c116dfa0a17ac470f11cf22 (patch)
tree57f74045ecf01d6af71a331ded1c1bdf8f2f5cfa /src/com
parent37c3e754751deb849f7fe2d59743deac0d7c6392 (diff)
parent1aaf351f6bbaa0b1dc6c08bd5a590e1930e2ef07 (diff)
downloadLegacyCamera-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.java39
-rw-r--r--src/com/android/camera/ui/HeadUpDisplay.java42
-rw-r--r--src/com/android/camera/ui/IndicatorBar.java8
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