resolved conflicts for merge of e293317f to master
Change-Id: I395d7d596414d118ebb788ef5a46e052785935a7
diff --git a/proguard.flags b/proguard.flags
index d1b41b1..5dcd2b9 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -2,3 +2,12 @@
-keep class * extends com.android.camera.CameraPreference {
<init>(...);
}
+
+-keep class com.android.camera.ActivityBase {
+ public int getResultCode();
+ public android.content.Intent getResultData();
+}
+
+-keep class com.android.camera.VideoCamera {
+ public boolean isRecording();
+}
diff --git a/res/drawable-hdpi/btn_ic_camera_shutter_large.png b/res/drawable-hdpi/btn_ic_camera_shutter_large.png
deleted file mode 100644
index 74d37cb..0000000
--- a/res/drawable-hdpi/btn_ic_camera_shutter_large.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_mode_switch_bg_v2.9.png b/res/drawable-hdpi/btn_mode_switch_bg_v2.9.png
deleted file mode 100644
index 5396f14..0000000
--- a/res/drawable-hdpi/btn_mode_switch_bg_v2.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_mode_switch_knob_v2_normal.png b/res/drawable-hdpi/btn_mode_switch_knob_v2_normal.png
deleted file mode 100644
index 7737fb3..0000000
--- a/res/drawable-hdpi/btn_mode_switch_knob_v2_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_mode_switch_knob_v2_pressed.png b/res/drawable-hdpi/btn_mode_switch_knob_v2_pressed.png
deleted file mode 100644
index fc431b5..0000000
--- a/res/drawable-hdpi/btn_mode_switch_knob_v2_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_shutter_large_normal.png b/res/drawable-hdpi/btn_shutter_large_normal.png
deleted file mode 100644
index b068536..0000000
--- a/res/drawable-hdpi/btn_shutter_large_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_shutter_large_pressed.png b/res/drawable-hdpi/btn_shutter_large_pressed.png
deleted file mode 100644
index eaed6c5..0000000
--- a/res/drawable-hdpi/btn_shutter_large_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/button_zoom_in_focused_holo.png b/res/drawable-hdpi/button_zoom_in_focused_holo.png
deleted file mode 100644
index 5787024..0000000
--- a/res/drawable-hdpi/button_zoom_in_focused_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/button_zoom_out_focused_holo.png b/res/drawable-hdpi/button_zoom_out_focused_holo.png
deleted file mode 100644
index b4659aa..0000000
--- a/res/drawable-hdpi/button_zoom_out_focused_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/divider_horizontal_holo_dark.9.png b/res/drawable-hdpi/divider_horizontal_holo_dark.9.png
deleted file mode 100644
index e720253..0000000
--- a/res/drawable-hdpi/divider_horizontal_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/focus_focus_failed.9.png b/res/drawable-hdpi/focus_focus_failed.9.png
index f0d9ca0..52336cc 100644
--- a/res/drawable-hdpi/focus_focus_failed.9.png
+++ b/res/drawable-hdpi/focus_focus_failed.9.png
Binary files differ
diff --git a/res/drawable-hdpi/focus_focused.9.png b/res/drawable-hdpi/focus_focused.9.png
index e7c5c57..d941c48 100644
--- a/res/drawable-hdpi/focus_focused.9.png
+++ b/res/drawable-hdpi/focus_focused.9.png
Binary files differ
diff --git a/res/drawable-hdpi/focus_focusing.9.png b/res/drawable-hdpi/focus_focusing.9.png
index 0bef57a..1838a6c 100644
--- a/res/drawable-hdpi/focus_focusing.9.png
+++ b/res/drawable-hdpi/focus_focusing.9.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_share.jpg b/res/drawable-hdpi/ic_viewfinder_share.jpg
new file mode 100644
index 0000000..7a8949d
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_share.jpg
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
deleted file mode 100644
index d2a39e4..0000000
--- a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png
deleted file mode 100644
index 398a4b9..0000000
--- a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
deleted file mode 100644
index 5567eb0..0000000
--- a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
deleted file mode 100644
index ce0cf42..0000000
--- a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
deleted file mode 100644
index cb66c52..0000000
--- a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/mode_switch_bg_v2.9.png b/res/drawable-hdpi/mode_switch_bg_v2.9.png
deleted file mode 100644
index a27c935..0000000
--- a/res/drawable-hdpi/mode_switch_bg_v2.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/divider_horizontal_holo_dark.9.png b/res/drawable-mdpi/divider_horizontal_holo_dark.9.png
deleted file mode 100644
index e720253..0000000
--- a/res/drawable-mdpi/divider_horizontal_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/focus_focus_failed.9.png b/res/drawable-mdpi/focus_focus_failed.9.png
old mode 100755
new mode 100644
index 62d0944..6b425ea
--- a/res/drawable-mdpi/focus_focus_failed.9.png
+++ b/res/drawable-mdpi/focus_focus_failed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/focus_focused.9.png b/res/drawable-mdpi/focus_focused.9.png
old mode 100755
new mode 100644
index 2cf4423..71adb2a
--- a/res/drawable-mdpi/focus_focused.9.png
+++ b/res/drawable-mdpi/focus_focused.9.png
Binary files differ
diff --git a/res/drawable-mdpi/focus_focusing.9.png b/res/drawable-mdpi/focus_focusing.9.png
old mode 100755
new mode 100644
index 3fea637..83bb2f0
--- a/res/drawable-mdpi/focus_focusing.9.png
+++ b/res/drawable-mdpi/focus_focusing.9.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_share.png b/res/drawable-mdpi/ic_viewfinder_share.png
new file mode 100644
index 0000000..a73bec5
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_share.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
deleted file mode 100644
index 199e0ef..0000000
--- a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png
deleted file mode 100644
index e0b4974..0000000
--- a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
deleted file mode 100644
index 1104ce5..0000000
--- a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
deleted file mode 100644
index 8b99109..0000000
--- a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
deleted file mode 100644
index 36e2c1a..0000000
--- a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw485dp/ic_viewfinder_share.png b/res/drawable-sw485dp/ic_viewfinder_share.png
new file mode 100644
index 0000000..d8f223a
--- /dev/null
+++ b/res/drawable-sw485dp/ic_viewfinder_share.png
Binary files differ
diff --git a/res/drawable/btn_camera_picker.xml b/res/drawable/btn_camera_picker.xml
deleted file mode 100644
index 109d57f..0000000
--- a/res/drawable/btn_camera_picker.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:color="@android:color/white" />
- <item android:color="@android:color/darker_gray" />
-</selector>
diff --git a/res/layout-sw485dp/basic_setting_popup.xml b/res/layout-sw485dp/basic_setting_popup.xml
index 9be5ada..06561a0 100644
--- a/res/layout-sw485dp/basic_setting_popup.xml
+++ b/res/layout-sw485dp/basic_setting_popup.xml
@@ -25,7 +25,7 @@
android:layout_marginRight="229dp"
android:orientation="vertical"
android:visibility="invisible">
- <FrameLayout android:id="@+id/topPanel"
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_top_holo_dark"
diff --git a/res/layout-sw485dp/other_setting_popup.xml b/res/layout-sw485dp/other_setting_popup.xml
index 4dfbe62..09744d6 100644
--- a/res/layout-sw485dp/other_setting_popup.xml
+++ b/res/layout-sw485dp/other_setting_popup.xml
@@ -27,7 +27,7 @@
android:orientation="vertical"
android:visibility="invisible">
- <FrameLayout android:id="@+id/topPanel"
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_top_holo_dark"
diff --git a/res/layout-sw485dp/preview_frame.xml b/res/layout-sw485dp/preview_frame.xml
index b054299..7f64286 100644
--- a/res/layout-sw485dp/preview_frame.xml
+++ b/res/layout-sw485dp/preview_frame.xml
@@ -26,14 +26,11 @@
<SurfaceView android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <ImageView android:id="@+id/preview_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/border_preview_holo"/>
<com.android.camera.ui.FocusRectangle
android:id="@+id/focus_rectangle"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_width="180dp"
+ android:layout_height="180dp"
+ android:layout_centerInParent="true"/>
<TextView android:id="@+id/zoom_ratio"
style="@style/OnViewfinderLabel"
android:layout_alignParentRight="true"
@@ -54,5 +51,17 @@
android:visibility="invisible"/>
<include layout="@layout/review_thumbnail"/>
<include layout="@layout/review_control"/>
+ <ImageView android:id="@+id/review_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:background="@android:color/black"/>
</RelativeLayout>
+ <!-- This is the border of preview and the corner is round. If it is the background,
+ preview will be on top and the inner corner will be square, which looks bad.
+ So this is put in the end of layout to keep corner round. -->
+ <ImageView android:id="@+id/preview_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/border_preview_holo"/>
</com.android.camera.PreviewFrameLayout>
diff --git a/res/layout-sw485dp/preview_frame_video.xml b/res/layout-sw485dp/preview_frame_video.xml
index dd003af..115383d 100644
--- a/res/layout-sw485dp/preview_frame_video.xml
+++ b/res/layout-sw485dp/preview_frame_video.xml
@@ -27,14 +27,6 @@
<SurfaceView android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <ImageView android:id="@+id/preview_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/border_preview_holo"/>
- <ImageView android:id="@+id/video_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
<include layout="@layout/review_thumbnail"/>
<TextView android:id="@+id/recording_time"
style="@style/OnViewfinderLabel"
@@ -64,5 +56,17 @@
android:paddingBottom="10dp"
android:src="@drawable/btn_ic_review_play"/>
</LinearLayout>
+ <ImageView android:id="@+id/review_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:background="@android:color/black"/>
</RelativeLayout>
+ <!-- This is the border of preview and the corner is round. If it is the background,
+ preview will be on top and the inner corner will be square, which looks bad.
+ So this is put in the end of layout to keep corner round. -->
+ <ImageView android:id="@+id/preview_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/border_preview_holo"/>
</com.android.camera.PreviewFrameLayout>
diff --git a/res/layout-sw485dp/review_thumbnail.xml b/res/layout-sw485dp/review_thumbnail.xml
index ce17517..7e7eb62 100644
--- a/res/layout-sw485dp/review_thumbnail.xml
+++ b/res/layout-sw485dp/review_thumbnail.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.camera.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.camera.ui.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="invisible"
android:id="@+id/review_thumbnail"
android:layout_width="112dp"
diff --git a/res/layout-sw485dp/setting_scale_image_item.xml b/res/layout-sw485dp/setting_scale_image_item.xml
deleted file mode 100644
index c5988fb..0000000
--- a/res/layout-sw485dp/setting_scale_image_item.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="96dp"
- android:layout_height="96dp"
- android:layout_marginTop="10dp"
- android:gravity="center"
- android:scaleType="fitCenter"
- android:minHeight="96dp"
- android:minWidth="96dp" />
-
diff --git a/res/layout/attach_camera_control.xml b/res/layout/attach_camera_control.xml
index fdb48b8..7c0e6dd 100644
--- a/res/layout/attach_camera_control.xml
+++ b/res/layout/attach_camera_control.xml
@@ -16,7 +16,6 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
- android:id="@+id/control_bar"
android:layout_height="match_parent"
android:layout_width="76dp"
android:layout_marginTop="13dp"
diff --git a/res/layout/camera_attach.xml b/res/layout/camera_attach.xml
index bf23952..3530451 100644
--- a/res/layout/camera_attach.xml
+++ b/res/layout/camera_attach.xml
@@ -16,7 +16,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
- android:id="@+id/camera"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout/camera_control.xml b/res/layout/camera_control.xml
index f4117a2..2b04ad8 100644
--- a/res/layout/camera_control.xml
+++ b/res/layout/camera_control.xml
@@ -15,7 +15,6 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/control_bar"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="76dp"
@@ -30,7 +29,7 @@
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
- <com.android.camera.RotateImageView android:id="@+id/video_switch_icon"
+ <com.android.camera.ui.RotateImageView android:id="@+id/video_switch_icon"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/btn_ic_mode_switch_video"/>
@@ -39,7 +38,7 @@
android:layout_height="70dp"
android:src="@drawable/btn_mode_switch_knob"
android:background="@drawable/btn_mode_switch_bg" />
- <com.android.camera.RotateImageView
+ <com.android.camera.ui.RotateImageView
android:id="@+id/camera_switch_icon"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
diff --git a/res/layout/preview_frame.xml b/res/layout/preview_frame.xml
index 5a4a700..904ef20 100644
--- a/res/layout/preview_frame.xml
+++ b/res/layout/preview_frame.xml
@@ -20,19 +20,25 @@
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:layout_weight="1">
+ <!-- To be consistent with xlarge layout, preview border is not inside the preview frame. -->
+ <ImageView android:id="@+id/preview_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/border_view_finder"/>
<RelativeLayout android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <ImageView android:id="@+id/preview_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/border_view_finder"/>
<SurfaceView android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <com.android.camera.ui.FocusRectangle
- android:id="@+id/focus_rectangle"
+ <com.android.camera.ui.FocusRectangle android:id="@+id/focus_rectangle"
+ android:layout_width="120dp"
+ android:layout_height="120dp"
+ android:layout_centerInParent="true"/>
+ <ImageView android:id="@+id/review_image"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:background="@android:color/black"/>
</RelativeLayout>
</com.android.camera.PreviewFrameLayout>
diff --git a/res/layout/preview_frame_video.xml b/res/layout/preview_frame_video.xml
index 55606e8..ec0dbb5 100644
--- a/res/layout/preview_frame_video.xml
+++ b/res/layout/preview_frame_video.xml
@@ -19,20 +19,17 @@
android:layout_height="match_parent"
android:layout_marginLeft="2dip"
android:layout_weight="1">
+ <!-- To be consistent with xlarge layout, preview border is not inside the preview frame. -->
+ <ImageView android:id="@+id/preview_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/border_view_finder"/>
<RelativeLayout android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <ImageView android:id="@+id/preview_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/border_view_finder"/>
<SurfaceView android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <ImageView android:id="@+id/video_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
<!-- Note: In this TextView the paddingRight="2"
attribute is required because otherwise the
text's drop shadow will be clipped. -->
@@ -47,5 +44,10 @@
android:layout_marginLeft="17dp"
android:paddingRight="2dp"
android:visibility="gone" />
+ <ImageView android:id="@+id/review_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:background="@android:color/black" />
</RelativeLayout>
</com.android.camera.PreviewFrameLayout>
diff --git a/res/layout/review_thumbnail.xml b/res/layout/review_thumbnail.xml
index 1b9039c..880d57b 100644
--- a/res/layout/review_thumbnail.xml
+++ b/res/layout/review_thumbnail.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.camera.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.camera.ui.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/review_thumbnail"
android:layout_width="52dp"
android:layout_height="52dp"
diff --git a/res/layout/thumbnail_item.xml b/res/layout/thumbnail_item.xml
deleted file mode 100644
index 3e67ee4..0000000
--- a/res/layout/thumbnail_item.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.camera.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:layout_height="96dp"
- android:layout_width="96dp"
- android:background="@drawable/border_last_picture"/>
diff --git a/res/layout/video_camera_attach.xml b/res/layout/video_camera_attach.xml
index 589a89f..2c9c20a 100644
--- a/res/layout/video_camera_attach.xml
+++ b/res/layout/video_camera_attach.xml
@@ -16,7 +16,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
- android:id="@+id/video_camera"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index e2f84b5..47b4f92 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"إعادة تصوير"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"المعرض"</string>
<string name="switch_camera_id" msgid="837545176602471325">"تبديل الكاميرا"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"تمكين اللقطات المتتابعة"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"تعطيل اللقطات المتتابعة"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"تسجيل اللقطات المتتابعة"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"تحديد كاميرا"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"رجوع"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"تكبير/تصغير <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"تبديل إلى الكاميرا"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"تبديل إلى الفيديو"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 8bd68aa..d54f5de 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Презаснимане"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Галерия"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Превключване на камерата"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Акт. на цайтрафер"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Деакт. на цайтрафера"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Запис на цайтрафера"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Избор на камера"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Задна"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Промяна на мащаба <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Превключване към камера"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Преминаване към видеоклип"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3e3ccd9..907e48d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Repeteix"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Canvia la càmera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Act. lapse de temps"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Desact. lapse temps"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"S\'està enregistrant lapse de temps"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Selecciona la càmera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Enrere"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Canvia a la càmera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Canvia al vídeo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 331ea33..666853e 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Pořídit další"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Přepnout fotoaparát"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zapnout časosběr"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Vypnout časosběr"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Časosběrný záznam"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Vybrat fotoaparát"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Zadní"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Přiblížení: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Přepnout do režimu fotoaparát"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Přepnout do režimu video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index e1281f5..849b142 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Tag igen"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Skift kamera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Aktiver tidsforløb"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Deaktiver tidsforløb"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Optagelse af tidsforløb"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Vælg kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bagest"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Skift til kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Skift til video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 9c8a5ad..aa4b7c4 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Neu aufnehmen"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Kamera wechseln"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zeitraffer ein"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Zeitraffer aus"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Zeitrafferaufnahme"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Kamera auswählen"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Rückseite"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoomen mit Faktor <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Zu Kamera wechseln"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Zu Video wechseln"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 81feb01..153a2b4 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Νέα λήψη"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Συλλογή"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Εναλλαγή κάμερας"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Εν. παρελ. χρόν."</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Απ. παρελ. χρόν."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Εγγραφή παρέλευσης χρόνου"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Επιλογή κάμερας"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Πίσω"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Ζουμ <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Αλλαγή σε λειτουργία φωτογραφικής μηχανής"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Αλλαγή σε λειτουργία βίντεο"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index a625895..5b3623f 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Retake"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Gallery"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Switch Camera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Enable Time Lapse"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Disable Time Lapse"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Time lapse recording"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Select camera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Back"</string>
@@ -119,4 +117,8 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Switch to camera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Switch to video"</string>
+ <string name="share_picture_via" msgid="1375127849431890447">"Share picture via"</string>
+ <string name="share_video_via" msgid="5152302809166549015">"Share video via"</string>
+ <string name="no_picture_to_share" msgid="7700541451734517445">"No picture to share"</string>
+ <string name="no_video_to_share" msgid="3775826212074938990">"No video to share"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 674f222..761046f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Volver a tomar"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galería"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambiar cámara"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Habilitar intervalo de tiempo"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Inhabilitar intervalo de tiempo"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Grabación a intervalos de tiempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar cámara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Parte trasera"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Cambiar a cámara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Cambiar a video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 5109f66..4c69159 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Repetir"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galería"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambiar cámara"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Habilitar intervalos tiempo"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Inhabilitar intervalos tiempo"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Grabación a intervalos de tiempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar cámara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Trasera"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Cambiar a cámara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Cambiar a vídeo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 7ccebf0..217f18e 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"عکس مجدد"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"گالری"</string>
<string name="switch_camera_id" msgid="837545176602471325">"جابجایی به دوربین"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"فعال کردن گذشت زمان"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"غیرفعال کردن گذشت زمان"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"زمان سپری شده ضبط"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"انتخاب دوربین"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"برگشت"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"بزرگنمایی <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"رفتن به دوربین"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"رفتن به ویدیو"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 18fd42e..fb78867 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Uusi otos"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Vaihda kameraa"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Intervallikuvaus"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Ei intervallikuv."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Intervallikuvauksen tallennus"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Valitse kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Takaisin"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoomaus <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Vaihda kameraan"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Vaihda videoon"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index d3ba31d..3941a0c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Autre photo"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Changer d\'appareil photo"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Activer Time Lapse"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Désact. Time Lapse"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Enregistrement mode time lapse"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Choisir appareil ph."</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Arrière"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Passer en mode photo"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Passer en mode vidéo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 93d919d..9044379 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Snimi opet"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerija"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Promijeni kameru"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Omogući usporavanje vremena"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Onem. uspor. snim."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Snimanje s vremenskim odmakom"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Odabir kamere"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Natrag"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Povećaj/smanji <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Prebaci na fotoaparat"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Prebaci na videozapis"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index a3c2a45..814d8c4 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Újravétel"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galéria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Kamera váltása"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Lassítás bekapcs."</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Lassítás kikapcs."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Gyorsított felvétel"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Webkamera kiválasztása"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Vissza"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Váltás kamerára"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Váltás videóra"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 9eeeb33..112ede9 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Ambil ulang"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Ubah Kamera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Aktifkan Selang Waktu"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Nonaktifkan Selang Waktu"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Perekaman time lapse"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Pilih kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Belakang"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Alihkan ke kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Alihkan ke video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7240c1b..85629e2 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Scatta"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambia fotocamera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Attiva rallentatore"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Disattiva rallentat."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Registrazione al rallentatore"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleziona fotocamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Posteriore"</string>
@@ -119,4 +117,8 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Passa a fotocamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Passa a video"</string>
+ <string name="share_picture_via" msgid="1375127849431890447">"Condividi foto via"</string>
+ <string name="share_video_via" msgid="5152302809166549015">"Condividi video via"</string>
+ <string name="no_picture_to_share" msgid="7700541451734517445">"Nessuna immagine da condividere"</string>
+ <string name="no_video_to_share" msgid="3775826212074938990">"Nessun video da condividere"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 84437f2..0aed7ae 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"צלם שוב"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"גלריה"</string>
<string name="switch_camera_id" msgid="837545176602471325">"החלף מצלמה"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"הפוך מעבר זמן לזמין"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"השבת מעבר זמן"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"הקלטה של מעבר זמן"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"בחר מצלמה"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"הקודם"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"זום <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"עבור למצלמה"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"עבור לווידאו"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 18b5694..1a07e47 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"撮り直し"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"ギャラリー"</string>
<string name="switch_camera_id" msgid="837545176602471325">"カメラを切り替え"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"低速度撮影を有効にする"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"低速度撮影を無効にする"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"低速度撮影"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"カメラを選択"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"背面"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"ズーム<xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"写真に切替"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"ムービーに切替"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index e7278d6..ae1b997 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"다시 촬영"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"갤러리"</string>
<string name="switch_camera_id" msgid="837545176602471325">"카메라 전환"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"시간 경과 사용"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"시간 경과 사용안함"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"시간 경과 기록"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"카메라 선택"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"후방"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"<xliff:g id="ZOOM_TEXT">%s</xliff:g> 확대/축소"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"카메라로 전환"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"동영상으로 전환"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 33a51f7..c87af1f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Perfotogr."</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerija"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Perjungti fotokamerą"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Įgal. laiko tarpą"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Neleisti laiko tarpo"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Laiko tarpo įrašymas"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Pasirinkti fotokam."</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Atgal"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Keisti mastelį <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Perjungti į fotoaparatą"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Perjungti į vaizdo įrašą"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 91cab61..9cf221f 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Uzņ. vēlr."</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerija"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Pārslēgt kameru"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Iesp. laika interv."</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Atsp. laika interv."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Ierakstīšana laika intervāla režīmā"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Atlasīt kameru"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Atpakaļ"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Tālummaiņa: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Pārslēgt uz kameras režīmu"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Pārslēgt uz video režīmu"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index e3c5446..442d791 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Ta på nytt"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Bytt kamera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Aktiver tidsforløp"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Deaktiv. tidsforløp"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Tidsforkortelsesopptak"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Velg kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bakside"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Bytt til kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Bytt til video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 0047f02..78daaeb 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Opn. maken"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerij"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Camera wijzigen"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Time-lapse aan"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Time-lapse uit"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Time-lapse-opname"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Camera selecteren"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Achterzijde"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Overschakelen naar camera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Overschakelen naar video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 56cb32f..7bebc4b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Zrób ponownie"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Przełącz aparat"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Wł. tryb poklatkowy"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Wył. tryb poklatkowy"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Nagrywanie poklatkowe"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Wybierz aparat"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Tył"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Powiększenie <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Przełącz na aparat"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Przełącz na wideo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index babc7a6..9dee621 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Repetir"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Trocar câmara"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Act. lapso de tempo"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Des. lapso de tempo"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Gravação com lapso de tempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar câmara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Traseira"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Mudar para câmara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Mudar para vídeo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index db9920a..37eb041 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Tirar outra"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Alternar câmera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Ativar tempo grav."</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Desat. tempo grav."</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Gravação de lapso de tempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Selecionar câmera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Traseira"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Alternar para câmera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Alternar para vídeo"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 8084ce0..a65ea44 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -39,8 +39,6 @@
<!-- outdated translation 7804864054896088338 --> <string name="review_retake" msgid="7776579640762112761">"AUTRA FOTO"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Catalog"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Midar la camera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Activar l\'acceleratur"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Deactivar l\'acceleratur"</string>
<!-- no translation found for time_lapse_title (4360632427760662691) -->
<skip />
<string name="pref_camera_id_title" msgid="6023059405578511534">"Tscherner la camera"</string>
@@ -126,4 +124,12 @@
<skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Midar a la camera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Midar a video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 7fdb5a7..16f0b0c 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Refaceţi"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Schimbaţi camera foto"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Activ. filmare lentă"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Dezact. film. lentă"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Înregistrare cu filmare lentă"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Select. camera foto"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Înapoi"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zoom <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Comutaţi la camera foto"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Comutaţi la camera video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index e949296..25528c5 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Еще раз"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Галерея"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Переключить камеру"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Вкл. замедл. съемку"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Откл. замедл. съемку"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Режим замедленной съемки"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Выберите камеру"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Задняя"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Масштаб: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Переключить на фото"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Переключить на видео"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 7b49218..9c368c2 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Nasnímať znova"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galéria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Prepnúť fotoaparát"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Povoliť časozber"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Zakázať časozber"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Časozberný záznam"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Vybrať fotoaparát"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Zozadu"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Priblíženie: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Prepnúť do režimu fotoaparát"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Prepnúť do režimu video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index ec80f87..743647e 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Znova posnemi"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerija"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Menjava kamere"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Omogoči časovni zamik"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Onemogoči časovni zamik"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Snemanje s časovnim zamikom"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Izberite kamero"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Nazaj"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Povečava: <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Preklopi na fotoaparat"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Preklopi na video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 97137c1..ecaac99 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Понови"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Галерија"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Пребаци камеру"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Омогући снимање у дужем интервалу"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Онемогући снимање у дужем интервалу"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Снимањe у дужем интервалу"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Изаберите камеру"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Назад"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Зум <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Пребаци на камеру"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Пребаци на видео"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index f2bdcaf..64f6c3b 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Ta om"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Byt kamera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Tidsavvikelse på"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Tidsavvikelse av"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Intervallinspelning"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Välj kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bakre"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Zooma <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Växla till kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Växla till video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 6066b41..207072e 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"ถ่ายใหม่"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"แกลเลอรี"</string>
<string name="switch_camera_id" msgid="837545176602471325">"เปลี่ยนกล้องถ่ายรูป"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"เปิดใช้งานการถ่ายภาพช้า"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"ปิดใช้งานการถ่ายภาพช้า"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"การบันทึกเป็นช่วงเวลา"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"เลือกกล้องถ่ายรูป"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"ย้อนกลับ"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"ย่อ/ขยาย <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"สลับเป็นกล้องถ่ายรูป"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"สลับเป็นวิดีโอ"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 16d55b3..2533f7b 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Kunin muli"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Gallery"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Lumipat ng Camera"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Paganahin Time Lapse"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Wag Gana Time Lapse"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Pagre-record ng paglipas ng oras"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Pumili ng camera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bumalik"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"I-zoom ang <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Lumipat sa kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Lumipat sa video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index fb31d16..391aab8 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Tekrar çek"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Kamerayı Değiştir"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zaman Atl Etkinlştr"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Zaman Atl Dvr Dş Brk"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Zaman atlamalı kayıt"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Kamera seçin"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Arka"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"<xliff:g id="ZOOM_TEXT">%s</xliff:g> zum"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Kameraya geç"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Videoya geç"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 3f48bd3..880e619 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Повтор"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Галерея"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Змінити камеру"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Уповільнена зйомка"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Вимк.уповільн.зйомку"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Запис уповільненої зйомки"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Вибрати камеру"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Задня камера"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Масштаб <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"На фото"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"На відео"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 97c2a8c..f283150 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"Chụp lại"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Thư viện"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Chuyển Máy ảnh"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Bật chế độ thời gian trôi"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Tắt chế độ thời gian trôi"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"Đang ghi âm khoảng thời gian"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Chọn camera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Quay lại"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"Thu phóng <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Chuyển sang máy ảnh"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Chuyển sang video"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 4efffce..cf6fa36 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"重拍"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"图库"</string>
<string name="switch_camera_id" msgid="837545176602471325">"切换相机"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"启用延时模式"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"停用延时模式"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"延时录制"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"选择相机"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"背面相机"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"缩放 <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"切换到相机"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"切换到视频"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 252ec33..ef46a57 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -39,8 +39,6 @@
<string name="review_retake" msgid="7776579640762112761">"重拍"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"圖庫"</string>
<string name="switch_camera_id" msgid="837545176602471325">"切換相機"</string>
- <string name="enable_time_lapse_mode" msgid="9176865387013576340">"啟用延時攝影"</string>
- <string name="disable_time_lapse_mode" msgid="1025813874111023552">"停用延時攝影"</string>
<string name="time_lapse_title" msgid="4360632427760662691">"延時攝影錄製"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"選取鏡頭"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"後置鏡頭"</string>
@@ -119,4 +117,12 @@
<string name="zoom_text" msgid="3450360177919418123">"變焦 <xliff:g id="ZOOM_TEXT">%s</xliff:g>"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"切換為相機"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"切換為影片"</string>
+ <!-- no translation found for share_picture_via (1375127849431890447) -->
+ <skip />
+ <!-- no translation found for share_video_via (5152302809166549015) -->
+ <skip />
+ <!-- no translation found for no_picture_to_share (7700541451734517445) -->
+ <skip />
+ <!-- no translation found for no_video_to_share (3775826212074938990) -->
+ <skip />
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a9d8482..8a1652a 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,7 +20,6 @@
<resources>
<color name="recording_time_elapsed_text">#FFFFFFFF</color>
<color name="recording_time_remaining_text">#FFFF0033</color>
- <color name="zoom_picker_btn_pressed">#FFFFAD00</color>
<color name="on_viewfinder_label_background_color">#77333333</color>
<color name="review_control_pressed_color">#FF6899FF</color>
<color name="icon_disabled_color">#DD777777</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a073872..8464613 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -13,7 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- General strings -->
@@ -58,25 +57,6 @@
<!-- alert to the user that the camera fails to read or write the SD card. -->
<string name="access_sd_fail" product="default">Fail to access SD card.</string>
- <!-- Settings stuff -->
-
- <!-- Menu items: -->
- <!-- menu pick to go to the settings screen -->
-
- <!-- menu pick to view the details of the currently selected image -->
-
- <!-- menu pick to show the location of the currently selected image on maps-->
-
- <!-- menu pick to rotate the currently selected image (brings up submenu) -->
-
- <!-- menu pick to rotate the currently selected image to the left -->
-
- <!-- menu pick to rotate the currently selected image to the right -->
-
- <!-- Confirmation dialog title after deleting a picture -->
- <!-- Confirmation dialog message after deleting a picture -->
- <!-- Confirmation dialog message after deleting a video -->
-
<!-- Confirmation dialog when restoring settings -->
<string name="confirm_restore_title">Restore defaults</string>
<string name="confirm_restore_message">Camera settings will be restored to defaults.</string>
@@ -93,35 +73,12 @@
<!-- button in review mode indicate the user want to retake another photo/video for attachment [CHAR LIMIT=10] -->
<string name="review_retake">Retake</string>
- <!-- button indicating that the picture just taken should be deleted -->
-
- <!-- button indicating that the picture just taken should be shared by email, mms, etc -->
-
- <!-- button indicating that the picture just taken should be set as a contact photo, wallpaper, etc -->
-
- <!-- button indicating that the picture just taken should be cropped -->
-
- <!-- Toast after trying to share a picture indicating that there are no applications which are capable of so doing. -->
-
- <!-- Toast after trying to share a video indicating that there are no applications which are capable of so doing. -->
-
- <!-- Menu item for playing the video. -->
-
<!-- Button indicating to go to the image gallery -->
<string name="camera_gallery_photos_text">Gallery</string>
<!-- Button indicating to switch to another camera -->
<string name="switch_camera_id">Switch Camera</string>
- <!-- Button indicating to enable the time lapse mode. Time lapse mode refers
- to capturing video at a rate much slower than it is played back. Appears as
- a Menu item in Camcorder mode. [CHAR LIMIT=20] -->
- <string name="enable_time_lapse_mode">Enable Time Lapse</string>
-
- <!-- Button indicating to disable the time lapse mode. Appears as a Menu item in
- Camcorder mode. [CHAR LIMIT=20] -->
- <string name="disable_time_lapse_mode">Disable Time Lapse</string>
-
<!-- A lable that overlays on top of the preview frame to indicate the camcorder is in time lapse mode [CHAR LIMIT=35] -->
<string name="time_lapse_title">Time lapse recording</string>
@@ -309,43 +266,9 @@
<string name="pref_exposure_title">Exposure</string>
<string name="pref_exposure_default" translatable="false">0</string>
- <!-- Framing grid settings in preference -->
-
- <!-- Message to show when there's no lat/lng information in the image -->
- <!-- Title of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
- <!-- Label in message of Details dialog -->
-
- <!-- Used to format image dimensions in Details dialog. e.g. 64 x 64 -->
- <!-- Used to format short video duration in Details dialog. minutes:seconds e.g. 00:30 -->
- <!-- Used to format video duration in Details dialog. hours:minutes:seconds e.g. 0:21:30 -->
- <!-- Unit of measure in the Details dialog frames per second. e.g. 20 fps -->
- <!-- Unit of measure in the Details dialog K bits per second. e.g. 192 Kbps -->
- <!-- Unit of measure in the Details dialog M bits per second. e.g. 2.3 Mbps -->
<!-- Details dialog "OK" button. Dismisses dialog. -->
<string name="details_ok">OK</string>
- <!-- Displayed in the title of the dialog for things to do with a picture that
- is to be sent to another application: -->
-
- <!-- Displayed in the title of the dialog for things to do with a picture that
- is to be "set as" (e.g. set as contact photo or set as wallpaper) -->
-
- <!-- Displayed in the title of the dialog for things to do with a video that
- is to be sent to another application. -->
-
<!-- Low-memory dialog message [CHAR LIMT=NONE] -->
<string name="spaceIsLow_content" product="nosdcard">Your USB storage is running out of space. Change the quality setting or delete some images or other files.</string>
<!-- Low-memory dialog message [CHAR LIMIT=NONE] -->
@@ -362,8 +285,7 @@
<!-- The title show on the zoom controller -->
<string name="zoom_control_title">Zoom</string>
- <string name="zoom_increment" translatable="false">+</string>
- <string name="zoom_decrement" translatable="false">-</string>
+
<!-- The text to show the current zoom factor. [CHAR LIMIT=NONE] -->
<string name="zoom_text">Zoom <xliff:g id="zoom_text" example="1.1x">%s</xliff:g></string>
@@ -372,4 +294,17 @@
<string name="setting_increment" translatable="false">></string>
<string name="setting_decrement" translatable="false"><</string>
+
+ <!-- Title of the dialog showing a list of applications that can share the captured picture. [CHAR LIMIT=30] -->
+ <string name="share_picture_via">Share picture via</string>
+
+ <!-- Title of the dialog showing a list of applications that can share the captured video. [CHAR LIMIT=30] -->
+ <string name="share_video_via">Share video via</string>
+
+ <!-- Toast saying that there is no picture to share. [CHAR LIMIT=30] -->
+ <string name="no_picture_to_share">No picture to share</string>
+
+ <!-- Toast saying that there is no video to share. [CHAR LIMIT=30] -->
+ <string name="no_video_to_share">No video to share</string>
+
</resources>
diff --git a/src/com/android/camera/ActivityBase.java b/src/com/android/camera/ActivityBase.java
index 5f9c8a5..5839668 100644
--- a/src/com/android/camera/ActivityBase.java
+++ b/src/com/android/camera/ActivityBase.java
@@ -18,11 +18,15 @@
import android.app.Activity;
import android.view.KeyEvent;
+import android.content.Intent;
/**
* Superclass of Camera and VideoCamera activities.
*/
public class ActivityBase extends Activity {
+ private int mResultCodeForTesting;
+ private Intent mResultDataForTesting;
+
@Override
public boolean onSearchRequested() {
return false;
@@ -38,4 +42,23 @@
return super.onKeyDown(keyCode, event);
}
+
+ protected void setResultEx(int resultCode) {
+ mResultCodeForTesting = resultCode;
+ setResult(resultCode);
+ }
+
+ protected void setResultEx(int resultCode, Intent data) {
+ mResultCodeForTesting = resultCode;
+ mResultDataForTesting = data;
+ setResult(resultCode, data);
+ }
+
+ public int getResultCode() {
+ return mResultCodeForTesting;
+ }
+
+ public Intent getResultData() {
+ return mResultDataForTesting;
+ }
}
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 5ae43da..6c89a6e 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -22,11 +22,11 @@
import com.android.camera.ui.GLRootView;
import com.android.camera.ui.HeadUpDisplay;
import com.android.camera.ui.IndicatorWheel;
+import com.android.camera.ui.RotateImageView;
import com.android.camera.ui.ZoomControllerListener;
import com.android.camera.ui.ZoomPicker;
import android.app.Activity;
-import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -36,9 +36,9 @@
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.database.Cursor;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.graphics.Rect;
+import android.hardware.Camera.Area;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
@@ -58,25 +58,23 @@
import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.Settings;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewStub;
import android.view.Window;
import android.view.WindowManager;
-import android.view.MenuItem.OnMenuItemClickListener;
import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
import android.widget.Toast;
import java.io.File;
@@ -88,18 +86,16 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
/** The Camera activity which can preview and take pictures. */
public class Camera extends ActivityBase implements View.OnClickListener,
- ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback,
- Switcher.OnSwitchListener {
+ View.OnTouchListener, ShutterButton.OnShutterButtonListener,
+ SurfaceHolder.Callback, Switcher.OnSwitchListener {
private static final String TAG = "camera";
- private static final String LAST_THUMB_PATH =
- Storage.THUMBNAILS + "/image_last_thumb";
+ private static final String LAST_THUMB_FILENAME = "image_last_thumb";
private static final int CROP_MSG = 1;
private static final int FIRST_TIME_INIT = 2;
@@ -107,6 +103,7 @@
private static final int CLEAR_SCREEN_DELAY = 4;
private static final int SET_CAMERA_PARAMETERS_WHEN_IDLE = 5;
private static final int CHECK_DISPLAY_ROTATION = 6;
+ private static final int CANCEL_AUTOFOCUS = 7;
// The subset of parameters we need to update in setCameraParameters().
private static final int UPDATE_PARAM_INITIALIZE = 1;
@@ -146,30 +143,36 @@
private int mOrientationCompensation = 0;
private ComboPreferences mPreferences;
- private static final int IDLE = 1;
- private static final int SNAPSHOT_IN_PROGRESS = 2;
-
private static final boolean SWITCH_CAMERA = true;
private static final boolean SWITCH_VIDEO = false;
- private int mStatus = IDLE;
private static final String sTempCropFilename = "crop-temp";
private android.hardware.Camera mCameraDevice;
private ContentProviderClient mMediaProviderClient;
- private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder = null;
private ShutterButton mShutterButton;
- private FocusRectangle mFocusRectangle;
private ToneGenerator mFocusToneGenerator;
private GestureDetector mPopupGestureDetector;
private SwitcherSet mSwitcher;
private boolean mStartPreviewFail = false;
+ private View mPreviewFrame; // Preview frame area.
+ private View mPreviewBorder;
+ private FocusRectangle mFocusRectangle;
+ private List<Area> mFocusArea; // focus area in driver format
+
private GLRootView mGLRootView;
- // The last captured picture.
+ // A button showing the last captured picture thumbnail. Clicking on it
+ // goes to gallery.
private RotateImageView mThumbnailButton;
+ // The bitmap of the last captured picture thumbnail and the URI of the
+ // original picture.
+ private Thumbnail mThumbnail;
+ // An review image having same size as preview. It is displayed when
+ // share button is pressed.
+ private ImageView mReviewImage;
// mCropValue and mSaveUri are used only if isImageCaptureIntent() is true.
private String mCropValue;
@@ -191,21 +194,22 @@
private final static String EXTRA_QUICK_CAPTURE =
"android.intent.extra.quickCapture";
- private boolean mPreviewing;
- // The display rotation in degrees. This is only valid when mPreviewing is
- // true.
+ // The display rotation in degrees. This is only valid when mCameraState is
+ // not PREVIEW_STOPPED.
private int mDisplayRotation;
private boolean mPausing;
private boolean mFirstTimeInitialized;
private boolean mIsImageCaptureIntent;
private boolean mRecordLocation;
- private static final int FOCUS_NOT_STARTED = 0;
- private static final int FOCUSING = 1;
- private static final int FOCUSING_SNAP_ON_FINISH = 2;
- private static final int FOCUS_SUCCESS = 3;
- private static final int FOCUS_FAIL = 4;
- private int mFocusState = FOCUS_NOT_STARTED;
+ private static final int PREVIEW_STOPPED = 0;
+ private static final int IDLE = 1; // preview is active
+ private static final int FOCUSING = 2;
+ private static final int FOCUSING_SNAP_ON_FINISH = 3;
+ private static final int FOCUS_SUCCESS = 4;
+ private static final int FOCUS_FAIL = 5;
+ private static final int SNAPSHOT_IN_PROGRESS = 6;
+ private int mCameraState = PREVIEW_STOPPED;
private ContentResolver mContentResolver;
private boolean mDidRegister = false;
@@ -246,6 +250,7 @@
private String mFocusMode;
private String mSceneMode;
private Toast mNotSelectableToast;
+ private Toast mNoShareToast;
private final Handler mHandler = new MainHandler();
// xlarge devices use indicator wheel. Other devices use head-up display.
@@ -312,6 +317,11 @@
}
break;
}
+
+ case CANCEL_AUTOFOCUS: {
+ cancelAutoFocus();
+ break;
+ }
}
}
}
@@ -366,7 +376,7 @@
// Initialize last picture button.
mContentResolver = getContentResolver();
- if (!mIsImageCaptureIntent) {
+ if (!mIsImageCaptureIntent) { // no thumbnail in image capture intent
findViewById(R.id.camera_switch).setOnClickListener(this);
initThumbnailButton();
}
@@ -376,8 +386,15 @@
mShutterButton.setOnShutterButtonListener(this);
mShutterButton.setVisibility(View.VISIBLE);
- mFocusRectangle = (FocusRectangle) findViewById(R.id.focus_rectangle);
- updateFocusIndicator();
+ // Initialize focus UI.
+ mPreviewFrame = findViewById(R.id.camera_preview);
+ mPreviewFrame.setOnTouchListener(this);
+ mPreviewBorder = (View) findViewById(R.id.preview_border);
+ // Set the length of focus rectangle according to preview frame size.
+ int len = Math.min(mPreviewFrame.getWidth(), mPreviewFrame.getHeight()) / 4;
+ ViewGroup.LayoutParams layout = mFocusRectangle.getLayoutParams();
+ layout.width = len;
+ layout.height = len;
initializeScreenBrightness();
installIntentFilter();
@@ -405,30 +422,23 @@
}
private void initThumbnailButton() {
- mThumbnailButton =
- (RotateImageView) findViewById(R.id.review_thumbnail);
- if (mThumbnailButton != null) {
- mThumbnailButton.setOnClickListener(this);
- mThumbnailButton.loadData(LAST_THUMB_PATH);
- updateThumbnailButton();
- }
+ mThumbnailButton.setOnClickListener(this);
+ // Load the thumbnail from the disk.
+ mThumbnail = Thumbnail.loadFrom(LAST_THUMB_FILENAME);
+ updateThumbnailButton();
}
private void updateThumbnailButton() {
- if (mThumbnailButton == null) return;
// Update last image if URI is invalid and the storage is ready.
- if (!mThumbnailButton.isUriValid() && mPicturesRemaining >= 0) {
- Storage.Thumbnail thumbnail =
- Storage.getLastImageThumbnail(mContentResolver);
- if (thumbnail != null) {
- mThumbnailButton.setData(thumbnail.getOriginalUri(),
- thumbnail.getBitmap(mContentResolver));
- } else {
- mThumbnailButton.setData(null, null);
- }
+ if ((mThumbnail == null || !Util.isUriValid(mThumbnail.getUri(), mContentResolver))
+ && mPicturesRemaining >= 0) {
+ mThumbnail = Thumbnail.getLastImageThumbnail(mContentResolver);
}
- mThumbnailButton.setVisibility(
- (mThumbnailButton.getUri() != null) ? View.VISIBLE : View.GONE);
+ if (mThumbnail != null) {
+ mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ } else {
+ mThumbnailButton.setBitmap(null);
+ }
}
// If the activity is paused and resumed, this method will be called in
@@ -527,27 +537,21 @@
return result;
}
- private int mLocation[] = new int[2];
- private class PopupGestureListener extends
- GestureDetector.SimpleOnGestureListener {
+ private class PopupGestureListener
+ extends GestureDetector.SimpleOnGestureListener {
public boolean onDown(MotionEvent e) {
// Check if the popup window is visible.
- View v = mIndicatorWheel.getActivePopupWindow();
- if (v == null) return false;
+ View popup = mIndicatorWheel.getActivePopupWindow();
+ if (popup == null) return false;
- int x = Math.round(e.getX());
- int y = Math.round(e.getY());
- // Dismiss the popup window if users touch on the outside.
- v.getLocationOnScreen(mLocation);
- if (x < mLocation[0] || (x > mLocation[0] + v.getWidth())
- || y < mLocation[1] || (y > mLocation[1] + v.getHeight())) {
- // Let indicator wheel handle its own event.
- mIndicatorWheel.getLocationOnScreen(mLocation);
- if (x < mLocation[0] || (x > mLocation[0] + mIndicatorWheel.getWidth())
- || y < mLocation[1] || (y > mLocation[1] + mIndicatorWheel.getHeight())) {
- mIndicatorWheel.dismissSettingPopup();
- }
+ // Let popup window, indicator wheel or preview frame handle the
+ // event by themselves. Dismiss the popup window if users touch on
+ // other areas.
+ if (!Util.pointInView(e.getX(), e.getY(), popup)
+ && !Util.pointInView(e.getX(), e.getY(), mIndicatorWheel)
+ && !Util.pointInView(e.getX(), e.getY(), mPreviewFrame)) {
+ mIndicatorWheel.dismissSettingPopup();
// Let event fall through.
}
return false;
@@ -688,7 +692,7 @@
mShutterCallbackTime = System.currentTimeMillis();
mShutterLag = mShutterCallbackTime - mCaptureStartTime;
Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
- clearFocusState();
+ updateFocusUI();
}
}
@@ -779,32 +783,41 @@
mFocusCallbackTime = System.currentTimeMillis();
mAutoFocusTime = mFocusCallbackTime - mFocusStartTime;
Log.v(TAG, "mAutoFocusTime = " + mAutoFocusTime + "ms");
- if (mFocusState == FOCUSING_SNAP_ON_FINISH) {
+ if (mCameraState == FOCUSING_SNAP_ON_FINISH) {
// Take the picture no matter focus succeeds or fails. No need
// to play the AF sound if we're about to play the shutter
// sound.
if (focused) {
- mFocusState = FOCUS_SUCCESS;
+ mCameraState = FOCUS_SUCCESS;
} else {
- mFocusState = FOCUS_FAIL;
+ mCameraState = FOCUS_FAIL;
}
+ updateFocusUI();
capture();
- } else if (mFocusState == FOCUSING) {
- // User is half-pressing the focus key. Play the focus tone.
- // Do not take the picture now.
+ } else if (mCameraState == FOCUSING) {
+ // This happens when (1) user is half-pressing the focus key or
+ // (2) touch focus is triggered. Play the focus tone. Do not
+ // take the picture now.
if (focused) {
- mFocusState = FOCUS_SUCCESS;
+ mCameraState = FOCUS_SUCCESS;
if (mFocusToneGenerator != null) {
mFocusToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2);
}
} else {
- mFocusState = FOCUS_FAIL;
+ mCameraState = FOCUS_FAIL;
}
- } else if (mFocusState == FOCUS_NOT_STARTED) {
+ updateFocusUI();
+ enableCameraControls(true);
+ // If this is triggered by touch focus, cancel focus after a
+ // while.
+ if (mFocusArea != null) {
+ mHandler.sendEmptyMessageDelayed(CANCEL_AUTOFOCUS, 3000);
+ }
+ } else if (mCameraState == IDLE) {
// User has released the focus key before focus completes.
// Do nothing.
}
- updateFocusIndicator();
+
}
}
@@ -838,17 +851,19 @@
if (!mIsImageCaptureIntent) {
long dateTaken = System.currentTimeMillis();
String title = createName(dateTaken);
-
- Storage.Thumbnail thumbnail = Storage.addImage(
- mContentResolver, title, dateTaken, loc, data);
-
- if (thumbnail != null && mThumbnailButton != null) {
- mThumbnailButton.setData(thumbnail.getOriginalUri(),
- thumbnail.getBitmap(mContentResolver));
- mThumbnailButton.setVisibility(View.VISIBLE);
-
- sendBroadcast(new Intent("com.android.camera.NEW_PICTURE",
- thumbnail.getOriginalUri()));
+ int orientation = Exif.getOrientation(data);
+ Uri uri = Storage.addImage(mContentResolver, title, dateTaken,
+ loc, orientation, data);
+ if (uri != null) {
+ // Create a thumbnail whose size is smaller than half of the surface view.
+ int ratio = (int) Math.ceil((double) mParameters.getPictureSize().width
+ / (mPreviewFrame.getWidth() / 2));
+ int inSampleSize = Util.nextPowerOf2(ratio);
+ mThumbnail = Thumbnail.createThumbnail(data, orientation, inSampleSize, uri);
+ if (mThumbnail != null) {
+ mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ }
+ sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));
}
} else {
mJpegImageData = data;
@@ -862,13 +877,12 @@
private void capture() {
// If we are already in the middle of taking a snapshot then ignore.
- if (mPausing || mStatus == SNAPSHOT_IN_PROGRESS || mCameraDevice == null) {
+ if (mPausing || mCameraState == SNAPSHOT_IN_PROGRESS || mCameraDevice == null) {
return;
}
mCaptureStartTime = System.currentTimeMillis();
mPostViewPictureCallbackTime = 0;
enableCameraControls(false);
- mStatus = SNAPSHOT_IN_PROGRESS;
mJpegImageData = null;
// See android.hardware.Camera.Parameters.setRotation for
@@ -925,7 +939,8 @@
mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback,
mPostViewPictureCallback, new JpegPictureCallback(loc));
- mPreviewing = false;
+ mCameraState = SNAPSHOT_IN_PROGRESS;
+ mHandler.removeMessages(CANCEL_AUTOFOCUS);
}
private boolean saveDataToFile(String filePath, byte[] data) {
@@ -959,14 +974,16 @@
} else {
setContentView(R.layout.camera);
}
- mSurfaceView = (SurfaceView) findViewById(R.id.camera_preview);
+ mFocusRectangle = (FocusRectangle) findViewById(R.id.focus_rectangle);
+ mThumbnailButton = (RotateImageView) findViewById(R.id.review_thumbnail);
+ mReviewImage = (ImageView) findViewById(R.id.review_image);
mPreferences = new ComboPreferences(this);
CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal());
mCameraId = CameraSettings.readPreferredCameraId(mPreferences);
- //Testing purpose. Launch a specific camera through the intent extras.
+ // Testing purpose. Launch a specific camera through the intent extras.
int intentCameraId = Util.getCameraFacingIntentExtras(this);
if (intentCameraId != -1) {
mCameraId = intentCameraId;
@@ -1004,7 +1021,8 @@
// don't set mSurfaceHolder here. We have it set ONLY within
// surfaceChanged / surfaceDestroyed, other parts of the code
// assume that when it is set, the surface is also set.
- SurfaceHolder holder = mSurfaceView.getHolder();
+ SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);
+ SurfaceHolder holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@@ -1098,11 +1116,19 @@
if (mIndicatorWheel == null) return;
loadCameraPreferences();
- String[] keys = new String[]{CameraSettings.KEY_FLASH_MODE,
- CameraSettings.KEY_WHITE_BALANCE,
- CameraSettings.KEY_COLOR_EFFECT,
- CameraSettings.KEY_SCENE_MODE};
- mIndicatorWheel.initialize(this, mPreferenceGroup, keys, true);
+ final String[] SETTING_KEYS = {
+ CameraSettings.KEY_FLASH_MODE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_SCENE_MODE};
+ final String[] OTHER_SETTING_KEYS = {
+ CameraSettings.KEY_RECORD_LOCATION,
+ CameraSettings.KEY_FOCUS_MODE,
+ CameraSettings.KEY_EXPOSURE,
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_PICTURE_SIZE,
+ CameraSettings.KEY_JPEG_QUALITY};
+ mIndicatorWheel.initialize(this, mPreferenceGroup, SETTING_KEYS,
+ OTHER_SETTING_KEYS);
mIndicatorWheel.setListener(new MyIndicatorWheelListener());
mPopupGestureDetector = new GestureDetector(this,
new PopupGestureListener());
@@ -1241,8 +1267,8 @@
restartPreview();
break;
case R.id.review_thumbnail:
- if (isCameraIdle()) {
- viewImage(mThumbnailButton);
+ if (isCameraIdle() && mThumbnail != null) {
+ Util.viewUri(mThumbnail.getUri(), this);
}
break;
case R.id.btn_done:
@@ -1276,7 +1302,7 @@
outputStream.write(data);
outputStream.close();
- setResult(RESULT_OK);
+ setResultEx(RESULT_OK);
finish();
} catch (IOException ex) {
// ignore exception
@@ -1287,7 +1313,7 @@
int orientation = Exif.getOrientation(data);
Bitmap bitmap = Util.makeBitmap(data, 50 * 1024);
bitmap = Util.rotate(bitmap, orientation);
- setResult(RESULT_OK,
+ setResultEx(RESULT_OK,
new Intent("inline-data").putExtra("data", bitmap));
finish();
}
@@ -1303,11 +1329,11 @@
tempStream.close();
tempUri = Uri.fromFile(path);
} catch (FileNotFoundException ex) {
- setResult(Activity.RESULT_CANCELED);
+ setResultEx(Activity.RESULT_CANCELED);
finish();
return;
} catch (IOException ex) {
- setResult(Activity.RESULT_CANCELED);
+ setResultEx(Activity.RESULT_CANCELED);
finish();
return;
} finally {
@@ -1334,7 +1360,7 @@
}
private void doCancel() {
- setResult(RESULT_CANCELED, new Intent());
+ setResultEx(RESULT_CANCELED, new Intent());
finish();
}
@@ -1433,8 +1459,10 @@
mJpegPictureCallbackTime = 0;
mZoomValue = 0;
+ mReviewImage.setVisibility(View.GONE);
+
// Start the preview if it is not started.
- if (!mPreviewing && !mStartPreviewFail) {
+ if (mCameraState == PREVIEW_STOPPED && !mStartPreviewFail) {
resetExposureCompensation();
if (!restartPreview()) return;
}
@@ -1450,7 +1478,7 @@
}
keepScreenOnAwhile();
- if (mPreviewing) {
+ if (mCameraState == IDLE) {
mOnResumeTime = SystemClock.uptimeMillis();
mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION, 100);
}
@@ -1475,9 +1503,7 @@
if (mFirstTimeInitialized) {
mOrientationListener.disable();
if (!mIsImageCaptureIntent) {
- if (mThumbnailButton != null) {
- mThumbnailButton.storeData(LAST_THUMB_PATH);
- }
+ if (mThumbnail != null) mThumbnail.saveTo(LAST_THUMB_FILENAME);
}
hidePostCaptureAlert();
}
@@ -1506,6 +1532,7 @@
mHandler.removeMessages(RESTART_PREVIEW);
mHandler.removeMessages(FIRST_TIME_INIT);
mHandler.removeMessages(CHECK_DISPLAY_ROTATION);
+ mHandler.removeMessages(CANCEL_AUTOFOCUS);
super.onPause();
}
@@ -1522,7 +1549,7 @@
intent.putExtras(extras);
}
}
- setResult(resultCode, intent);
+ setResultEx(resultCode, intent);
finish();
File path = getFileStreamPath(sTempCropFilename);
@@ -1534,54 +1561,125 @@
}
private boolean canTakePicture() {
- return isCameraIdle() && mPreviewing && (mPicturesRemaining > 0);
+ return isCameraIdle() && (mPicturesRemaining > 0);
}
private void autoFocus() {
- // Initiate autofocus only when preview is started and snapshot is not
- // in progress.
- if (canTakePicture()) {
- enableCameraControls(false);
- Log.v(TAG, "Start autofocus.");
- mFocusStartTime = System.currentTimeMillis();
- mFocusState = FOCUSING;
- updateFocusIndicator();
- mCameraDevice.autoFocus(mAutoFocusCallback);
- }
+ Log.v(TAG, "Start autofocus.");
+ mFocusStartTime = System.currentTimeMillis();
+ mCameraDevice.autoFocus(mAutoFocusCallback);
+ mCameraState = FOCUSING;
+ enableCameraControls(false);
+ updateFocusUI();
+ mHandler.removeMessages(CANCEL_AUTOFOCUS);
}
private void cancelAutoFocus() {
- // User releases half-pressed focus key.
- if (mStatus != SNAPSHOT_IN_PROGRESS && (mFocusState == FOCUSING
- || mFocusState == FOCUS_SUCCESS || mFocusState == FOCUS_FAIL)) {
- Log.v(TAG, "Cancel autofocus.");
- enableCameraControls(true);
- mCameraDevice.cancelAutoFocus();
- }
- if (mFocusState != FOCUSING_SNAP_ON_FINISH) {
- clearFocusState();
- }
+ Log.v(TAG, "Cancel autofocus.");
+ mCameraDevice.cancelAutoFocus();
+ mCameraState = IDLE;
+ enableCameraControls(true);
+ resetTouchFocus();
+ setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ updateFocusUI();
+ mHandler.removeMessages(CANCEL_AUTOFOCUS);
}
- private void clearFocusState() {
- mFocusState = FOCUS_NOT_STARTED;
- updateFocusIndicator();
- }
-
- private void updateFocusIndicator() {
- if (mFocusRectangle == null) return;
-
- if (mFocusState == FOCUSING || mFocusState == FOCUSING_SNAP_ON_FINISH) {
+ private void updateFocusUI() {
+ if (mCameraState == FOCUSING || mCameraState == FOCUSING_SNAP_ON_FINISH) {
mFocusRectangle.showStart();
- } else if (mFocusState == FOCUS_SUCCESS) {
+ } else if (mCameraState == FOCUS_SUCCESS) {
mFocusRectangle.showSuccess();
- } else if (mFocusState == FOCUS_FAIL) {
+ } else if (mCameraState == FOCUS_FAIL) {
mFocusRectangle.showFail();
} else {
mFocusRectangle.clear();
}
}
+ // Preview area is touched. Handle touch focus.
+ @Override
+ public boolean onTouch(View v, MotionEvent e) {
+ if (e.getAction() != MotionEvent.ACTION_DOWN) return false;
+
+ // Do not trigger touch focus when popup window is dismissed.
+ if (collapseCameraControls()) return false;
+
+ if (mPausing || !mFirstTimeInitialized || !canTakePicture()) {
+ return false;
+ }
+
+ // Take a picture if metering area or focus area is supported.
+ if (mParameters.getMaxNumMeteringAreas() == 0
+ && (mParameters.getMaxNumFocusAreas() == 0
+ || (!mFocusMode.equals(Parameters.FOCUS_MODE_AUTO) &&
+ !mFocusMode.equals(Parameters.FOCUS_MODE_MACRO) &&
+ !mFocusMode.equals(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)))) {
+ return false;
+ }
+
+ // Calculate the position of the focus rectangle.
+ int x = Math.round(e.getX());
+ int y = Math.round(e.getY());
+ int focusWidth = mFocusRectangle.getWidth();
+ int focusHeight = mFocusRectangle.getHeight();
+ int left = Util.clamp(x - focusWidth / 2, 0,
+ mPreviewFrame.getWidth() - focusWidth);
+ int top = Util.clamp(y - focusHeight / 2, 0,
+ mPreviewFrame.getHeight() - focusHeight);
+ Log.d(TAG, "x=" + x + ". y=" + y);
+ Log.d(TAG, "Margin left=" + left + ". top=" + top);
+ Log.d(TAG, "Preview width=" + mPreviewFrame.getWidth() +
+ ". height=" + mPreviewFrame.getHeight());
+ Log.d(TAG, "focusWidth=" + focusWidth + ". focusHeight=" + focusHeight);
+
+ // Convert the coordinates to driver format. The coordinates range from
+ // -1000 to 1000.
+ if (mFocusArea == null) {
+ mFocusArea = new ArrayList<Area>();
+ mFocusArea.add(new Area(new Rect(), 1));
+ }
+ Rect rect = mFocusArea.get(0).rect;
+ convertToFocusArea(left, top, focusWidth, focusHeight, mPreviewFrame.getWidth(),
+ mPreviewFrame.getHeight(), mFocusArea.get(0).rect);
+
+ // Use margin to set the focus rectangle to the touched area.
+ RelativeLayout.LayoutParams p =
+ (RelativeLayout.LayoutParams) mFocusRectangle.getLayoutParams();
+ p.setMargins(left + mPreviewBorder.getPaddingLeft(),
+ top + mPreviewBorder.getPaddingTop(), 0, 0);
+ // Disable "center" rule because we no longer want to put it in the center.
+ int[] rules = p.getRules();
+ rules[RelativeLayout.CENTER_IN_PARENT] = 0;
+ mFocusRectangle.requestLayout();
+
+ // Set the focus area and do autofocus.
+ setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ autoFocus();
+
+ return true;
+ }
+
+ // Convert the touch point to the focus area in driver format.
+ public static void convertToFocusArea(int left, int top, int focusWidth, int focusHeight,
+ int previewWidth, int previewHeight, Rect rect) {
+ rect.left = Math.round((float) left / previewWidth * 2000 - 1000);
+ rect.top = Math.round((float) top / previewHeight * 2000 - 1000);
+ rect.right = Math.round((float) (left + focusWidth) / previewWidth * 2000 - 1000);
+ rect.bottom = Math.round((float) (top + focusHeight) / previewHeight * 2000 - 1000);
+ }
+
+ void resetTouchFocus() {
+ // Put focus rectangle to the center.
+ RelativeLayout.LayoutParams p =
+ (RelativeLayout.LayoutParams) mFocusRectangle.getLayoutParams();
+ int[] rules = p.getRules();
+ rules[RelativeLayout.CENTER_IN_PARENT] = RelativeLayout.TRUE;
+ p.setMargins(0, 0, 0, 0);
+
+ mFocusArea = null;
+ }
+
@Override
public void onBackPressed() {
if (!isCameraIdle()) {
@@ -1642,22 +1740,22 @@
private void doSnap() {
if (collapseCameraControls()) return;
- Log.v(TAG, "doSnap: mFocusState=" + mFocusState);
+ Log.v(TAG, "doSnap: mCameraState=" + mCameraState);
// If the user has half-pressed the shutter and focus is completed, we
// can take the photo right away. If the focus mode is infinity, we can
// also take the photo.
if (mFocusMode.equals(Parameters.FOCUS_MODE_INFINITY)
|| mFocusMode.equals(Parameters.FOCUS_MODE_FIXED)
|| mFocusMode.equals(Parameters.FOCUS_MODE_EDOF)
- || (mFocusState == FOCUS_SUCCESS
- || mFocusState == FOCUS_FAIL)) {
+ || (mCameraState == FOCUS_SUCCESS
+ || mCameraState == FOCUS_FAIL)) {
capture();
- } else if (mFocusState == FOCUSING) {
+ } else if (mCameraState == FOCUSING) {
// Half pressing the shutter (i.e. the focus button event) will
// already have requested AF for us, so just request capture on
// focus here.
- mFocusState = FOCUSING_SNAP_ON_FINISH;
- } else if (mFocusState == FOCUS_NOT_STARTED) {
+ mCameraState = FOCUSING_SNAP_ON_FINISH;
+ } else if (mCameraState == IDLE) {
// Focus key down event is dropped for some reasons. Just ignore.
}
}
@@ -1669,9 +1767,19 @@
|| mFocusMode.equals(Parameters.FOCUS_MODE_FIXED)
|| mFocusMode.equals(Parameters.FOCUS_MODE_EDOF))) {
if (pressed) { // Focus key down.
- autoFocus();
+ // Do not do focus if there is not enoguh storage. Do not focus
+ // if touch focus has been triggered, that is, camera state is
+ // FOCUS_SUCCESS or FOCUS_FAIL.
+ if (canTakePicture() && mCameraState != FOCUS_SUCCESS
+ && mCameraState != FOCUS_FAIL) {
+ autoFocus();
+ }
} else { // Focus key up.
- cancelAutoFocus();
+ // User releases half-pressed focus key.
+ if (mCameraState == FOCUSING || mCameraState == FOCUS_SUCCESS
+ || mCameraState == FOCUS_FAIL) {
+ cancelAutoFocus();
+ }
}
}
}
@@ -1704,7 +1812,8 @@
// changed. Sometimes this happens when the device is held in portrait
// and camera app is opened. Rotation animation takes some time and
// display rotation in onCreate may not be what we want.
- if (mPreviewing && (Util.getDisplayRotation(this) == mDisplayRotation)
+ if (mCameraState != PREVIEW_STOPPED
+ && (Util.getDisplayRotation(this) == mDisplayRotation)
&& holder.isCreating()) {
// Set preview display if the surface is being created and preview
// was already started. That means preview display was set to null
@@ -1741,7 +1850,7 @@
CameraHolder.instance().release();
mCameraDevice.setZoomChangeListener(null);
mCameraDevice = null;
- mPreviewing = false;
+ mCameraState = PREVIEW_STOPPED;
}
}
@@ -1781,12 +1890,14 @@
private void startPreview() throws CameraHardwareException {
if (mPausing || isFinishing()) return;
+ resetTouchFocus();
+
ensureCameraDevice();
mCameraDevice.setErrorCallback(mErrorCallback);
// If we're previewing already, stop the preview first (this will blank
// the screen).
- if (mPreviewing) stopPreview();
+ if (mCameraState != PREVIEW_STOPPED) stopPreview();
setPreviewDisplay(mSurfaceHolder);
mDisplayRotation = Util.getDisplayRotation(this);
@@ -1801,19 +1912,18 @@
closeCamera();
throw new RuntimeException("startPreview failed", ex);
}
- mPreviewing = true;
mZoomState = ZOOM_STOPPED;
- mStatus = IDLE;
+ mCameraState = IDLE;
}
private void stopPreview() {
- if (mCameraDevice != null && mPreviewing) {
+ if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
Log.v(TAG, "stopPreview");
mCameraDevice.stopPreview();
}
- mPreviewing = false;
+ mCameraState = PREVIEW_STOPPED;
// If auto focus was in progress, it would have been canceled.
- clearFocusState();
+ updateFocusUI();
}
private static boolean isSupported(String value, List<String> supported) {
@@ -1839,6 +1949,16 @@
}
private void updateCameraParametersPreference() {
+ if (mParameters.getMaxNumFocusAreas() > 0) {
+ mParameters.setFocusAreas(mFocusArea);
+ Log.d(TAG, "Parameter focus areas=" + mParameters.get("focus-areas"));
+ }
+
+ if (mParameters.getMaxNumMeteringAreas() > 0) {
+ // Use the same area for focus and metering.
+ mParameters.setMeteringAreas(mFocusArea);
+ }
+
// Set picture size.
String pictureSize = mPreferences.getString(
CameraSettings.KEY_PICTURE_SIZE, null);
@@ -2021,25 +2141,6 @@
MenuHelper.gotoCameraImageGallery(this);
}
- private void viewImage(RotateImageView view) {
- if(!view.isUriValid()) {
- Log.e(TAG, "Uri invalid. uri=" + view.getUri());
- return;
- }
-
- try {
- startActivity(new Intent(
- Util.REVIEW_ACTION, view.getUri()));
- } catch (ActivityNotFoundException ex) {
- try {
- startActivity(new Intent(
- Intent.ACTION_VIEW, view.getUri()));
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "review image fail. uri=" + view.getUri(), e);
- }
- }
- }
-
private void startReceivingLocationUpdates() {
if (mLocationManager != null) {
try {
@@ -2048,7 +2149,7 @@
1000,
0F,
mLocationListeners[1]);
- } catch (java.lang.SecurityException ex) {
+ } catch (SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "provider does not exist " + ex.getMessage());
@@ -2060,7 +2161,7 @@
0F,
mLocationListeners[0]);
showGpsOnScreenIndicator(false);
- } catch (java.lang.SecurityException ex) {
+ } catch (SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "provider does not exist " + ex.getMessage());
@@ -2094,7 +2195,7 @@
}
private boolean isCameraIdle() {
- return mStatus == IDLE && mFocusState == FOCUS_NOT_STARTED;
+ return mCameraState == IDLE || mCameraState == FOCUS_SUCCESS || mCameraState == FOCUS_FAIL;
}
private boolean isImageCaptureIntent() {
@@ -2331,10 +2432,30 @@
String str = getResources().getString(R.string.not_selectable_in_scene_mode);
mNotSelectableToast = Toast.makeText(Camera.this, str, Toast.LENGTH_SHORT);
}
- mNotSelectableToast.cancel();
mNotSelectableToast.show();
}
+ private void onShareButtonClicked() {
+ if (mPausing) return;
+
+ // Share the last captured picture.
+ if (mThumbnail != null) {
+ mReviewImage.setImageBitmap(mThumbnail.getBitmap());
+ mReviewImage.setVisibility(View.VISIBLE);
+
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("image/jpeg");
+ intent.putExtra(Intent.EXTRA_STREAM, mThumbnail.getUri());
+ startActivity(Intent.createChooser(intent, getString(R.string.share_picture_via)));
+ } else { // No last picture
+ if (mNoShareToast == null) {
+ mNoShareToast = Toast.makeText(this,
+ getResources().getString(R.string.no_picture_to_share), Toast.LENGTH_SHORT);
+ }
+ mNoShareToast.show();
+ }
+ }
+
private class MyIndicatorWheelListener implements IndicatorWheel.Listener {
public void onSharedPreferenceChanged() {
Camera.this.onSharedPreferenceChanged();
@@ -2347,6 +2468,10 @@
public void onOverriddenPreferencesClicked() {
Camera.this.onOverriddenPreferencesClicked();
}
+
+ public void onShareButtonClicked() {
+ Camera.this.onShareButtonClicked();
+ }
}
private class MyCameraPickerListener implements CameraPicker.Listener {
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 86dacd0..225cf88 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -56,8 +56,7 @@
public static final int CURRENT_VERSION = 4;
public static final int CURRENT_LOCAL_VERSION = 1;
- // max video duration in seconds for mms and youtube.
- private static final int MMS_VIDEO_DURATION = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW).duration;
+ // max video duration in seconds for youtube.
private static final int YOUTUBE_VIDEO_DURATION = 15 * 60; // 15 mins
private static final int DEFAULT_VIDEO_DURATION = 0; // no limit
@@ -181,21 +180,6 @@
if (timeLapseInterval != null) resetIfInvalid(timeLapseInterval);
}
- private static List<String> getSupportedTimeLapseProfiles(int cameraId) {
- ArrayList<String> supportedProfiles = new ArrayList<String>();
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_480P)) {
- supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_480P));
- }
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_720P)) {
- supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_720P));
- }
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_1080P)) {
- supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_1080P));
- }
-
- return supportedProfiles;
- }
-
private void buildExposureCompensation(
PreferenceGroup group, ListPreference exposure) {
int max = mParameters.getMaxExposureCompensation();
@@ -358,9 +342,11 @@
|| context.getString(R.string.pref_video_quality_high).equals(quality);
}
- public static int getVideoDurationInMillis(Context context, String quality) {
+ public static int getVideoDurationInMillis(Context context, String quality, int cameraId) {
if (context.getString(R.string.pref_video_quality_mms).equals(quality)) {
- return MMS_VIDEO_DURATION * 1000;
+ int mmsVideoDuration = CamcorderProfile.get(cameraId,
+ CamcorderProfile.QUALITY_LOW).duration;
+ return mmsVideoDuration * 1000;
} else if (context.getString(R.string.pref_video_quality_youtube).equals(quality)) {
return YOUTUBE_VIDEO_DURATION * 1000;
}
@@ -417,11 +403,13 @@
CharSequence[] entries = videoQuality.getEntries();
CharSequence[] values = videoQuality.getEntryValues();
if (Util.isMmsCapable(mContext)) {
+ int mmsVideoDuration = CamcorderProfile.get(mCameraId,
+ CamcorderProfile.QUALITY_LOW).duration;
// We need to fill in the device-dependent value (in seconds).
for (int i = 0; i < entries.length; ++i) {
if (mContext.getString(R.string.pref_video_quality_mms).equals(values[i])) {
entries[i] = entries[i].toString().replace(
- "30", Integer.toString(MMS_VIDEO_DURATION));
+ "30", Integer.toString(mmsVideoDuration));
break;
}
}
diff --git a/src/com/android/camera/IconIndicator.java b/src/com/android/camera/IconIndicator.java
deleted file mode 100644
index c032502..0000000
--- a/src/com/android/camera/IconIndicator.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-import com.android.camera.R;
-
-/**
- * This class draws an icon which changes according to the mode. For example,
- * The flash icon can have on, off, and auto modes. The user can use
- * {@link #setMode(String)} to change the mode (and the icon).
- */
-public class IconIndicator extends ImageView {
-
- private Drawable[] mIcons;
- private CharSequence[] mModes;
-
- public IconIndicator(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.IconIndicator, defStyle, 0);
- Drawable icons[] = loadIcons(context.getResources(),
- a.getResourceId(R.styleable.IconIndicator_icons, 0));
- CharSequence modes[] =
- a.getTextArray(R.styleable.IconIndicator_modes);
- a.recycle();
-
- setModesAndIcons(modes, icons);
- setImageDrawable(mIcons.length > 0 ? mIcons[0] : null);
- }
-
- public IconIndicator(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- private Drawable[] loadIcons(Resources resources, int iconsId) {
- TypedArray array = resources.obtainTypedArray(iconsId);
- int n = array.length();
- Drawable drawable[] = new Drawable[n];
- for (int i = 0; i < n; ++i) {
- int id = array.getResourceId(i, 0);
- drawable[i] = id == 0 ? null : resources.getDrawable(id);
- }
- array.recycle();
- return drawable;
- }
-
- private void setModesAndIcons(CharSequence[] modes, Drawable icons[]) {
- if (modes.length != icons.length || icons.length == 0) {
- throw new IllegalArgumentException();
- }
- mIcons = icons;
- mModes = modes;
- }
-
- public void setMode(String mode) {
- for (int i = 0, n = mModes.length; i < n; ++i) {
- if (mModes[i].equals(mode)) {
- setImageDrawable(mIcons[i]);
- return;
- }
- }
- throw new IllegalArgumentException("unknown mode: " + mode);
- }
-}
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index fba5738..860a642 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -39,35 +39,13 @@
public class MenuHelper {
private static final String TAG = "MenuHelper";
- public static final int INCLUDE_ALL = 0xFFFFFFFF;
- public static final int INCLUDE_VIEWPLAY_MENU = (1 << 0);
- public static final int INCLUDE_SHARE_MENU = (1 << 1);
- public static final int INCLUDE_SET_MENU = (1 << 2);
- public static final int INCLUDE_CROP_MENU = (1 << 3);
- public static final int INCLUDE_DELETE_MENU = (1 << 4);
- public static final int INCLUDE_ROTATE_MENU = (1 << 5);
- public static final int INCLUDE_DETAILS_MENU = (1 << 6);
- public static final int INCLUDE_SHOWMAP_MENU = (1 << 7);
-
- public static final int INCLUDE_IMAGES = (1 << 0);
- public static final int INCLUDE_VIDEOS = (1 << 2);
-
- public static final int MENU_IMAGE_SHARE = 1;
- public static final int MENU_IMAGE_SHOWMAP = 2;
+ // TODO: These should be public and added to frameworks.
+ private static final int INCLUDE_IMAGES = (1 << 0);
+ private static final int INCLUDE_VIDEOS = (1 << 2);
public static final int POSITION_SWITCH_CAMERA_MODE = 1;
public static final int POSITION_GOTO_GALLERY = 2;
public static final int POSITION_SWITCH_CAMERA_ID = 3;
- public static final int POSITION_SWITCH_TIME_LAPSE_MODE = 4;
-
- public static final String EMPTY_STRING = "";
- public static final String JPEG_MIME_TYPE = "image/jpeg";
- // valid range is -180f to +180f
- public static final float INVALID_LATLNG = 255f;
-
- /** Activity result code used to report crop results.
- */
- public static final int RESULT_COMMON_MENU_CROP = 490;
private static final int NO_ANIMATION = 0;
private static final String CAMERA_CLASS = "com.android.camera.Camera";
diff --git a/src/com/android/camera/OnScreenHint.java b/src/com/android/camera/OnScreenHint.java
index e471031..110b374 100644
--- a/src/com/android/camera/OnScreenHint.java
+++ b/src/com/android/camera/OnScreenHint.java
@@ -41,7 +41,6 @@
*/
public class OnScreenHint {
static final String TAG = "OnScreenHint";
- static final boolean LOCAL_LOGV = false;
int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
int mX, mY;
diff --git a/src/com/android/camera/PreviewFrameLayout.java b/src/com/android/camera/PreviewFrameLayout.java
index 982e088..8fee82d 100644
--- a/src/com/android/camera/PreviewFrameLayout.java
+++ b/src/com/android/camera/PreviewFrameLayout.java
@@ -29,8 +29,6 @@
* A layout which handles the preview aspect ratio.
*/
public class PreviewFrameLayout extends RelativeLayout {
- private static final int MIN_HORIZONTAL_MARGIN = 10; // 10dp
-
/** A callback to be invoked when the preview frame's size changes. */
public interface OnSizeChangedListener {
public void onSizeChanged();
@@ -39,7 +37,6 @@
private double mAspectRatio = 4.0 / 3.0;
private View mFrame;
private View mBorderView;
- private RadioGroup mCameraPicker;
private OnSizeChangedListener mSizeListener;
private final DisplayMetrics mMetrics = new DisplayMetrics();
@@ -57,19 +54,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mFrame = (View) findViewById(R.id.frame);
- if (mFrame == null) {
- throw new IllegalStateException(
- "must provide child with id as \"frame\"");
- }
- mCameraPicker = (RadioGroup) findViewById(R.id.camera_picker);
-
- View preview = (View) findViewById(R.id.camera_preview);
- ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)
- preview.getLayoutParams();
mBorderView = (View) findViewById(R.id.preview_border);
- View f = mBorderView;
- params.setMargins(f.getPaddingLeft(), f.getPaddingTop(), f.getPaddingRight(), f.getPaddingBottom());
- preview.setLayoutParams(params);
}
public void setAspectRatio(double ratio) {
@@ -83,44 +68,40 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ // Calculate the width and the height of preview frame.
int frameWidth = getWidth();
int frameHeight = getHeight();
-
View f = mBorderView;
int horizontalPadding = f.getPaddingLeft() + f.getPaddingRight();
int verticalPadding = f.getPaddingBottom() + f.getPaddingTop();
int previewHeight = frameHeight - verticalPadding;
int previewWidth = frameWidth - horizontalPadding;
-
- // resize frame and preview for aspect ratio
if (previewWidth > previewHeight * mAspectRatio) {
previewWidth = (int) (previewHeight * mAspectRatio + .5);
} else {
previewHeight = (int) (previewWidth / mAspectRatio + .5);
}
+ // Measure and layout preview frame.
+ int hSpace = ((r - l) - previewWidth) / 2;
+ int vSpace = ((b - t) - previewHeight) / 2;
+ mFrame.measure(
+ MeasureSpec.makeMeasureSpec(previewWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(previewHeight, MeasureSpec.EXACTLY));
+ mFrame.layout(hSpace, vSpace, frameWidth + hSpace, frameHeight + vSpace);
+
+ // Measure and layout the border of preview frame.
frameWidth = previewWidth + horizontalPadding;
frameHeight = previewHeight + verticalPadding;
-
- int hSpace = ((r - l) - frameWidth) / 2;
- int vSpace = ((b - t) - frameHeight) / 2;
- mFrame.measure(
+ hSpace = ((r - l) - frameWidth) / 2;
+ vSpace = ((b - t) - frameHeight) / 2;
+ mBorderView.measure(
MeasureSpec.makeMeasureSpec(frameWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(frameHeight, MeasureSpec.EXACTLY));
- mFrame.layout(hSpace, vSpace, frameWidth + hSpace, frameHeight + vSpace);
+ mBorderView.layout(hSpace, vSpace, frameWidth + hSpace, frameHeight + vSpace);
+
if (mSizeListener != null) {
mSizeListener.onSizeChanged();
}
- if (mCameraPicker != null) {
- mCameraPicker.measure(
- MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.AT_MOST),
- MeasureSpec.makeMeasureSpec(b - t, MeasureSpec.AT_MOST));
- int width = mCameraPicker.getMeasuredWidth();
- int height = mCameraPicker.getMeasuredHeight();
- int ct = t + ((ViewGroup.MarginLayoutParams)
- mCameraPicker.getLayoutParams()).topMargin;
- int cl = (r - l - width) / 2;
- mCameraPicker.layout(cl, ct, cl + width, ct + height);
- }
}
}
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 23a9282..86fb443 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -17,20 +17,13 @@
package com.android.camera;
import android.content.ContentResolver;
-import android.content.ContentUris;
import android.content.ContentValues;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
import android.location.Location;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.ImageColumns;
-import android.provider.MediaStore.Video;
-import android.provider.MediaStore.Video.VideoColumns;
import android.util.Log;
import java.io.File;
@@ -39,13 +32,11 @@
class Storage {
private static final String TAG = "CameraStorage";
- private static final String DCIM =
+ public static final String DCIM =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
public static final String DIRECTORY = DCIM + "/Camera";
- public static final String THUMBNAILS = DCIM + "/.thumbnails";
-
// Match the code in MediaProvider.computeBucketValues().
public static final String BUCKET_ID =
String.valueOf(DIRECTORY.toLowerCase().hashCode());
@@ -54,109 +45,10 @@
public static final long PREPARING = -2L;
public static final long UNKNOWN_SIZE = -3L;
- public static class Thumbnail {
- private Uri mBaseUri;
- private long mId;
- private Uri mUri;
- private Bitmap mBitmap;
- private int mOrientation;
+ private static final int BUFSIZE = 4096;
- private Thumbnail(Uri baseUri, long id, int orientation) {
- mBaseUri = baseUri;
- mId = id;
- mOrientation = orientation;
- }
-
- private Thumbnail(Uri uri, Bitmap bitmap, int orientation) {
- mUri = uri;
- mBitmap = bitmap;
- mOrientation = orientation;
- }
-
- public Uri getOriginalUri() {
- if (mUri == null && mBaseUri != null) {
- mUri = ContentUris.withAppendedId(mBaseUri, mId);
- }
- return mUri;
- }
-
- public Bitmap getBitmap(ContentResolver resolver) {
- if (mBitmap == null) {
- if (Images.Media.EXTERNAL_CONTENT_URI.equals(mBaseUri)) {
- mBitmap = Images.Thumbnails.getThumbnail(resolver, mId,
- Images.Thumbnails.MICRO_KIND, null);
- } else if (Video.Media.EXTERNAL_CONTENT_URI.equals(mBaseUri)) {
- mBitmap = Video.Thumbnails.getThumbnail(resolver, mId,
- Video.Thumbnails.MICRO_KIND, null);
- }
- }
- if (mBitmap != null && mOrientation != 0) {
- // We only rotate the thumbnail once even if we get OOM.
- Matrix m = new Matrix();
- m.setRotate(mOrientation, mBitmap.getWidth() * 0.5f,
- mBitmap.getHeight() * 0.5f);
- mOrientation = 0;
-
- try {
- Bitmap rotated = Bitmap.createBitmap(mBitmap, 0, 0,
- mBitmap.getWidth(), mBitmap.getHeight(), m, true);
- mBitmap.recycle();
- mBitmap = rotated;
- } catch (Throwable t) {
- Log.w(TAG, "Failed to rotate thumbnail", t);
- }
- }
- return mBitmap;
- }
- }
-
- public static Thumbnail getLastImageThumbnail(ContentResolver resolver) {
- Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
-
- Uri query = baseUri.buildUpon().appendQueryParameter("limit", "1").build();
- String[] projection = new String[] {ImageColumns._ID, ImageColumns.ORIENTATION};
- String selection = ImageColumns.MIME_TYPE + "='image/jpeg' AND " +
- ImageColumns.BUCKET_ID + '=' + BUCKET_ID;
- String order = ImageColumns.DATE_TAKEN + " DESC," + ImageColumns._ID + " DESC";
-
- Cursor cursor = null;
- try {
- cursor = resolver.query(query, projection, selection, null, order);
- if (cursor != null && cursor.moveToFirst()) {
- return new Thumbnail(baseUri, cursor.getLong(0), cursor.getInt(1));
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- return null;
- }
-
- public static Thumbnail getLastVideoThumbnail(ContentResolver resolver) {
- Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
-
- Uri query = baseUri.buildUpon().appendQueryParameter("limit", "1").build();
- String[] projection = new String[] {VideoColumns._ID};
- String selection = VideoColumns.BUCKET_ID + '=' + BUCKET_ID;
- String order = VideoColumns.DATE_TAKEN + " DESC," + VideoColumns._ID + " DESC";
-
- Cursor cursor = null;
- try {
- cursor = resolver.query(query, projection, selection, null, order);
- if (cursor != null && cursor.moveToFirst()) {
- return new Thumbnail(baseUri, cursor.getLong(0), 0);
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- return null;
- }
-
- public static Thumbnail addImage(ContentResolver resolver, String title,
- long date, Location location, byte[] jpeg) {
+ public static Uri addImage(ContentResolver resolver, String title,
+ long date, Location location, int orientation, byte[] jpeg) {
// Save the image.
String path = DIRECTORY + '/' + title + ".jpg";
FileOutputStream out = null;
@@ -173,9 +65,6 @@
}
}
- // Get the orientation.
- int orientation = Exif.getOrientation(jpeg);
-
// Insert into MediaStore.
ContentValues values = new ContentValues(9);
values.put(ImageColumns.TITLE, title);
@@ -196,16 +85,7 @@
Log.e(TAG, "Failed to write MediaStore");
return null;
}
-
- // Create the thumbnail.
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = 16;
- Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length, options);
- if (bitmap == null) {
- Log.e(TAG, "Failed to create thumbnail");
- return null;
- }
- return new Thumbnail(uri, bitmap, orientation);
+ return uri;
}
public static long getAvailableSpace() {
diff --git a/src/com/android/camera/Thumbnail.java b/src/com/android/camera/Thumbnail.java
new file mode 100644
index 0000000..8479c49
--- /dev/null
+++ b/src/com/android/camera/Thumbnail.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.net.Uri;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.Video;
+import android.provider.MediaStore.Video.VideoColumns;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+class Thumbnail {
+ private static final String TAG = "Thumbnail";
+
+ private static final String DIRECTORY = Storage.DCIM + "/.thumbnails/";
+ private static final int BUFSIZE = 4096;
+
+ private Uri mUri;
+ private Bitmap mBitmap;
+
+ public Thumbnail(Uri uri, Bitmap bitmap, int orientation) {
+ mUri = uri;
+ mBitmap = rotateImage(bitmap, orientation);
+ }
+
+ public Uri getUri() {
+ return mUri;
+ }
+
+ public Bitmap getBitmap() {
+ return mBitmap;
+ }
+
+ private static Bitmap rotateImage(Bitmap bitmap, int orientation) {
+ if (orientation != 0) {
+ // We only rotate the thumbnail once even if we get OOM.
+ Matrix m = new Matrix();
+ m.setRotate(orientation, bitmap.getWidth() * 0.5f,
+ bitmap.getHeight() * 0.5f);
+
+ try {
+ Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0,
+ bitmap.getWidth(), bitmap.getHeight(), m, true);
+ bitmap.recycle();
+ return rotated;
+ } catch (Throwable t) {
+ Log.w(TAG, "Failed to rotate thumbnail", t);
+ }
+ }
+ return bitmap;
+ }
+
+ // Stores the bitmap to the specified file.
+ public void saveTo(String filename) {
+ String path = DIRECTORY + filename;
+ FileOutputStream f = null;
+ BufferedOutputStream b = null;
+ DataOutputStream d = null;
+ try {
+ f = new FileOutputStream(path);
+ b = new BufferedOutputStream(f, BUFSIZE);
+ d = new DataOutputStream(b);
+ d.writeUTF(mUri.toString());
+ mBitmap.compress(Bitmap.CompressFormat.PNG, 100, d);
+ d.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Fail to store bitmap. path=" + path, e);
+ } finally {
+ Util.closeSilently(f);
+ Util.closeSilently(b);
+ Util.closeSilently(d);
+ }
+ }
+
+
+ // Loads the data from the specified file.
+ // Returns null if failure.
+ public static Thumbnail loadFrom(String filename) {
+ Uri uri = null;
+ Bitmap bitmap = null;
+ FileInputStream f = null;
+ BufferedInputStream b = null;
+ DataInputStream d = null;
+ try {
+ f = new FileInputStream(DIRECTORY + filename);
+ b = new BufferedInputStream(f, BUFSIZE);
+ d = new DataInputStream(b);
+ uri = Uri.parse(d.readUTF());
+ bitmap = BitmapFactory.decodeStream(d);
+ d.close();
+ } catch (IOException e) {
+ Log.i(TAG, "Fail to load bitmap. " + e);
+ return null;
+ } finally {
+ Util.closeSilently(f);
+ Util.closeSilently(b);
+ Util.closeSilently(d);
+ }
+ return new Thumbnail(uri, bitmap, 0);
+ }
+
+ public static Thumbnail getLastImageThumbnail(ContentResolver resolver) {
+ Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
+
+ Uri query = baseUri.buildUpon().appendQueryParameter("limit", "1").build();
+ String[] projection = new String[] {ImageColumns._ID, ImageColumns.ORIENTATION};
+ String selection = ImageColumns.MIME_TYPE + "='image/jpeg' AND " +
+ ImageColumns.BUCKET_ID + '=' + Storage.BUCKET_ID;
+ String order = ImageColumns.DATE_TAKEN + " DESC," + ImageColumns._ID + " DESC";
+
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(query, projection, selection, null, order);
+ if (cursor != null && cursor.moveToFirst()) {
+ long id = cursor.getLong(0);
+ int orientation = cursor.getInt(1);
+ Bitmap bitmap = Images.Thumbnails.getThumbnail(resolver, id,
+ Images.Thumbnails.MINI_KIND, null);
+ Uri uri = ContentUris.withAppendedId(baseUri, id);
+ // Ensure there's no OOM. Ensure database and storage are in sync.
+ if (bitmap != null && Util.isUriValid(uri, resolver)) {
+ return new Thumbnail(uri, bitmap, orientation);
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return null;
+ }
+
+ public static Thumbnail getLastVideoThumbnail(ContentResolver resolver) {
+ Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+
+ Uri query = baseUri.buildUpon().appendQueryParameter("limit", "1").build();
+ String[] projection = new String[] {VideoColumns._ID};
+ String selection = VideoColumns.BUCKET_ID + '=' + Storage.BUCKET_ID;
+ String order = VideoColumns.DATE_TAKEN + " DESC," + VideoColumns._ID + " DESC";
+
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(query, projection, selection, null, order);
+ if (cursor != null && cursor.moveToFirst()) {
+ long id = cursor.getLong(0);
+ Bitmap bitmap = Video.Thumbnails.getThumbnail(resolver, id,
+ Video.Thumbnails.MINI_KIND, null);
+ Uri uri = ContentUris.withAppendedId(baseUri, id);
+ // Ensure there's no OOM. Ensure database and storage are in sync.
+ if (bitmap != null && Util.isUriValid(uri, resolver)) {
+ return new Thumbnail(uri, bitmap, 0);
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return null;
+ }
+
+ public static Thumbnail createThumbnail(byte[] jpeg, int orientation, int inSampleSize,
+ Uri uri) {
+ // Create the thumbnail.
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inSampleSize = inSampleSize;
+ Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length, options);
+ if (bitmap == null) {
+ Log.e(TAG, "Failed to create thumbnail");
+ return null;
+ }
+ return new Thumbnail(uri, bitmap, orientation);
+ }
+}
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index cfef950..bf33dc9 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -18,14 +18,19 @@
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
import android.content.Context;
+import android.content.ContentResolver;
import android.content.DialogInterface;
+import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Display;
@@ -35,6 +40,7 @@
import android.view.animation.TranslateAnimation;
import java.io.Closeable;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.StringTokenizer;
@@ -44,16 +50,16 @@
*/
public class Util {
private static final String TAG = "Util";
- public static final int DIRECTION_LEFT = 0;
- public static final int DIRECTION_RIGHT = 1;
- public static final int DIRECTION_UP = 2;
- public static final int DIRECTION_DOWN = 3;
+ private static final int DIRECTION_LEFT = 0;
+ private static final int DIRECTION_RIGHT = 1;
+ private static final int DIRECTION_UP = 2;
+ private static final int DIRECTION_DOWN = 3;
public static final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
// Private intent extras. Test only.
- public static final String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
+ private static final String EXTRAS_CAMERA_FACING =
+ "android.intent.extras.CAMERA_FACING";
private Util() {
}
@@ -215,54 +221,6 @@
.show();
}
- public static Animation slideOut(View view, int to) {
- view.setVisibility(View.INVISIBLE);
- Animation anim;
- switch (to) {
- case DIRECTION_LEFT:
- anim = new TranslateAnimation(0, -view.getWidth(), 0, 0);
- break;
- case DIRECTION_RIGHT:
- anim = new TranslateAnimation(0, view.getWidth(), 0, 0);
- break;
- case DIRECTION_UP:
- anim = new TranslateAnimation(0, 0, 0, -view.getHeight());
- break;
- case DIRECTION_DOWN:
- anim = new TranslateAnimation(0, 0, 0, view.getHeight());
- break;
- default:
- throw new IllegalArgumentException(Integer.toString(to));
- }
- anim.setDuration(500);
- view.startAnimation(anim);
- return anim;
- }
-
- public static Animation slideIn(View view, int from) {
- view.setVisibility(View.VISIBLE);
- Animation anim;
- switch (from) {
- case DIRECTION_LEFT:
- anim = new TranslateAnimation(-view.getWidth(), 0, 0, 0);
- break;
- case DIRECTION_RIGHT:
- anim = new TranslateAnimation(view.getWidth(), 0, 0, 0);
- break;
- case DIRECTION_UP:
- anim = new TranslateAnimation(0, 0, -view.getHeight(), 0);
- break;
- case DIRECTION_DOWN:
- anim = new TranslateAnimation(0, 0, view.getHeight(), 0);
- break;
- default:
- throw new IllegalArgumentException(Integer.toString(from));
- }
- anim.setDuration(500);
- view.startAnimation(anim);
- return anim;
- }
-
public static <T> T checkNotNull(T object) {
if (object == null) throw new NullPointerException();
return object;
@@ -272,10 +230,6 @@
return (a == b) || (a == null ? false : a.equals(b));
}
- public static boolean isPowerOf2(int n) {
- return (n & -n) == n;
- }
-
public static int nextPowerOf2(int n) {
n -= 1;
n |= n >>> 16;
@@ -404,7 +358,7 @@
} catch (java.lang.reflect.InvocationTargetException ite) {
// Failure, must be another device.
// Assume that it is voice capable.
- } catch (java.lang.IllegalAccessException iae) {
+ } catch (IllegalAccessException iae) {
// Failure, must be an other device.
// Assume that it is voice capable.
} catch (NoSuchMethodException nsme) {
@@ -443,4 +397,45 @@
return (intentCameraId == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
}
+ private static int mLocation[] = new int[2];
+
+ // This method is not thread-safe.
+ public static boolean pointInView(float x, float y, View v) {
+ v.getLocationInWindow(mLocation);
+ return x >= mLocation[0] && x < (mLocation[0] + v.getWidth())
+ && y >= mLocation[1] && y < (mLocation[1] + v.getHeight());
+ }
+
+ public static boolean isUriValid(Uri uri, ContentResolver resolver) {
+ if (uri == null) return false;
+
+ try {
+ ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
+ if (pfd == null) {
+ Log.e(TAG, "Fail to open URI. URI=" + uri);
+ return false;
+ }
+ pfd.close();
+ } catch (IOException ex) {
+ return false;
+ }
+ return true;
+ }
+
+ public static void viewUri(Uri uri, Context context) {
+ if (!isUriValid(uri, context.getContentResolver())) {
+ Log.e(TAG, "Uri invalid. uri=" + uri);
+ return;
+ }
+
+ try {
+ context.startActivity(new Intent(Util.REVIEW_ACTION, uri));
+ } catch (ActivityNotFoundException ex) {
+ try {
+ context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "review image fail. uri=" + uri, e);
+ }
+ }
+ }
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 7d67270..010099e 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -21,6 +21,7 @@
import com.android.camera.ui.GLRootView;
import com.android.camera.ui.HeadUpDisplay;
import com.android.camera.ui.IndicatorWheel;
+import com.android.camera.ui.RotateImageView;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -89,8 +90,7 @@
private static final String TAG = "videocamera";
- private static final String LAST_THUMB_PATH =
- Storage.THUMBNAILS + "/video_last_thumb";
+ private static final String LAST_THUMB_FILENAME = "video_last_thumb";
private static final int CHECK_DISPLAY_ROTATION = 3;
private static final int CLEAR_SCREEN_DELAY = 4;
@@ -139,9 +139,7 @@
private PreferenceGroup mPreferenceGroup;
private PreviewFrameLayout mPreviewFrameLayout;
- private SurfaceView mVideoPreview;
private SurfaceHolder mSurfaceHolder = null;
- private ImageView mVideoFrame;
private GLRootView mGLRootView;
// xlarge devices use indicator wheel. Other devices use head-up display.
private CamcorderHeadUpDisplay mHeadUpDisplay;
@@ -150,12 +148,23 @@
private CameraPicker mCameraPicker;
private View mReviewControl;
+ private Toast mNoShareToast;
+ // A button showing the last captured video thumbnail. Clicking on it
+ // goes to gallery.
+ private RotateImageView mThumbnailButton;
+ // The bitmap of the last captured video thumbnail and the URI of the
+ // original video.
+ private Thumbnail mThumbnail;
+ // An review image having same size as preview. It is displayed when
+ // recording is stopped in capture intent or share button is pressed.
+ private ImageView mReviewImage;
+ private ShutterButton mShutterButton;
+ private TextView mRecordingTimeView;
+ private SwitcherSet mSwitcher;
+
private boolean mIsVideoCaptureIntent;
private boolean mQuickCapture;
- // The last recorded video.
- private RotateImageView mThumbnailButton;
-
private boolean mOpenCameraFail = false;
private long mStorageSpace;
@@ -163,6 +172,7 @@
private MediaRecorder mMediaRecorder;
private boolean mMediaRecorderRecording = false;
private long mRecordingStartTime;
+ private boolean mRecordingTimeCountsDown = false;
private long mOnResumeTime;
// The video file that the hardware camera is about to record into
// (or is recording into.)
@@ -203,11 +213,6 @@
private ContentResolver mContentResolver;
- private ShutterButton mShutterButton;
- private TextView mRecordingTimeView;
- private SwitcherSet mSwitcher;
- private boolean mRecordingTimeCountsDown = false;
-
private final ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>();
private final Handler mHandler = new MainHandler();
@@ -290,7 +295,7 @@
// handled in ACTION_MEDIA_EJECT
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
Toast.makeText(VideoCamera.this,
- getResources().getString(R.string.wait), 5000);
+ getResources().getString(R.string.wait), Toast.LENGTH_LONG).show();
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
updateAndShowStorageHint();
}
@@ -395,13 +400,13 @@
findViewById(R.id.frame_layout);
mPreviewFrameLayout.setOnSizeChangedListener(this);
- mVideoPreview = (SurfaceView) findViewById(R.id.camera_preview);
- mVideoFrame = (ImageView) findViewById(R.id.video_frame);
+ mReviewImage = (ImageView) findViewById(R.id.review_image);
// don't set mSurfaceHolder here. We have it set ONLY within
// surfaceCreated / surfaceDestroyed, other parts of the code
// assume that when it is set, the surface is also set.
- SurfaceHolder holder = mVideoPreview.getHolder();
+ SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);
+ SurfaceHolder holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@@ -526,12 +531,14 @@
if (mIndicatorWheel == null) return;
loadCameraPreferences();
- String[] keys = new String[]{CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
- CameraSettings.KEY_WHITE_BALANCE,
- CameraSettings.KEY_COLOR_EFFECT,
+ final String[] SETTING_KEYS = {
+ CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
CameraSettings.KEY_VIDEO_QUALITY,
CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL};
- mIndicatorWheel.initialize(this, mPreferenceGroup, keys, false);
+ final String[] OTHER_SETTING_KEYS = {
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_COLOR_EFFECT};
+ mIndicatorWheel.initialize(this, mPreferenceGroup, SETTING_KEYS, OTHER_SETTING_KEYS);
mIndicatorWheel.setListener(new MyIndicatorWheelListener());
mPopupGestureDetector = new GestureDetector(this,
new PopupGestureListener());
@@ -594,7 +601,7 @@
Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri);
try {
startActivity(intent);
- } catch (android.content.ActivityNotFoundException ex) {
+ } catch (ActivityNotFoundException ex) {
Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
}
}
@@ -616,7 +623,9 @@
doReturnToCaller(false);
break;
case R.id.review_thumbnail:
- if (!mMediaRecorderRecording) viewVideo(mThumbnailButton);
+ if (!mMediaRecorderRecording && mThumbnail != null) {
+ Util.viewUri(mThumbnail.getUri(), this);
+ }
break;
case R.id.btn_gallery:
gotoGallery();
@@ -724,7 +733,7 @@
mMaxVideoDurationInMs = 1000 * seconds;
} else {
mMaxVideoDurationInMs =
- CameraSettings.getVideoDurationInMillis(this, quality);
+ CameraSettings.getVideoDurationInMillis(this, quality, mCameraId);
}
// Read time lapse recording interval.
@@ -825,6 +834,8 @@
super.onResume();
mPausing = false;
+ mReviewImage.setVisibility(View.GONE);
+
// Start orientation listener as soon as possible because it takes
// some time to get first orientation.
mOrientationListener.enable();
@@ -956,8 +967,8 @@
}
resetScreenOn();
- if (!mIsVideoCaptureIntent && mThumbnailButton != null) {
- mThumbnailButton.storeData(LAST_THUMB_PATH);
+ if (!mIsVideoCaptureIntent && mThumbnail != null) {
+ mThumbnail.saveTo(LAST_THUMB_FILENAME);
}
if (mStorageHint != null) {
@@ -1102,7 +1113,7 @@
} else {
resultCode = RESULT_CANCELED;
}
- setResult(resultCode, resultIntent);
+ setResultEx(resultCode, resultIntent);
finish();
}
@@ -1359,6 +1370,7 @@
// from MediaRecorder.OnErrorListener
public void onError(MediaRecorder mr, int what, int extra) {
+ Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
// We may have run out of space on the sdcard.
stopVideoRecording();
@@ -1393,6 +1405,11 @@
sendBroadcast(i);
}
+ // For testing.
+ public boolean isRecording() {
+ return mMediaRecorderRecording;
+ }
+
private void startVideoRecording() {
Log.v(TAG, "startVideoRecording");
@@ -1453,7 +1470,12 @@
}
private void getThumbnail() {
- acquireVideoThumb();
+ Bitmap videoFrame = ThumbnailUtils.createVideoThumbnail(
+ mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
+ if (videoFrame != null) {
+ mThumbnail = new Thumbnail(mCurrentVideoUri, videoFrame, 0);
+ mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ }
}
private void showAlert() {
@@ -1461,18 +1483,20 @@
fadeOut(findViewById(R.id.shutter_button));
}
if (mCurrentVideoFilename != null) {
- Bitmap src = ThumbnailUtils.createVideoThumbnail(
+ Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(
mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
- // MetadataRetriever already rotates the thumbnail. We should rotate
- // it back (and mirror if it is front-facing camera).
- CameraInfo[] info = CameraHolder.instance().getCameraInfo();
- if (info[mCameraId].facing == CameraInfo.CAMERA_FACING_BACK) {
- src = Util.rotateAndMirror(src, -mOrientationHint, false);
- } else {
- src = Util.rotateAndMirror(src, -mOrientationHint, true);
+ if (bitmap != null) {
+ // MetadataRetriever already rotates the thumbnail. We should rotate
+ // it back (and mirror if it is front-facing camera).
+ CameraInfo[] info = CameraHolder.instance().getCameraInfo();
+ if (info[mCameraId].facing == CameraInfo.CAMERA_FACING_BACK) {
+ bitmap = Util.rotateAndMirror(bitmap, -mOrientationHint, false);
+ } else {
+ bitmap = Util.rotateAndMirror(bitmap, -mOrientationHint, true);
+ }
+ mReviewImage.setImageBitmap(bitmap);
+ mReviewImage.setVisibility(View.VISIBLE);
}
- mVideoFrame.setImageBitmap(src);
- mVideoFrame.setVisibility(View.VISIBLE);
}
int[] pickIds = {R.id.btn_retake, R.id.btn_done, R.id.btn_play};
for (int id : pickIds) {
@@ -1487,7 +1511,7 @@
}
private void hideAlert() {
- mVideoFrame.setVisibility(View.INVISIBLE);
+ mReviewImage.setVisibility(View.INVISIBLE);
fadeIn(findViewById(R.id.shutter_button));
mShutterButton.setEnabled(true);
enableCameraControls(true);
@@ -1523,25 +1547,7 @@
}
private boolean isAlertVisible() {
- return this.mVideoFrame.getVisibility() == View.VISIBLE;
- }
-
- private void viewVideo(RotateImageView view) {
- if(view.isUriValid()) {
- Intent intent = new Intent(Util.REVIEW_ACTION, view.getUri());
- try {
- startActivity(intent);
- } catch (ActivityNotFoundException ex) {
- try {
- intent = new Intent(Intent.ACTION_VIEW, view.getUri());
- startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "review video fail. uri=" + view.getUri(), e);
- }
- }
- } else {
- Log.e(TAG, "Uri invalid. uri=" + view.getUri());
- }
+ return this.mReviewImage.getVisibility() == View.VISIBLE;
}
private void stopVideoRecording() {
@@ -1589,39 +1595,22 @@
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
- private void acquireVideoThumb() {
- if (mThumbnailButton != null) {
- Bitmap videoFrame = ThumbnailUtils.createVideoThumbnail(
- mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
- mThumbnailButton.setData(mCurrentVideoUri, videoFrame);
- if (videoFrame != null) {
- mThumbnailButton.setVisibility(View.VISIBLE);
- }
- }
- }
-
private void initThumbnailButton() {
- mThumbnailButton = (RotateImageView)findViewById(R.id.review_thumbnail);
- if (mThumbnailButton != null) {
- mThumbnailButton.setOnClickListener(this);
- mThumbnailButton.loadData(LAST_THUMB_PATH);
- }
+ mThumbnailButton = (RotateImageView) findViewById(R.id.review_thumbnail);
+ mThumbnailButton.setOnClickListener(this);
+ // Load the thumbnail from the disk.
+ mThumbnail = Thumbnail.loadFrom(LAST_THUMB_FILENAME);
}
private void updateThumbnailButton() {
- if (mThumbnailButton == null) return;
- if (!mThumbnailButton.isUriValid()) {
- Storage.Thumbnail thumbnail =
- Storage.getLastVideoThumbnail(mContentResolver);
- if (thumbnail != null) {
- mThumbnailButton.setData(thumbnail.getOriginalUri(),
- thumbnail.getBitmap(mContentResolver));
- } else {
- mThumbnailButton.setData(null, null);
- }
+ if (mThumbnail == null || !Util.isUriValid(mThumbnail.getUri(), mContentResolver)) {
+ mThumbnail = Thumbnail.getLastVideoThumbnail(mContentResolver);
}
- mThumbnailButton.setVisibility(
- (mThumbnailButton.getUri() != null) ? View.VISIBLE : View.GONE);
+ if (mThumbnail != null) {
+ mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ } else {
+ mThumbnailButton.setBitmap(null);
+ }
}
private static String millisecondToTimeString(long milliSeconds, boolean displayCentiSeconds) {
@@ -1905,6 +1894,27 @@
}
+ private void onShareButtonClicked() {
+ if (mPausing) return;
+
+ // Share the last captured video.
+ if (mThumbnail != null) {
+ mReviewImage.setImageBitmap(mThumbnail.getBitmap());
+ mReviewImage.setVisibility(View.VISIBLE);
+
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("video/*");
+ intent.putExtra(Intent.EXTRA_STREAM, mThumbnail.getUri());
+ startActivity(Intent.createChooser(intent, getString(R.string.share_video_via)));
+ } else { // No last picture
+ if (mNoShareToast == null) {
+ mNoShareToast = Toast.makeText(this,
+ getResources().getString(R.string.no_video_to_share), Toast.LENGTH_SHORT);
+ }
+ mNoShareToast.show();
+ }
+ }
+
private class MyIndicatorWheelListener implements IndicatorWheel.Listener {
public void onSharedPreferenceChanged() {
VideoCamera.this.onSharedPreferenceChanged();
@@ -1916,6 +1926,10 @@
public void onOverriddenPreferencesClicked() {
}
+
+ public void onShareButtonClicked() {
+ VideoCamera.this.onShareButtonClicked();
+ }
}
private class MyCameraPickerListener implements CameraPicker.Listener {
@@ -1934,28 +1948,20 @@
return super.dispatchTouchEvent(m);
}
- private int mLocation[] = new int[2];
private class PopupGestureListener extends
GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
// Check if the popup window is visible.
- View v = mIndicatorWheel.getActivePopupWindow();
- if (v == null) return false;
+ View popup = mIndicatorWheel.getActivePopupWindow();
+ if (popup == null) return false;
- int x = Math.round(e.getX());
- int y = Math.round(e.getY());
-
- // Dismiss the popup window if users touch on the outside.
- v.getLocationOnScreen(mLocation);
- if (x < mLocation[0] || (x > mLocation[0] + v.getWidth())
- || y < mLocation[1] || (y > mLocation[1] + v.getHeight())) {
- // Let indicator wheel handle its own event.
- mIndicatorWheel.getLocationOnScreen(mLocation);
- if (x < mLocation[0] || (x > mLocation[0] + mIndicatorWheel.getWidth())
- || y < mLocation[1] || (y > mLocation[1] + mIndicatorWheel.getHeight())) {
- mIndicatorWheel.dismissSettingPopup();
- }
+ // Let popup window or indicator wheel handle the event by
+ // themselves. Dismiss the popup window if users touch on other
+ // areas.
+ if (!Util.pointInView(e.getX(), e.getY(), popup)
+ && !Util.pointInView(e.getX(), e.getY(), mIndicatorWheel)) {
+ mIndicatorWheel.dismissSettingPopup();
// Let event fall through.
}
return false;
diff --git a/src/com/android/camera/ui/AbstractSettingPopup.java b/src/com/android/camera/ui/AbstractSettingPopup.java
index 32fbe67..794152e 100644
--- a/src/com/android/camera/ui/AbstractSettingPopup.java
+++ b/src/com/android/camera/ui/AbstractSettingPopup.java
@@ -44,4 +44,6 @@
mTitle = (TextView) findViewById(R.id.title);
mSettingList = (ViewGroup) findViewById(R.id.settingList);
}
+
+ abstract public void reloadPreference();
}
diff --git a/src/com/android/camera/ui/BasicSettingPopup.java b/src/com/android/camera/ui/BasicSettingPopup.java
index 2e33720..1496e9e 100644
--- a/src/com/android/camera/ui/BasicSettingPopup.java
+++ b/src/com/android/camera/ui/BasicSettingPopup.java
@@ -80,6 +80,7 @@
}
// The value of the preference may have changed. Update the UI.
+ @Override
public void reloadPreference() {
int index = mPreference.findIndexOfValue(mPreference.getValue());
if (index != -1) {
diff --git a/src/com/android/camera/ui/IndicatorWheel.java b/src/com/android/camera/ui/IndicatorWheel.java
index e24fbc5..1a374da 100644
--- a/src/com/android/camera/ui/IndicatorWheel.java
+++ b/src/com/android/camera/ui/IndicatorWheel.java
@@ -38,13 +38,12 @@
import android.view.ViewGroup;
import android.view.View;
-import java.lang.Math;
import java.util.ArrayList;
/**
* A view that contains shutter button and camera setting indicators. The
* indicators are spreaded around the shutter button. The first child is always
- * the shutter button.
+ * the shutter button. The last indicator is always the share button.
*/
public class IndicatorWheel extends ViewGroup implements
BasicSettingPopup.Listener, OtherSettingsPopup.Listener {
@@ -84,9 +83,12 @@
private Context mContext;
private PreferenceGroup mPreferenceGroup;
- private ArrayList<String> mPreferenceKeys;
- private BasicSettingPopup[] mBasicSettingPopups;
- private OtherSettingsPopup mOtherSettingsPopup;
+ // Preference key of every setting (except other settings) on the wheel .
+ private ArrayList<String> mPrefKeys;
+ private String[] mOtherSettingPrefKeys;
+ // Popup window of every camera setting on the wheel.
+ private AbstractSettingPopup[] mSettingPopups;
+ private int mIndicatorCount;
private Animation mFadeIn, mFadeOut;
// The previous view that has the animation. The animation may have stopped.
@@ -96,6 +98,7 @@
public void onSharedPreferenceChanged();
public void onRestorePreferencesClicked();
public void onOverriddenPreferencesClicked();
+ public void onShareButtonClicked();
}
public void setListener(Listener listener) {
@@ -141,8 +144,7 @@
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) return false;
- int count = getChildCount();
- if (count <= 1) return false;
+ if (mIndicatorCount == 0) return false;
// Check if any setting is pressed.
int action = event.getAction();
@@ -155,17 +157,16 @@
double radius = Math.sqrt(dx * dx + dy * dy);
// Ignore the event if it's too near to the shutter button or too far
// from the shutter button.
-
if (radius >= mShutterButtonRadius && radius <= mWheelRadius + mStrokeWidth) {
double delta = Math.atan2(dy, dx);
if (delta < 0) delta += Math.PI * 2;
// Check which sector is pressed.
if (delta > mSectorInitialRadians[0]) {
- for (int i = 1; i < count; i++) {
- if (delta < mSectorInitialRadians[i]) {
+ for (int i = 0; i < mIndicatorCount; i++) {
+ if (delta < mSectorInitialRadians[i + 1]) {
// If the touch is moving around the same indicator with
// popup opened, return now to avoid redundent works.
- if (action == MotionEvent.ACTION_MOVE && (mSelectedIndex == i - 1)) {
+ if (action == MotionEvent.ACTION_MOVE && (mSelectedIndex == i)) {
return false;
}
@@ -173,7 +174,7 @@
dismissSettingPopup();
// Do nothing if scene mode overrides the setting.
- View child = getChildAt(i);
+ View child = getChildAt(i + 1); // first child is shutter button
if (child instanceof IndicatorButton) {
if (((IndicatorButton) child).isOverridden()) {
// Do not notify in ACTION_MOVE to avoid lots of
@@ -185,13 +186,13 @@
}
}
if (action == MotionEvent.ACTION_DOWN
- && (selectedIndex == i - 1) && (mJustDeselectedIndex != i - 1)) {
+ && (selectedIndex == i) && (mJustDeselectedIndex != i)) {
// The same indicator is pressed with popup opened.
- mJustDeselectedIndex = i - 1;
+ mJustDeselectedIndex = i;
} else {
- if ((mJustDeselectedIndex != i - 1)
+ if ((mJustDeselectedIndex != i)
|| (selectedIndex == -1 && action == MotionEvent.ACTION_DOWN)) {
- showSettingPopup(i - 1);
+ showSettingPopup(i);
mJustDeselectedIndex = -1;
}
}
@@ -213,12 +214,13 @@
invalidate();
}
- public void removeIndicators() {
+ private void removeIndicators() {
// Remove everything but the shutter button.
int count = getChildCount();
if (count > 1) {
removeViews(1, count - 1);
}
+ mIndicatorCount = 0;
}
@Override
@@ -372,7 +374,7 @@
}
// Scene mode may override other camera settings (ex: flash mode).
- public void overrideSettings(String key, String value) {
+ private void overrideSettings(String key, String value) {
int count = getChildCount();
for (int j = 1; j < count; j++) {
View v = getChildAt(j);
@@ -425,43 +427,49 @@
}
}
- protected boolean addIndicator(
- Context context, PreferenceGroup group, String key) {
- IconListPreference pref = (IconListPreference) group.findPreference(key);
- if (pref == null) return false;
- IndicatorButton b = new IndicatorButton(context, pref);
- addView(b);
- return true;
+ private void addIndicator(Context context, IconListPreference pref) {
+ addView(new IndicatorButton(context, pref));
+ mIndicatorCount++;
}
- private void addOtherSettingIndicator(Context context) {
+ private void addIndicator(Context context, int resId) {
ImageView b = new ImageView(context);
- b.setImageResource(R.drawable.ic_viewfinder_settings);
+ b.setImageResource(resId);
b.setClickable(false);
addView(b);
+ mIndicatorCount++;
}
public void initialize(Context context, PreferenceGroup group,
- String[] keys, boolean enableOtherSettings) {
+ String[] keys, String[] otherSettingKeys) {
// Reset the variables and states.
dismissSettingPopup();
removeIndicators();
- mOtherSettingsPopup = null;
mSelectedIndex = -1;
- mPreferenceKeys = new ArrayList<String>();
+ mPrefKeys = new ArrayList<String>();
// Initialize all variables and icons.
mPreferenceGroup = group;
for (int i = 0; i < keys.length; i++) {
- if (addIndicator(context, group, keys[i])) {
- mPreferenceKeys.add(keys[i]);
+ IconListPreference pref = (IconListPreference) group.findPreference(keys[i]);
+ if (pref != null) {
+ addIndicator(context, pref);
+ mPrefKeys.add(keys[i]);
}
}
- mBasicSettingPopups = new BasicSettingPopup[mPreferenceKeys.size()];
- if (enableOtherSettings) {
- addOtherSettingIndicator(context);
+ int len = mPrefKeys.size();
+ // Add other settings indicator.
+ mOtherSettingPrefKeys = otherSettingKeys;
+ if (mOtherSettingPrefKeys != null) {
+ addIndicator(context, R.drawable.ic_viewfinder_settings);
+ len++;
}
+ mSettingPopups = new AbstractSettingPopup[len];
+
+ // Add share button. It is always the last one.
+ addIndicator(context, R.drawable.ic_viewfinder_share);
+
requestLayout();
}
@@ -486,53 +494,51 @@
}
}
- private void initializeSettingPopup(int index) {
- IconListPreference pref = (IconListPreference)
- mPreferenceGroup.findPreference(mPreferenceKeys.get(index));
-
- LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- ViewGroup root = (ViewGroup) getRootView().findViewById(R.id.app_root);
- BasicSettingPopup popup = (BasicSettingPopup) inflater.inflate(
- R.layout.basic_setting_popup, root, false);
- mBasicSettingPopups[index] = popup;
- popup.setSettingChangedListener(this);
- popup.initialize(pref);
- root.addView(popup);
+ public void onShareButtonClicked() {
+ if (mListener != null) {
+ mListener.onShareButtonClicked();
+ }
}
- private void initializeOtherSettingPopup() {
+ private void initializeSettingPopup(int index) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ViewGroup root = (ViewGroup) getRootView().findViewById(R.id.app_root);
- mOtherSettingsPopup = (OtherSettingsPopup) inflater.inflate(
- R.layout.other_setting_popup, root, false);
- mOtherSettingsPopup.setOtherSettingChangedListener(this);
- mOtherSettingsPopup.initialize(mPreferenceGroup);
- root.addView(mOtherSettingsPopup);
+ if (index < mPrefKeys.size()) {
+ IconListPreference pref = (IconListPreference)
+ mPreferenceGroup.findPreference(mPrefKeys.get(index));
+
+ BasicSettingPopup popup = (BasicSettingPopup) inflater.inflate(
+ R.layout.basic_setting_popup, root, false);
+ mSettingPopups[index] = popup;
+ popup.setSettingChangedListener(this);
+ popup.initialize(pref);
+ } else {
+ // Initialize other settings popup window.
+ OtherSettingsPopup popup = (OtherSettingsPopup) inflater.inflate(
+ R.layout.other_setting_popup, root, false);
+ mSettingPopups[index] = popup;
+ popup.setSettingChangedListener(this);
+ popup.initialize(mPreferenceGroup, mOtherSettingPrefKeys);
+ }
+ root.addView(mSettingPopups[index]);
}
private void showSettingPopup(int index) {
if (index == mSelectedIndex) return;
- if (index < mBasicSettingPopups.length) {
- if (mBasicSettingPopups[index] == null) {
- initializeSettingPopup(index);
- }
- } else if (mOtherSettingsPopup == null) {
- initializeOtherSettingPopup();
+ // The share button is the last indicator.
+ if (index == mIndicatorCount - 1) {
+ onShareButtonClicked();
+ return;
}
- View popup;
+ if (mSettingPopups[index] == null) initializeSettingPopup(index);
+
if (mPrevAnimatingView != null) mPrevAnimatingView.clearAnimation();
- if (index == mBasicSettingPopups.length) {
- popup = mOtherSettingsPopup;
- } else {
- popup = mBasicSettingPopups[index];
- }
- popup.startAnimation(mFadeIn);
- popup.setVisibility(View.VISIBLE);
- mPrevAnimatingView = popup;
+ mSettingPopups[index].startAnimation(mFadeIn);
+ mSettingPopups[index].setVisibility(View.VISIBLE);
+ mPrevAnimatingView = mSettingPopups[index];
setHighlight(index, true);
mSelectedIndex = index;
invalidate();
@@ -540,16 +546,10 @@
public boolean dismissSettingPopup() {
if (mSelectedIndex >= 0) {
- View popup;
if (mPrevAnimatingView != null) mPrevAnimatingView.clearAnimation();
- if (mSelectedIndex == mBasicSettingPopups.length) {
- popup = mOtherSettingsPopup;
- } else {
- popup = mBasicSettingPopups[mSelectedIndex];
- }
- popup.startAnimation(mFadeOut);
- popup.setVisibility(View.INVISIBLE);
- mPrevAnimatingView = popup;
+ mSettingPopups[mSelectedIndex].startAnimation(mFadeOut);
+ mSettingPopups[mSelectedIndex].setVisibility(View.INVISIBLE);
+ mPrevAnimatingView = mSettingPopups[mSelectedIndex];
setHighlight(mSelectedIndex, false);
mSelectedIndex = -1;
invalidate();
@@ -560,11 +560,7 @@
public View getActivePopupWindow() {
if (mSelectedIndex >= 0) {
- if (mSelectedIndex == mBasicSettingPopups.length) {
- return mOtherSettingsPopup;
- } else {
- return mBasicSettingPopups[mSelectedIndex];
- }
+ return mSettingPopups[mSelectedIndex];
} else {
return null;
}
@@ -576,25 +572,26 @@
throw new IllegalArgumentException();
}
- if (mOtherSettingsPopup == null) {
- initializeOtherSettingPopup();
- }
-
+ // Override the setting indicator.
for (int i = 0; i < keyvalues.length; i += 2) {
String key = keyvalues[i];
String value = keyvalues[i + 1];
overrideSettings(key, value);
- mOtherSettingsPopup.overrideSettings(key, value);
+ }
+
+ // Override other settings.
+ if (mOtherSettingPrefKeys != null) {
+ int index = mPrefKeys.size();
+ if (mSettingPopups[index] == null) initializeSettingPopup(index);
+ OtherSettingsPopup popup = (OtherSettingsPopup) mSettingPopups[index];
+ popup.overrideSettings(keyvalues);
}
}
public void reloadPreferences() {
mPreferenceGroup.reloadValue();
- for (BasicSettingPopup popup: mBasicSettingPopups) {
+ for (AbstractSettingPopup popup: mSettingPopups) {
if (popup != null) popup.reloadPreference();
}
- if (mOtherSettingsPopup != null) {
- mOtherSettingsPopup.reloadPreference();
- }
}
}
diff --git a/src/com/android/camera/ui/OtherSettingsPopup.java b/src/com/android/camera/ui/OtherSettingsPopup.java
index 018eb1c..920d270 100644
--- a/src/com/android/camera/ui/OtherSettingsPopup.java
+++ b/src/com/android/camera/ui/OtherSettingsPopup.java
@@ -41,12 +41,6 @@
implements InLineSettingPicker.Listener,
AdapterView.OnItemClickListener {
private static final String TAG = "OtherSettingsPopup";
- private static final String[] OTHER_SETTING_KEYS = {
- CameraSettings.KEY_RECORD_LOCATION,
- CameraSettings.KEY_FOCUS_MODE,
- CameraSettings.KEY_EXPOSURE,
- CameraSettings.KEY_PICTURE_SIZE,
- CameraSettings.KEY_JPEG_QUALITY};
private static final String ITEM_KEY = "key";
private static final String ITEM_TITLE = "text";
private static final String ITEM_VALUE = "value";
@@ -100,7 +94,7 @@
}
}
- public void setOtherSettingChangedListener(Listener listener) {
+ public void setSettingChangedListener(Listener listener) {
mListener = listener;
}
@@ -109,12 +103,12 @@
mContext = context;
}
- public void initialize(PreferenceGroup group) {
+ public void initialize(PreferenceGroup group, String[] keys) {
mPreferenceGroup = group;
// Prepare the setting items.
- for (int i = 0; i < OTHER_SETTING_KEYS.length; ++i) {
+ for (int i = 0; i < keys.length; ++i) {
HashMap<String, Object> map = new HashMap<String, Object>();
- ListPreference pref = group.findPreference(OTHER_SETTING_KEYS[i]);
+ ListPreference pref = group.findPreference(keys[i]);
if (pref != null) {
map.put(ITEM_KEY, pref);
map.put(ITEM_TITLE, pref.getTitle());
@@ -145,14 +139,18 @@
}
// Scene mode can override other camera settings (ex: flash mode).
- public void overrideSettings(String key, String value) {
+ public void overrideSettings(final String ... keyvalues) {
int count = mSettingList.getChildCount();
- for (int i = 0; i < count; i++) {
- ListPreference pref = (ListPreference) mListItem.get(i).get(ITEM_KEY);
- if (pref != null && key.equals(pref.getKey())) {
- InLineSettingPicker picker =
- (InLineSettingPicker) mSettingList.getChildAt(i);
- picker.overrideSettings(value);
+ for (int i = 0; i < keyvalues.length; i += 2) {
+ String key = keyvalues[i];
+ String value = keyvalues[i + 1];
+ for (int j = 0; j < count; j++) {
+ ListPreference pref = (ListPreference) mListItem.get(j).get(ITEM_KEY);
+ if (pref != null && key.equals(pref.getKey())) {
+ InLineSettingPicker picker =
+ (InLineSettingPicker) mSettingList.getChildAt(j);
+ picker.overrideSettings(value);
+ }
}
}
}
@@ -165,6 +163,7 @@
}
}
+ @Override
public void reloadPreference() {
int count = mSettingList.getChildCount();
for (int i = 0; i < count; i++) {
diff --git a/src/com/android/camera/RotateImageView.java b/src/com/android/camera/ui/RotateImageView.java
similarity index 64%
rename from src/com/android/camera/RotateImageView.java
rename to src/com/android/camera/ui/RotateImageView.java
index 531169b..2d88a47 100644
--- a/src/com/android/camera/RotateImageView.java
+++ b/src/com/android/camera/ui/RotateImageView.java
@@ -14,33 +14,21 @@
* limitations under the License.
*/
-package com.android.camera;
+package com.android.camera.ui;
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
-import android.graphics.drawable.TransitionDrawable;
+import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.Rect;
+import android.graphics.drawable.TransitionDrawable;
import android.media.ThumbnailUtils;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
import android.util.AttributeSet;
-import android.util.Log;
-import android.view.animation.AnimationUtils;
import android.view.ViewGroup.LayoutParams;
+import android.view.animation.AnimationUtils;
import android.widget.ImageView;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
/**
* A @{code ImageView} which can rotate it's content.
*/
@@ -60,8 +48,6 @@
private long mAnimationStartTime = 0;
private long mAnimationEndTime = 0;
- private Uri mUri;
-
public RotateImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -137,79 +123,14 @@
private Drawable[] mThumbs;
private TransitionDrawable mThumbTransition;
- public void setData(Uri uri, Bitmap original) {
+ public void setBitmap(Bitmap bitmap) {
// Make sure uri and original are consistently both null or both
// non-null.
- if (uri == null || original == null) {
- uri = null;
- original = null;
- }
- mUri = uri;
- updateThumb(original);
- }
-
- public Uri getUri() {
- return mUri;
- }
-
- private static final int BUFSIZE = 4096;
-
- // Stores the data from the specified file.
- // Returns true for success.
- public boolean storeData(String filePath) {
- if (mUri == null) {
- return false;
- }
-
- FileOutputStream f = null;
- BufferedOutputStream b = null;
- DataOutputStream d = null;
- try {
- f = new FileOutputStream(filePath);
- b = new BufferedOutputStream(f, BUFSIZE);
- d = new DataOutputStream(b);
- d.writeUTF(mUri.toString());
- mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
- d.close();
- } catch (IOException e) {
- return false;
- } finally {
- Util.closeSilently(f);
- Util.closeSilently(b);
- Util.closeSilently(d);
- }
- return true;
- }
-
- // Loads the data from the specified file.
- // Returns true for success.
- public boolean loadData(String filePath) {
- FileInputStream f = null;
- BufferedInputStream b = null;
- DataInputStream d = null;
- try {
- f = new FileInputStream(filePath);
- b = new BufferedInputStream(f, BUFSIZE);
- d = new DataInputStream(b);
- Uri uri = Uri.parse(d.readUTF());
- Bitmap thumb = BitmapFactory.decodeStream(d);
- setData(uri, thumb);
- d.close();
- } catch (IOException e) {
- return false;
- } finally {
- Util.closeSilently(f);
- Util.closeSilently(b);
- Util.closeSilently(d);
- }
- return true;
- }
-
- private void updateThumb(Bitmap original) {
- if (original == null) {
+ if (bitmap == null) {
mThumb = null;
mThumbs = null;
setImageDrawable(null);
+ setVisibility(GONE);
return;
}
@@ -219,7 +140,7 @@
final int miniThumbHeight = param.height
- getPaddingTop() - getPaddingBottom();
mThumb = ThumbnailUtils.extractThumbnail(
- original, miniThumbWidth, miniThumbHeight);
+ bitmap, miniThumbWidth, miniThumbHeight);
Drawable drawable;
if (mThumbs == null || !mEnableAnimation) {
mThumbs = new Drawable[2];
@@ -232,23 +153,6 @@
setImageDrawable(mThumbTransition);
mThumbTransition.startTransition(500);
}
- }
-
- public boolean isUriValid() {
- if (mUri == null) {
- return false;
- }
- try {
- ParcelFileDescriptor pfd =
- getContext().getContentResolver().openFileDescriptor(mUri, "r");
- if (pfd == null) {
- Log.e(TAG, "Fail to open URI. URI=" + mUri);
- return false;
- }
- pfd.close();
- } catch (IOException ex) {
- return false;
- }
- return true;
+ setVisibility(VISIBLE);
}
}
diff --git a/tests/src/com/android/camera/functional/CameraTest.java b/tests/src/com/android/camera/functional/CameraTest.java
index 9d71301..5d2fd2d 100644
--- a/tests/src/com/android/camera/functional/CameraTest.java
+++ b/tests/src/com/android/camera/functional/CameraTest.java
@@ -1,6 +1,23 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.camera.functional;
import com.android.camera.Camera;
+import com.android.camera.R;
import com.android.camera.VideoCamera;
import android.app.Activity;
@@ -12,6 +29,7 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
+import android.view.KeyEvent;
import java.io.File;
import java.lang.ref.WeakReference;
diff --git a/tests/src/com/android/camera/functional/ImageCaptureIntentTest.java b/tests/src/com/android/camera/functional/ImageCaptureIntentTest.java
new file mode 100644
index 0000000..e9067be
--- /dev/null
+++ b/tests/src/com/android/camera/functional/ImageCaptureIntentTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera.functional;
+
+import com.android.camera.Camera;
+import com.android.camera.R;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.UiThreadTest;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+public class ImageCaptureIntentTest extends ActivityInstrumentationTestCase2 <Camera> {
+ private static final String TAG = "ImageCaptureIntentTest";
+ private Intent mIntent;
+
+ public ImageCaptureIntentTest() {
+ super(Camera.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ }
+
+ @LargeTest
+ public void testNoExtraOutput() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ takePicture();
+ pressDone();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
+ Intent resultData = getActivity().getResultData();
+ Bitmap bitmap = (Bitmap) resultData.getParcelableExtra("data");
+ assertNotNull(bitmap);
+ assertTrue(bitmap.getWidth() > 0);
+ assertTrue(bitmap.getHeight() > 0);
+ }
+
+ @LargeTest
+ public void testExtraOutput() throws Exception {
+ File file = new File(Environment.getExternalStorageDirectory(),
+ "test.jpg");
+ BufferedInputStream stream = null;
+ byte[] jpegData;
+
+ try {
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
+ setActivityIntent(mIntent);
+ getActivity();
+
+ takePicture();
+ pressDone();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
+
+ // Verify the jpeg file
+ int fileLength = (int) file.length();
+ assertTrue(fileLength > 0);
+ jpegData = new byte[fileLength];
+ stream = new BufferedInputStream(new FileInputStream(file));
+ stream.read(jpegData);
+ } finally {
+ if (stream != null) stream.close();
+ file.delete();
+ }
+
+ Bitmap b = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
+ assertTrue(b.getWidth() > 0);
+ assertTrue(b.getHeight() > 0);
+ }
+
+ @LargeTest
+ public void testRetake() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ takePicture();
+ pressRetake();
+ takePicture();
+ pressDone();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
+ Intent resultData = getActivity().getResultData();
+ Bitmap bitmap = (Bitmap) resultData.getParcelableExtra("data");
+ assertNotNull(bitmap);
+ assertTrue(bitmap.getWidth() > 0);
+ assertTrue(bitmap.getHeight() > 0);
+ }
+
+ @LargeTest
+ public void testCancel() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ pressCancel();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
+ }
+
+ @LargeTest
+ public void testSnapshotCancel() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ takePicture();
+ pressCancel();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
+ }
+
+ private void takePicture() throws Exception {
+ getInstrumentation().sendKeySync(
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS));
+ getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
+ Thread.sleep(4000);
+ }
+
+ private void pressDone() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_done).performClick();
+ }
+ });
+ }
+
+ private void pressRetake() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_retake).performClick();
+ }
+ });
+ }
+
+ private void pressCancel() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_cancel).performClick();
+ }
+ });
+ }
+}
diff --git a/tests/src/com/android/camera/functional/VideoCaptureIntentTest.java b/tests/src/com/android/camera/functional/VideoCaptureIntentTest.java
new file mode 100644
index 0000000..b2a007e
--- /dev/null
+++ b/tests/src/com/android/camera/functional/VideoCaptureIntentTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera.functional;
+
+import com.android.camera.VideoCamera;
+import com.android.camera.R;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+import android.media.MediaMetadataRetriever;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Video.VideoColumns;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.UiThreadTest;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.net.URI;
+
+public class VideoCaptureIntentTest extends ActivityInstrumentationTestCase2 <VideoCamera> {
+ private static final String TAG = "VideoCaptureIntentTest";
+ private Intent mIntent;
+ private Uri mVideoUri;
+ private File mFile, mFile2;
+
+ public VideoCaptureIntentTest() {
+ super(VideoCamera.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mVideoUri != null) {
+ ContentResolver resolver = getActivity().getContentResolver();
+ Uri query = mVideoUri.buildUpon().build();
+ String[] projection = new String[] {VideoColumns.DATA};
+
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(query, projection, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ new File(cursor.getString(0)).delete();
+ }
+ } finally {
+ if (cursor != null) cursor.close();
+ }
+
+ resolver.delete(mVideoUri, null, null);
+ }
+ if (mFile != null) mFile.delete();
+ if (mFile2 != null) mFile2.delete();
+ super.tearDown();
+ }
+
+ @LargeTest
+ public void testNoExtraOutput() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressDone();
+
+ Intent resultData = getActivity().getResultData();
+ mVideoUri = resultData.getData();
+ assertNotNull(mVideoUri);
+ verify(getActivity(), mVideoUri);
+ }
+
+ @LargeTest
+ public void testExtraOutput() throws Exception {
+ mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
+
+ Uri uri = Uri.fromFile(mFile);
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressDone();
+
+ verify(getActivity(), uri);
+ }
+
+ @LargeTest
+ public void testRetake() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressRetake();
+ recordVideo();
+ pressDone();
+
+ Intent resultData = getActivity().getResultData();
+ mVideoUri = resultData.getData();
+ assertNotNull(mVideoUri);
+ verify(getActivity(), mVideoUri);
+ }
+
+ @LargeTest
+ public void testCancel() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ pressCancel();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
+ }
+
+ @LargeTest
+ public void testRecordCancel() throws Exception {
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressCancel();
+
+ assertTrue(getActivity().isFinishing());
+ assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
+ }
+
+ @LargeTest
+ public void testExtraSizeLimit() throws Exception {
+ mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
+ final long sizeLimit = 10000; // bytes
+
+ Uri uri = Uri.fromFile(mFile);
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo(5000);
+ pressDone();
+
+ verify(getActivity(), uri);
+ long length = mFile.length();
+ Log.v(TAG, "Video size is " + length + " bytes.");
+ assertTrue(length > 0);
+ assertTrue("Actual size=" + length, length <= sizeLimit);
+ }
+
+ @LargeTest
+ public void testExtraDurationLimit() throws Exception {
+ mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
+ final int durationLimit = 2; // seconds
+
+ Uri uri = Uri.fromFile(mFile);
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo(5000);
+ pressDone();
+
+ int duration = verify(getActivity(), uri);
+ // The duraion should be close to to the limit. The last video duration
+ // also has duration, so the total duration may exceeds the limit a
+ // little bit.
+ Log.v(TAG, "Video length is " + duration + " ms.");
+ assertTrue(duration < (durationLimit + 1) * 1000);
+ }
+
+ @LargeTest
+ public void testExtraVideoQuality() throws Exception {
+ mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
+ mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp");
+
+ Uri uri = Uri.fromFile(mFile);
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressDone();
+
+ verify(getActivity(), uri);
+ setActivity(null);
+
+ uri = Uri.fromFile(mFile2);
+ mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality
+ setActivityIntent(mIntent);
+ getActivity();
+
+ recordVideo();
+ pressDone();
+
+ verify(getActivity(), uri);
+ assertTrue(mFile.length() <= mFile2.length());
+ }
+
+ // Verify result code, result data, and the duration.
+ private int verify(VideoCamera activity, Uri uri) throws Exception {
+ assertTrue(activity.isFinishing());
+ assertEquals(Activity.RESULT_OK, activity.getResultCode());
+
+ // Verify the video file
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ retriever.setDataSource(activity, uri);
+ String duration = retriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_DURATION);
+ assertNotNull(duration);
+ int durationValue = Integer.parseInt(duration);
+ Log.v(TAG, "Video duration is " + durationValue);
+ assertTrue(durationValue > 0);
+ return durationValue;
+ }
+
+ private void recordVideo(int ms) throws Exception {
+ getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
+ Thread.sleep(ms);
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ // If recording is in progress, stop it. Run these atomically in
+ // UI thread.
+ if (getActivity().isRecording()) {
+ getActivity().findViewById(R.id.shutter_button).performClick();
+ }
+ }
+ });
+ }
+
+ private void recordVideo() throws Exception {
+ recordVideo(2000);
+ }
+
+ private void pressDone() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_done).performClick();
+ }
+ });
+ }
+
+ private void pressRetake() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_retake).performClick();
+ }
+ });
+ }
+
+ private void pressCancel() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ getActivity().findViewById(R.id.btn_cancel).performClick();
+ }
+ });
+ }
+}
diff --git a/tests/src/com/android/camera/stress/CameraStartUp.java b/tests/src/com/android/camera/stress/CameraStartUp.java
index 3e1ae25..781093d 100644
--- a/tests/src/com/android/camera/stress/CameraStartUp.java
+++ b/tests/src/com/android/camera/stress/CameraStartUp.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.camera.stress;
import com.android.camera.Camera;
diff --git a/tests/src/com/android/camera/unittest/CameraTest.java b/tests/src/com/android/camera/unittest/CameraTest.java
index 0e851e4..b0aa13b 100644
--- a/tests/src/com/android/camera/unittest/CameraTest.java
+++ b/tests/src/com/android/camera/unittest/CameraTest.java
@@ -1,7 +1,24 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.camera.unittest;
import com.android.camera.Camera;
+import android.graphics.Rect;
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -23,4 +40,20 @@
assertEquals(0, Camera.roundOrientation(270 + 45));
assertEquals(0, Camera.roundOrientation(359));
}
+
+ public void testConvertToFocusArea() {
+ Rect rect = new Rect();
+ Camera.convertToFocusArea(0, 0, 100, 100, 800, 480, rect);
+ assertEquals(new Rect(-1000, -1000, -750, -583), rect);
+ Camera.convertToFocusArea(0, 0, 400, 240, 800, 480, rect);
+ assertEquals(new Rect(-1000, -1000, 0, 0), rect);
+ Camera.convertToFocusArea(400, 240, 400, 240, 800, 480, rect);
+ assertEquals(new Rect(0, 0, 1000, 1000), rect);
+ Camera.convertToFocusArea(200, 120, 400, 240, 800, 480, rect);
+ assertEquals(new Rect(-500, -500, 500, 500), rect);
+ Camera.convertToFocusArea(0, 0, 800, 480, 800, 480, rect);
+ assertEquals(new Rect(-1000, -1000, 1000, 1000), rect);
+ Camera.convertToFocusArea(860, 620, 100, 100, 960, 720, rect);
+ assertEquals(new Rect(792, 722, 1000, 1000), rect);
+ }
}