summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml28
-rwxr-xr-x[-rw-r--r--]jni/feature_mos/src/mosaic_renderer/Renderer.cpp10
-rwxr-xr-x[-rw-r--r--]jni/feature_mos/src/mosaic_renderer/Renderer.h4
-rwxr-xr-x[-rw-r--r--]jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp2
-rwxr-xr-x[-rw-r--r--]jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp2
-rwxr-xr-x[-rw-r--r--]jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp2
-rw-r--r--jni/mosaic_renderer_jni.cpp83
-rw-r--r--res/drawable-xxhdpi/ic_refocus_editor_cancel.pngbin0 -> 1744 bytes
-rw-r--r--res/drawable-xxhdpi/ic_refocus_editor_confirm.pngbin0 -> 1566 bytes
-rw-r--r--res/drawable-xxhdpi/ic_scene_mode_refocus.pngbin0 -> 13604 bytes
-rw-r--r--res/layout-land/pano_preview_progress.xml135
-rw-r--r--res/layout-port/pano_preview_progress.xml136
-rw-r--r--res/layout/pano_module_capture.xml104
-rw-r--r--res/layout/refocus_editor.xml68
-rw-r--r--res/raw/camera_click_x5.oggbin0 -> 21306 bytes
-rw-r--r--res/values/arrays.xml3
-rw-r--r--res/values/qcomstrings.xml4
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/com/android/camera/CameraActivity.java43
-rw-r--r--src/com/android/camera/CameraSettings.java14
-rw-r--r--src/com/android/camera/MosaicPreviewRenderer.java9
-rw-r--r--src/com/android/camera/MosaicRenderer.java10
-rw-r--r--src/com/android/camera/PhotoMenu.java42
-rw-r--r--src/com/android/camera/PhotoModule.java109
-rw-r--r--src/com/android/camera/PhotoUI.java16
-rw-r--r--src/com/android/camera/RefocusActivity.java249
-rw-r--r--src/com/android/camera/VideoMenu.java17
-rw-r--r--src/com/android/camera/VideoModule.java9
-rw-r--r--src/com/android/camera/WideAnglePanoramaModule.java34
-rw-r--r--src/com/android/camera/WideAnglePanoramaUI.java8
-rw-r--r--src/com/android/camera/ui/CameraControls.java106
-rw-r--r--src/com/android/camera/util/CameraUtil.java14
32 files changed, 974 insertions, 291 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bf13fac83..9ff2d16fc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -93,18 +93,6 @@
</intent-filter>
</activity-alias>
- <activity-alias
- android:name="com.android.camera.CameraGestureActivity"
- android:icon="@mipmap/ic_launcher_camera"
- android:label="@string/camera_gesture_title"
- android:targetActivity="com.android.camera.CameraActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity-alias>
-
<!-- Video camera and capture use the Camcorder label and icon. -->
<activity-alias
android:name="com.android.camera.VideoCamera"
@@ -150,6 +138,17 @@
android:resource="@layout/keyguard_widget" />
</activity>
+ <activity-alias
+ android:name="com.android.camera.CameraGestureActivity"
+ android:icon="@mipmap/ic_launcher_camera"
+ android:label="@string/camera_gesture_title"
+ android:targetActivity="com.android.camera.SecureCameraActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity-alias>
+
<activity
android:name="com.android.camera.crop.CropActivity"
android:label="@string/crop_action"
@@ -157,6 +156,11 @@
android:configChanges="keyboardHidden|orientation|screenSize">
</activity>
+ <activity
+ android:name="com.android.camera.RefocusActivity"
+ android:configChanges="keyboardHidden|orientation|screenSize">
+ </activity>
+
<receiver android:name="com.android.camera.DisableCameraReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp
index 8d0632402..b9938eb6b 100644..100755
--- a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp
+++ b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp
@@ -111,8 +111,8 @@ GLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentS
}
// Set this renderer to use the default frame-buffer (screen) and
-// set the viewport size to be the given x, y, width and height (pixels).
-bool Renderer::SetupGraphics(int x, int y, int width, int height)
+// set the viewport size to be the given width and height (pixels).
+bool Renderer::SetupGraphics(int width, int height)
{
bool succeeded = false;
do {
@@ -131,10 +131,8 @@ bool Renderer::SetupGraphics(int x, int y, int width, int height)
mFrameBuffer = NULL;
mSurfaceWidth = width;
mSurfaceHeight = height;
- mSurfaceXOffset = x;
- mSurfaceYOffset = y;
- glViewport(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight);
+ glViewport(0, 0, mSurfaceWidth, mSurfaceHeight);
if (!checkGlError("glViewport")) break;
succeeded = true;
} while (false);
@@ -178,7 +176,7 @@ bool Renderer::Clear(float r, float g, float b, float a)
bool succeeded = false;
do {
bool rt = (mFrameBuffer == NULL)?
- SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) :
+ SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
SetupGraphics(mFrameBuffer);
if(!rt)
diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.h b/jni/feature_mos/src/mosaic_renderer/Renderer.h
index ffb9cbd25..a43e8028e 100644..100755
--- a/jni/feature_mos/src/mosaic_renderer/Renderer.h
+++ b/jni/feature_mos/src/mosaic_renderer/Renderer.h
@@ -18,7 +18,7 @@ class Renderer {
virtual bool InitializeGLProgram() = 0;
bool SetupGraphics(FrameBuffer* buffer);
- bool SetupGraphics(int x, int y, int width, int height);
+ bool SetupGraphics(int width, int height);
bool Clear(float r, float g, float b, float a);
@@ -59,8 +59,6 @@ class Renderer {
int mSurfaceWidth; // Width of target surface.
int mSurfaceHeight; // Height of target surface.
- int mSurfaceXOffset; // X Offset target surface.
- int mSurfaceYOffset; // Y Offset of target surface.
FrameBuffer *mFrameBuffer;
};
diff --git a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
index 4725463f2..88aac3626 100644..100755
--- a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
+++ b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp
@@ -119,7 +119,7 @@ bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine)
bool succeeded = false;
do {
bool rt = (mFrameBuffer == NULL)?
- SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) :
+ SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
SetupGraphics(mFrameBuffer);
if(!rt)
diff --git a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp
index c030ce25e..af6779a3f 100644..100755
--- a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp
+++ b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp
@@ -110,7 +110,7 @@ bool WarpRenderer::DrawTexture(GLfloat *affine)
bool succeeded = false;
do {
bool rt = (mFrameBuffer == NULL)?
- SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) :
+ SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
SetupGraphics(mFrameBuffer);
if(!rt)
diff --git a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp
index b30e6f7b6..f7dcf6f61 100644..100755
--- a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp
+++ b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp
@@ -79,7 +79,7 @@ bool YVURenderer::DrawTexture()
bool succeeded = false;
do {
bool rt = (mFrameBuffer == NULL)?
- SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) :
+ SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
SetupGraphics(mFrameBuffer);
if(!rt)
diff --git a/jni/mosaic_renderer_jni.cpp b/jni/mosaic_renderer_jni.cpp
index f35599375..36f8064c7 100644
--- a/jni/mosaic_renderer_jni.cpp
+++ b/jni/mosaic_renderer_jni.cpp
@@ -27,7 +27,6 @@
#include "mosaic_renderer/SurfaceTextureRenderer.h"
#include "mosaic_renderer/YVURenderer.h"
-
#include "mosaic/Log.h"
#define LOG_TAG "MosaicRenderer"
@@ -37,7 +36,6 @@
GLuint gSurfaceTextureID[1];
bool gWarpImage = true;
-bool gPreviewBackgroundImage = true;
// Low-Res input image frame in YUVA format for preview rendering and processing
// and high-res YUVA input image for processing.
@@ -89,9 +87,6 @@ FrameBuffer gBuffer[2];
// Shader to warp and render the preview FBO to the screen
WarpRenderer gPreview;
-// Shader to render the fullscreen preview background FBO to the screen
-WarpRenderer gPreviewBackground;
-
// Index of the gBuffer FBO gWarper1 is going to write into
int gCurrentFBOIndex = 0;
@@ -145,12 +140,6 @@ double g_dAffinetransPan[16];
GLfloat g_dTranslationToFBOCenterGL[16];
double g_dTranslationToFBOCenter[16];
-
-
-
-
-
-
// GL 4x4 Identity transformation
GLfloat g_dAffinetransIdentGL[] = {
1., 0., 0., 0.,
@@ -326,8 +315,8 @@ void UpdateWarpTransformation(float *trs)
// Alignment is done based on low-res data.
// To render the preview mosaic, the translation of the high-res mosaic is estimated to
// H2L_FACTOR x low-res-based tranlation.
- //gThisH1t[2] *= H2L_FACTOR;
- //gThisH1t[5] *= H2L_FACTOR;
+ gThisH1t[2] *= H2L_FACTOR;
+ gThisH1t[5] *= H2L_FACTOR;
db_Identity3x3(T);
T[2] = -gCenterOffsetX;
@@ -379,7 +368,6 @@ void UpdateWarpTransformation(float *trs)
db_Identity3x3(H);
H[2] = gPanOffset;
-
// Hp = inv(Km) * H * Km
db_Identity3x3(Htemp1);
db_Multiply3x3_3x3(Htemp1, H, gKm);
@@ -409,13 +397,13 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR)
gPreviewImageHeight[HR], 4);
sem_post(&gPreviewImage_semaphore);
- gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR];
- gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR];
+ gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[HR];
+ gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[HR];
// The origin is such that the current frame will sit with its center
// at the center of the previewFBO
- gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[LR] / 2);
- gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[LR] / 2);
+ gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[HR] / 2);
+ gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[HR] / 2);
gPanOffset = 0.0f;
@@ -424,8 +412,8 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR)
gPanViewfinder = true;
- int w = gPreviewImageWidth[LR];
- int h = gPreviewImageHeight[LR];
+ int w = gPreviewImageWidth[HR];
+ int h = gPreviewImageHeight[HR];
int wm = gPreviewFBOWidth;
int hm = gPreviewFBOHeight;
@@ -505,8 +493,6 @@ extern "C"
JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping(
JNIEnv * env, jobject obj, jboolean flag);
- JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground(
- JNIEnv * env, jobject obj, jboolean flag);
};
@@ -538,7 +524,6 @@ JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init(
gBufferInput[HR].InitializeGLContext();
gBufferInputYVU[LR].InitializeGLContext();
gBufferInputYVU[HR].InitializeGLContext();
- gPreviewBackground.InitializeGLProgram();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -563,16 +548,13 @@ void calculateUILayoutScaling(int width, int height, bool isLandscape) {
//
// Scale the preview FBO's height to the height of view and
// maintain the aspect ratio of the current frame on the screen.
-
gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE;
// Note that OpenGL scales a texture to view's width and height automatically.
// The "width / height" inverts the scaling, so as to maintain the aspect ratio
// of the current frame.
-
gUILayoutScalingX = ((float) gPreviewFBOWidth / gPreviewFBOHeight)
/ ((float) width / height) * PREVIEW_FBO_HEIGHT_SCALE;
-
} else {
// ___
// __________ | | ______
@@ -591,10 +573,8 @@ void calculateUILayoutScaling(int width, int height, bool isLandscape) {
// Note that OpenGL scales a texture to view's width and height automatically.
// The "height / width" inverts the scaling, so as to maintain the aspect ratio
// of the current frame.
-
gUILayoutScalingX = ((float) gPreviewFBOHeight / gPreviewFBOWidth)
/ ((float) width / height) * PREVIEW_FBO_WIDTH_SCALE;
-
}
}
@@ -602,7 +582,7 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset(
JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation)
{
gIsLandscapeOrientation = isLandscapeOrientation;
- calculateUILayoutScaling(gPreviewFBOWidth, gPreviewFBOHeight, gIsLandscapeOrientation);
+ calculateUILayoutScaling(width, height, gIsLandscapeOrientation);
gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA);
gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA);
@@ -656,23 +636,20 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset(
gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName());
gWarper1.SetInputTextureType(GL_TEXTURE_2D);
- // gBufferInput[LR] --> gWarper2 --> gBuffer[gCurrentFBOIndex]
+ // gBufferInput[HR] --> gWarper2 --> gBuffer[gCurrentFBOIndex]
gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]);
// gWarp2's destination buffer is the same to gWarp1's. No need to clear it
// again.
- gWarper2.SetViewportMatrix(gPreviewImageWidth[LR],
- gPreviewImageHeight[LR], gBuffer[gCurrentFBOIndex].GetWidth(),
+ gWarper2.SetViewportMatrix(gPreviewImageWidth[HR],
+ gPreviewImageHeight[HR], gBuffer[gCurrentFBOIndex].GetWidth(),
gBuffer[gCurrentFBOIndex].GetHeight());
gWarper2.SetScalingMatrix(1.0f, 1.0f);
- gWarper2.SetInputTextureName(gBufferInput[LR].GetTextureName());
+ gWarper2.SetInputTextureName(gBufferInput[HR].GetTextureName());
gWarper2.SetInputTextureType(GL_TEXTURE_2D);
- int xoffset = (width/2 - gPreviewFBOWidth/2);
- int yoffset = (height/2 - gPreviewFBOHeight/2);
-
// gBuffer[gCurrentFBOIndex] --> gPreview --> Screen
- gPreview.SetupGraphics(xoffset,yoffset,gPreviewFBOWidth, gPreviewFBOHeight);
+ gPreview.SetupGraphics(width, height);
gPreview.SetViewportMatrix(1, 1, 1, 1);
// Scale the previewFBO so that the viewfinder window fills the layout height
@@ -680,13 +657,6 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset(
gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY);
gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName());
gPreview.SetInputTextureType(GL_TEXTURE_2D);
-
- // gBufferInput[HR] --> gPreviewBackground --> screen
- gPreviewBackground.SetupGraphics(0,0,width, height);
- gPreviewBackground.SetViewportMatrix(1,1,1,1);
- gPreviewBackground.SetScalingMatrix(1.0f, -1.0f);
- gPreviewBackground.SetInputTextureName(gBufferInput[HR].GetTextureName());
- gPreviewBackground.SetInputTextureType(GL_TEXTURE_2D);
}
JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess(
@@ -761,18 +731,15 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step(
{
if(!gWarpImage) // ViewFinder
{
- if (gIsLandscapeOrientation) {
- gPreviewBackground.DrawTexture(g_dAffinetransIdentGL);
- } else {
- gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL);
- }
- }
- else if(gPreviewBackgroundImage)
- {
+ gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]);
+ gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName());
+
+ gWarper2.DrawTexture(g_dTranslationToFBOCenterGL);
+
if (gIsLandscapeOrientation) {
- gPreviewBackground.DrawTexture(g_dAffinetransIdentGL);
+ gPreview.DrawTexture(g_dAffinetransIdentGL);
} else {
- gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL);
+ gPreview.DrawTexture(g_dAffinetransRotation90GL);
}
}
else
@@ -807,7 +774,7 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping(
gWarper1.Clear(0.0, 0.0, 0.0, 1.0);
// Clear the screen to black.
gPreview.Clear(0.0, 0.0, 0.0, 1.0);
- gPreviewBackground.Clear(0.0, 0.0, 0.0, 1.0);
+
gLastTx = 0.0f;
gPanOffset = 0.0f;
gPanViewfinder = true;
@@ -835,9 +802,3 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_updateMatrix(
g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i];
}
}
-
-JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground(
- JNIEnv * env, jobject obj, jboolean flag)
-{
- gPreviewBackgroundImage = (bool)flag;
-}
diff --git a/res/drawable-xxhdpi/ic_refocus_editor_cancel.png b/res/drawable-xxhdpi/ic_refocus_editor_cancel.png
new file mode 100644
index 000000000..e58839ddd
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_refocus_editor_cancel.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_refocus_editor_confirm.png b/res/drawable-xxhdpi/ic_refocus_editor_confirm.png
new file mode 100644
index 000000000..9e4dd5e6f
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_refocus_editor_confirm.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_scene_mode_refocus.png b/res/drawable-xxhdpi/ic_scene_mode_refocus.png
new file mode 100644
index 000000000..1bfab604b
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_scene_mode_refocus.png
Binary files differ
diff --git a/res/layout-land/pano_preview_progress.xml b/res/layout-land/pano_preview_progress.xml
index 772b8529e..c6c131741 100644
--- a/res/layout-land/pano_preview_progress.xml
+++ b/res/layout-land/pano_preview_progress.xml
@@ -14,37 +14,106 @@
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/panorama_preview_progress"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="bottom|center_horizontal">
-
- <com.android.camera.PanoProgressBar
- android:id="@+id/pano_pan_progress_bar"
- android:visibility="gone"
- android:src="@drawable/ic_pan_progression"
- android:layout_centerInParent="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <ImageView
- android:id="@+id/pano_pan_left_indicator"
- android:src="@drawable/pano_direction_left_indicator"
- android:visibility="gone"
- android:layout_marginRight="5dp"
- android:layout_toLeftOf="@id/pano_pan_progress_bar"
- android:layout_centerVertical="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <ImageView
- android:id="@+id/pano_pan_right_indicator"
- android:src="@drawable/pano_direction_right_indicator"
- android:visibility="gone"
- android:layout_marginLeft="5dp"
- android:layout_toRightOf="@id/pano_pan_progress_bar"
- android:layout_centerVertical="true"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/panorama_capture_layout"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <!-- The top bar with capture indication -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <TextView
+ android:id="@+id/pano_capture_indicator"
+ android:text="@string/pano_capture_indication"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_gravity="center"
+ android:id="@+id/pano_preview_layout"
+ android:layout_weight="@integer/SRI_pano_layout_weight"
+ android:layout_width="match_parent"
+ android:layout_height="0dp">
+
+ <TextureView
+ android:id="@+id/pano_preview_textureview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <View
+ android:id="@+id/pano_preview_area_border"
+ android:visibility="gone"
+ android:background="@drawable/ic_pan_border_fast"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </FrameLayout>
+
+ <!-- The bottom bar with progress bar and direction indicators -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
+ android:paddingTop="20dp"
+ android:gravity="top"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.android.camera.PanoProgressBar
+ android:id="@+id/pano_pan_progress_bar"
+ android:visibility="gone"
+ android:src="@drawable/ic_pan_progression"
+ android:layout_centerInParent="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_left_indicator"
+ android:src="@drawable/pano_direction_left_indicator"
+ android:visibility="gone"
+ android:layout_marginRight="5dp"
+ android:layout_toLeftOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_right_indicator"
+ android:src="@drawable/pano_direction_right_indicator"
+ android:visibility="gone"
+ android:layout_marginLeft="5dp"
+ android:layout_toRightOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </RelativeLayout>
+ </FrameLayout>
+
+
+ </LinearLayout>
+
+ <!-- The hint for "Too fast" text view -->
+ <TextView
+ android:id="@+id/pano_capture_too_fast_textview"
+ android:text="@string/pano_too_fast_prompt"
+ android:textAppearance="?android:textAppearanceMedium"
android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-</RelativeLayout>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:visibility="gone" />
+</FrameLayout>
diff --git a/res/layout-port/pano_preview_progress.xml b/res/layout-port/pano_preview_progress.xml
index 426ef0ba7..c6c131741 100644
--- a/res/layout-port/pano_preview_progress.xml
+++ b/res/layout-port/pano_preview_progress.xml
@@ -14,38 +14,106 @@
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/panorama_preview_progress"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginBottom="100dp">
-
- <com.android.camera.PanoProgressBar
- android:id="@+id/pano_pan_progress_bar"
- android:visibility="gone"
- android:src="@drawable/ic_pan_progression"
- android:layout_centerInParent="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <ImageView
- android:id="@+id/pano_pan_left_indicator"
- android:src="@drawable/pano_direction_left_indicator"
- android:visibility="gone"
- android:layout_marginRight="5dp"
- android:layout_toLeftOf="@id/pano_pan_progress_bar"
- android:layout_centerVertical="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <ImageView
- android:id="@+id/pano_pan_right_indicator"
- android:src="@drawable/pano_direction_right_indicator"
- android:visibility="gone"
- android:layout_marginLeft="5dp"
- android:layout_toRightOf="@id/pano_pan_progress_bar"
- android:layout_centerVertical="true"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/panorama_capture_layout"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <!-- The top bar with capture indication -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <TextView
+ android:id="@+id/pano_capture_indicator"
+ android:text="@string/pano_capture_indication"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_gravity="center"
+ android:id="@+id/pano_preview_layout"
+ android:layout_weight="@integer/SRI_pano_layout_weight"
+ android:layout_width="match_parent"
+ android:layout_height="0dp">
+
+ <TextureView
+ android:id="@+id/pano_preview_textureview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <View
+ android:id="@+id/pano_preview_area_border"
+ android:visibility="gone"
+ android:background="@drawable/ic_pan_border_fast"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </FrameLayout>
+
+ <!-- The bottom bar with progress bar and direction indicators -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
+ android:paddingTop="20dp"
+ android:gravity="top"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.android.camera.PanoProgressBar
+ android:id="@+id/pano_pan_progress_bar"
+ android:visibility="gone"
+ android:src="@drawable/ic_pan_progression"
+ android:layout_centerInParent="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_left_indicator"
+ android:src="@drawable/pano_direction_left_indicator"
+ android:visibility="gone"
+ android:layout_marginRight="5dp"
+ android:layout_toLeftOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_right_indicator"
+ android:src="@drawable/pano_direction_right_indicator"
+ android:visibility="gone"
+ android:layout_marginLeft="5dp"
+ android:layout_toRightOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </RelativeLayout>
+ </FrameLayout>
+
+
+ </LinearLayout>
+
+ <!-- The hint for "Too fast" text view -->
+ <TextView
+ android:id="@+id/pano_capture_too_fast_textview"
+ android:text="@string/pano_too_fast_prompt"
+ android:textAppearance="?android:textAppearanceMedium"
android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-</RelativeLayout>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:visibility="gone" />
+</FrameLayout>
diff --git a/res/layout/pano_module_capture.xml b/res/layout/pano_module_capture.xml
index d842ea12c..c6c131741 100644
--- a/res/layout/pano_module_capture.xml
+++ b/res/layout/pano_module_capture.xml
@@ -19,36 +19,94 @@
android:layout_height="match_parent"
android:layout_width="match_parent">
- <FrameLayout
- android:layout_gravity="center"
- android:id="@+id/pano_preview_layout"
- android:layout_weight="@integer/SRI_pano_layout_weight"
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <TextureView
- android:id="@+id/pano_preview_textureview"
+ <!-- The top bar with capture indication -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <TextView
+ android:id="@+id/pano_capture_indicator"
+ android:text="@string/pano_capture_indication"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
- <View
- android:id="@+id/pano_preview_area_border"
- android:visibility="gone"
- android:background="@drawable/ic_pan_border_fast"
+ <FrameLayout
+ android:layout_gravity="center"
+ android:id="@+id/pano_preview_layout"
+ android:layout_weight="@integer/SRI_pano_layout_weight"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </FrameLayout>
+ android:layout_height="0dp">
- <include layout="@layout/pano_preview_progress" />
+ <TextureView
+ android:id="@+id/pano_preview_textureview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <View
+ android:id="@+id/pano_preview_area_border"
+ android:visibility="gone"
+ android:background="@drawable/ic_pan_border_fast"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </FrameLayout>
+
+ <!-- The bottom bar with progress bar and direction indicators -->
+ <FrameLayout
+ style="@style/PanoViewHorizontalBar"
+ android:paddingTop="20dp"
+ android:gravity="top"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.android.camera.PanoProgressBar
+ android:id="@+id/pano_pan_progress_bar"
+ android:visibility="gone"
+ android:src="@drawable/ic_pan_progression"
+ android:layout_centerInParent="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_left_indicator"
+ android:src="@drawable/pano_direction_left_indicator"
+ android:visibility="gone"
+ android:layout_marginRight="5dp"
+ android:layout_toLeftOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/pano_pan_right_indicator"
+ android:src="@drawable/pano_direction_right_indicator"
+ android:visibility="gone"
+ android:layout_marginLeft="5dp"
+ android:layout_toRightOf="@id/pano_pan_progress_bar"
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </RelativeLayout>
+ </FrameLayout>
+
+
+ </LinearLayout>
- <TextView
- android:id="@+id/pano_capture_indicator"
- android:text="@string/pano_capture_indication"
- android:textAppearance="?android:textAppearanceMedium"
- android:layout_gravity="top|center_horizontal"
- android:visibility="gone"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
<!-- The hint for "Too fast" text view -->
<TextView
android:id="@+id/pano_capture_too_fast_textview"
diff --git a/res/layout/refocus_editor.xml b/res/layout/refocus_editor.xml
new file mode 100644
index 000000000..c4b42bb4c
--- /dev/null
+++ b/res/layout/refocus_editor.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (c) 2015, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/refocus_image"
+ android:adjustViewBounds="true"
+ android:scaleType="fitXY"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#80000000">
+
+ <ImageView
+ android:id="@+id/refocus_cancel"
+ android:src="@drawable/ic_refocus_editor_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true" />
+ <TextView
+ android:id="@+id/refocus_all"
+ android:text="@string/all_in_focus"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:onClick="allInFocus" />
+ <ImageView
+ android:id="@+id/refocus_done"
+ android:src="@drawable/ic_refocus_editor_confirm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true" />
+ </RelativeLayout>
+</FrameLayout>
diff --git a/res/raw/camera_click_x5.ogg b/res/raw/camera_click_x5.ogg
new file mode 100644
index 000000000..542432fd7
--- /dev/null
+++ b/res/raw/camera_click_x5.ogg
Binary files differ
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 581146cc6..bb87126b2 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -397,6 +397,7 @@
<!-- Camera Preferences Scene Mode dialog box entries -->
<string-array name="pref_camera_scenemode_entries" translatable="false">
<item>@string/pref_camera_scenemode_entry_auto</item>
+ <item>@string/pref_camera_scenemode_entry_refocus</item>
<!-- <item>@string/pref_camera_scenemode_entry_portrait</item> -->
<item>@string/pref_camera_scenemode_entry_landscape</item>
<item>@string/pref_camera_scenemode_entry_sports</item>
@@ -411,6 +412,7 @@
<array name="scenemode_thumbnails" translatable="false">
<item>@drawable/ic_scene_mode_auto</item>
+ <item>@drawable/ic_scene_mode_refocus</item>
<!-- <item>@drawable/ic_scene_mode_portrait</item> -->
<item>@drawable/ic_scene_mode_landscape</item>
<item>@drawable/ic_scene_mode_sports</item>
@@ -441,6 +443,7 @@
<string-array name="pref_camera_scenemode_entryvalues" translatable="false">
<item>auto</item>
+ <item>@string/pref_camera_advanced_feature_value_refocus_on</item>
<!-- <item>portrait</item> -->
<item>landscape</item>
<item>sports</item>
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index 77a905ae3..6ba2af63f 100644
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Not a Contribution.
@@ -865,5 +865,7 @@
<!-- The alas of CameraActivity for gesture operation -->
<string name="camera_gesture_title">Launch camera</string>
+
+ <string name="all_in_focus">All in Focus</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0ad549a41..33597b74b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -396,6 +396,8 @@
<string name="pref_camera_scenemode_entry_sunset">Sunset</string>
<!-- Scene mode optimized for taking indoor low-lights pictures. [CHAR LIMIT=16] -->
<string name="pref_camera_scenemode_entry_party">Party</string>
+ <!-- Scene mode for refocus feature [CHAR LIMIT=16] -->
+ <string name="pref_camera_scenemode_entry_refocus">Macro+</string>
<!-- Settings menu, scene mode labels [CHAR LIMIT=50] -->
<string name="pref_camera_scenemode_label_auto">NONE</string>
@@ -714,4 +716,6 @@ CHAR LIMIT = NONE] -->
<string name="pref_camera_video_rotation_label_270">270</string>
<string name="remaining_photos_format">%d left</string>
+
+ <string name="refocus_toast">To re-focus last photo, tap here</string>
</resources>
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 8fd8f9daa..e9786431b 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -49,6 +49,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemProperties;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.Settings;
@@ -101,6 +102,8 @@ import java.io.File;
import static com.android.camera.CameraManager.CameraOpenErrorCallback;
+import android.media.AudioManager;
+
public class CameraActivity extends Activity
implements ModuleSwitcher.ModuleSwitchListener,
ActionBar.OnMenuVisibilityListener,
@@ -122,6 +125,9 @@ public class CameraActivity extends Activity
// panorama. If the extra is not set, it is in the normal camera mode.
public static final String SECURE_CAMERA_EXTRA = "secure_camera";
+ // This string is used for judge start activity from screenoff or not
+ public static final String GESTURE_CAMERA_NAME = "com.android.camera.CameraGestureActivity";
+
/**
* Request code from an activity we started that indicated that we do not
* want to reset the view to the preview in onResume.
@@ -187,7 +193,6 @@ public class CameraActivity extends Activity
private ViewGroup mUndoDeletionBar;
private boolean mIsUndoingDeletion = false;
private boolean mIsEditActivityInProgress = false;
- protected boolean mIsModuleSwitchInProgress = false;
private View mPreviewCover;
private FrameLayout mPreviewContentLayout;
@@ -210,6 +215,10 @@ public class CameraActivity extends Activity
public static int SETTING_LIST_WIDTH_2 = 250;
private Bitmap mPreviewThumbnailBitmap;
+ private AudioManager mAudioManager;
+ private int mShutterVol;
+ private int mOriginalMasterVol;
+
private class MyOrientationEventListener
extends OrientationEventListener {
public MyOrientationEventListener(Context context) {
@@ -524,6 +533,15 @@ public class CameraActivity extends Activity
if (img == null)
return;
Uri uri = img.getContentUri();
+ if (mCurrentModule instanceof PhotoModule) {
+ if (((PhotoModule) mCurrentModule).isRefocus()) {
+ Intent intent = new Intent();
+ intent.setClass(this, RefocusActivity.class);
+ intent.setData(uri);
+ startActivity(intent);
+ return;
+ }
+ }
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
@@ -1156,11 +1174,14 @@ public class CameraActivity extends Activity
super.onCreate(state);
GcamHelper.init(getContentResolver());
+ mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ mOriginalMasterVol = mAudioManager.getMasterVolume();
+ mShutterVol = SystemProperties.getInt("persist.camera.snapshot.volume", -1);
+ if (mShutterVol >= 0 && mShutterVol <= 100 )
+ mAudioManager.setMasterVolume(mShutterVol,0);
+
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.camera_filmstrip);
- int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- getWindow().addFlags(flags);
mActionBar = getActionBar();
mActionBar.addOnMenuVisibilityListener(this);
@@ -1174,7 +1195,8 @@ public class CameraActivity extends Activity
Intent intent = getIntent();
String action = intent.getAction();
if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
- || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
+ || ACTION_IMAGE_CAPTURE_SECURE.equals(action)
+ || intent.getComponent().getClassName().equals(GESTURE_CAMERA_NAME)) {
mSecureCamera = true;
} else {
mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
@@ -1185,6 +1207,9 @@ public class CameraActivity extends Activity
Window win = getWindow();
WindowManager.LayoutParams params = win.getAttributes();
params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+ if (intent.getComponent().getClassName().equals(GESTURE_CAMERA_NAME)) {
+ params.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+ }
win.setAttributes(params);
// Filter for screen off so that we can finish secure camera activity
@@ -1365,6 +1390,8 @@ public class CameraActivity extends Activity
@Override
public void onPause() {
+ if (mShutterVol >= 0 && mShutterVol <= 100)
+ mAudioManager.setMasterVolume(mOriginalMasterVol,0);
// Delete photos that are pending deletion
performDeletion();
mOrientationListener.disable();
@@ -1388,6 +1415,8 @@ public class CameraActivity extends Activity
@Override
public void onResume() {
+ if (mShutterVol >= 0 && mShutterVol <= 100)
+ mAudioManager.setMasterVolume(mShutterVol,0);
// TODO: Handle this in OrientationManager.
// Auto-rotate off
if (Settings.System.getInt(getContentResolver(),
@@ -1455,6 +1484,8 @@ public class CameraActivity extends Activity
@Override
public void onDestroy() {
+ if (mShutterVol >= 0 && mShutterVol <= 100)
+ mAudioManager.setMasterVolume(mOriginalMasterVol,0);
if (mSecureCamera) {
unregisterReceiver(mScreenOffReceiver);
}
@@ -1583,7 +1614,6 @@ public class CameraActivity extends Activity
return;
}
- mIsModuleSwitchInProgress = true;
CameraHolder.instance().keep();
closeModule(mCurrentModule);
setModuleFromIndex(moduleIndex);
@@ -1598,7 +1628,6 @@ public class CameraActivity extends Activity
// starts up.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, moduleIndex).apply();
- mIsModuleSwitchInProgress = false;
}
/**
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 37fc39718..63581b8ba 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -769,9 +769,19 @@ public class CameraSettings {
filterUnsupportedOptions(group,
whiteBalance, mParameters.getSupportedWhiteBalance());
}
+
if (sceneMode != null) {
- filterUnsupportedOptions(group,
- sceneMode, mParameters.getSupportedSceneModes());
+ List<String> supportedSceneModes = mParameters.getSupportedSceneModes();
+ List<String> supportedAdvancedFeatures =
+ getSupportedAdvancedFeatures(mParameters);
+ if (CameraUtil.isSupported(
+ mContext.getString(R.string
+ .pref_camera_advanced_feature_value_refocus_on),
+ supportedAdvancedFeatures)) {
+ supportedSceneModes.add(mContext.getString(R.string
+ .pref_camera_advanced_feature_value_refocus_on));
+ }
+ filterUnsupportedOptions(group, sceneMode, supportedSceneModes);
}
if (flashMode != null) {
filterUnsupportedOptions(group,
diff --git a/src/com/android/camera/MosaicPreviewRenderer.java b/src/com/android/camera/MosaicPreviewRenderer.java
index 77c260eb5..42da4d9e7 100644
--- a/src/com/android/camera/MosaicPreviewRenderer.java
+++ b/src/com/android/camera/MosaicPreviewRenderer.java
@@ -83,13 +83,10 @@ public class MosaicPreviewRenderer {
mInputSurfaceTexture.updateTexImage();
mInputSurfaceTexture.getTransformMatrix(mTransformMatrix);
- // Call setPreviewBackground to render high-res RGB textures to full screen.
- MosaicRenderer.setPreviewBackground(true);
- MosaicRenderer.preprocess(mTransformMatrix);
- MosaicRenderer.step();
- MosaicRenderer.setPreviewBackground(false);
-
MosaicRenderer.setWarping(true);
+ // Call preprocess to render it to low-res and high-res RGB textures.
+ MosaicRenderer.preprocess(mTransformMatrix);
+ // Now, transfer the textures from GPU to CPU memory for processing
MosaicRenderer.transferGPUtoCPU();
MosaicRenderer.updateMatrix();
MosaicRenderer.step();
diff --git a/src/com/android/camera/MosaicRenderer.java b/src/com/android/camera/MosaicRenderer.java
index daf94abe6..92d9cb7b6 100644
--- a/src/com/android/camera/MosaicRenderer.java
+++ b/src/com/android/camera/MosaicRenderer.java
@@ -86,14 +86,4 @@ public class MosaicRenderer
* @param flag boolean flag to set the warping to true or false.
*/
public static native void setWarping(boolean flag);
- /**
- * This function allows toggling between drawing the background full
- * screen preview image data to screen and drawing the warped smaller
- * preview on top of it. To render the full screen background preview,
- * we set the falsg to true and to render the warped image on top of this
- * we set the flag to false and flag in setWarping to true.
- *
- * @param flag boolean flag to set the warping to true or false.
- */
- public static native void setPreviewBackground(boolean flag);
}
diff --git a/src/com/android/camera/PhotoMenu.java b/src/com/android/camera/PhotoMenu.java
index 1568c32c0..d10a679b3 100644
--- a/src/com/android/camera/PhotoMenu.java
+++ b/src/com/android/camera/PhotoMenu.java
@@ -69,7 +69,8 @@ public class PhotoMenu extends MenuController
private static final int POPUP_NONE = 0;
private static final int POPUP_FIRST_LEVEL = 1;
private static final int POPUP_SECOND_LEVEL = 2;
- private static final int POPUP_IN_ANIMATION = 3;
+ private static final int POPUP_IN_ANIMATION_SLIDE = 3;
+ private static final int POPUP_IN_ANIMATION_FADE = 4;
private static final int PREVIEW_MENU_NONE = 0;
private static final int PREVIEW_MENU_IN_ANIMATION = 1;
private static final int PREVIEW_MENU_ON = 2;
@@ -225,9 +226,9 @@ public class PhotoMenu extends MenuController
}
private void animateFadeOut(final ListView v, final int level) {
- if (v == null || mPopupStatus == POPUP_IN_ANIMATION)
+ if (v == null || mPopupStatus == POPUP_IN_ANIMATION_FADE)
return;
- mPopupStatus = POPUP_IN_ANIMATION;
+ mPopupStatus = POPUP_IN_ANIMATION_FADE;
ViewPropertyAnimator vp = v.animate();
vp.alpha(0f).setDuration(ANIMATION_DURATION);
@@ -274,9 +275,9 @@ public class PhotoMenu extends MenuController
}
private void animateSlideOut(final ListView v, final int level) {
- if (v == null || mPopupStatus == POPUP_IN_ANIMATION)
+ if (v == null || mPopupStatus == POPUP_IN_ANIMATION_SLIDE)
return;
- mPopupStatus = POPUP_IN_ANIMATION;
+ mPopupStatus = POPUP_IN_ANIMATION_SLIDE;
ViewPropertyAnimator vp = v.animate();
vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION);
@@ -413,7 +414,9 @@ public class PhotoMenu extends MenuController
}
public boolean isOverMenu(MotionEvent ev) {
- if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION)
+ if (mPopupStatus == POPUP_NONE
+ || mPopupStatus == POPUP_IN_ANIMATION_SLIDE
+ || mPopupStatus == POPUP_IN_ANIMATION_FADE)
return false;
if (mUI.getMenuLayout() == null)
return false;
@@ -439,7 +442,7 @@ public class PhotoMenu extends MenuController
}
public boolean isMenuBeingAnimated() {
- return mPopupStatus == POPUP_IN_ANIMATION;
+ return mPopupStatus == POPUP_IN_ANIMATION_SLIDE || mPopupStatus == POPUP_IN_ANIMATION_FADE;
}
public boolean isPreviewMenuBeingShown() {
@@ -681,8 +684,11 @@ public class PhotoMenu extends MenuController
@Override
public void onClick(View v) {
addSceneMode();
- View view = mUI.getPreviewMenuLayout().getChildAt(0);
- animateSlideIn(view, previewMenuSize, false);
+ ViewGroup menuLayout = mUI.getPreviewMenuLayout();
+ if (menuLayout != null) {
+ View view = menuLayout.getChildAt(0);
+ animateSlideIn(view, previewMenuSize, false);
+ }
}
});
}
@@ -830,8 +836,11 @@ public class PhotoMenu extends MenuController
@Override
public void onClick(View v) {
addFilterMode();
- View view = mUI.getPreviewMenuLayout().getChildAt(0);
- animateSlideIn(view, previewMenuSize, false);
+ ViewGroup menuLayout = mUI.getPreviewMenuLayout();
+ if (menuLayout != null) {
+ View view = mUI.getPreviewMenuLayout().getChildAt(0);
+ animateSlideIn(view, previewMenuSize, false);
+ }
}
});
}
@@ -1094,6 +1103,17 @@ public class PhotoMenu extends MenuController
}
}
+ String refocusOn = mActivity.getString(R.string
+ .pref_camera_advanced_feature_value_refocus_on);
+ if (notSame(pref, CameraSettings.KEY_SCENE_MODE, refocusOn)) {
+ ListPreference lp = mPreferenceGroup
+ .findPreference(CameraSettings.KEY_ADVANCED_FEATURES);
+ if (lp != null && refocusOn.equals(lp.getValue())) {
+ setPreference(CameraSettings.KEY_ADVANCED_FEATURES,
+ mActivity.getString(R.string.pref_camera_advanced_feature_default));
+ }
+ }
+
if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) {
buttonSetEnabled(mFilterModeSwitcher, false);
} else {
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 1e238be80..843d860f7 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -35,7 +35,9 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
+import android.media.AudioManager;
import android.media.CameraProfile;
+import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -192,6 +194,7 @@ public class PhotoModule
private boolean mTouchAfAecFlag;
private boolean mLongshotSave = false;
private boolean mRefocus = false;
+ private boolean mLastPhotoTakenWithRefocus = false;
// The degrees of the device rotated clockwise from its natural orientation.
private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
@@ -253,6 +256,9 @@ public class PhotoModule
// when the image is ready to be saved.
private NamedImages mNamedImages;
+ private SoundPool mSoundPool;
+ private int mRefocusSound;
+
private Runnable mDoSnapRunnable = new Runnable() {
@Override
public void run() {
@@ -358,6 +364,7 @@ public class PhotoModule
private boolean mAnimateCapture = true;
private int mJpegFileSizeEstimation = 0;
+ private int mRemainingPhotos = -1;
private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
new MediaSaveService.OnMediaSavedListener() {
@@ -524,7 +531,7 @@ public class PhotoModule
mPreferences.setLocalId(mActivity, mCameraId);
CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
- if (mOpenCameraThread == null && !mActivity.mIsModuleSwitchInProgress) {
+ if (mOpenCameraThread == null) {
mOpenCameraThread = new OpenCameraThread();
mOpenCameraThread.start();
}
@@ -558,6 +565,8 @@ public class PhotoModule
mAm.getMemoryInfo(memInfo);
SECONDARY_SERVER_MEM = memInfo.secondaryServerThreshold;
+ mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
+ mRefocusSound = mSoundPool.load(mActivity, R.raw.camera_click_x5, 1);
}
private void initializeControlByIntent() {
@@ -1028,6 +1037,9 @@ public class PhotoModule
}
});
}
+ if (mRefocus) {
+ mSoundPool.play(mRefocusSound, 1.0f, 1.0f, 0, 0, 1.0f);
+ }
}
}
private final class StatsCallback
@@ -1243,7 +1255,20 @@ public class PhotoModule
}
startFaceDetection();
}
- if ((mRefocus) && (mReceivedSnapNum == 6)) {
+
+ mLastPhotoTakenWithRefocus = mRefocus;
+ if (mRefocus) {
+ final String[] NAMES = { "00.jpg", "01.jpg", "02.jpg", "03.jpg",
+ "04.jpg", "DepthMapImage.y", "AllFocusImage.jpg" };
+ try {
+ FileOutputStream out = mActivity.openFileOutput(NAMES[mReceivedSnapNum - 1],
+ Context.MODE_PRIVATE);
+ out.write(jpegData, 0, jpegData.length);
+ out.close();
+ } catch (Exception e) {
+ }
+ }
+ if (mRefocus && (mReceivedSnapNum == 7)) {
Size s = mParameters.getPictureSize();
mNamedImages.nameNewImage(mCaptureStartTime, mRefocus);
NamedEntity name = mNamedImages.getNextNameEntity();
@@ -1259,9 +1284,9 @@ public class PhotoModule
}
mActivity.getMediaSaveService().addImage(
jpegData, title, date, mLocation, s.width, s.height,
- 0, null, mOnMediaSavedListener, mContentResolver, ".jpeg");
-
- } else {
+ 0, null, mOnMediaSavedListener, mContentResolver, PIXEL_FORMAT_JPEG);
+ mUI.showRefocusToast(mRefocus);
+ } else if (!mRefocus) {
ExifInterface exif = Exif.getExif(jpegData);
int orientation = Exif.getOrientation(exif);
if (!mIsImageCaptureIntent) {
@@ -1351,7 +1376,7 @@ public class PhotoModule
// the mean time and fill it, but that could have happened between the
// shutter press and saving the JPEG too.
mActivity.updateStorageSpaceAndHint();
- updateRemainingPhotos();
+ mUI.updateRemainingPhotos(--mRemainingPhotos);
long now = System.currentTimeMillis();
mJpegCallbackFinishTime = now - mJpegPictureCallbackTime;
Log.v(TAG, "mJpegCallbackFinishTime = "
@@ -1604,6 +1629,7 @@ public class PhotoModule
new JpegPictureCallback(loc));
}
} else {
+ mCameraDevice.enableShutterSound(!mRefocus);
mCameraDevice.takePicture(mHandler,
new ShutterCallback(!animateBefore),
mRawPictureCallback, mPostViewPictureCallback,
@@ -1763,9 +1789,7 @@ public class PhotoModule
} else {
mUI.overrideSettings(CameraSettings.KEY_PICTURE_FORMAT, null);
}
- if ((ubiFocus != null && ubiFocus.equals(ubiFocusOn)) ||
- (multiTouchFocus != null && multiTouchFocus.equals(multiTouchFocusOn)) ||
- (reFocus != null && reFocus.equals(reFocusOn)) ||
+ if ((multiTouchFocus != null && multiTouchFocus.equals(multiTouchFocusOn)) ||
(chromaFlash != null && chromaFlash.equals(chromaFlashOn)) ||
(optiZoom != null && optiZoom.equals(optiZoomOn)) ||
(fssr != null && fssr.equals(fssrOn)) ||
@@ -2097,10 +2121,12 @@ public class PhotoModule
}
//Need to disable focus for ZSL mode
- if(mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
- mFocusManager.setZslEnable(true);
- } else {
- mFocusManager.setZslEnable(false);
+ if (mFocusManager != null) {
+ if (mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
+ mFocusManager.setZslEnable(true);
+ } else {
+ mFocusManager.setZslEnable(false);
+ }
}
// If the user wants to do a snapshot while the previous one is still
@@ -2108,7 +2134,8 @@ public class PhotoModule
// one and re-start the preview. Snapshot in progress also includes the
// state that autofocus is focusing and a picture will be taken when
// focus callback arrives.
- if ((mFocusManager.isFocusingSnapOnFinish() || mCameraState == SNAPSHOT_IN_PROGRESS)
+ if ((((mFocusManager != null) && mFocusManager.isFocusingSnapOnFinish())
+ || mCameraState == SNAPSHOT_IN_PROGRESS)
&& !mIsImageCaptureIntent) {
mSnapshotOnIdle = true;
return;
@@ -2240,11 +2267,12 @@ public class PhotoModule
private void updateRemainingPhotos() {
if (mJpegFileSizeEstimation != 0) {
- mUI.updateRemainingPhotos((int) (mActivity.getStorageSpaceBytes()
- / mJpegFileSizeEstimation));
+ mRemainingPhotos = (int) (mActivity.getStorageSpaceBytes()
+ / mJpegFileSizeEstimation);
} else {
- mUI.updateRemainingPhotos(-1);
+ mRemainingPhotos = -1;
}
+ mUI.updateRemainingPhotos(mRemainingPhotos);
}
private void onResumeTasks() {
@@ -2844,7 +2872,16 @@ public class PhotoModule
//mUnsupportedJpegQuality = true;
}else {
mParameters.setJpegQuality(JpegEncodingQualityMappings.getQualityNumber(jpegQuality));
- setJpegFileSizeEstimation(pic_size, jpegQuality);
+ int jpegFileSize = estimateJpegFileSize(pic_size, jpegQuality);
+ if (jpegFileSize != mJpegFileSizeEstimation) {
+ mJpegFileSizeEstimation = jpegFileSize;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ updateRemainingPhotos();
+ }
+ });
+ }
}
}
@@ -3242,7 +3279,7 @@ public class PhotoModule
}
}
- private void setJpegFileSizeEstimation(final Size size, final String quality) {
+ private int estimateJpegFileSize(final Size size, final String quality) {
int[] ratios = mActivity.getResources().getIntArray(R.array.jpegquality_compression_ratio);
String[] qualities = mActivity.getResources().getStringArray(
R.array.pref_camera_jpegquality_entryvalues);
@@ -3255,9 +3292,9 @@ public class PhotoModule
}
if (ratio == 0) {
- mJpegFileSizeEstimation = 0;
+ return 0;
} else {
- mJpegFileSizeEstimation = size.width * size.height * 3 / ratio;
+ return size.width * size.height * 3 / ratio;
}
}
@@ -3472,6 +3509,10 @@ public class PhotoModule
mActivity.getString(R.string.pref_camera_scenemode_default));
}
}
+
+ String refocusOn = mActivity.getString(R.string
+ .pref_camera_advanced_feature_value_refocus_on);
+
if (CameraUtil.isSupported(mSceneMode, mParameters.getSupportedSceneModes())) {
if (!mParameters.getSceneMode().equals(mSceneMode)) {
mParameters.setSceneMode(mSceneMode);
@@ -3483,9 +3524,16 @@ public class PhotoModule
mParameters = mCameraDevice.getParameters();
}
} else {
- mSceneMode = mParameters.getSceneMode();
- if (mSceneMode == null) {
- mSceneMode = Parameters.SCENE_MODE_AUTO;
+ if (refocusOn.equals(mSceneMode)) {
+ try {
+ mUI.setPreference(CameraSettings.KEY_ADVANCED_FEATURES, refocusOn);
+ } catch (NullPointerException e) {
+ }
+ } else {
+ mSceneMode = mParameters.getSceneMode();
+ if (mSceneMode == null) {
+ mSceneMode = Parameters.SCENE_MODE_AUTO;
+ }
}
}
@@ -4124,6 +4172,12 @@ public class PhotoModule
return;
}
+ if (CameraSettings.KEY_CAMERA_SAVEPATH.equals(pref.getKey())) {
+ Storage.setSaveSDCard(
+ mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
+ mActivity.updateStorageSpaceAndHint();
+ }
+
//call generic onSharedPreferenceChanged
onSharedPreferenceChanged();
}
@@ -4171,8 +4225,6 @@ public class PhotoModule
disableSkinToneSeekBar();
}
}
- Storage.setSaveSDCard(
- mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
}
@Override
@@ -4423,6 +4475,10 @@ public class PhotoModule
}
}
}
+
+ public boolean isRefocus() {
+ return mLastPhotoTakenWithRefocus;
+ }
}
/* Below is no longer needed, except to get rid of compile error
@@ -4600,5 +4656,4 @@ class DrawAutoHDR extends View{
public void setPhotoModuleObject (PhotoModule photoModule) {
mPhotoModule = photoModule;
}
-
}
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index b4e08c398..d4cec7bc0 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -529,6 +529,10 @@ public class PhotoUI implements PieListener,
task.execute();
}
+ public void showRefocusToast(boolean show) {
+ mCameraControls.showRefocusToast(show);
+ }
+
private void openMenu() {
if (mPieRenderer != null) {
// If autofocus is not finished, cancel autofocus so that the
@@ -553,7 +557,9 @@ public class PhotoUI implements PieListener,
mMenuButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mMenu.openFirstLevel();
+ if(mMenu != null){
+ mMenu.openFirstLevel();
+ }
}
});
if (mController.isImageCaptureIntent()) {
@@ -917,8 +923,11 @@ public class PhotoUI implements PieListener,
}
public boolean sendTouchToMenu(MotionEvent ev) {
- View v = mMenuLayout.getChildAt(0);
- return v.dispatchTouchEvent(ev);
+ if (mMenuLayout != null) {
+ View v = mMenuLayout.getChildAt(0);
+ return v.dispatchTouchEvent(ev);
+ }
+ return false;
}
public void dismissSceneModeMenu() {
@@ -962,6 +971,7 @@ public class PhotoUI implements PieListener,
ret = true;
}
onShowSwitcherPopup();
+ mCameraControls.showRefocusToast(false);
return ret;
}
diff --git a/src/com/android/camera/RefocusActivity.java b/src/com/android/camera/RefocusActivity.java
new file mode 100644
index 000000000..2102d1a78
--- /dev/null
+++ b/src/com/android/camera/RefocusActivity.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.camera;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Build;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+
+import org.codeaurora.snapcam.R;
+
+public class RefocusActivity extends Activity {
+ private static final String TAG = "RefocusActivity";
+ private static final String[] NAMES = {
+ "00", "01", "02", "03", "04", "AllFocusImage"
+ };
+
+ private Uri mUri;
+
+ private ImageView mImageView;
+ private int mWidth;
+ private int mHeight;
+
+ private DepthMap mDepthMap;
+ private int mCurrentImage = -1;
+ private int mRequestedImage = -1;
+ private LoadImageTask mLoadImageTask;
+
+ @Override
+ public void onCreate(Bundle state) {
+ super.onCreate(state);
+
+ new Thread(new Runnable() {
+ public void run() {
+ mDepthMap = new DepthMap(getFilesDir() + "/DepthMapImage.y");
+ }
+ }).start();
+
+ mUri = getIntent().getData();
+ setResult(RESULT_CANCELED, new Intent());
+
+ setContentView(R.layout.refocus_editor);
+ mImageView = (ImageView) findViewById(R.id.refocus_image);
+ mImageView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_UP:
+ float x = event.getX();
+ float y = event.getY();
+ int w = v.getWidth();
+ int h = v.getHeight();
+ if (mDepthMap != null) {
+ int depth = mDepthMap.getDepth(x / (float) w, y / (float) h);
+ setCurrentImage(depth);
+ }
+ break;
+ }
+ return true;
+ }
+ });
+
+ findViewById(R.id.refocus_all).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ allInFocus();
+ }
+ });
+
+ findViewById(R.id.refocus_cancel).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ finish();
+ }
+ });
+
+ findViewById(R.id.refocus_done).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ if (mRequestedImage != NAMES.length - 1) {
+ new SaveImageTask().execute(getFilesDir() + "/" + NAMES[mRequestedImage]
+ + ".jpg");
+ } else {
+ finish();
+ }
+ }
+ });
+
+ Display display = getWindowManager().getDefaultDisplay();
+ Point size = new Point();
+ display.getSize(size);
+ mWidth = size.x;
+ mHeight = size.y;
+
+ allInFocus();
+ }
+
+ private void setCurrentImage(int depth) {
+ if (depth >= 0 && depth < NAMES.length && depth != mRequestedImage) {
+ mRequestedImage = depth;
+ if (mLoadImageTask != null) {
+ mLoadImageTask.cancel(true);
+ }
+ if (depth != mCurrentImage) {
+ mCurrentImage = depth;
+ mLoadImageTask = new LoadImageTask();
+ mLoadImageTask.execute(getFilesDir() + "/" + NAMES[depth] + ".jpg");
+ }
+ }
+ }
+
+ private void allInFocus() {
+ setCurrentImage(NAMES.length - 1);
+ }
+
+ private class SaveImageTask extends AsyncTask<String, Void, Void> {
+ protected Void doInBackground(String... path) {
+ try {
+ OutputStream out = getContentResolver().openOutputStream(mUri);
+ FileInputStream in = new FileInputStream(path[0]);
+ byte[] buf = new byte[4096];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ } catch (Exception e) {
+ }
+ Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mUri);
+ sendBroadcast(intent);
+ return null;
+ }
+
+ protected void onPostExecute(Void v) {
+ finish();
+ }
+ }
+
+ private class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
+ protected Bitmap doInBackground(String... path) {
+ final BitmapFactory.Options o = new BitmapFactory.Options();
+ o.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(path[0], o);
+
+ int h = o.outHeight;
+ int w = o.outWidth;
+ int sample = 1;
+
+ if (h > mHeight || w > mWidth) {
+ while (h / sample / 2 > mHeight && w / sample / 2 > mWidth) {
+ sample *= 2;
+ }
+ }
+
+ o.inJustDecodeBounds = false;
+ o.inSampleSize = sample;
+ return BitmapFactory.decodeFile(path[0], o);
+ }
+
+ protected void onPostExecute(Bitmap result) {
+ mImageView.setImageBitmap(result);
+ }
+ }
+
+ private class DepthMap {
+ private byte[] mData;
+ private int mWidth;
+ private int mHeight;
+ private boolean mFail = true;
+
+ public DepthMap(final String path) {
+ File file = new File(path);
+ try {
+ FileInputStream stream = new FileInputStream(file);
+ mData = new byte[(int) file.length()];
+ stream.read(mData);
+ stream.close();
+ } catch (Exception e) {
+ }
+
+ int length = (int) mData.length;
+ if (length > 25) {
+ mFail = (mData[length - 25] != 0);
+ mWidth = readInteger(length - 24);
+ mHeight = readInteger(length - 20);
+ }
+ if (mWidth * mHeight + 25 > length) {
+ mFail = true;
+ }
+ }
+
+ public int getDepth(float x, float y) {
+ if (mFail || x > 1.0f || y > 1.0f) {
+ return NAMES.length - 1;
+ } else {
+ return mData[(int) ((y * mHeight + x) * mWidth)];
+ }
+ }
+
+ private int readInteger(int offset) {
+ int result = mData[offset] & 0xff;
+ for (int i = 1; i < 4; ++i) {
+ result <<= 8;
+ result += mData[offset + i] & 0xff;
+ }
+ return result;
+ }
+ }
+}
diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java
index 3f9cde7f0..1f9c6d1a0 100644
--- a/src/com/android/camera/VideoMenu.java
+++ b/src/com/android/camera/VideoMenu.java
@@ -66,7 +66,8 @@ public class VideoMenu extends MenuController
private static final int POPUP_NONE = 0;
private static final int POPUP_FIRST_LEVEL = 1;
private static final int POPUP_SECOND_LEVEL = 2;
- private static final int POPUP_IN_ANIMATION = 3;
+ private static final int POPUP_IN_ANIMATION_SLIDE = 3;
+ private static final int POPUP_IN_ANIMATION_FADE = 4;
private static final int PREVIEW_MENU_NONE = 0;
private static final int PREVIEW_MENU_IN_ANIMATION = 1;
private static final int PREVIEW_MENU_ON = 2;
@@ -164,9 +165,9 @@ public class VideoMenu extends MenuController
}
private void animateFadeOut(final ListView v, final int level) {
- if (v == null || mPopupStatus == POPUP_IN_ANIMATION)
+ if (v == null || mPopupStatus == POPUP_IN_ANIMATION_FADE)
return;
- mPopupStatus = POPUP_IN_ANIMATION;
+ mPopupStatus = POPUP_IN_ANIMATION_FADE;
ViewPropertyAnimator vp = v.animate();
vp.alpha(0f).setDuration(ANIMATION_DURATION);
@@ -213,9 +214,9 @@ public class VideoMenu extends MenuController
}
private void animateSlideOut(final ListView v, final int level) {
- if (v == null || mPopupStatus == POPUP_IN_ANIMATION)
+ if (v == null || mPopupStatus == POPUP_IN_ANIMATION_SLIDE)
return;
- mPopupStatus = POPUP_IN_ANIMATION;
+ mPopupStatus = POPUP_IN_ANIMATION_SLIDE;
ViewPropertyAnimator vp = v.animate();
vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION);
@@ -340,7 +341,9 @@ public class VideoMenu extends MenuController
}
public boolean isOverMenu(MotionEvent ev) {
- if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION)
+ if (mPopupStatus == POPUP_NONE
+ || mPopupStatus == POPUP_IN_ANIMATION_SLIDE
+ || mPopupStatus == POPUP_IN_ANIMATION_FADE)
return false;
if (mUI.getMenuLayout() == null)
return false;
@@ -366,7 +369,7 @@ public class VideoMenu extends MenuController
}
public boolean isMenuBeingAnimated() {
- return mPopupStatus == POPUP_IN_ANIMATION;
+ return mPopupStatus == POPUP_IN_ANIMATION_SLIDE || mPopupStatus == POPUP_IN_ANIMATION_FADE;
}
public boolean isPreviewMenuBeingShown() {
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 1bd395188..59874dd81 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -646,6 +646,7 @@ public class VideoModule implements CameraModule,
mUI.animateCapture();
}
}
+ mUI.showUIafterRecording();
}
public void onVideoSaved() {
@@ -687,10 +688,8 @@ public class VideoModule implements CameraModule,
if (stop) {
onStopVideoRecording();
- mUI.showUIafterRecording();
} else {
startVideoRecording();
- mUI.hideUIwhileRecording();
}
mUI.enableShutter(false);
@@ -1597,6 +1596,7 @@ public class VideoModule implements CameraModule,
mStartRecPending = true;
mUI.cancelAnimations();
mUI.setSwipingEnabled(false);
+ mUI.hideUIwhileRecording();
mActivity.updateStorageSpaceAndHint();
if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
@@ -2276,6 +2276,11 @@ public class VideoModule implements CameraModule,
mParameters.setVideoRotation(videoRotation);
}
+ //set low-power mode if supported
+ String lpmSupported = mParameters.get("low-power-mode-supported");
+ if ("true".equals(lpmSupported)) {
+ mParameters.set("low-power-mode", 1);
+ }
}
@SuppressWarnings("deprecation")
private void setCameraParameters() {
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index bc9fd8602..40878581e 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -44,7 +44,6 @@ import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.Display;
import android.widget.Toast;
import com.android.camera.PhotoModule;
import com.android.camera.CameraManager.CameraProxy;
@@ -110,8 +109,6 @@ public class WideAnglePanoramaModule
private boolean mUsingFrontCamera;
private int mCameraPreviewWidth;
private int mCameraPreviewHeight;
- private int mScreenWidth;
- private int mScreenHeight;
private int mCameraState;
private int mCaptureState;
private PowerManager.WakeLock mPartialWakeLock;
@@ -372,13 +369,14 @@ public class WideAnglePanoramaModule
return true;
}
- private boolean findBestPreviewSize(List<Size> supportedSizes, boolean need4To3, boolean need16To9,
+ private boolean findBestPreviewSize(List<Size> supportedSizes, boolean need4To3,
boolean needSmaller) {
int pixelsDiff = DEFAULT_CAPTURE_PIXELS;
boolean hasFound = false;
for (Size size : supportedSizes) {
int h = size.height;
int w = size.width;
+ // we only want 4:3 format.
int d = DEFAULT_CAPTURE_PIXELS - h * w;
if (needSmaller && d < 0) { // no bigger preview than 960x720.
continue;
@@ -386,9 +384,6 @@ public class WideAnglePanoramaModule
if (need4To3 && (h * 4 != w * 3)) {
continue;
}
- if (need16To9 && (h * 16 != w * 9)) {
- continue;
- }
d = Math.abs(d);
if (d < pixelsDiff) {
mCameraPreviewWidth = w;
@@ -401,26 +396,12 @@ public class WideAnglePanoramaModule
}
private void setupCaptureParams(Parameters parameters) {
- boolean need4To3 = false;
- boolean need16To9 = false;
List<Size> supportedSizes = parameters.getSupportedPreviewSizes();
- Display mDisplay = mActivity.getWindowManager().getDefaultDisplay();
- mScreenWidth = mDisplay.getWidth();
- mScreenHeight = mDisplay.getHeight();
-
- if(mScreenHeight * 4 == mScreenWidth * 3) {
- need4To3 = true;
- }
-
- if(mScreenHeight * 16 == mScreenWidth * 9) {
- need16To9 = true;
- }
-
- if (!findBestPreviewSize(supportedSizes, need4To3, need16To9, true)) {
- Log.w(TAG, "No preview size supported matching the screen aspect ratio");
- if (!findBestPreviewSize(supportedSizes, false, false, true)) {
+ if (!findBestPreviewSize(supportedSizes, true, true)) {
+ Log.w(TAG, "No 4:3 ratio preview size supported.");
+ if (!findBestPreviewSize(supportedSizes, false, true)) {
Log.w(TAG, "Can't find a supported preview size smaller than 960x720.");
- findBestPreviewSize(supportedSizes, false, false, false);
+ findBestPreviewSize(supportedSizes, false, false);
}
}
Log.d(TAG, "camera preview h = "
@@ -511,9 +492,6 @@ public class WideAnglePanoramaModule
}
mPreviewUIWidth = r - l;
mPreviewUIHeight = b - t;
- Parameters parameters = mCameraDevice.getParameters();
- setupCaptureParams(parameters);
- configureCamera(parameters);
configMosaicPreview();
if (capturePending == true){
mMainHandler.post(new Runnable() {
diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java
index 4b403f2d9..9594ac0e6 100644
--- a/src/com/android/camera/WideAnglePanoramaUI.java
+++ b/src/com/android/camera/WideAnglePanoramaUI.java
@@ -441,6 +441,14 @@ public class WideAnglePanoramaUI implements
private void setViews(Resources appRes) {
int weight = appRes.getInteger(R.integer.SRI_pano_layout_weight);
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPreviewLayout.getLayoutParams();
+ lp.weight = weight;
+ mPreviewLayout.setLayoutParams(lp);
+
+ lp = (LinearLayout.LayoutParams) mReview.getLayoutParams();
+ lp.weight = weight;
+ mPreviewLayout.setLayoutParams(lp);
+
mSavingProgressBar = (PanoProgressBar) mRootView.findViewById(R.id.pano_saving_progress_bar);
mSavingProgressBar.setIndicatorWidth(0);
mSavingProgressBar.setMaxProgress(100);
diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java
index 14f27a36d..0938ffc19 100644
--- a/src/com/android/camera/ui/CameraControls.java
+++ b/src/com/android/camera/ui/CameraControls.java
@@ -19,13 +19,18 @@ package com.android.camera.ui;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.content.Context;
-import android.util.Log;
+import android.graphics.Canvas;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.Paint;
+import android.graphics.Path;
import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -51,6 +56,8 @@ public class CameraControls extends RotatableLayout {
private View mPreview;
private View mSceneModeSwitcher;
private View mFilterModeSwitcher;
+ private ArrowTextView mRefocusToast;
+
private int mSize;
private static final int WIDTH_GRID = 5;
private static final int HEIGHT_GRID = 7;
@@ -154,8 +161,15 @@ public class CameraControls extends RotatableLayout {
public CameraControls(Context context, AttributeSet attrs) {
super(context, attrs);
+
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
+
+ mRefocusToast = new ArrowTextView(context);
+ addView(mRefocusToast);
+ setClipChildren(false);
+
+ setMeasureAllChildren(true);
}
public CameraControls(Context context) {
@@ -294,6 +308,46 @@ public class CameraControls extends RotatableLayout {
toIndex(mHdrSwitcher, w, h, rotation, 3, 0, HDR_INDEX);
toIndex(mFilterModeSwitcher, w, h, rotation, 1, 0, FILTER_MODE_INDEX);
toIndex(mSceneModeSwitcher, w, h, rotation, 0, 0, SCENE_MODE_INDEX);
+ layoutToast(mRefocusToast, w, h, rotation);
+ }
+
+ private void layoutToast(final View v, int w, int h, int rotation) {
+ int tw = v.getMeasuredWidth();
+ int th = v.getMeasuredHeight();
+ int l, t, r, b, c;
+ switch (rotation) {
+ case 90:
+ c = (int) (h / WIDTH_GRID * (WIDTH_GRID - 0.5));
+ t = c - th / 2;
+ b = c + th / 2;
+ r = (int) (w / HEIGHT_GRID * (HEIGHT_GRID - 1.25));
+ l = r - tw;
+ mRefocusToast.setArrow(tw, th / 2, tw + th / 2, th, tw, th);
+ break;
+ case 180:
+ t = (int) (h / HEIGHT_GRID * 1.25);
+ b = t + th;
+ r = (int) (w / WIDTH_GRID * (WIDTH_GRID - 0.25));
+ l = r - tw;
+ mRefocusToast.setArrow(tw - th / 2, 0, tw, 0, tw, - th / 2);
+ break;
+ case 270:
+ c = (int) (h / WIDTH_GRID * 0.5);
+ t = c - th / 2;
+ b = c + th / 2;
+ l = (int) (w / HEIGHT_GRID * 1.25);
+ r = l + tw;
+ mRefocusToast.setArrow(0, 0, 0, th / 2, - th / 2, 0);
+ break;
+ default:
+ l = w / WIDTH_GRID / 4;
+ b = (int) (h / HEIGHT_GRID * (HEIGHT_GRID - 1.25));
+ r = l + tw;
+ t = b - th;
+ mRefocusToast.setArrow(0, th, th / 2, th, 0, th * 3 / 2);
+ break;
+ }
+ mRefocusToast.layout(l, t, r, b);
}
private void center(View v, int l, int t, int r, int b, int orientation, int rotation,
@@ -433,6 +487,7 @@ public class CameraControls extends RotatableLayout {
break;
}
mRemainingPhotos.setVisibility(View.INVISIBLE);
+ mRefocusToast.setVisibility(View.GONE);
}
public void showUI() {
@@ -523,6 +578,7 @@ public class CameraControls extends RotatableLayout {
if (mRemainingPhotos.getVisibility() == View.INVISIBLE) {
mRemainingPhotos.setVisibility(View.VISIBLE);
}
+ mRefocusToast.setVisibility(View.GONE);
}
private void center(View v, Rect other, int rotation) {
@@ -767,4 +823,52 @@ public class CameraControls extends RotatableLayout {
}
invalidate();
}
+
+ public void showRefocusToast(boolean show) {
+ mRefocusToast.setVisibility(show ? View.VISIBLE : View.GONE);
+ mRemainingPhotos.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+
+ private class ArrowTextView extends TextView {
+ private static final int TEXT_SIZE = 14;
+ private static final int PADDING_SIZE = 18;
+ private static final int BACKGROUND = 0x80000000;
+
+ private Paint mPaint;
+ private Path mPath;
+
+ public ArrowTextView(Context context) {
+ super(context);
+
+ setText(context.getString(R.string.refocus_toast));
+ setBackgroundColor(BACKGROUND);
+ setVisibility(View.GONE);
+ setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ setTextSize(TEXT_SIZE);
+ setPadding(PADDING_SIZE, PADDING_SIZE, PADDING_SIZE, PADDING_SIZE);
+
+ mPaint = new Paint();
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(BACKGROUND);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (mPath != null) {
+ canvas.drawPath(mPath, mPaint);
+ }
+ }
+
+ public void setArrow(float x1, float y1, float x2, float y2, float x3, float y3) {
+ mPath = new Path();
+ mPath.reset();
+ mPath.moveTo(x1, y1);
+ mPath.lineTo(x2, y2);
+ mPath.lineTo(x3, y3);
+ mPath.lineTo(x1, y1);
+ }
+ }
}
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 08ce84d87..dbd2cc36d 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -1073,18 +1073,10 @@ public class CameraUtil {
}
public static int determineRatio(int width, int height) {
- int s = width, l = height;
- if (width > height) {
- l = width;
- s = height;
- }
- if (l * 3 == s * 4) {
- return RATIO_4_3;
- } else if (l * 9 == s * 16) {
- return RATIO_16_9;
- } else {
- return RATIO_UNKNOWN;
+ if (height != 0) {
+ return determineRatio(((float) width) / height);
}
+ return RATIO_UNKNOWN;
}
public static int determineRatio(float ratio) {