diff options
author | Owen Lin <owenlin@google.com> | 2010-05-05 15:03:49 +0800 |
---|---|---|
committer | Owen Lin <owenlin@google.com> | 2010-05-10 18:30:21 +0800 |
commit | 0d73bccf89870682007dd32d4a84bcdb812e2cc7 (patch) | |
tree | 75bab272e9b5757011624136f548ddd18806f995 | |
parent | cdf69cba3617c446e4fe9a92b4b4199c6ed36d01 (diff) | |
download | LegacyCamera-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
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; } |