summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Lin <owenlin@google.com>2010-05-05 15:03:49 +0800
committerOwen Lin <owenlin@google.com>2010-05-10 18:30:21 +0800
commit0d73bccf89870682007dd32d4a84bcdb812e2cc7 (patch)
tree75bab272e9b5757011624136f548ddd18806f995
parentcdf69cba3617c446e4fe9a92b4b4199c6ed36d01 (diff)
downloadLegacyCamera-0d73bccf89870682007dd32d4a84bcdb812e2cc7.zip
LegacyCamera-0d73bccf89870682007dd32d4a84bcdb812e2cc7.tar.gz
LegacyCamera-0d73bccf89870682007dd32d4a84bcdb812e2cc7.tar.bz2
Handle events in the main thread and use GLThread only as a rendering thread.
Coordinate the two threads by synchronizing on the GLRootView instance. Change-Id: I94459f6afeb468660df7219800bc48b621edecd4
-rw-r--r--src/com/android/camera/Camera.java69
-rw-r--r--src/com/android/camera/ui/AbstractIndicator.java2
-rw-r--r--src/com/android/camera/ui/BasicIndicator.java2
-rw-r--r--src/com/android/camera/ui/CameraEGLConfigChooser.java2
-rw-r--r--src/com/android/camera/ui/CameraHeadUpDisplay.java32
-rw-r--r--src/com/android/camera/ui/CanvasTexture.java2
-rw-r--r--src/com/android/camera/ui/FrameTexture.java2
-rw-r--r--src/com/android/camera/ui/GLListView.java60
-rw-r--r--src/com/android/camera/ui/GLOptionHeader.java2
-rw-r--r--src/com/android/camera/ui/GLOptionItem.java2
-rw-r--r--src/com/android/camera/ui/GLOutOfMemoryException.java1
-rw-r--r--src/com/android/camera/ui/GLRootView.java91
-rw-r--r--src/com/android/camera/ui/GpsIndicator.java2
-rw-r--r--src/com/android/camera/ui/HeadUpDisplay.java200
-rw-r--r--src/com/android/camera/ui/IndicatorBar.java2
-rw-r--r--src/com/android/camera/ui/LinearLayout.java2
-rw-r--r--src/com/android/camera/ui/MeasureHelper.java2
-rw-r--r--src/com/android/camera/ui/NinePatchTexture.java2
-rw-r--r--src/com/android/camera/ui/OtherSettingsIndicator.java2
-rw-r--r--src/com/android/camera/ui/PopupWindow.java2
-rw-r--r--src/com/android/camera/ui/PreferenceAdapter.java2
-rw-r--r--src/com/android/camera/ui/RawTexture.java2
-rw-r--r--src/com/android/camera/ui/ResourceTexture.java2
-rw-r--r--src/com/android/camera/ui/RestoreSettingsItem.java2
-rw-r--r--src/com/android/camera/ui/RotatePane.java2
-rw-r--r--src/com/android/camera/ui/StringTexture.java2
-rw-r--r--src/com/android/camera/ui/Texture.java2
-rw-r--r--src/com/android/camera/ui/ZoomController.java10
-rw-r--r--src/com/android/camera/ui/ZoomControllerListener.java6
-rw-r--r--src/com/android/camera/ui/ZoomIndicator.java10
30 files changed, 218 insertions, 303 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 7f928bd..b42c1a5 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -77,7 +77,7 @@ import com.android.camera.gallery.IImageList;
import com.android.camera.ui.CameraHeadUpDisplay;
import com.android.camera.ui.GLRootView;
import com.android.camera.ui.HeadUpDisplay;
-import com.android.camera.ui.ZoomController;
+import com.android.camera.ui.ZoomControllerListener;
import java.io.File;
import java.io.FileNotFoundException;
@@ -316,11 +316,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
setOrientationIndicator(mLastOrientation);
}
if (mGLRootView != null) {
- mGLRootView.queueEvent(new Runnable() {
- public void run() {
- mHeadUpDisplay.setOrientation(mLastOrientation);
- }
- });
+ mHeadUpDisplay.setOrientation(mLastOrientation);
}
}
}
@@ -396,10 +392,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mOrientationListener.enable();
// Start location update if needed.
- synchronized (mPreferences) {
- mRecordLocation = RecordLocationPreference.get(
- mPreferences, getContentResolver());
- }
+ mRecordLocation = RecordLocationPreference.get(
+ mPreferences, getContentResolver());
if (mRecordLocation) startReceivingLocationUpdates();
installIntentFilter();
@@ -998,22 +992,17 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private void overrideHudSettings(final String flashMode,
final String whiteBalance, final String focusMode) {
- mGLRootView.queueEvent(new Runnable() {
- public void run() {
- mHeadUpDisplay.overrideSettings(
- CameraSettings.KEY_FLASH_MODE, flashMode);
- mHeadUpDisplay.overrideSettings(
- CameraSettings.KEY_WHITE_BALANCE, whiteBalance);
- mHeadUpDisplay.overrideSettings(
- CameraSettings.KEY_FOCUS_MODE, focusMode);
- }});
+ mHeadUpDisplay.overrideSettings(
+ CameraSettings.KEY_FLASH_MODE, flashMode,
+ CameraSettings.KEY_WHITE_BALANCE, whiteBalance,
+ CameraSettings.KEY_FOCUS_MODE, focusMode);
}
- private void updateSceneModeInHud() {
+ private void updateSceneModeInHud() {
// If scene mode is set, we cannot set flash mode, white balance, and
- // focus mode, instead, we read it from driver
+ // focus mode, instead, we read it from driver
if (!Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
- overrideHudSettings(mParameters.getFlashMode(),
+ overrideHudSettings(mParameters.getFlashMode(),
mParameters.getWhiteBalance(), mParameters.getFocusMode());
} else {
overrideHudSettings(null, null, null);
@@ -1035,14 +1024,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (mParameters.isZoomSupported()) {
mHeadUpDisplay.setZoomRatios(getZoomRatios());
mHeadUpDisplay.setZoomIndex(mZoomValue);
- mHeadUpDisplay.setZoomListener(new ZoomController.ZoomListener() {
+ mHeadUpDisplay.setZoomListener(new ZoomControllerListener() {
public void onZoomChanged(
- final int index, float ratio, boolean isMoving) {
- mHandler.post(new Runnable() {
- public void run() {
- onZoomValueChanged(index);
- }
- });
+ int index, float ratio, boolean isMoving) {
+ onZoomValueChanged(index);
}
});
}
@@ -1908,9 +1893,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
- synchronized (mPreferences) {
- updateCameraParametersPreference();
- }
+ updateCameraParametersPreference();
}
mCameraDevice.setParameters(mParameters);
@@ -2110,11 +2093,9 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
boolean recordLocation;
- synchronized (mPreferences) {
- recordLocation = RecordLocationPreference.get(
- mPreferences, getContentResolver());
- mQuickCapture = getQuickCaptureSettings();
- }
+ recordLocation = RecordLocationPreference.get(
+ mPreferences, getContentResolver());
+ mQuickCapture = getQuickCaptureSettings();
if (mRecordLocation != recordLocation) {
if (mRecordLocation) {
@@ -2153,22 +2134,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {
- // The callback functions here will be called from the GLThread. So,
- // we need to post these runnables to the main thread
public void onSharedPreferencesChanged() {
- mHandler.post(new Runnable() {
- public void run() {
- Camera.this.onSharedPreferenceChanged();
- }
- });
+ Camera.this.onSharedPreferenceChanged();
}
public void onRestorePreferencesClicked() {
- mHandler.post(new Runnable() {
- public void run() {
- Camera.this.onRestorePreferencesClicked();
- }
- });
+ Camera.this.onRestorePreferencesClicked();
}
public void onPopupWindowVisibilityChanged(int visibility) {
diff --git a/src/com/android/camera/ui/AbstractIndicator.java b/src/com/android/camera/ui/AbstractIndicator.java
index 583c974..d805c96 100644
--- a/src/com/android/camera/ui/AbstractIndicator.java
+++ b/src/com/android/camera/ui/AbstractIndicator.java
@@ -9,7 +9,7 @@ import android.view.animation.Transformation;
import javax.microedition.khronos.opengles.GL11;
-public abstract class AbstractIndicator extends GLView {
+abstract class AbstractIndicator extends GLView {
private static final int DEFAULT_PADDING = 3;
private int mOrientation = 0;
diff --git a/src/com/android/camera/ui/BasicIndicator.java b/src/com/android/camera/ui/BasicIndicator.java
index 43761b3..dc52af7 100644
--- a/src/com/android/camera/ui/BasicIndicator.java
+++ b/src/com/android/camera/ui/BasicIndicator.java
@@ -8,7 +8,7 @@ import com.android.camera.R;
import com.android.camera.Util;
import com.android.camera.ui.GLListView.OnItemSelectedListener;
-public class BasicIndicator extends AbstractIndicator {
+class BasicIndicator extends AbstractIndicator {
private final ResourceTexture mIcon[];
private final IconListPreference mPreference;
diff --git a/src/com/android/camera/ui/CameraEGLConfigChooser.java b/src/com/android/camera/ui/CameraEGLConfigChooser.java
index 44d7394..6a3bb2a 100644
--- a/src/com/android/camera/ui/CameraEGLConfigChooser.java
+++ b/src/com/android/camera/ui/CameraEGLConfigChooser.java
@@ -26,7 +26,7 @@ import javax.microedition.khronos.egl.EGLDisplay;
* choose a configuration that support RGBA_8888 format and if possible,
* with stencil buffer, but is not required.
*/
-public class CameraEGLConfigChooser implements EGLConfigChooser {
+class CameraEGLConfigChooser implements EGLConfigChooser {
private static final int COLOR_BITS = 8;
diff --git a/src/com/android/camera/ui/CameraHeadUpDisplay.java b/src/com/android/camera/ui/CameraHeadUpDisplay.java
index 9883698..4d98302 100644
--- a/src/com/android/camera/ui/CameraHeadUpDisplay.java
+++ b/src/com/android/camera/ui/CameraHeadUpDisplay.java
@@ -53,22 +53,29 @@ public class CameraHeadUpDisplay extends HeadUpDisplay {
addIndicator(context, group, CameraSettings.KEY_FLASH_MODE);
}
- public void setZoomListener(ZoomController.ZoomListener listener) {
+ public void setZoomListener(ZoomControllerListener listener) {
+ // The rendering thread won't access listener variable, so we don't
+ // need to do concurrency protection here
mZoomIndicator.setZoomListener(listener);
}
public void setZoomIndex(int index) {
- mZoomIndicator.setZoomIndex(index);
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ mZoomIndicator.setZoomIndex(index);
+ }
+ } else {
+ mZoomIndicator.setZoomIndex(index);
+ }
}
public void setGpsHasSignal(final boolean hasSignal) {
GLRootView root = getGLRootView();
if (root != null) {
- root.queueEvent(new Runnable() {
- public void run() {
- mGpsIndicator.setHasSignal(hasSignal);
- }
- });
+ synchronized (root) {
+ mGpsIndicator.setHasSignal(hasSignal);
+ }
} else {
mGpsIndicator.setHasSignal(hasSignal);
}
@@ -80,6 +87,17 @@ public class CameraHeadUpDisplay extends HeadUpDisplay {
* <code>setZoomIndex()</code>
*/
public void setZoomRatios(float[] zoomRatios) {
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized(root) {
+ setZoomRatiosLocked(zoomRatios);
+ }
+ } else {
+ setZoomRatiosLocked(zoomRatios);
+ }
+ }
+
+ private void setZoomRatiosLocked(float[] zoomRatios) {
if (mZoomIndicator == null) {
mZoomIndicator = new ZoomIndicator(mContext);
mIndicatorBar.addComponent(mZoomIndicator);
diff --git a/src/com/android/camera/ui/CanvasTexture.java b/src/com/android/camera/ui/CanvasTexture.java
index fa0b76e..32ec8f1 100644
--- a/src/com/android/camera/ui/CanvasTexture.java
+++ b/src/com/android/camera/ui/CanvasTexture.java
@@ -5,7 +5,7 @@ import android.graphics.Canvas;
import android.graphics.Bitmap.Config;
/** Using a canvas to draw the texture */
-public abstract class CanvasTexture extends Texture {
+abstract class CanvasTexture extends Texture {
protected Canvas mCanvas;
public CanvasTexture(int width, int height) {
diff --git a/src/com/android/camera/ui/FrameTexture.java b/src/com/android/camera/ui/FrameTexture.java
index cc56f8c..ab7ace3 100644
--- a/src/com/android/camera/ui/FrameTexture.java
+++ b/src/com/android/camera/ui/FrameTexture.java
@@ -4,7 +4,7 @@ import android.graphics.Rect;
import javax.microedition.khronos.opengles.GL11;
-public abstract class FrameTexture extends Texture {
+abstract class FrameTexture extends Texture {
public FrameTexture() {
}
diff --git a/src/com/android/camera/ui/GLListView.java b/src/com/android/camera/ui/GLListView.java
index dcba22f..c4a607c 100644
--- a/src/com/android/camera/ui/GLListView.java
+++ b/src/com/android/camera/ui/GLListView.java
@@ -18,7 +18,7 @@ import com.android.camera.Util;
import javax.microedition.khronos.opengles.GL11;
-public class GLListView extends GLView {
+class GLListView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "GLListView";
private static final int INDEX_NONE = -1;
@@ -61,43 +61,40 @@ public class GLListView extends GLView {
public GLListView(Context context) {
mScroller = new Scroller(context);
- }
-
- private final Runnable mHideScrollBar = new Runnable() {
- public void run() {
- setScrollBarVisible(false);
- }
- };
-
- @Override
- protected void onVisibilityChanged(int visibility) {
- super.onVisibilityChanged(visibility);
- if (visibility == GLView.VISIBLE && mScrollHeight > getHeight()) {
- setScrollBarVisible(true);
- mHandler.sendEmptyMessageDelayed(
- HIDE_SCROLL_BAR, SCROLL_BAR_TIMEOUT);
- }
- }
-
- @Override
- protected void onAttachToRoot(GLRootView root) {
- super.onAttachToRoot(root);
- mHandler = new Handler(root.getTimerLooper()) {
+ mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ handleMessageLocked(msg);
+ }
+ } else {
+ handleMessageLocked(msg);
+ }
+ }
+
+ private void handleMessageLocked(Message msg) {
switch(msg.what) {
case HIDE_SCROLL_BAR:
- root.queueEvent(mHideScrollBar);
+ setScrollBarVisible(false);
break;
}
}
};
- mGestureDetector =
- new GestureDetector(root.getContext(),
- new MyGestureListener(), mHandler);
+ mGestureDetector = new GestureDetector(
+ context, new MyGestureListener(), mHandler);
}
+ @Override
+ protected void onVisibilityChanged(int visibility) {
+ super.onVisibilityChanged(visibility);
+ if (visibility == GLView.VISIBLE && mScrollHeight > getHeight()) {
+ setScrollBarVisible(true);
+ mHandler.sendEmptyMessageDelayed(
+ HIDE_SCROLL_BAR, SCROLL_BAR_TIMEOUT);
+ }
+ }
private void setScrollBarVisible(boolean visible) {
if (mScrollBarVisible == visible || mScrollbar == null) return;
@@ -357,13 +354,8 @@ public class GLListView extends GLView {
@Override
public void onShowPress(MotionEvent e) {
- if (!mScrollable) return;
- final int y = (int) e.getY();
- getGLRootView().queueEvent(new Runnable() {
- public void run() {
- if (mIsPressed) findAndSetHighlightItem(y);
- }
- });
+ if (!mScrollable || !mIsPressed) return;
+ findAndSetHighlightItem((int) e.getY());
}
@Override
diff --git a/src/com/android/camera/ui/GLOptionHeader.java b/src/com/android/camera/ui/GLOptionHeader.java
index a11935c..a922026 100644
--- a/src/com/android/camera/ui/GLOptionHeader.java
+++ b/src/com/android/camera/ui/GLOptionHeader.java
@@ -8,7 +8,7 @@ import com.android.camera.R;
import javax.microedition.khronos.opengles.GL11;
-public class GLOptionHeader extends GLView {
+class GLOptionHeader extends GLView {
private static final int FONT_COLOR = 0xFF979797;
private static final float FONT_SIZE = 12;
private static final int HORIZONTAL_PADDINGS = 4;
diff --git a/src/com/android/camera/ui/GLOptionItem.java b/src/com/android/camera/ui/GLOptionItem.java
index 9d2deee..2176121 100644
--- a/src/com/android/camera/ui/GLOptionItem.java
+++ b/src/com/android/camera/ui/GLOptionItem.java
@@ -10,7 +10,7 @@ import com.android.camera.R;
import javax.microedition.khronos.opengles.GL11;
-public class GLOptionItem extends GLView {
+class GLOptionItem extends GLView {
private static final int FONT_COLOR = Color.WHITE;
private static final float FONT_SIZE = 18;
diff --git a/src/com/android/camera/ui/GLOutOfMemoryException.java b/src/com/android/camera/ui/GLOutOfMemoryException.java
index 2e2bac7..e262b1d 100644
--- a/src/com/android/camera/ui/GLOutOfMemoryException.java
+++ b/src/com/android/camera/ui/GLOutOfMemoryException.java
@@ -1,5 +1,4 @@
package com.android.camera.ui;
public class GLOutOfMemoryException extends Exception {
-
}
diff --git a/src/com/android/camera/ui/GLRootView.java b/src/com/android/camera/ui/GLRootView.java
index dc10be4..0bbc3ed 100644
--- a/src/com/android/camera/ui/GLRootView.java
+++ b/src/com/android/camera/ui/GLRootView.java
@@ -8,9 +8,6 @@ import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
-import android.os.ConditionVariable;
-import android.os.Looper;
-import android.os.Process;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -23,14 +20,20 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Stack;
-import java.util.concurrent.Callable;
-import java.util.concurrent.FutureTask;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
+// The root component of all <code>GLView</code>s. The rendering is done in GL
+// thread while the event handling is done in the main thread. To synchronize
+// the two threads, the entry points of this package need to synchronize on the
+// <code>GLRootView</code> instance unless it can be proved that the rendering
+// thread won't access the same thing as the method. The entry points include:
+// (1) The public methods of HeadUpDisplay
+// (2) The public methods of CameraHeadUpDisplay
+// (3) The overridden methods in GLRootView.
public class GLRootView extends GLSurfaceView
implements GLSurfaceView.Renderer {
private static final String TAG = "GLRootView";
@@ -72,15 +75,8 @@ public class GLRootView extends GLSurfaceView
private int mFlags = FLAG_NEED_LAYOUT;
private long mAnimationTime;
- private Thread mGLThread;
-
- private boolean mIsQueueActive = true;
private CameraEGLConfigChooser mEglConfigChooser = new CameraEGLConfigChooser();
-
- // TODO: move this part (handler) into GLSurfaceView
- private final Looper mLooper;
-
public GLRootView(Context context) {
this(context, null);
}
@@ -88,7 +84,6 @@ public class GLRootView extends GLSurfaceView
public GLRootView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
- mLooper = Looper.getMainLooper();
}
void registerLaunchedAnimation(Animation animation) {
@@ -147,14 +142,6 @@ public class GLRootView extends GLSurfaceView
freeTransformation(trans);
}
- public void runInGLThread(Runnable runnable) {
- if (Thread.currentThread() == mGLThread) {
- runnable.run();
- } else {
- queueEvent(runnable);
- }
- }
-
public CameraEGLConfigChooser getEGLConfigChooser() {
return mEglConfigChooser;
}
@@ -240,10 +227,6 @@ public class GLRootView extends GLSurfaceView
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
- // Increase the priority of the render thread
- Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
- mGLThread = Thread.currentThread();
-
// Disable unused state
gl.glDisable(GL11.GL_LIGHTING);
@@ -409,8 +392,7 @@ public class GLRootView extends GLSurfaceView
drawTexture(texture, x, y, width, height, mTransformation.getAlpha());
}
- // This is a GLSurfaceView.Renderer callback
- public void onDrawFrame(GL10 gl) {
+ public synchronized void onDrawFrame(GL10 gl) {
if (ENABLE_FPS_TEST) {
long now = System.nanoTime();
if (mFrameCountingStart == 0) {
@@ -442,31 +424,11 @@ public class GLRootView extends GLSurfaceView
}
@Override
- public boolean dispatchTouchEvent(MotionEvent event) {
+ public synchronized 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));
- queueEventOrThrowException(task);
- try {
- return task.get();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private class TouchEventHandler implements Callable<Boolean> {
-
- private final MotionEvent mEvent;
-
- public TouchEventHandler(MotionEvent event) {
- mEvent = event;
- }
-
- public Boolean call() throws Exception {
- if (mContentView == null) return false;
- return mContentView.dispatchTouchEvent(mEvent);
- }
+ return mContentView != null
+ ? mContentView.dispatchTouchEvent(event)
+ : false;
}
public DisplayMetrics getDisplayMetrics() {
@@ -528,31 +490,4 @@ public class GLRootView extends GLSurfaceView
texture.setTextureSize(newWidth, 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/GpsIndicator.java b/src/com/android/camera/ui/GpsIndicator.java
index a97ed2a..51cc04a 100644
--- a/src/com/android/camera/ui/GpsIndicator.java
+++ b/src/com/android/camera/ui/GpsIndicator.java
@@ -6,7 +6,7 @@ import com.android.camera.R;
import com.android.camera.IconListPreference;
import com.android.camera.PreferenceGroup;
-public class GpsIndicator extends BasicIndicator {
+class GpsIndicator extends BasicIndicator {
private static final int GPS_ON_INDEX = 1;
diff --git a/src/com/android/camera/ui/HeadUpDisplay.java b/src/com/android/camera/ui/HeadUpDisplay.java
index 2c6a00b..819fde7 100644
--- a/src/com/android/camera/ui/HeadUpDisplay.java
+++ b/src/com/android/camera/ui/HeadUpDisplay.java
@@ -3,8 +3,6 @@ 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;
@@ -27,12 +25,9 @@ import com.android.camera.ListPreference;
import com.android.camera.PreferenceGroup;
import com.android.camera.R;
-// 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
-// the main UI thread so that the camera settings can be updated by reading the
-// updated preferences. The two threads synchronize on the monitor of the
-// default SharedPrefernce instance.
+// This is the UI for the on-screen settings. Since the rendering is run in the
+// GL thread. If any values will be changed in the main thread, it needs to
+// synchronize on the <code>GLRootView</code> instance.
public class HeadUpDisplay extends GLView {
private static final int INDICATOR_BAR_TIMEOUT = 5500;
private static final int POPUP_WINDOW_TIMEOUT = 5000;
@@ -65,7 +60,32 @@ public class HeadUpDisplay extends GLView {
protected Listener mListener;
- private Handler mHandler;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ handleMessageLocked(msg);
+ }
+ } else {
+ handleMessageLocked(msg);
+ }
+ }
+
+ private void handleMessageLocked(Message msg) {
+ switch(msg.what) {
+ case DESELECT_INDICATOR:
+ mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE);
+ break;
+ case DEACTIVATE_INDICATOR_BAR:
+ if (mIndicatorBar != null) {
+ mIndicatorBar.setActivated(false);
+ }
+ break;
+ }
+ }
+ };
private final OnSharedPreferenceChangeListener mSharedPreferenceChangeListener =
new OnSharedPreferenceChangeListener() {
@@ -81,27 +101,6 @@ public class HeadUpDisplay extends GLView {
initializeStaticVariables(context);
}
- @Override
- protected void onAttachToRoot(GLRootView root) {
- super.onAttachToRoot(root);
- mHandler = new Handler(root.getTimerLooper()) {
- @Override
- public void handleMessage(Message msg) {
- GLRootView root = getGLRootView();
- Runnable runnable = null;
- switch(msg.what) {
- case DESELECT_INDICATOR:
- runnable = mDeselectIndicator;
- break;
- case DEACTIVATE_INDICATOR_BAR:
- runnable = mDeactivateIndicatorBar;
- break;
- }
- if (runnable != null) root.queueEvent(runnable);
- }
- };
- }
-
private static void initializeStaticVariables(Context context) {
if (sIndicatorBarRightMargin >= 0) return;
@@ -110,18 +109,6 @@ public class HeadUpDisplay extends GLView {
sPopupTriangleOffset = dpToPixel(context, POPUP_TRIANGLE_OFFSET);
}
- private final Runnable mDeselectIndicator = new Runnable () {
- public void run() {
- mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE);
- }
- };
-
- private final Runnable mDeactivateIndicatorBar = new Runnable () {
- public void run() {
- if (mIndicatorBar != null) mIndicatorBar.setActivated(false);
- }
- };
-
/**
* The callback interface. All the callbacks will be called from the
* GLThread.
@@ -133,23 +120,22 @@ public class HeadUpDisplay extends GLView {
}
public void overrideSettings(final String ... keyvalues) {
- if (keyvalues.length % 2 != 0) {
- throw new IllegalArgumentException();
- }
GLRootView root = getGLRootView();
if (root != null) {
- root.queueEvent(new Runnable() {
- public void run() {
- for (int i = 0, n = keyvalues.length; i < n; i += 2) {
- mIndicatorBar.overrideSettings(
- keyvalues[i], keyvalues[i + 1]);
- }
- }
- });
- } else {
- for (int i = 0, n = keyvalues.length; i < n; i += 2) {
- mIndicatorBar.overrideSettings(keyvalues[i], keyvalues[i + 1]);
+ synchronized (root) {
+ overrideSettingsLocked(keyvalues);
}
+ } else {
+ overrideSettingsLocked(keyvalues);
+ }
+ }
+
+ public void overrideSettingsLocked(final String ... keyvalues) {
+ if (keyvalues.length % 2 != 0) {
+ throw new IllegalArgumentException();
+ }
+ for (int i = 0, n = keyvalues.length; i < n; i += 2) {
+ mIndicatorBar.overrideSettings(keyvalues[i], keyvalues[i + 1]);
}
}
@@ -240,12 +226,18 @@ public class HeadUpDisplay extends GLView {
DEACTIVATE_INDICATOR_BAR, INDICATOR_BAR_TIMEOUT);
}
- public void deactivateIndicatorBar() {
- if (mIndicatorBar == null) return;
- mIndicatorBar.setActivated(false);
+ public void setOrientation(int orientation) {
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ setOrientationLocked(orientation);
+ }
+ } else {
+ setOrientationLocked(orientation);
+ }
}
- public void setOrientation(int orientation) {
+ private void setOrientationLocked(int orientation) {
mOrientation = orientation;
mIndicatorBar.setOrientation(orientation);
if (mPopupWindow == null) return;
@@ -279,6 +271,8 @@ public class HeadUpDisplay extends GLView {
}
public void setEnabled(boolean enabled) {
+ // The mEnabled variable is not related to the rendering thread, so we
+ // don't need to synchronize on the GLRootView.
if (mEnabled == enabled) return;
mEnabled = enabled;
}
@@ -357,59 +351,63 @@ public class HeadUpDisplay extends GLView {
}
}
- private final Callable<Boolean> mCollapse = new Callable<Boolean>() {
- public Boolean call() {
- if (!mIndicatorBar.isActivated()) return false;
- mHandler.removeMessages(DESELECT_INDICATOR);
- mHandler.removeMessages(DEACTIVATE_INDICATOR_BAR);
+ public boolean collapse() {
+ // We don't need to synchronize on GLRootView, since both the
+ // <code>isActivated()</code> and rendering thread are read-only to
+ // the variables inside.
+ if (!mIndicatorBar.isActivated()) return false;
+ mHandler.removeMessages(DESELECT_INDICATOR);
+ mHandler.removeMessages(DEACTIVATE_INDICATOR_BAR);
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE);
+ mIndicatorBar.setActivated(false);
+ }
+ } else {
mIndicatorBar.setSelectedIndex(IndicatorBar.INDEX_NONE);
mIndicatorBar.setActivated(false);
- return true;
- }
- };
-
- public boolean collapse() {
- FutureTask<Boolean> task = new FutureTask<Boolean>(mCollapse);
- getGLRootView().runInGLThread(task);
- try {
- return task.get().booleanValue();
- } catch (Exception e) {
- throw new RuntimeException(e);
}
+ return true;
}
public void setListener(Listener listener) {
+ // No synchronization: mListener won't be accessed in rendering thread
mListener = listener;
}
public void restorePreferences(final Parameters param) {
- getGLRootView().runInGLThread(new Runnable() {
- public void run() {
- OnSharedPreferenceChangeListener l =
- mSharedPreferenceChangeListener;
- // Unregister the listener since "upgrade preference" will
- // change bunch of preferences. We can handle them with one
- // onSharedPreferencesChanged();
- mSharedPrefs.unregisterOnSharedPreferenceChangeListener(l);
- Context context = getGLRootView().getContext();
- synchronized (mSharedPrefs) {
- Editor editor = mSharedPrefs.edit();
- editor.clear();
- editor.commit();
- }
- CameraSettings.upgradePreferences(mSharedPrefs);
- CameraSettings.initialCameraPictureSize(context, param);
- reloadPreferences();
- if (mListener != null) {
- mListener.onSharedPreferencesChanged();
- }
- mSharedPrefs.registerOnSharedPreferenceChangeListener(l);
- }
- });
+ // Do synchronization in "reloadPreferences()"
+
+ OnSharedPreferenceChangeListener l =
+ mSharedPreferenceChangeListener;
+ // Unregister the listener since "upgrade preference" will
+ // change bunch of preferences. We can handle them with one
+ // onSharedPreferencesChanged();
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(l);
+ Context context = getGLRootView().getContext();
+ Editor editor = mSharedPrefs.edit();
+ editor.clear();
+ editor.commit();
+ CameraSettings.upgradePreferences(mSharedPrefs);
+ CameraSettings.initialCameraPictureSize(context, param);
+ reloadPreferences();
+ if (mListener != null) {
+ mListener.onSharedPreferencesChanged();
+ }
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(l);
}
public void reloadPreferences() {
- mPreferenceGroup.reloadValue();
- mIndicatorBar.reloadPreferences();
+ GLRootView root = getGLRootView();
+ if (root != null) {
+ synchronized (root) {
+ mPreferenceGroup.reloadValue();
+ mIndicatorBar.reloadPreferences();
+ }
+ } else {
+ mPreferenceGroup.reloadValue();
+ mIndicatorBar.reloadPreferences();
+ }
}
}
diff --git a/src/com/android/camera/ui/IndicatorBar.java b/src/com/android/camera/ui/IndicatorBar.java
index e5ee82a..0b29c23 100644
--- a/src/com/android/camera/ui/IndicatorBar.java
+++ b/src/com/android/camera/ui/IndicatorBar.java
@@ -7,7 +7,7 @@ import android.view.MotionEvent;
import android.view.View.MeasureSpec;
import android.view.animation.AlphaAnimation;
-public class IndicatorBar extends GLView {
+class IndicatorBar extends GLView {
public static final int INDEX_NONE = -1;
diff --git a/src/com/android/camera/ui/LinearLayout.java b/src/com/android/camera/ui/LinearLayout.java
index 4f251d9..1da665f 100644
--- a/src/com/android/camera/ui/LinearLayout.java
+++ b/src/com/android/camera/ui/LinearLayout.java
@@ -3,7 +3,7 @@ package com.android.camera.ui;
import android.graphics.Rect;
import android.view.View.MeasureSpec;
-public class LinearLayout extends GLView {
+class LinearLayout extends GLView {
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
diff --git a/src/com/android/camera/ui/MeasureHelper.java b/src/com/android/camera/ui/MeasureHelper.java
index 1749443..51b49c1 100644
--- a/src/com/android/camera/ui/MeasureHelper.java
+++ b/src/com/android/camera/ui/MeasureHelper.java
@@ -3,7 +3,7 @@ package com.android.camera.ui;
import android.graphics.Rect;
import android.view.View.MeasureSpec;
-public class MeasureHelper {
+class MeasureHelper {
private final GLView mComponent;
private int mPreferredWidth;
diff --git a/src/com/android/camera/ui/NinePatchTexture.java b/src/com/android/camera/ui/NinePatchTexture.java
index 60d6f30..7c27737 100644
--- a/src/com/android/camera/ui/NinePatchTexture.java
+++ b/src/com/android/camera/ui/NinePatchTexture.java
@@ -8,7 +8,7 @@ import android.graphics.drawable.NinePatchDrawable;
import javax.microedition.khronos.opengles.GL11;
-public class NinePatchTexture extends FrameTexture {
+class NinePatchTexture extends FrameTexture {
private MyTexture mDelegate;
diff --git a/src/com/android/camera/ui/OtherSettingsIndicator.java b/src/com/android/camera/ui/OtherSettingsIndicator.java
index 3fbef39..807143f 100644
--- a/src/com/android/camera/ui/OtherSettingsIndicator.java
+++ b/src/com/android/camera/ui/OtherSettingsIndicator.java
@@ -7,7 +7,7 @@ import com.android.camera.R;
import java.util.HashMap;
-public class OtherSettingsIndicator extends AbstractIndicator {
+class OtherSettingsIndicator extends AbstractIndicator {
private final ListPreference mPreference[];
private final GLListView.Model mAdapters[];
diff --git a/src/com/android/camera/ui/PopupWindow.java b/src/com/android/camera/ui/PopupWindow.java
index c12dce9..cc6fce2 100644
--- a/src/com/android/camera/ui/PopupWindow.java
+++ b/src/com/android/camera/ui/PopupWindow.java
@@ -10,7 +10,7 @@ import android.view.animation.ScaleAnimation;
import javax.microedition.khronos.opengles.GL11;
-public class PopupWindow extends GLView {
+class PopupWindow extends GLView {
protected Texture mAnchor;
protected int mAnchorOffset;
diff --git a/src/com/android/camera/ui/PreferenceAdapter.java b/src/com/android/camera/ui/PreferenceAdapter.java
index ddac613..e13e9f3 100644
--- a/src/com/android/camera/ui/PreferenceAdapter.java
+++ b/src/com/android/camera/ui/PreferenceAdapter.java
@@ -8,7 +8,7 @@ import com.android.camera.Util;
import java.util.ArrayList;
-public class PreferenceAdapter
+class PreferenceAdapter
implements GLListView.Model, GLListView.OnItemSelectedListener {
private static final int ICON_NONE = 0;
diff --git a/src/com/android/camera/ui/RawTexture.java b/src/com/android/camera/ui/RawTexture.java
index aecea9d..d01a8ba 100644
--- a/src/com/android/camera/ui/RawTexture.java
+++ b/src/com/android/camera/ui/RawTexture.java
@@ -4,7 +4,7 @@ import android.graphics.Bitmap;
import javax.microedition.khronos.opengles.GL11;
-public class RawTexture extends Texture {
+class RawTexture extends Texture {
private RawTexture(GL11 gl, int id) {
super(gl, id, STATE_LOADED);
diff --git a/src/com/android/camera/ui/ResourceTexture.java b/src/com/android/camera/ui/ResourceTexture.java
index e63a2ef..8a947ee 100644
--- a/src/com/android/camera/ui/ResourceTexture.java
+++ b/src/com/android/camera/ui/ResourceTexture.java
@@ -6,7 +6,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-public class ResourceTexture extends Texture {
+class ResourceTexture extends Texture {
private final Context mContext;
private final int mResId;
diff --git a/src/com/android/camera/ui/RestoreSettingsItem.java b/src/com/android/camera/ui/RestoreSettingsItem.java
index 2c74149..f1a2342 100644
--- a/src/com/android/camera/ui/RestoreSettingsItem.java
+++ b/src/com/android/camera/ui/RestoreSettingsItem.java
@@ -7,7 +7,7 @@ import android.graphics.Rect;
import javax.microedition.khronos.opengles.GL11;
-public class RestoreSettingsItem extends GLView {
+class RestoreSettingsItem extends GLView {
private static final int FONT_COLOR = Color.WHITE;
private static final float FONT_SIZE = 18;
diff --git a/src/com/android/camera/ui/RotatePane.java b/src/com/android/camera/ui/RotatePane.java
index 0a7eefd..fa41412 100644
--- a/src/com/android/camera/ui/RotatePane.java
+++ b/src/com/android/camera/ui/RotatePane.java
@@ -6,7 +6,7 @@ import android.view.MotionEvent;
import javax.microedition.khronos.opengles.GL11;
-public class RotatePane extends GLView {
+class RotatePane extends GLView {
public static final int UP = 0;
public static final int RIGHT = 1;
diff --git a/src/com/android/camera/ui/StringTexture.java b/src/com/android/camera/ui/StringTexture.java
index 12334b4..8b01df6 100644
--- a/src/com/android/camera/ui/StringTexture.java
+++ b/src/com/android/camera/ui/StringTexture.java
@@ -5,7 +5,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
-public class StringTexture extends CanvasTexture {
+class StringTexture extends CanvasTexture {
private static int DEFAULT_PADDING = 1;
private final String mText;
diff --git a/src/com/android/camera/ui/Texture.java b/src/com/android/camera/ui/Texture.java
index e1d6e39..0106337 100644
--- a/src/com/android/camera/ui/Texture.java
+++ b/src/com/android/camera/ui/Texture.java
@@ -8,7 +8,7 @@ import android.opengl.GLUtils;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
-public abstract class Texture {
+abstract class Texture {
@SuppressWarnings("unused")
private static final String TAG = "Texture";
diff --git a/src/com/android/camera/ui/ZoomController.java b/src/com/android/camera/ui/ZoomController.java
index 83e2d09..e62cfb8 100644
--- a/src/com/android/camera/ui/ZoomController.java
+++ b/src/com/android/camera/ui/ZoomController.java
@@ -14,7 +14,7 @@ import java.util.Arrays;
import javax.microedition.khronos.opengles.GL11;
-public class ZoomController extends GLView {
+class ZoomController extends GLView {
private static final int LABEL_COLOR = Color.WHITE;
private static final DecimalFormat sZoomFormat = new DecimalFormat("#.#x");
@@ -52,11 +52,7 @@ public class ZoomController extends GLView {
private int mSliderLeft;
private int mSliderPosition = INVALID_POSITION;
private float mValueGap;
- private ZoomListener mZoomListener;
-
- public interface ZoomListener {
- public void onZoomChanged(int index, float ratio, boolean isMoving);
- }
+ private ZoomControllerListener mZoomListener;
public ZoomController(Context context) {
initializeStaticVariable(context);
@@ -255,7 +251,7 @@ public class ZoomController extends GLView {
}
}
- public void setZoomListener(ZoomListener listener) {
+ public void setZoomListener(ZoomControllerListener listener) {
mZoomListener = listener;
}
diff --git a/src/com/android/camera/ui/ZoomControllerListener.java b/src/com/android/camera/ui/ZoomControllerListener.java
new file mode 100644
index 0000000..76209d7
--- /dev/null
+++ b/src/com/android/camera/ui/ZoomControllerListener.java
@@ -0,0 +1,6 @@
+package com.android.camera.ui;
+
+public interface ZoomControllerListener {
+ public void onZoomChanged(int index, float ratio, boolean isMoving);
+}
+
diff --git a/src/com/android/camera/ui/ZoomIndicator.java b/src/com/android/camera/ui/ZoomIndicator.java
index 4e7f1f4..c115f25 100644
--- a/src/com/android/camera/ui/ZoomIndicator.java
+++ b/src/com/android/camera/ui/ZoomIndicator.java
@@ -3,11 +3,11 @@ package com.android.camera.ui;
import android.content.Context;
import com.android.camera.R;
-import com.android.camera.ui.ZoomController.ZoomListener;
+import com.android.camera.ui.ZoomControllerListener;
import java.text.DecimalFormat;
-public class ZoomIndicator extends AbstractIndicator {
+class ZoomIndicator extends AbstractIndicator {
private static final DecimalFormat sZoomFormat = new DecimalFormat("#.#x");
private static final float FONT_SIZE = 18;
private static final int FONT_COLOR = 0xA8FFFFFF;
@@ -18,7 +18,7 @@ public class ZoomIndicator extends AbstractIndicator {
private ZoomController mZoomController;
private LinearLayout mPopupContent;
- private ZoomListener mZoomListener;
+ private ZoomControllerListener mZoomListener;
private int mZoomIndex = 0;
private int mDrawIndex = -1;
private float mZoomRatios[];
@@ -97,7 +97,7 @@ public class ZoomIndicator extends AbstractIndicator {
requestLayout();
}
- private class MyZoomListener implements ZoomController.ZoomListener {
+ private class MyZoomListener implements ZoomControllerListener {
public void onZoomChanged(int index, float value, boolean isMoving) {
if (mZoomListener != null) {
mZoomListener.onZoomChanged(index, value, isMoving);
@@ -112,7 +112,7 @@ public class ZoomIndicator extends AbstractIndicator {
invalidate();
}
- public void setZoomListener(ZoomListener listener) {
+ public void setZoomListener(ZoomControllerListener listener) {
mZoomListener = listener;
}