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">&gt;</string>
     <string name="setting_decrement" translatable="false">&lt;</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);
+    }
 }