summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/dependency.json58
-rwxr-xr-xres/drawable-hdpi/bar_beautify_rectangle_blue.pngbin0 -> 177 bytes
-rwxr-xr-xres/drawable-hdpi/bar_beautify_rectangle_white.pngbin0 -> 213 bytes
-rwxr-xr-xres/drawable-hdpi/ic_beautify_oval.pngbin0 -> 699 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_auto.pngbin0 -> 15909 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_backlight.pngbin0 -> 16619 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_beach.pngbin0 -> 16872 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_best_photo.pngbin0 -> 16748 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_blur_buster.pngbin0 -> 16951 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_candlelight.pngbin0 -> 16162 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_chroma_flash.pngbin0 -> 16378 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_dual_camera.pngbin0 -> 17729 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_flowers.pngbin0 -> 16751 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_hdr.pngbin0 -> 16507 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_landscape.pngbin0 -> 15962 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_night.pngbin0 -> 16104 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_optizoom.pngbin0 -> 16078 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_panorama.pngbin0 -> 16353 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_portrait.pngbin0 -> 16157 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_pro_mode.pngbin0 -> 15799 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_sharp_photo.pngbin0 -> 16431 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_snow.pngbin0 -> 16669 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_sports.pngbin0 -> 16644 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_sunset.pngbin0 -> 16147 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_time_lapse.pngbin0 -> 15712 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_tracking_focus.pngbin0 -> 16118 bytes
-rw-r--r--res/drawable-hdpi/ic_scene_mode_black_ubifocus.pngbin0 -> 16780 bytes
-rwxr-xr-xres/drawable-mdpi/bar_beautify_rectangle_blue.pngbin0 -> 125 bytes
-rwxr-xr-xres/drawable-mdpi/bar_beautify_rectangle_white.pngbin0 -> 133 bytes
-rwxr-xr-xres/drawable-mdpi/ic_beautify_oval.pngbin0 -> 348 bytes
-rw-r--r--res/drawable/auto_blue.pngbin0 -> 15604 bytes
-rwxr-xr-xres/drawable/beautify_progressbar_style.xml35
-rw-r--r--res/drawable/cloudy.pngbin0 -> 15579 bytes
-rw-r--r--res/drawable/cloudy_blue.pngbin0 -> 16055 bytes
-rw-r--r--res/drawable/fluorescent.pngbin0 -> 15489 bytes
-rw-r--r--res/drawable/fluorescent_blue.pngbin0 -> 15780 bytes
-rw-r--r--res/drawable/icon_exposure.pngbin0 -> 15376 bytes
-rw-r--r--res/drawable/icon_exposure_blue.pngbin0 -> 15822 bytes
-rw-r--r--res/drawable/icon_iso.pngbin0 -> 15154 bytes
-rw-r--r--res/drawable/icon_iso_blue.pngbin0 -> 15587 bytes
-rw-r--r--res/drawable/icon_manual.pngbin0 -> 15598 bytes
-rw-r--r--res/drawable/icon_manual_blue.pngbin0 -> 16161 bytes
-rw-r--r--res/drawable/icon_white_balance.pngbin0 -> 15152 bytes
-rw-r--r--res/drawable/icon_white_balance_blue.pngbin0 -> 15610 bytes
-rw-r--r--res/drawable/icon_x.pngbin0 -> 14900 bytes
-rw-r--r--res/drawable/incandecent.pngbin0 -> 15932 bytes
-rw-r--r--res/drawable/incandecent_blue.pngbin0 -> 16688 bytes
-rw-r--r--res/drawable/promode.pngbin0 -> 15598 bytes
-rw-r--r--res/drawable/radial_menu.pngbin0 -> 29304 bytes
-rw-r--r--res/drawable/selected_dot.pngbin0 -> 15155 bytes
-rw-r--r--res/drawable/sunlight.pngbin0 -> 16575 bytes
-rw-r--r--res/drawable/sunlight_blue.pngbin0 -> 17676 bytes
-rw-r--r--res/drawable/white_dot.pngbin0 -> 14571 bytes
-rwxr-xr-x[-rw-r--r--]res/layout/bestpicture_page.xml6
-rwxr-xr-x[-rw-r--r--]res/layout/capture_module.xml31
-rwxr-xr-x[-rw-r--r--]res/layout/one_ui_layout.xml79
-rw-r--r--res/layout/pano_capture_module.xml4
-rw-r--r--res/layout/pro_mode_layout.xml148
-rw-r--r--res/layout/scene_mode_instructional.xml102
-rw-r--r--res/layout/scene_mode_label.xml56
-rw-r--r--res/values/camera2arrays.xml56
-rwxr-xr-x[-rw-r--r--]res/values/dimens.xml3
-rw-r--r--res/values/qcomstrings.xml32
-rw-r--r--res/values/styles.xml14
-rw-r--r--res/xml/capture_preferences.xml8
-rw-r--r--res/xml/setting_menu_preferences.xml13
-rwxr-xr-x[-rw-r--r--]rs/rotator.rs29
-rw-r--r--[-rwxr-xr-x]src/com/android/camera/AndroidCameraManagerImpl.java26
-rw-r--r--src/com/android/camera/CameraActivity.java84
-rw-r--r--src/com/android/camera/CameraSettings.java4
-rw-r--r--src/com/android/camera/CaptureModule.java623
-rw-r--r--src/com/android/camera/CaptureUI.java282
-rw-r--r--src/com/android/camera/ComboPreferences.java4
-rw-r--r--src/com/android/camera/PanoCaptureModule.java4
-rw-r--r--src/com/android/camera/PanoCaptureUI.java132
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/PauseButton.java4
-rw-r--r--src/com/android/camera/PhotoModule.java13
-rw-r--r--src/com/android/camera/PhotoUI.java2
-rw-r--r--src/com/android/camera/RecordLocationPreference.java11
-rw-r--r--src/com/android/camera/SettingsActivity.java37
-rw-r--r--src/com/android/camera/SettingsManager.java84
-rw-r--r--src/com/android/camera/VideoModule.java6
-rw-r--r--src/com/android/camera/VideoUI.java2
-rw-r--r--src/com/android/camera/WideAnglePanoramaModule.java3
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/imageprocessor/FrameProcessor.java12
-rw-r--r--src/com/android/camera/ui/CameraControls.java1
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/ui/CountDownView.java11
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/ui/OneUICameraControls.java217
-rw-r--r--src/com/android/camera/ui/PanoCaptureProcessView.java30
-rw-r--r--src/com/android/camera/ui/ProMode.java378
-rw-r--r--src/com/android/camera/util/CameraUtil.java94
-rwxr-xr-x[-rw-r--r--]src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java35
92 files changed, 2483 insertions, 290 deletions
diff --git a/assets/dependency.json b/assets/dependency.json
index b8c396895..cbc96587d 100644
--- a/assets/dependency.json
+++ b/assets/dependency.json
@@ -42,15 +42,69 @@
"100":
{"pref_camera2_longshot_key":"off",
"pref_camera2_mono_only_key":"off",
- "pref_camera2_flashmode_key":"off"}
+ "pref_camera2_flashmode_key":"off",
+ "pref_camera2_coloreffect_key":"0"}
,
"0":
{"pref_camera2_clearsight_key":"off",
"pref_camera2_mono_preview_key":"off",
"pref_camera2_mpo_key":"off"}
,
+ "18":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "102":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "101":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "3":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "4":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "13":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "15":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "10":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "5":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "8":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "9":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "103":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "104":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
"105":
- {"pref_camera2_flashmode_key":"off"}
+ {"pref_camera2_flashmode_key":"off",
+ "pref_camera2_coloreffect_key":"0",
+ "pref_camera2_longshot_key":"off"}
+ ,
+ "106":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "107":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "108":
+ {"pref_camera2_coloreffect_key":"0"}
+ ,
+ "109":
+ {"pref_camera2_coloreffect_key":"0"}
},
"pref_camera2_clearsight_key":
{
diff --git a/res/drawable-hdpi/bar_beautify_rectangle_blue.png b/res/drawable-hdpi/bar_beautify_rectangle_blue.png
new file mode 100755
index 000000000..37b6cdafb
--- /dev/null
+++ b/res/drawable-hdpi/bar_beautify_rectangle_blue.png
Binary files differ
diff --git a/res/drawable-hdpi/bar_beautify_rectangle_white.png b/res/drawable-hdpi/bar_beautify_rectangle_white.png
new file mode 100755
index 000000000..06bc65042
--- /dev/null
+++ b/res/drawable-hdpi/bar_beautify_rectangle_white.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_beautify_oval.png b/res/drawable-hdpi/ic_beautify_oval.png
new file mode 100755
index 000000000..be86fdc03
--- /dev/null
+++ b/res/drawable-hdpi/ic_beautify_oval.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_auto.png b/res/drawable-hdpi/ic_scene_mode_black_auto.png
new file mode 100644
index 000000000..3f68e8e47
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_auto.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_backlight.png b/res/drawable-hdpi/ic_scene_mode_black_backlight.png
new file mode 100644
index 000000000..a70502f79
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_backlight.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_beach.png b/res/drawable-hdpi/ic_scene_mode_black_beach.png
new file mode 100644
index 000000000..d66a5ff23
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_beach.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_best_photo.png b/res/drawable-hdpi/ic_scene_mode_black_best_photo.png
new file mode 100644
index 000000000..5ddd1aac2
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_best_photo.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_blur_buster.png b/res/drawable-hdpi/ic_scene_mode_black_blur_buster.png
new file mode 100644
index 000000000..a5b930f5e
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_blur_buster.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_candlelight.png b/res/drawable-hdpi/ic_scene_mode_black_candlelight.png
new file mode 100644
index 000000000..cc8606e09
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_candlelight.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_chroma_flash.png b/res/drawable-hdpi/ic_scene_mode_black_chroma_flash.png
new file mode 100644
index 000000000..9c8c1108e
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_chroma_flash.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_dual_camera.png b/res/drawable-hdpi/ic_scene_mode_black_dual_camera.png
new file mode 100644
index 000000000..16b803601
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_dual_camera.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_flowers.png b/res/drawable-hdpi/ic_scene_mode_black_flowers.png
new file mode 100644
index 000000000..527329e75
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_flowers.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_hdr.png b/res/drawable-hdpi/ic_scene_mode_black_hdr.png
new file mode 100644
index 000000000..3baa45485
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_hdr.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_landscape.png b/res/drawable-hdpi/ic_scene_mode_black_landscape.png
new file mode 100644
index 000000000..45a247e8d
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_landscape.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_night.png b/res/drawable-hdpi/ic_scene_mode_black_night.png
new file mode 100644
index 000000000..6cf2ce8eb
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_night.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_optizoom.png b/res/drawable-hdpi/ic_scene_mode_black_optizoom.png
new file mode 100644
index 000000000..331705738
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_optizoom.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_panorama.png b/res/drawable-hdpi/ic_scene_mode_black_panorama.png
new file mode 100644
index 000000000..38c4a1b39
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_panorama.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_portrait.png b/res/drawable-hdpi/ic_scene_mode_black_portrait.png
new file mode 100644
index 000000000..564e3da51
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_portrait.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_pro_mode.png b/res/drawable-hdpi/ic_scene_mode_black_pro_mode.png
new file mode 100644
index 000000000..bb9cd76ac
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_pro_mode.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_sharp_photo.png b/res/drawable-hdpi/ic_scene_mode_black_sharp_photo.png
new file mode 100644
index 000000000..a475cc724
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_sharp_photo.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_snow.png b/res/drawable-hdpi/ic_scene_mode_black_snow.png
new file mode 100644
index 000000000..2ac492c08
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_snow.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_sports.png b/res/drawable-hdpi/ic_scene_mode_black_sports.png
new file mode 100644
index 000000000..932be9821
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_sports.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_sunset.png b/res/drawable-hdpi/ic_scene_mode_black_sunset.png
new file mode 100644
index 000000000..68b653527
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_sunset.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_time_lapse.png b/res/drawable-hdpi/ic_scene_mode_black_time_lapse.png
new file mode 100644
index 000000000..868e51d3d
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_time_lapse.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_tracking_focus.png b/res/drawable-hdpi/ic_scene_mode_black_tracking_focus.png
new file mode 100644
index 000000000..e86a330c2
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_tracking_focus.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_scene_mode_black_ubifocus.png b/res/drawable-hdpi/ic_scene_mode_black_ubifocus.png
new file mode 100644
index 000000000..eb174e728
--- /dev/null
+++ b/res/drawable-hdpi/ic_scene_mode_black_ubifocus.png
Binary files differ
diff --git a/res/drawable-mdpi/bar_beautify_rectangle_blue.png b/res/drawable-mdpi/bar_beautify_rectangle_blue.png
new file mode 100755
index 000000000..454787c9c
--- /dev/null
+++ b/res/drawable-mdpi/bar_beautify_rectangle_blue.png
Binary files differ
diff --git a/res/drawable-mdpi/bar_beautify_rectangle_white.png b/res/drawable-mdpi/bar_beautify_rectangle_white.png
new file mode 100755
index 000000000..70b4c951f
--- /dev/null
+++ b/res/drawable-mdpi/bar_beautify_rectangle_white.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_beautify_oval.png b/res/drawable-mdpi/ic_beautify_oval.png
new file mode 100755
index 000000000..373a99a28
--- /dev/null
+++ b/res/drawable-mdpi/ic_beautify_oval.png
Binary files differ
diff --git a/res/drawable/auto_blue.png b/res/drawable/auto_blue.png
new file mode 100644
index 000000000..acf632e16
--- /dev/null
+++ b/res/drawable/auto_blue.png
Binary files differ
diff --git a/res/drawable/beautify_progressbar_style.xml b/res/drawable/beautify_progressbar_style.xml
new file mode 100755
index 000000000..962d8dedb
--- /dev/null
+++ b/res/drawable/beautify_progressbar_style.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@android:id/background"
+ android:drawable="@drawable/bar_beautify_rectangle_white" />
+ <item android:id="@android:id/progress">
+ <clip android:drawable="@drawable/bar_beautify_rectangle_blue" />
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/res/drawable/cloudy.png b/res/drawable/cloudy.png
new file mode 100644
index 000000000..b29ab9e5d
--- /dev/null
+++ b/res/drawable/cloudy.png
Binary files differ
diff --git a/res/drawable/cloudy_blue.png b/res/drawable/cloudy_blue.png
new file mode 100644
index 000000000..303a2703e
--- /dev/null
+++ b/res/drawable/cloudy_blue.png
Binary files differ
diff --git a/res/drawable/fluorescent.png b/res/drawable/fluorescent.png
new file mode 100644
index 000000000..d25f7473e
--- /dev/null
+++ b/res/drawable/fluorescent.png
Binary files differ
diff --git a/res/drawable/fluorescent_blue.png b/res/drawable/fluorescent_blue.png
new file mode 100644
index 000000000..7fb7836dd
--- /dev/null
+++ b/res/drawable/fluorescent_blue.png
Binary files differ
diff --git a/res/drawable/icon_exposure.png b/res/drawable/icon_exposure.png
new file mode 100644
index 000000000..ff5397251
--- /dev/null
+++ b/res/drawable/icon_exposure.png
Binary files differ
diff --git a/res/drawable/icon_exposure_blue.png b/res/drawable/icon_exposure_blue.png
new file mode 100644
index 000000000..544b98ab4
--- /dev/null
+++ b/res/drawable/icon_exposure_blue.png
Binary files differ
diff --git a/res/drawable/icon_iso.png b/res/drawable/icon_iso.png
new file mode 100644
index 000000000..85662af5e
--- /dev/null
+++ b/res/drawable/icon_iso.png
Binary files differ
diff --git a/res/drawable/icon_iso_blue.png b/res/drawable/icon_iso_blue.png
new file mode 100644
index 000000000..001d8c9f5
--- /dev/null
+++ b/res/drawable/icon_iso_blue.png
Binary files differ
diff --git a/res/drawable/icon_manual.png b/res/drawable/icon_manual.png
new file mode 100644
index 000000000..53e2ff5ec
--- /dev/null
+++ b/res/drawable/icon_manual.png
Binary files differ
diff --git a/res/drawable/icon_manual_blue.png b/res/drawable/icon_manual_blue.png
new file mode 100644
index 000000000..52b2daa19
--- /dev/null
+++ b/res/drawable/icon_manual_blue.png
Binary files differ
diff --git a/res/drawable/icon_white_balance.png b/res/drawable/icon_white_balance.png
new file mode 100644
index 000000000..1fbd36fd3
--- /dev/null
+++ b/res/drawable/icon_white_balance.png
Binary files differ
diff --git a/res/drawable/icon_white_balance_blue.png b/res/drawable/icon_white_balance_blue.png
new file mode 100644
index 000000000..ca84b89d8
--- /dev/null
+++ b/res/drawable/icon_white_balance_blue.png
Binary files differ
diff --git a/res/drawable/icon_x.png b/res/drawable/icon_x.png
new file mode 100644
index 000000000..a807409c8
--- /dev/null
+++ b/res/drawable/icon_x.png
Binary files differ
diff --git a/res/drawable/incandecent.png b/res/drawable/incandecent.png
new file mode 100644
index 000000000..d601e4b5c
--- /dev/null
+++ b/res/drawable/incandecent.png
Binary files differ
diff --git a/res/drawable/incandecent_blue.png b/res/drawable/incandecent_blue.png
new file mode 100644
index 000000000..0c3eabf13
--- /dev/null
+++ b/res/drawable/incandecent_blue.png
Binary files differ
diff --git a/res/drawable/promode.png b/res/drawable/promode.png
new file mode 100644
index 000000000..53e2ff5ec
--- /dev/null
+++ b/res/drawable/promode.png
Binary files differ
diff --git a/res/drawable/radial_menu.png b/res/drawable/radial_menu.png
new file mode 100644
index 000000000..a5757f1a0
--- /dev/null
+++ b/res/drawable/radial_menu.png
Binary files differ
diff --git a/res/drawable/selected_dot.png b/res/drawable/selected_dot.png
new file mode 100644
index 000000000..9114f6ce6
--- /dev/null
+++ b/res/drawable/selected_dot.png
Binary files differ
diff --git a/res/drawable/sunlight.png b/res/drawable/sunlight.png
new file mode 100644
index 000000000..cc33dcc3d
--- /dev/null
+++ b/res/drawable/sunlight.png
Binary files differ
diff --git a/res/drawable/sunlight_blue.png b/res/drawable/sunlight_blue.png
new file mode 100644
index 000000000..c390ec653
--- /dev/null
+++ b/res/drawable/sunlight_blue.png
Binary files differ
diff --git a/res/drawable/white_dot.png b/res/drawable/white_dot.png
new file mode 100644
index 000000000..847fd84fe
--- /dev/null
+++ b/res/drawable/white_dot.png
Binary files differ
diff --git a/res/layout/bestpicture_page.xml b/res/layout/bestpicture_page.xml
index d6b6022c8..5a1b604f0 100644..100755
--- a/res/layout/bestpicture_page.xml
+++ b/res/layout/bestpicture_page.xml
@@ -34,9 +34,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<ImageView
android:id="@+id/image_view"
android:adjustViewBounds="true"
- android:scaleType="fitXY"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:scaleType="fitCenter"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="match_parent"
diff --git a/res/layout/capture_module.xml b/res/layout/capture_module.xml
index fc05fd0ca..44d5c59c6 100644..100755
--- a/res/layout/capture_module.xml
+++ b/res/layout/capture_module.xml
@@ -67,30 +67,27 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <com.android.camera.ui.RotateLayout
- android:id="@+id/recording_time_rect"
+
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/recording_time_rect"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <com.android.camera.PauseButton
- android:id="@+id/video_pause"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="70dp"
- android:padding="23dp"
- android:src="@drawable/btn_pause_recording"/>
-
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:visibility="gone"
+ android:layout_marginLeft="24dp"
+ android:layout_marginTop="80dp">
<include
android:id="@+id/labels"
layout="@layout/viewfinder_labels_video"/>
- </LinearLayout>
- </com.android.camera.ui.RotateLayout>
+ </com.android.camera.ui.RotateLayout>
+ </FrameLayout>
+
+ <include
+ layout="@layout/scene_mode_label"/>
<include
style="@style/CameraControls"
diff --git a/res/layout/one_ui_layout.xml b/res/layout/one_ui_layout.xml
index 2a87b6cd2..53174698c 100644..100755
--- a/res/layout/one_ui_layout.xml
+++ b/res/layout/one_ui_layout.xml
@@ -21,6 +21,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <com.android.camera.ui.ProMode
+ android:id="@+id/promode_slider"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
<com.android.camera.ui.FlashToggleButton
android:id="@+id/flash_button"
style="@style/OneUIMenuButton"
@@ -35,8 +40,8 @@
<com.android.camera.ShutterButton
android:id="@+id/shutter_button"
- android:layout_width="70dp"
- android:layout_height="70dp"
+ android:layout_width="@dimen/one_ui_bottom_large"
+ android:layout_height="@dimen/one_ui_bottom_large"
android:clickable="true"
android:contentDescription="@string/accessibility_shutter_button"
android:focusable="true"
@@ -45,14 +50,24 @@
<com.android.camera.ui.RotateImageView
android:id="@+id/video_button"
- android:layout_width="55dp"
- android:layout_height="55dp"
+ android:layout_width="@dimen/one_ui_bottom_small"
+ android:layout_height="@dimen/one_ui_bottom_small"
android:clickable="true"
android:contentDescription="@string/accessibility_shutter_button"
android:focusable="true"
android:scaleType="fitCenter"
android:src="@drawable/video_capture" />
+ <com.android.camera.PauseButton
+ android:id="@+id/video_pause"
+ android:layout_width="@dimen/one_ui_bottom_small"
+ android:layout_height="@dimen/one_ui_bottom_small"
+ android:focusable="true"
+ android:clickable="true"
+ android:scaleType="fitCenter"
+ android:visibility="gone"
+ android:src="@drawable/btn_pause_recording"/>
+
<com.android.camera.ui.RotateImageView
android:id="@+id/preview_thumb"
android:layout_width="@dimen/capture_size"
@@ -91,42 +106,53 @@
android:id="@+id/makeup_seekbar_layout"
android:visibility="gone">
<ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="5dp"
- android:paddingRight="5dp"
+ android:layout_width="12dp"
+ android:layout_height="20dp"
+ android:layout_marginLeft="23dp"
+ android:layout_marginRight="23dp"
android:id="@+id/seekbar_toggle">
</ImageView>
<RelativeLayout
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/seekbar_body">
<com.android.camera.ui.RotateLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
android:layout_alignParentLeft="true"
android:id="@+id/makeup_low_text">
<TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/makeup_seekbar_low">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="12sp"
+ android:gravity="center"
+ android:text="@string/makeup_seekbar_low"
+ android:textColor="@android:color/white">
</TextView>
</com.android.camera.ui.RotateLayout>
<SeekBar
- android:layout_width="match_parent"
+ android:layout_width="220dp"
android:layout_height="wrap_content"
- android:paddingLeft="100dp"
- android:paddingRight="100dp"
+ android:maxHeight="3dip"
+ android:minHeight="1dip"
+ android:layout_marginLeft="10dp"
+ android:layout_toRightOf="@+id/makeup_low_text"
+ android:progressDrawable="@drawable/beautify_progressbar_style"
+ android:thumb="@drawable/ic_beautify_oval"
android:id="@+id/makeup_seekbar"/>
<com.android.camera.ui.RotateLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_toRightOf="@+id/makeup_seekbar"
+ android:layout_marginLeft="10dp"
android:id="@+id/makeup_high_text">
<TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/makeup_seekbar_high">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="12sp"
+ android:gravity="center"
+ android:text="@string/makeup_seekbar_high"
+ android:textColor="@android:color/white">
</TextView>
</com.android.camera.ui.RotateLayout>
</RelativeLayout>
@@ -156,4 +182,11 @@
android:visibility="gone" />
</LinearLayout>
+ <include layout="@layout/pro_mode_layout" />
+
+ <ImageView
+ android:id="@+id/promode_close_button"
+ android:layout_height="20dp"
+ android:layout_width="20dp"
+ android:src="@drawable/icon_x" />
</com.android.camera.ui.OneUICameraControls>
diff --git a/res/layout/pano_capture_module.xml b/res/layout/pano_capture_module.xml
index e382570ef..c8809af37 100644
--- a/res/layout/pano_capture_module.xml
+++ b/res/layout/pano_capture_module.xml
@@ -34,6 +34,10 @@
android:id="@+id/preview_process_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
+
+ <include
+ layout="@layout/scene_mode_label"/>
+
<include
style="@style/CameraControls"
layout="@layout/camera_controls"
diff --git a/res/layout/pro_mode_layout.xml b/res/layout/pro_mode_layout.xml
new file mode 100644
index 000000000..54ccb556c
--- /dev/null
+++ b/res/layout/pro_mode_layout.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/pro_mode_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="invisible">
+
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/exposure_rotate_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:id="@+id/exposure_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/exposure"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:src="@drawable/icon_exposure" />
+
+ <TextView
+ android:id="@+id/exposure_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/manual_rotate_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:id="@+id/manual_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/manual"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:src="@drawable/icon_manual" />
+
+ <TextView
+ android:id="@+id/manual_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/white_balance_rotate_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:id="@+id/white_balance_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/white_balance"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:src="@drawable/icon_white_balance" />
+
+ <TextView
+ android:id="@+id/white_balance_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/iso_rotate_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:id="@+id/iso_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/iso"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:layout_gravity="center"
+ android:src="@drawable/icon_iso" />
+
+ <TextView
+ android:id="@+id/iso_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+
+</LinearLayout>
diff --git a/res/layout/scene_mode_instructional.xml b/res/layout/scene_mode_instructional.xml
new file mode 100644
index 000000000..588dc3549
--- /dev/null
+++ b/res/layout/scene_mode_instructional.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/mode_layout_rect"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/transparent"
+ android:gravity="center">
+
+ <LinearLayout
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="30dp"
+ android:layout_marginTop="15dp"
+ android:orientation="horizontal"
+ android:gravity="center">
+ <ImageView
+ android:id="@+id/scene_mode_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/chroma_flash"/>
+ <TextView
+ android:id="@+id/scene_mode_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:layout_toRightOf="@id/scene_mode_icon"
+ android:text="@string/pref_camera_scenemode_entry_chromaflash"
+ android:textColor="@android:color/black"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/scene_mode_instructional"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="15dp"
+ android:layout_marginLeft="30dp"
+ android:layout_marginRight="30dp"
+ android:text="@string/pref_camera2_scene_mode_chroma_flash_instructional_content"
+ android:textColor="@android:color/black"
+ android:layout_below="@id/title" />
+ <CheckBox
+ android:id="@+id/remember_selected"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="15dp"
+ android:layout_marginLeft="30dp"
+ android:layout_below="@id/scene_mode_instructional"
+ android:text="@string/pref_camera2_not_show_again"
+ android:textColor="@android:color/black"/>
+
+ <View
+ android:id="@+id/separator"
+ android:layout_width="wrap_content"
+ android:layout_height="1dp"
+ android:layout_marginTop="15dp"
+ android:layout_marginBottom="15dp"
+ android:layout_below="@id/remember_selected"
+ android:background="#c0c0c0" />
+
+ <Button
+ android:id="@+id/scene_mode_instructional_ok"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/separator"
+ android:background="@android:color/transparent"
+ android:layout_marginRight="30dp"
+ android:layout_alignParentRight="true"
+ android:text="@string/pref_camera2_scene_mode_instructional_ok"
+ android:textColor="@android:color/black"/>
+</RelativeLayout>
+
diff --git a/res/layout/scene_mode_label.xml b/res/layout/scene_mode_label.xml
new file mode 100644
index 000000000..e0d8d43b8
--- /dev/null
+++ b/res/layout/scene_mode_label.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ Not a Contribution.
+
+ Copyright (C) 2013 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="90dp"
+ android:layout_marginRight="20dp"
+ android:gravity="right">
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/scene_mode_label_rect"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <LinearLayout
+ android:id="@+id/scene_mode_label_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:background="#90000000"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/scene_mode_label"
+ android:singleLine="true"
+ android:text="@string/pref_camera_scenemode_entry_chromaflash"
+ android:textColor="@android:color/white"
+ android:textSize="16dp"
+ style="@style/OnViewfinderSceneLabel" />
+ <ImageView
+ android:id="@+id/scene_mode_label_close"
+ android:layout_width="15dp"
+ android:layout_height="15dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="5dp"
+ android:src="@drawable/x" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml
index 80c695d58..fbb70b984 100644
--- a/res/values/camera2arrays.xml
+++ b/res/values/camera2arrays.xml
@@ -157,6 +157,7 @@
<item>107</item>
<item>108</item>
<item>104</item>
+ <item>109</item>
</string-array>
<!-- Camera Preferences Scene Mode dialog box entries -->
@@ -183,6 +184,7 @@
<item>@string/pref_camera_scenemode_entry_sharpshooter</item>
<item>@string/pref_camera_scenemode_entry_trackingfocus</item>
<item>@string/pref_camera_scenemode_entry_panorama</item>
+ <item>@string/pref_camera_scenemode_entry_promode</item>
</string-array>
<array name="pref_camera2_scenemode_thumbnails" translatable="false">
@@ -208,8 +210,62 @@
<item>@drawable/sharp_photo</item>
<item>@drawable/tracking_focus</item>
<item>@drawable/scene_panorama</item>
+ <item>@drawable/promode</item>
</array>
+ <array name="pref_camera2_scenemode_black_thumbnails" translatable="false">
+ <item>@drawable/ic_scene_mode_black_auto</item>
+ <item>@drawable/ic_scene_mode_black_dual_camera</item>
+ <item>@drawable/ic_scene_mode_black_hdr</item>
+ <item>@drawable/ic_scene_mode_black_ubifocus</item>
+ <item>@drawable/ic_scene_mode_black_optizoom</item>
+ <item>@drawable/ic_scene_mode_black_portrait</item>
+ <item>@drawable/ic_scene_mode_black_landscape</item>
+ <item>@drawable/ic_scene_mode_black_sports</item>
+ <item>@drawable/ic_scene_mode_black_flowers</item>
+ <item>@drawable/ic_scene_mode_black_backlight</item>
+ <item>@drawable/ic_scene_mode_black_candlelight</item>
+ <item>@drawable/ic_scene_mode_black_sunset</item>
+ <item>@drawable/ic_scene_mode_black_night</item>
+ <item>@drawable/ic_scene_mode_black_beach</item>
+ <item>@drawable/ic_scene_mode_black_snow</item>
+ <item>@drawable/ic_scene_mode_smartauto</item>
+ <item>@drawable/ic_scene_mode_black_best_photo</item>
+ <item>@drawable/ic_scene_mode_black_chroma_flash</item>
+ <item>@drawable/ic_scene_mode_black_blur_buster</item>
+ <item>@drawable/ic_scene_mode_black_sharp_photo</item>
+ <item>@drawable/ic_scene_mode_black_tracking_focus</item>
+ <item>@drawable/ic_scene_mode_black_panorama</item>
+ <item>@drawable/ic_scene_mode_black_dual_camera</item>
+ </array>
+
+ <!-- Camera Preferences Scene Mode dialog box entries -->
+ <string-array name="pref_camera2_scenemode_instructional_entries" translatable="false">
+ <item>@string/pref_camera_scenemode_entry_auto</item>
+ <item>@string/pref_camera2_scene_mode_dual_camera_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_hdr_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_ubi_focus_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_opti_zoom_instructional_content</item>
+ <item>""</item>
+ <item>""</item>
+ <item>@string/pref_camera2_scene_mode_sports_instructional_content</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>""</item>
+ <item>@string/pref_camera2_scene_mode_best_photo_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_chroma_flash_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_blur_buster_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_sharp_photo_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_tracking_focus_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_panorama_instructional_content</item>
+ <item>@string/pref_camera2_scene_mode_pro_instructional_content</item>
+ </string-array>
+
<string-array name="pref_camera2_whitebalance_entryvalues" translatable="false">
<item>1</item>
<item>2</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2a58a33e2..d89d0a990 100644..100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -180,4 +180,7 @@
<dimen name="refocus_circle_diameter_3">95dp</dimen>
<dimen name="refocus_cross_length">19dp</dimen>
<dimen name="refocus_stroke_width">2dp</dimen>
+
+ <dimen name="one_ui_bottom_large">75dp</dimen>
+ <dimen name="one_ui_bottom_small">55dp</dimen>
</resources>
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index 34c9b32cf..509fae318 100644
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -1029,6 +1029,7 @@
<string name="pref_camera_scenemode_entry_sharpshooter" translatable="true">SharpPhoto</string>
<string name="pref_camera_scenemode_entry_trackingfocus" translatable="true">TrackingFocus</string>
<string name="pref_camera_scenemode_entry_panorama" translatable="true">Panorama</string>
+ <string name="pref_camera_scenemode_entry_promode" translatable="true">ProMode</string>
<string name="bestpicture_done" translatable="true">DONE</string>
<string name="bestpicture_at_least_one_picture" translatable="true">At least, one picture has to be chosen.</string>
@@ -1040,10 +1041,10 @@
<string name="pref_camera2_shutter_sound_entry_off" translatable="true">Off</string>
<string name="pref_camera2_shutter_sound_title" translatable="true">Shutter Sound</string>
- <string name="pref_camera2_timer_entry_off" translatable="false">Off</string>
- <string name="pref_camera2_timer_entry_2sec" translatable="false">2 seconds</string>
- <string name="pref_camera2_timer_entry_5sec" translatable="false">5 seconds</string>
- <string name="pref_camera2_timer_entry_10sec" translatable="false">10 seconds</string>
+ <string name="pref_camera2_timer_entry_off" translatable="true">Off</string>
+ <string name="pref_camera2_timer_entry_2sec" translatable="true">2 seconds</string>
+ <string name="pref_camera2_timer_entry_5sec" translatable="true">5 seconds</string>
+ <string name="pref_camera2_timer_entry_10sec" translatable="true">10 seconds</string>
<string name="pref_camera2_timer_value_off" translatable="false">0</string>
<string name="pref_camera2_timer_value_2sec" translatable="false">2</string>
@@ -1056,5 +1057,28 @@
<string name="makeup_ui_ok_button" translatable="true">OK</string>
<string name="makeup_seekbar_low" translatable="true">low</string>
<string name="makeup_seekbar_high" translatable="true">high</string>
+
+ <string name="perf_camera2_version_info" translatable="true">Version Info</string>
+ <string name="perf_camera2_preferences_category_general" translatable="true">General</string>
+ <string name="perf_camera2_preferences_category_photo" translatable="true">Still camera</string>
+ <string name="perf_camera2_preferences_category_video" translatable="true">Video camera</string>
+ <string name="perf_camera2_preferences_category_system" translatable="true">System</string>
+
+ <string name="pref_camera2_scene_mode_dual_camera_instructional_content" translatable="true">In dual camera mode, your pictures will be clearer. You can also apply background effects, by editing your dual camera pictures in the Gallery.</string>
+ <string name="pref_camera2_scene_mode_ubi_focus_instructional_content" translatable="true">With UbiFocus, your camera will take five pictures and combine them into one picture,where everything is in focus. You can choose to re-focus, after you take the picture.</string>
+ <string name="pref_camera2_scene_mode_opti_zoom_instructional_content" translatable="true">Use Optizoom when you want to zoom in for a clear picture.You can zoom before, or after taking the picture.</string>
+ <string name="pref_camera2_scene_mode_sports_instructional_content" translatable="true">Sports mode helps you take better sports or action shots.\n\nImporves your photos, but has no effect on video recording.</string>
+ <string name="pref_camera2_scene_mode_hdr_instructional_content" translatable="true">When you are in mixed lighting conditions such as low light and backlit scenes select "HDR" for best possible pictures.</string>
+ <string name="pref_camera2_scene_mode_best_photo_instructional_content" translatable="true">Allows you to take a burst of 10 photos, and you can choose the best one(s).</string>
+ <string name="pref_camera2_scene_mode_chroma_flash_instructional_content" translatable="true">With ChromaFlash, the lighting in your flash photos will be optimized for all of the people and objects in your pictures.This feature applies only to the back camera.</string>
+ <string name="pref_camera2_scene_mode_sharp_photo_instructional_content" translatable="true">Sharp Phot reduces blur that is due to motion in the scene, or due to hand motion.</string>
+ <string name="pref_camera2_scene_mode_tracking_focus_instructional_content" translatable="true">Allows you to track and focus a selected person or object while taking pictures or videos. To start, position the focus rectangle on a person or object you want to track.</string>
+ <string name="pref_camera2_scene_mode_time_lapse_instructional_content" translatable="true">With Time Lapse, you can transform a long video recording into a few seconds of video.This effect applies to videos, but not photos.</string>
+ <string name="pref_camera2_scene_mode_panorama_instructional_content" translatable="true">Allows you to pan left or right to take a wide landscape photo. You can alse pan up or down to take tall photos.</string>
+ <string name="pref_camera2_scene_mode_blur_buster_instructional_content" translatable="true">BlurBuster reduces blur from shaky hands.It can be helpful when taking photos in difficult places.</string>
+ <string name="pref_camera2_scene_mode_pro_instructional_content" translatable="true">With Pro Mode, you can manually control settings for ISO,Exposure, White Balance, and Focus. You will have easy access to all of these advanced settings</string>
+
+ <string name="pref_camera2_not_show_again">Do not show again</string>
+ <string name="pref_camera2_scene_mode_instructional_ok" translatable="true">OK</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 082c5ed8a..8432c11e9 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -316,4 +316,18 @@
<style name="PanoViewHorizontalBar">
<item name="android:background">@android:color/transparent</item>
</style>
+
+ <style name="OnViewfinderSceneLabel">
+ <item name="android:gravity">center</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_marginLeft">10dp</item>
+ <item name="android:layout_marginRight">10dp</item>
+ <item name="android:layout_marginTop">5dp</item>
+ <item name="android:layout_marginBottom">5dp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:textColor">@android:color/white</item>
+ <item name="android:textSize">16dp</item>
+ <item name="android:background">@android:color/transparent</item>
+ </style>
</resources>
diff --git a/res/xml/capture_preferences.xml b/res/xml/capture_preferences.xml
index f3603c443..8ad300fe7 100644
--- a/res/xml/capture_preferences.xml
+++ b/res/xml/capture_preferences.xml
@@ -124,6 +124,14 @@
camera:title="@string/pref_camera_scenemode_title"/>
<IconListPreference
+ camera:defaultValue="@string/pref_camera2_scenemode_default"
+ camera:entries="@array/pref_camera2_scenemode_instructional_entries"
+ camera:entryValues="@array/pref_camera2_scenemode_entryvalues"
+ camera:key="pref_camera2_scenemode_instructional"
+ camera:thumbnails="@array/pref_camera2_scenemode_black_thumbnails"
+ camera:title="@string/pref_camera_scenemode_title"/>
+
+ <IconListPreference
camera:defaultValue="@string/setting_off_value"
camera:entries="@array/pref_camera2_redeyereduction_entries"
camera:entryValues="@array/pref_camera2_redeyereduction_entryvalues"
diff --git a/res/xml/setting_menu_preferences.xml b/res/xml/setting_menu_preferences.xml
index 87660713a..80097f497 100644
--- a/res/xml/setting_menu_preferences.xml
+++ b/res/xml/setting_menu_preferences.xml
@@ -31,7 +31,7 @@
<PreferenceCategory
android:key="general"
android:layout="@layout/preferences_category"
- android:title="GENERAL">
+ android:title="@string/perf_camera2_preferences_category_general">
<SwitchPreference
android:defaultValue="false"
android:icon="@drawable/gps_location"
@@ -60,7 +60,7 @@
<PreferenceCategory
android:key="photo"
android:layout="@layout/preferences_category"
- android:title="STILL CAMERA">
+ android:title="@string/perf_camera2_preferences_category_photo">
<ListPreference
android:defaultValue="@string/pref_camera2_timer_value_off"
android:entries="@array/pref_camera2_timer_entries"
@@ -169,7 +169,7 @@
<PreferenceCategory
android:key="video"
android:layout="@layout/preferences_category"
- android:title="VIDEO CAMERA">
+ android:title="@string/perf_camera2_preferences_category_video">
<ListPreference
android:entries="@array/pref_camera2_video_quality_entries"
android:entryValues="@array/pref_camera2_video_quality_entryvalues"
@@ -196,11 +196,14 @@
android:layout="@layout/preference"
android:title="@string/pref_camera_dis_title" />
- <SwitchPreference
- android:defaultValue="false"
+ <ListPreference
+ android:defaultValue="@string/pref_camera_noise_reduction_default"
+ android:entries="@array/pref_camera2_noise_reduction_entries"
+ android:entryValues="@array/pref_camera2_noise_reduction_entryvalues"
android:icon="@drawable/noise_reduction"
android:key="pref_camera2_noise_reduction_key"
android:layout="@layout/preference"
+ android:summary="%s"
android:title="@string/pref_camera_noise_reduction_title" />
<ListPreference
diff --git a/rs/rotator.rs b/rs/rotator.rs
index 5a27e00f7..62257d2cf 100644..100755
--- a/rs/rotator.rs
+++ b/rs/rotator.rs
@@ -35,32 +35,51 @@ rs_allocation gIn;
uint32_t width;
uint32_t height;
uint32_t pad;
-bool gFlip;
+uint32_t degree;
uchar __attribute__((kernel)) rotate90andMerge(uint32_t x, uint32_t y) {
uchar yValue = rsGetElementAt_uchar(gIn, x + y*width);
- if(gFlip) {
+ if(degree == 180) {
if(x >= width - pad)
return (uchar)0;
rsSetElementAt_uchar(gOut, yValue, (width-1-x-pad)*height + height - 1 - y);
- } else {
+ } else if (degree == 90) {
rsSetElementAt_uchar(gOut, yValue, x*height + height - 1 - y);
+ } else if (degree == 270) {
+ if(x >= width - pad)
+ return (uchar)0;
+ rsSetElementAt_uchar(gOut, yValue, (width-1-x-pad)*height + y);
+ } else if (degree == 0) {
+ if(x >= width - pad)
+ return (uchar)0;
+ rsSetElementAt_uchar(gOut, yValue, x*height + y);
}
+
if(x%2 == 0 && y%2 == 0) {
uint32_t ySize = width*height;
uint32_t index = ySize + x + ((y/2) * width);
uchar vValue = rsGetElementAt_uchar(gIn, index);
uchar uValue = rsGetElementAt_uchar(gIn, index + 1);
- if(gFlip) {
+ if(degree == 180) {
if(x >= width - pad)
return (uchar)0;
rsSetElementAt_uchar(gOut, uValue, ySize + (width-2-x-pad)/2*height + height - 1 - y);
rsSetElementAt_uchar(gOut, vValue, ySize + (width-2-x-pad)/2*height + height - 1 - y - 1);
- } else {
+ } else if (degree == 90) {
rsSetElementAt_uchar(gOut, uValue, ySize + x/2*height + height - 1 - y);
rsSetElementAt_uchar(gOut, vValue, ySize + x/2*height + height - 1 - y - 1);
+ } else if (degree == 270) {
+ if(x >= (width - pad))
+ return (uchar)0;
+ rsSetElementAt_uchar(gOut, uValue, ySize + (width-1-x-pad)/2*height + y -1);
+ rsSetElementAt_uchar(gOut, vValue, ySize + (width-1-x-pad)/2*height + y);
+ } else if (degree == 0) {
+ if(x >= (width - pad))
+ return (uchar)0;
+ rsSetElementAt_uchar(gOut, uValue, ySize + x/2*height + y - 1);
+ rsSetElementAt_uchar(gOut, vValue, ySize + x/2*height + y);
}
}
return (uchar)0;
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
index 486629895..438be2e90 100755..100644
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ b/src/com/android/camera/AndroidCameraManagerImpl.java
@@ -200,6 +200,30 @@ class AndroidCameraManagerImpl implements CameraManager {
return true;
}
+ public boolean waitDone(long timeout) {
+ final Object waitDoneLock = new Object();
+ final Runnable unlockRunnable = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (waitDoneLock) {
+ waitDoneLock.notifyAll();
+ }
+ }
+ };
+
+ synchronized (waitDoneLock) {
+ mCameraHandler.post(unlockRunnable);
+ try {
+ waitDoneLock.wait(timeout);
+ mCameraHandler.removeCallbacks(unlockRunnable);
+ } catch (InterruptedException ex) {
+ Log.v(TAG, "waitDone interrupted");
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* This method does not deal with the API level check. Everyone should
* check first for supported operations before sending message to this handler.
@@ -499,7 +523,7 @@ class AndroidCameraManagerImpl implements CameraManager {
@Override
public void stopPreview() {
mCameraHandler.sendEmptyMessage(STOP_PREVIEW);
- mCameraHandler.waitDone();
+ mCameraHandler.waitDone(200);
}
@Override
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 26e7ca933..d3c39793a 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -234,7 +234,6 @@ public class CameraActivity extends Activity
private View mPreviewCover;
private FrameLayout mPreviewContentLayout;
private boolean mPaused = true;
- private boolean mHasCriticalPermissions;
private boolean mForceReleaseCamera = false;
private Uri[] mNfcPushUris = new Uri[1];
@@ -310,7 +309,6 @@ public class CameraActivity extends Activity
public void onCameraDisabled(int cameraId) {
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_OPEN_FAIL, "security");
-
CameraUtil.showErrorAndFinish(CameraActivity.this,
R.string.camera_disabled);
}
@@ -319,27 +317,21 @@ public class CameraActivity extends Activity
public void onDeviceOpenFailure(int cameraId) {
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_OPEN_FAIL, "open");
-
- CameraUtil.showErrorAndFinish(CameraActivity.this,
- R.string.cannot_connect_camera);
+ showOpenCameraErrorDialog();
}
@Override
public void onReconnectionFailure(CameraManager mgr) {
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_OPEN_FAIL, "reconnect");
-
- CameraUtil.showErrorAndFinish(CameraActivity.this,
- R.string.cannot_connect_camera);
+ showOpenCameraErrorDialog();
}
@Override
public void onStartPreviewFailure(int cameraId) {
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_START_PREVIEW_FAIL, "startpreview");
-
- CameraUtil.showErrorAndFinish(CameraActivity.this,
- R.string.cannot_connect_camera);
+ showOpenCameraErrorDialog();
}
};
@@ -1448,11 +1440,6 @@ public class CameraActivity extends Activity
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
- if (checkPermissions() || !mHasCriticalPermissions) {
- Log.v(TAG, "onCreate: Missing critical permissions.");
- finish();
- return;
- }
// Check if this is in the secure camera mode.
Intent intent = getIntent();
String action = intent.getAction();
@@ -1464,8 +1451,6 @@ public class CameraActivity extends Activity
mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
}
- mCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
-
if (mSecureCamera) {
// Change the window flags so that secure camera can show when locked
Window win = getWindow();
@@ -1479,9 +1464,20 @@ public class CameraActivity extends Activity
Log.d(TAG, "acquire wake lock");
}
win.setAttributes(params);
+ }
+ if (mSecureCamera && !hasCriticalPermissions()) {
+ return;
+ }
+ if (isStartRequsetPermission()) {
+ Log.v(TAG, "onCreate: Missing critical permissions.");
+ finish();
+ return;
}
+
+ mCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ null, null, null, null);
GcamHelper.init(getContentResolver());
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
@@ -1677,6 +1673,10 @@ public class CameraActivity extends Activity
@Override
public void onPause() {
+ if (mSecureCamera && !hasCriticalPermissions()) {
+ super.onPause();
+ return;
+ }
// Delete photos that are pending deletion
performDeletion();
mOrientationListener.disable();
@@ -1725,9 +1725,8 @@ public class CameraActivity extends Activity
* Critical permissions are: camera, microphone and storage. The app cannot run without them.
* Non-critical permission is location.
*/
- private boolean checkPermissions() {
- boolean requestPermission = false;
-
+ private boolean hasCriticalPermissions() {
+ boolean hasCriticalPermission = false;
if (checkSelfPermission(Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.RECORD_AUDIO) ==
@@ -1736,27 +1735,38 @@ public class CameraActivity extends Activity
PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
- mHasCriticalPermissions = true;
+ hasCriticalPermission = true;
} else {
- mHasCriticalPermissions = false;
+ hasCriticalPermission = false;
}
+ return hasCriticalPermission;
+ }
+
+ private boolean isStartRequsetPermission() {
+ boolean isStartPermissionActivity = false;
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean isRequestShown = prefs.getBoolean(CameraSettings.KEY_REQUEST_PERMISSION, false);
- if(!isRequestShown || !mHasCriticalPermissions) {
- Log.v(TAG, "Request permission");
+
+ if(!mSecureCamera && (!isRequestShown || !hasCriticalPermissions())) {
+ Log.v(TAG, "Start Request Permission");
Intent intent = new Intent(this, PermissionsActivity.class);
startActivity(intent);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(CameraSettings.KEY_REQUEST_PERMISSION, true);
editor.apply();
- requestPermission = true;
- }
- return requestPermission;
+ isStartPermissionActivity = true;
+ }
+ return isStartPermissionActivity;
}
@Override
public void onResume() {
- if (checkPermissions() || !mHasCriticalPermissions) {
+ if (mSecureCamera && !hasCriticalPermissions()) {
+ super.onResume();
+ showOpenCameraErrorDialog();
+ return;
+ }
+ if (isStartRequsetPermission()) {
super.onResume();
Log.v(TAG, "onResume: Missing critical permissions.");
finish();
@@ -1814,6 +1824,9 @@ public class CameraActivity extends Activity
@Override
public void onStart() {
super.onStart();
+ if (mSecureCamera && !hasCriticalPermissions()) {
+ return;
+ }
bindMediaSaveService();
mPanoramaViewHelper.onStart();
}
@@ -1821,6 +1834,9 @@ public class CameraActivity extends Activity
@Override
protected void onStop() {
super.onStop();
+ if (mSecureCamera && !hasCriticalPermissions()) {
+ return;
+ }
mPanoramaViewHelper.onStop();
unbindMediaSaveService();
}
@@ -2352,4 +2368,14 @@ public class CameraActivity extends Activity
public CameraModule getCurrentModule() {
return mCurrentModule;
}
+
+ private void showOpenCameraErrorDialog() {
+ if (!hasCriticalPermissions()) {
+ CameraUtil.showErrorAndFinish(CameraActivity.this,
+ R.string.error_permissions);
+ } else {
+ CameraUtil.showErrorAndFinish(CameraActivity.this,
+ R.string.cannot_connect_camera);
+ }
+ }
}
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 069fb8701..97c4eae0a 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -1027,6 +1027,10 @@ public class CameraSettings {
return;
}
+ if (numOfCameras > 2 ) {
+ numOfCameras = 2;
+ }
+
CharSequence[] entryValues = new CharSequence[numOfCameras];
for (int i = 0; i < numOfCameras; ++i) {
entryValues[i] = "" + i;
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 42f94b6f5..e870161f3 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -56,11 +56,14 @@ import android.media.ImageReader;
import android.media.MediaActionSound;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
+import android.media.EncoderCapabilities;
+import android.media.EncoderCapabilities.VideoEncoderCap;
import android.net.Uri;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.Bundle;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore;
@@ -72,10 +75,10 @@ import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
+import android.view.WindowManager;
import android.widget.Toast;
import com.android.camera.exif.ExifInterface;
-import com.android.camera.Exif;
import com.android.camera.imageprocessor.filter.BlurbusterFilter;
import com.android.camera.imageprocessor.filter.ChromaflashFilter;
import com.android.camera.imageprocessor.filter.ImageFilter;
@@ -94,6 +97,7 @@ import com.android.camera.util.CameraUtil;
import com.android.camera.util.PersistUtil;
import com.android.camera.util.SettingTranslation;
import com.android.camera.util.ApiHelper;
+import com.android.camera.util.AccessibilityUtils;
import com.android.internal.util.MemInfoReader;
import org.codeaurora.snapcam.R;
@@ -104,7 +108,6 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -116,7 +119,7 @@ public class CaptureModule implements CameraModule, PhotoController,
MediaSaveService.Listener, ClearSightImageProcessor.Callback,
SettingsManager.Listener, LocationManager.Listener,
CountDownView.OnCountDownFinishedListener,
- MediaRecorder.OnInfoListener{
+ MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
public static final int DUAL_MODE = 0;
public static final int BAYER_MODE = 1;
public static final int MONO_MODE = 2;
@@ -168,6 +171,8 @@ public class CaptureModule implements CameraModule, PhotoController,
private static final int NORMAL_SESSION_MAX_FPS = 60;
+ private static final int SCREEN_DELAY = 2 * 60 * 1000;
+
MeteringRectangle[][] mAFRegions = new MeteringRectangle[MAX_NUM_CAM][];
MeteringRectangle[][] mAERegions = new MeteringRectangle[MAX_NUM_CAM][];
CaptureRequest.Key<Byte> BayerMonoLinkEnableKey =
@@ -193,6 +198,12 @@ public class CaptureModule implements CameraModule, PhotoController,
public static CameraCharacteristics.Key<Byte> MetaDataMonoOnlyKey =
new CameraCharacteristics.Key<>("org.codeaurora.qcamera3.sensor_meta_data.is_mono_only",
Byte.class);
+ public static CaptureRequest.Key<Integer> SELECT_PRIORITY =
+ new CaptureRequest.Key<>("org.codeaurora.qcamera3.iso_exp_priority.select_priority",
+ Integer.class);
+ public static CaptureRequest.Key<Long> ISO_EXP =
+ new CaptureRequest.Key<>("org.codeaurora.qcamera3.iso_exp_priority.use_iso_exp_priority",
+ Long.class);
private boolean[] mTakingPicture = new boolean[MAX_NUM_CAM];
private int mControlAFMode = CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
private int mLastResultAFState = -1;
@@ -206,7 +217,8 @@ public class CaptureModule implements CameraModule, PhotoController,
private boolean mIsLinked = false;
private long mCaptureStartTime;
private boolean mPaused = true;
- private boolean mSurfaceReady = false;
+ private Semaphore mSurfaceReadyLock = new Semaphore(1);
+ private boolean mSurfaceReady = true;
private boolean[] mCameraOpened = new boolean[MAX_NUM_CAM];
private CameraDevice[] mCameraDevice = new CameraDevice[MAX_NUM_CAM];
private String[] mCameraId = new String[MAX_NUM_CAM];
@@ -224,6 +236,14 @@ public class CaptureModule implements CameraModule, PhotoController,
private int mDisplayOrientation;
private boolean mIsRefocus = false;
private int mChosenImageFormat;
+ private Toast mToast;
+
+ private boolean mStartRecPending = false;
+ private boolean mStopRecPending = false;
+
+ boolean mUnsupportedResolution = false;
+
+ private static final int SDCARD_SIZE_LIMIT = 4000 * 1024 * 1024;
/**
* A {@link CameraCaptureSession } for camera preview.
@@ -281,6 +301,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private int mTimeBetweenTimeLapseFrameCaptureMs = 0;
private boolean mCaptureTimeLapse = false;
private CamcorderProfile mProfile;
+ private static final int CLEAR_SCREEN_DELAY = 4;
private static final int UPDATE_RECORD_TIME = 5;
private ContentValues mCurrentVideoValues;
private String mVideoFilename;
@@ -300,6 +321,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private MediaActionSound mSound;
private Size mSupportedMaxPictureSize;
+
private class SelfieThread extends Thread {
public void run() {
try {
@@ -527,8 +549,6 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onError(CameraDevice cameraDevice, int error) {
int id = Integer.parseInt(cameraDevice.getId());
Log.e(TAG, "onError " + id + " " + error);
- cameraDevice.close();
- mCameraDevice[id] = null;
mCameraOpenCloseLock.release();
mCamerasOpened = false;
if (null != mActivity) {
@@ -622,10 +642,10 @@ public class CaptureModule implements CameraModule, PhotoController,
break;
}
case STATE_AF_AE_LOCKED: {
- Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
- Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
- Log.d(TAG, "STATE_AF_AE_LOCKED id: " + id + " afState:" + afState + " aeState:" + aeState);
- break;
+ Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
+ Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+ Log.d(TAG, "STATE_AF_AE_LOCKED id: " + id + " afState:" + afState + " aeState:" + aeState);
+ break;
}
case STATE_WAITING_TOUCH_FOCUS:
break;
@@ -781,8 +801,15 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ private void applyFocusDistance(CaptureRequest.Builder builder, String value) {
+ if (value == null) return;
+ float valueF = Float.valueOf(value);
+ builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
+ builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, valueF);
+ }
+
private void createSessions() {
- if (mPaused || !mCamerasOpened || !mSurfaceReady) return;
+ if (mPaused || !mCamerasOpened ) return;
if (isBackCamera()) {
switch (getCameraMode()) {
case DUAL_MODE:
@@ -811,12 +838,42 @@ public class CaptureModule implements CameraModule, PhotoController,
return builder;
}
+ private void waitForPreviewSurfaceReady() {
+ try {
+ if (!mSurfaceReady) {
+ if (!mSurfaceReadyLock.tryAcquire(2000, TimeUnit.MILLISECONDS)) {
+ Log.d(TAG, "Time out waiting for surface.");
+ throw new RuntimeException("Time out waiting for surface.");
+ }
+ mSurfaceReadyLock.release();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void updatePreviewSurfaceReadyState(boolean rdy) {
+ if (rdy != mSurfaceReady) {
+ if (rdy) {
+ Log.i(TAG, "Preview Surface is ready!");
+ mSurfaceReadyLock.release();
+ mSurfaceReady = true;
+ } else {
+ try {
+ Log.i(TAG, "Preview Surface is not ready!");
+ mSurfaceReady = false;
+ mSurfaceReadyLock.acquire();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
private void createSession(final int id) {
- if (mPaused || !mCameraOpened[id] || !mSurfaceReady) return;
+ if (mPaused || !mCameraOpened[id]) return;
Log.d(TAG, "createSession " + id);
List<Surface> list = new LinkedList<Surface>();
try {
- Surface surface = getPreviewSurfaceForSession(id);
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder[id] = getRequestBuilder(id);
mPreviewRequestBuilder[id].setTag(id);
@@ -866,7 +923,10 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
- Log.e(TAG, "cameracapturesession - onConfigureFailed "+id);
+ Log.e(TAG, "cameracapturesession - onConfigureFailed "+ id);
+ if (mActivity.isFinishing()) {
+ return;
+ }
new AlertDialog.Builder(mActivity)
.setTitle("Camera Initialization Failed")
.setMessage("Closing SnapdragonCamera")
@@ -886,6 +946,8 @@ public class CaptureModule implements CameraModule, PhotoController,
Log.d(TAG, "cameracapturesession - onClosed");
}
};
+ waitForPreviewSurfaceReady();
+ Surface surface = getPreviewSurfaceForSession(id);
if(id == getMainCameraId()) {
mFrameProcessor.setOutputSurface(surface);
@@ -934,6 +996,9 @@ public class CaptureModule implements CameraModule, PhotoController,
}
public void setAFModeToPreview(int id, int afMode) {
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
Log.d(TAG, "setAFModeToPreview " + afMode);
mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AF_MODE, afMode);
applyAFRegions(mPreviewRequestBuilder[id], id);
@@ -942,14 +1007,17 @@ public class CaptureModule implements CameraModule, PhotoController,
try {
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
public void setFlashModeToPreview(int id, boolean isFlashOn) {
Log.d(TAG, "setFlashModeToPreview " + isFlashOn);
- if(isFlashOn) {
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
+ if (isFlashOn) {
mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
} else {
@@ -962,29 +1030,32 @@ public class CaptureModule implements CameraModule, PhotoController,
try {
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
public void setFocusDistanceToPreview(int id, float fd) {
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
mPreviewRequestBuilder[id].set(CaptureRequest.LENS_FOCUS_DISTANCE, fd);
mPreviewRequestBuilder[id].setTag(id);
try {
- if(id == MONO_ID && !canStartMonoPreview()) {
+ if (id == MONO_ID && !canStartMonoPreview()) {
mCaptureSession[id].capture(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
} else {
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
}
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
public void reinit() {
- mSettingsManager.reinit(getMainCameraId());
+ mSettingsManager.init();
}
public boolean isRefocus() {
@@ -1009,8 +1080,6 @@ public class CaptureModule implements CameraModule, PhotoController,
mCameraOpened[i] = false;
mTakingPicture[i] = false;
}
- mSurfaceReady = false;
-
for (int i = 0; i < MAX_NUM_CAM; i++) {
mState[i] = STATE_PREVIEW;
}
@@ -1073,7 +1142,9 @@ public class CaptureModule implements CameraModule, PhotoController,
* Lock the focus as the first step for a still image capture.
*/
private void lockFocus(int id) {
- if (mActivity == null || mCameraDevice[id] == null) {
+ if (mActivity == null || mCameraDevice[id] == null
+ || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ mUI.enableShutter(true);
warningToast("Camera is not ready yet to take a picture.");
return;
}
@@ -1116,14 +1187,15 @@ public class CaptureModule implements CameraModule, PhotoController,
mLockRequestHashCode[id] = request.hashCode();
mState[id] = STATE_WAITING_AF_LOCK;
mCaptureSession[id].capture(request, mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
private void autoFocusTrigger(int id) {
Log.d(TAG, "autoFocusTrigger " + id);
- if (null == mActivity || null == mCameraDevice[id]) {
+ if (null == mActivity || null == mCameraDevice[id]
+ || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
warningToast("Camera is not ready yet to take a picture.");
return;
}
@@ -1137,9 +1209,10 @@ public class CaptureModule implements CameraModule, PhotoController,
mState[id] = STATE_WAITING_TOUCH_FOCUS;
mCaptureSession[id].capture(builder.build(), mCaptureCallback, mCameraHandler);
setAFModeToPreview(id, mControlAFMode);
- Message message = mCameraHandler.obtainMessage(CANCEL_TOUCH_FOCUS, mCameraId[id]);
+ Message message = mCameraHandler.obtainMessage(
+ CANCEL_TOUCH_FOCUS, Integer.valueOf(mCameraId[id]), 0);
mCameraHandler.sendMessageDelayed(message, CANCEL_TOUCH_FOCUS_DELAY);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -1213,10 +1286,12 @@ public class CaptureModule implements CameraModule, PhotoController,
Location location = mLocationManager.getCurrentLocation();
if(location != null) {
- Log.d(TAG, "captureStillPicture gps: " + location.toString());
+ // make copy so that we don't alter the saved location since we may re-use it
+ location = new Location(location);
// workaround for Google bug. Need to convert timestamp from ms -> sec
location.setTime(location.getTime()/1000);
captureBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, location);
+ Log.d(TAG, "captureStillPicture gps: " + location.toString());
} else {
Log.d(TAG, "captureStillPicture no location - getRecordLocation: " + getRecordLocation());
}
@@ -1299,6 +1374,13 @@ public class CaptureModule implements CameraModule, PhotoController,
unlockFocus(id);
}
}, mCaptureCallbackHandler);
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mUI.enableVideo(false);
+ }
+ });
+
} else {
checkAndPlayShutterSound(id);
if(isMpoOn()) {
@@ -1323,7 +1405,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private void captureVideoSnapshot(final int id) {
Log.d(TAG, "captureStillPicture " + id);
try {
- if (null == mActivity || null == mCameraDevice[id]) {
+ if (null == mActivity || null == mCameraDevice[id] || mCurrentSession == null) {
warningToast("Camera is not ready yet to take a video snapshot.");
return;
}
@@ -1373,6 +1455,9 @@ public class CaptureModule implements CameraModule, PhotoController,
*/
private void runPrecaptureSequence(int id) {
Log.d(TAG, "runPrecaptureSequence: " + id);
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
try {
CaptureRequest.Builder builder = getRequestBuilder(id);
builder.setTag(id);
@@ -1383,7 +1468,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mState[id] = STATE_WAITING_PRECAPTURE;
mCaptureSession[id].capture(request, mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -1528,6 +1613,9 @@ public class CaptureModule implements CameraModule, PhotoController,
*/
public void unlockFocus(int id) {
Log.d(TAG, "unlockFocus " + id);
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
try {
CaptureRequest.Builder builder = getRequestBuilder(id);
builder.setTag(id);
@@ -1555,15 +1643,12 @@ public class CaptureModule implements CameraModule, PhotoController,
public void run() {
mUI.stopSelfieFlash();
mUI.enableShutter(true);
+ mUI.enableVideo(true);
}
});
}
- } catch (NullPointerException e) {
- Log.w(TAG, "Session is already closed");
- } catch (IllegalStateException e) {
+ } catch (NullPointerException | IllegalStateException | CameraAccessException e) {
Log.w(TAG, "Session is already closed");
- } catch (CameraAccessException e) {
- e.printStackTrace();
}
}
@@ -1584,6 +1669,15 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ public boolean isAllSessionClosed() {
+ for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
+ if (mCaptureSession[i] != null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private void closeSessions() {
for (int i = MAX_NUM_CAM-1; i >= 0; i--) {
if (null != mCaptureSession[i]) {
@@ -1666,13 +1760,16 @@ public class CaptureModule implements CameraModule, PhotoController,
* Lock the exposure for capture
*/
private void lockExposure(int id) {
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
Log.d(TAG, "lockExposure: " + id);
try {
applySettingsForLockExposure(mPreviewRequestBuilder[id], id);
mState[id] = STATE_WAITING_AE_LOCK;
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id].build(),
mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -1828,6 +1925,7 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onPauseBeforeSuper() {
mPaused = true;
+ mToast = null;
mUI.onPause();
if (mIsRecordingVideo) {
stopRecordingVideo(getMainCameraId());
@@ -1839,6 +1937,7 @@ public class CaptureModule implements CameraModule, PhotoController,
if (selfieThread != null) {
selfieThread.interrupt();
}
+ resetScreenOn();
mUI.stopSelfieFlash();
}
@@ -1855,6 +1954,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mFirstPreviewLoaded = false;
stopBackgroundThread();
mLastJpegData = null;
+ setProModeVisible();
}
@Override
@@ -1869,6 +1969,7 @@ public class CaptureModule implements CameraModule, PhotoController,
}
mLongshotActive = false;
mZoomValue = 1.0f;
+ updatePreviewSurfaceReadyState(false);
}
private ArrayList<Integer> getFrameProcFilterId() {
@@ -2025,7 +2126,6 @@ public class CaptureModule implements CameraModule, PhotoController,
Log.d(TAG, "onResume " + getCameraMode());
initializeValues();
updatePreviewSize();
- mUI.showSurfaceView();
mCameraIdList = new ArrayList<>();
if (mSound == null) {
@@ -2054,6 +2154,7 @@ public class CaptureModule implements CameraModule, PhotoController,
msg.arg1 = FRONT_ID;
mCameraHandler.sendMessage(msg);
}
+ mUI.showSurfaceView();
if (!mFirstTimeInitialized) {
initializeFirstTime();
} else {
@@ -2067,6 +2168,8 @@ public class CaptureModule implements CameraModule, PhotoController,
}
});
mUI.enableShutter(true);
+ mUI.enableVideo(true);
+ setProModeVisible();
String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
if(isPanoSetting(scene)) {
@@ -2284,16 +2387,17 @@ public class CaptureModule implements CameraModule, PhotoController,
}
private boolean isTouchToFocusAllowed() {
- if (isTakingPicture() || mIsRecordingVideo || isSceneModeOn()) return false;
+ if (isTakingPicture() || mIsRecordingVideo || isTouchAfEnabledSceneMode()) return false;
return true;
}
- private boolean isSceneModeOn() {
+ private boolean isTouchAfEnabledSceneMode() {
String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
if (scene == null) return false;
int mode = Integer.parseInt(scene);
- if (mode != SettingsManager.SCENE_MODE_DUAL_INT && mode != CaptureRequest
- .CONTROL_SCENE_MODE_DISABLED) return true;
+ if (mode != CaptureRequest.CONTROL_SCENE_MODE_DISABLED
+ && mode < SettingsManager.SCENE_MODE_CUSTOM_START)
+ return true;
return false;
}
@@ -2331,8 +2435,8 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onCountDownFinished() {
- mUI.showUIAfterCountDown();
checkSelfieFlashAndTakePicture();
+ mUI.showUIAfterCountDown();
}
@Override
@@ -2372,17 +2476,16 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onPreviewUIReady() {
+ updatePreviewSurfaceReadyState(true);
+
if (mPaused || mIsRecordingVideo) {
return;
}
- Log.d(TAG, "onPreviewUIReady");
- mSurfaceReady = true;
- createSessions();
}
@Override
public void onPreviewUIDestroyed() {
- mSurfaceReady = false;
+ updatePreviewSurfaceReadyState(false);
}
@Override
@@ -2532,34 +2635,58 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
- private void startRecordingVideo(int cameraId) {
+ private boolean startRecordingVideo(final int cameraId) {
if (null == mCameraDevice[cameraId]) {
- return;
+ return false;
}
Log.d(TAG, "StartRecordingVideo " + cameraId);
+ mStartRecPending = true;
mIsRecordingVideo = true;
mMediaRecorderPausing = false;
mUI.hideUIwhileRecording();
- mUI.clearFocus();
- mCameraHandler.removeMessages(CANCEL_TOUCH_FOCUS, mCameraId[cameraId]);
- mState[cameraId] = STATE_PREVIEW;
- mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
- closePreviewSession();
- mFrameProcessor.onClose();
- boolean changed = mUI.setPreviewSize(mVideoPreviewSize.getWidth(),
- mVideoPreviewSize.getHeight());
- if (changed) {
- mUI.hideSurfaceView();
- mUI.showSurfaceView();
+
+ mActivity.updateStorageSpaceAndHint();
+ if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
+ Log.w(TAG, "Storage issue, ignore the start request");
+ mStartRecPending = false;
+ mIsRecordingVideo = false;
+ return false;
}
- mUI.resetTrackingFocus();
try {
setUpMediaRecorder(cameraId);
+ if (mUnsupportedResolution == true ) {
+ Log.v(TAG, "Unsupported Resolution according to target");
+ mStartRecPending = false;
+ mIsRecordingVideo = false;
+ return false;
+ }
+ if (mMediaRecorder == null) {
+ Log.e(TAG, "Fail to initialize media recorder");
+ mStartRecPending = false;
+ mIsRecordingVideo = false;
+ return false;
+ }
+
+ requestAudioFocus();
+ mUI.clearFocus();
+ mCameraHandler.removeMessages(CANCEL_TOUCH_FOCUS, mCameraId[cameraId]);
+ mState[cameraId] = STATE_PREVIEW;
+ mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+ closePreviewSession();
+ mFrameProcessor.onClose();
+ boolean changed = mUI.setPreviewSize(mVideoPreviewSize.getWidth(),
+ mVideoPreviewSize.getHeight());
+ if (changed) {
+ mUI.hideSurfaceView();
+ mUI.showSurfaceView();
+ }
+ mUI.resetTrackingFocus();
+
createVideoSnapshotImageReader();
mVideoRequestBuilder = mCameraDevice[cameraId].createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mVideoRequestBuilder.setTag(cameraId);
-
+ mPreviewRequestBuilder[cameraId] = mVideoRequestBuilder;
List<Surface> surfaces = new ArrayList<>();
Surface surface = getPreviewSurfaceForSession(cameraId);
@@ -2585,11 +2712,12 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
mCurrentSession = cameraCaptureSession;
+ mCaptureSession[cameraId] = cameraCaptureSession;
CameraConstrainedHighSpeedCaptureSession session =
(CameraConstrainedHighSpeedCaptureSession) mCurrentSession;
try {
- List list = session
- .createHighSpeedRequestList(mVideoRequestBuilder.build());
+ List list = CameraUtil
+ .createHighSpeedRequestList(mVideoRequestBuilder.build(),cameraId);
session.setRepeatingBurst(list, mCaptureCallback, mCameraHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to start high speed video recording "
@@ -2604,7 +2732,17 @@ public class CaptureModule implements CameraModule, PhotoController,
+ e.getMessage());
e.printStackTrace();
}
- mMediaRecorder.start();
+ try {
+ mMediaRecorder.start(); // Recording is now started
+ } catch (RuntimeException e) {
+ Toast.makeText(mActivity,"Could not start media recorder.\n " +
+ "Can't start video recording.", Toast.LENGTH_LONG).show();
+ releaseMediaRecorder();
+ releaseAudioFocus();
+ mStartRecPending = false;
+ mIsRecordingVideo = false;
+ return;
+ }
mUI.clearFocus();
mUI.resetPauseButton();
mRecordingTotalTime = 0L;
@@ -2612,6 +2750,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mUI.enableShutter(false);
mUI.showRecordingUI(true, true);
updateRecordingTime();
+ keepScreenOn();
}
@Override
@@ -2628,20 +2767,34 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
Log.d(TAG, "StartRecordingVideo session onConfigured");
mCurrentSession = cameraCaptureSession;
+ mCaptureSession[cameraId] = cameraCaptureSession;
try {
setUpVideoCaptureRequestBuilder(mVideoRequestBuilder);
mCurrentSession.setRepeatingRequest(mVideoRequestBuilder.build(),
- mCaptureCallback, mCameraHandler);
+ mCaptureCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
+ } catch (IllegalStateException e) {
+ e.printStackTrace();
+ }
+ try {
+ mMediaRecorder.start(); // Recording is now started
+ } catch (RuntimeException e) {
+ Toast.makeText(mActivity,"Could not start media recorder.\n " +
+ "Can't start video recording.", Toast.LENGTH_LONG).show();
+ releaseMediaRecorder();
+ releaseAudioFocus();
+ mStartRecPending = false;
+ mIsRecordingVideo = false;
+ return;
}
- mMediaRecorder.start();
mUI.clearFocus();
mUI.resetPauseButton();
mRecordingTotalTime = 0L;
mRecordingStartTime = SystemClock.uptimeMillis();
mUI.showRecordingUI(true, false);
updateRecordingTime();
+ keepScreenOn();
}
@Override
@@ -2655,6 +2808,8 @@ public class CaptureModule implements CameraModule, PhotoController,
} catch (IOException e) {
e.printStackTrace();
}
+ mStartRecPending = false;
+ return true;
}
private void updateTimeLapseSetting() {
@@ -2724,7 +2879,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private void applyVideoStabilization(CaptureRequest.Builder builder) {
String value = mSettingsManager.getValue(SettingsManager.KEY_DIS);
if (value == null) return;
- if (value.equals("enable")) {
+ if (value.equals("on")) {
builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, CaptureRequest
.CONTROL_VIDEO_STABILIZATION_MODE_ON);
} else {
@@ -2828,14 +2983,31 @@ public class CaptureModule implements CameraModule, PhotoController,
private void stopRecordingVideo(int cameraId) {
Log.d(TAG, "stopRecordingVideo " + cameraId);
+ mStopRecPending = true;
+ boolean shouldAddToMediaStoreNow = false;
// Stop recording
mFrameProcessor.setVideoOutputSurface(null);
mFrameProcessor.onClose();
closePreviewSession();
- mMediaRecorder.stop();
- mMediaRecorder.reset();
- mMediaRecorder.setOnInfoListener(null);
- saveVideo();
+ try {
+ mMediaRecorder.setOnErrorListener(null);
+ mMediaRecorder.setOnInfoListener(null);
+ mMediaRecorder.stop();
+ shouldAddToMediaStoreNow = true;
+ AccessibilityUtils.makeAnnouncement(mUI.getVideoButton(),
+ mActivity.getString(R.string.video_recording_stopped));
+ } catch (RuntimeException e) {
+ Log.w(TAG, "MediaRecoder stop fail", e);
+ if (mVideoFilename != null) deleteVideoFile(mVideoFilename);
+ }
+ if (shouldAddToMediaStoreNow) {
+ saveVideo();
+ }
+ keepScreenOnAwhile();
+ // release media recorder
+ releaseMediaRecorder();
+ releaseAudioFocus();
+
mUI.showRecordingUI(false, false);
mUI.enableShutter(true);
@@ -2848,11 +3020,11 @@ public class CaptureModule implements CameraModule, PhotoController,
if (changed) {
mUI.hideSurfaceView();
mUI.showSurfaceView();
- } else {
- createSession(cameraId);
}
+ createSessions();
mUI.showUIafterRecording();
mUI.resetTrackingFocus();
+ mStopRecPending = false;
}
private void closePreviewSession() {
@@ -2933,9 +3105,20 @@ public class CaptureModule implements CameraModule, PhotoController,
if (mCaptureTimeLapse) {
size = CameraSettings.getTimeLapseQualityFor(size);
}
+
+ Intent intent = mActivity.getIntent();
+ Bundle myExtras = intent.getExtras();
+
+ if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();
+
updateHFRSetting();
boolean hfr = mHighSpeedCapture && !mHighSpeedRecordingMode;
+
mProfile = CamcorderProfile.get(cameraId, size);
+ int videoWidth = mProfile.videoFrameWidth;
+ int videoHeight = mProfile.videoFrameHeight;
+ mUnsupportedResolution = false;
+
int videoEncoder = SettingTranslation
.getVideoEncoder(mSettingsManager.getValue(SettingsManager.KEY_VIDEO_ENCODER));
int audioEncoder = SettingTranslation
@@ -2988,6 +3171,54 @@ public class CaptureModule implements CameraModule, PhotoController,
mMediaRecorder.setVideoEncodingBitRate(scaledBitrate);
}
+ long requestedSizeLimit = 0;
+ if (isVideoCaptureIntent() && myExtras != null) {
+ requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
+ }
+ //check if codec supports the resolution, otherwise throw toast
+ List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
+ for (VideoEncoderCap videoEnc: videoEncoders) {
+ if (videoEnc.mCodec == videoEncoder) {
+ if (videoWidth > videoEnc.mMaxFrameWidth ||
+ videoWidth < videoEnc.mMinFrameWidth ||
+ videoHeight > videoEnc.mMaxFrameHeight ||
+ videoHeight < videoEnc.mMinFrameHeight) {
+ Log.e(TAG, "Selected codec " + videoEncoder +
+ " does not support "+ videoWidth + "x" + videoHeight
+ + " resolution");
+ Log.e(TAG, "Codec capabilities: " +
+ "mMinFrameWidth = " + videoEnc.mMinFrameWidth + " , " +
+ "mMinFrameHeight = " + videoEnc.mMinFrameHeight + " , " +
+ "mMaxFrameWidth = " + videoEnc.mMaxFrameWidth + " , " +
+ "mMaxFrameHeight = " + videoEnc.mMaxFrameHeight);
+ mUnsupportedResolution = true;
+ RotateTextToast.makeText(mActivity, R.string.error_app_unsupported,
+ Toast.LENGTH_LONG).show();
+ return;
+ }
+ break;
+ }
+ }
+
+ // Set maximum file size.
+ long maxFileSize = mActivity.getStorageSpaceBytes() - Storage.LOW_STORAGE_THRESHOLD_BYTES;
+ if (requestedSizeLimit > 0 && requestedSizeLimit < maxFileSize) {
+ maxFileSize = requestedSizeLimit;
+ }
+
+ if (Storage.isSaveSDCard() && maxFileSize > SDCARD_SIZE_LIMIT) {
+ maxFileSize = SDCARD_SIZE_LIMIT;
+ }
+ Log.i(TAG, "MediaRecorder setMaxFileSize: " + maxFileSize);
+ try {
+ mMediaRecorder.setMaxFileSize(maxFileSize);
+ } catch (RuntimeException exception) {
+ // We are going to ignore failure of setMaxFileSize here, as
+ // a) The composer selected may simply not support it, or
+ // b) The underlying media framework may not handle 64-bit range
+ // on the size restriction.
+ }
+
Location loc = mLocationManager.getCurrentLocation();
if (loc != null) {
mMediaRecorder.setLocation((float) loc.getLatitude(),
@@ -3004,16 +3235,30 @@ public class CaptureModule implements CameraModule, PhotoController,
} else {
mMediaRecorder.setOrientationHint(rotation);
}
- mMediaRecorder.prepare();
+ try {
+ mMediaRecorder.prepare();
+ } catch (IOException e) {
+ Log.e(TAG, "prepare failed for " + mVideoFilename, e);
+ releaseMediaRecorder();
+ throw new RuntimeException(e);
+ }
+
+ mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.setOnInfoListener(this);
}
public void onVideoButtonClick() {
+ if (isRecorderReady() == false) return;
+
if (getCameraMode() == DUAL_MODE) return;
if (mIsRecordingVideo) {
stopRecordingVideo(getMainCameraId());
} else {
- startRecordingVideo(getMainCameraId());
+ if (!startRecordingVideo(getMainCameraId())) {
+ // Show ui when start recording failed.
+ mUI.showUIafterRecording();
+ releaseMediaRecorder();
+ }
}
}
@@ -3099,7 +3344,7 @@ public class CaptureModule implements CameraModule, PhotoController,
}
private void estimateJpegFileSize() {
- String quality = mSettingsManager.getValue(SettingsManager
+ String quality = mSettingsManager.getValue(SettingsManager
.KEY_JPEG_QUALITY);
int[] ratios = mActivity.getResources().getIntArray(R.array.jpegquality_compression_ratio);
String[] qualities = mActivity.getResources().getStringArray(
@@ -3159,6 +3404,10 @@ public class CaptureModule implements CameraModule, PhotoController,
return true;
}
+ if ( mIsRecordingVideo ) {
+ Log.e(TAG, " cancel longshot:not supported when recording");
+ return true;
+ }
return false;
}
@@ -3202,6 +3451,9 @@ public class CaptureModule implements CameraModule, PhotoController,
}
private boolean applyPreferenceToPreview(int cameraId, String key, String value) {
+ if (!checkSessionAndBuilder(mCaptureSession[cameraId], mPreviewRequestBuilder[cameraId])) {
+ return false;
+ }
boolean updatePreview = false;
switch (key) {
case SettingsManager.KEY_WHITE_BALANCE:
@@ -3228,11 +3480,17 @@ public class CaptureModule implements CameraModule, PhotoController,
updatePreview = true;
applyFaceDetection(mPreviewRequestBuilder[cameraId]);
break;
+ case SettingsManager.KEY_FOCUS_DISTANCE:
+ updatePreview = true;
+ applyFocusDistance(mPreviewRequestBuilder[cameraId], value);
}
return updatePreview;
}
private void applyZoomAndUpdate(int id) {
+ if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+ return;
+ }
applyZoom(mPreviewRequestBuilder[id], id);
try {
if(id == MONO_ID && !canStartMonoPreview()) {
@@ -3242,7 +3500,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
.build(), mCaptureCallback, mCameraHandler);
}
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -3277,8 +3535,9 @@ public class CaptureModule implements CameraModule, PhotoController,
request.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
return;
}
- if (mode != CaptureRequest.CONTROL_SCENE_MODE_DISABLED && mode !=
- SettingsManager.SCENE_MODE_DUAL_INT) {
+ if (mode != CaptureRequest.CONTROL_SCENE_MODE_DISABLED
+ && mode != SettingsManager.SCENE_MODE_DUAL_INT
+ && mode != SettingsManager.SCENE_MODE_PROMODE_INT) {
request.set(CaptureRequest.CONTROL_SCENE_MODE, mode);
request.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
} else {
@@ -3296,9 +3555,14 @@ public class CaptureModule implements CameraModule, PhotoController,
private void applyIso(CaptureRequest.Builder request) {
String value = mSettingsManager.getValue(SettingsManager.KEY_ISO);
if (value == null) return;
- if (value.equals("auto")) return;
- int intValue = Integer.parseInt(value);
- request.set(CaptureRequest.SENSOR_SENSITIVITY, intValue);
+ if (value.equals("auto")) {
+ request.set(SELECT_PRIORITY, null);
+ request.set(ISO_EXP, null);
+ } else {
+ long intValue = Integer.parseInt(value);
+ request.set(SELECT_PRIORITY, 0);
+ request.set(ISO_EXP, intValue);
+ }
}
private void applyColorEffect(CaptureRequest.Builder request) {
@@ -3350,11 +3614,11 @@ public class CaptureModule implements CameraModule, PhotoController,
}
private void applyFaceDetection(CaptureRequest.Builder request) {
- String value = mSettingsManager.getValue(SettingsManager.KEY_FACE_DETECTION);
- if (value != null && value.equals("on")) {
- request.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
- CaptureRequest.STATISTICS_FACE_DETECT_MODE_SIMPLE);
- }
+ String value = mSettingsManager.getValue(SettingsManager.KEY_FACE_DETECTION);
+ if (value != null && value.equals("on")) {
+ request.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
+ CaptureRequest.STATISTICS_FACE_DETECT_MODE_SIMPLE);
+ }
}
private void applyFlash(CaptureRequest.Builder request, int id) {
@@ -3542,6 +3806,9 @@ public class CaptureModule implements CameraModule, PhotoController,
case SettingsManager.KEY_FLASH_MODE:
if (count == 0) restartSession(false);
return;
+ case SettingsManager.KEY_SCENE_MODE:
+ restartAll();
+ return;
}
if (isBackCamera()) {
@@ -3564,30 +3831,39 @@ public class CaptureModule implements CameraModule, PhotoController,
}
if (updatePreviewBayer) {
try {
- mCaptureSession[BAYER_ID].setRepeatingRequest(mPreviewRequestBuilder[BAYER_ID]
- .build(), mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ if (checkSessionAndBuilder(mCaptureSession[BAYER_ID],
+ mPreviewRequestBuilder[BAYER_ID])) {
+ mCaptureSession[BAYER_ID].setRepeatingRequest(mPreviewRequestBuilder[BAYER_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
if (updatePreviewMono) {
try {
- if(canStartMonoPreview()) {
- mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID]
- .build(), mCaptureCallback, mCameraHandler);
- } else {
- mCaptureSession[MONO_ID].capture(mPreviewRequestBuilder[MONO_ID]
- .build(), mCaptureCallback, mCameraHandler);
+ if (checkSessionAndBuilder(mCaptureSession[MONO_ID],
+ mPreviewRequestBuilder[MONO_ID])) {
+ if (canStartMonoPreview()) {
+ mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[MONO_ID].capture(mPreviewRequestBuilder[MONO_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
}
- } catch (CameraAccessException e) {
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
if (updatePreviewFront) {
try {
- mCaptureSession[FRONT_ID].setRepeatingRequest(mPreviewRequestBuilder[FRONT_ID]
- .build(), mCaptureCallback, mCameraHandler);
- } catch (CameraAccessException e) {
+ if (checkSessionAndBuilder(mCaptureSession[FRONT_ID],
+ mPreviewRequestBuilder[FRONT_ID])) {
+ mCaptureSession[FRONT_ID].setRepeatingRequest(mPreviewRequestBuilder[FRONT_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
+ } catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@@ -3628,25 +3904,36 @@ public class CaptureModule implements CameraModule, PhotoController,
}
public void restartSession(boolean isSurfaceChanged) {
+ Log.d(TAG, "restartSession isSurfaceChanged = " + isSurfaceChanged);
+ if (isAllSessionClosed()) return;
+
+ closeProcessors();
+ closeSessions();
+
if(isSurfaceChanged) {
mUI.hideSurfaceView();
+ mUI.showSurfaceView();
}
- closeProcessors();
- closeSessions();
+
initializeValues();
updatePreviewSize();
openProcessors();
- if(isSurfaceChanged) {
- mUI.showSurfaceView();
- } else {
- createSessions();
- }
+ createSessions();
if(isTrackingFocusSettingOn()) {
mUI.resetTrackingFocus();
}
+ resetStateMachine();
}
+ private void resetStateMachine() {
+ for (int i = 0; i < MAX_NUM_CAM; i++) {
+ mState[i] = STATE_PREVIEW;
+ }
+ mUI.enableShutter(true);
+ }
+
+
private Size getOptimalPreviewSize(Size pictureSize, Size[] prevSizes, int screenW, int
screenH) {
if (pictureSize.getWidth() <= screenH && pictureSize.getHeight() <= screenW) {
@@ -3822,6 +4109,11 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case CLEAR_SCREEN_DELAY: {
+ mActivity.getWindow().clearFlags(
+ WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ break;
+ }
case UPDATE_RECORD_TIME: {
updateRecordingTime();
break;
@@ -3835,6 +4127,18 @@ public class CaptureModule implements CameraModule, PhotoController,
enableRecordingLocation(false);
}
+ // from MediaRecorder.OnErrorListener
+ @Override
+ public void onError(MediaRecorder mr, int what, int extra) {
+ Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
+ stopRecordingVideo(getMainCameraId());
+ mUI.showUIafterRecording();
+ if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
+ // We may have run out of space on the sdcard.
+ mActivity.updateStorageSpaceAndHint();
+ }
+ }
+
// from MediaRecorder.OnInfoListener
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
@@ -3863,4 +4167,109 @@ public class CaptureModule implements CameraModule, PhotoController,
Storage.setSaveSDCard(mSettingsManager.getValue(SettingsManager
.KEY_CAMERA_SAVEPATH).equals("1"));
}
+
+ private void deleteVideoFile(String fileName) {
+ Log.v(TAG, "Deleting video " + fileName);
+ File f = new File(fileName);
+ if (!f.delete()) {
+ Log.v(TAG, "Could not delete " + fileName);
+ }
+ }
+
+ private void releaseMediaRecorder() {
+ Log.v(TAG, "Releasing media recorder.");
+ if (mMediaRecorder != null) {
+ cleanupEmptyFile();
+ mMediaRecorder.reset();
+ mMediaRecorder.release();
+ mMediaRecorder = null;
+ }
+ mVideoFilename = null;
+ }
+
+ private void cleanupEmptyFile() {
+ if (mVideoFilename != null) {
+ File f = new File(mVideoFilename);
+ if (f.length() == 0 && f.delete()) {
+ Log.v(TAG, "Empty video file deleted: " + mVideoFilename);
+ mVideoFilename = null;
+ }
+ }
+ }
+
+ private void showToast(String tips) {
+ if (mToast == null) {
+ mToast = Toast.makeText(mActivity, tips, Toast.LENGTH_LONG);
+ }
+ mToast.setText(tips);
+ mToast.show();
+ }
+
+ private boolean isRecorderReady() {
+ if ((mStartRecPending == true || mStopRecPending == true))
+ return false;
+ else
+ return true;
+ }
+
+ /*
+ * Make sure we're not recording music playing in the background, ask the
+ * MediaPlaybackService to pause playback.
+ */
+ private void requestAudioFocus() {
+ AudioManager am = (AudioManager)mActivity.getSystemService(Context.AUDIO_SERVICE);
+ // Send request to obtain audio focus. This will stop other
+ // music stream.
+ int result = am.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
+ Log.v(TAG, "Audio focus request failed");
+ }
+ }
+
+ private void releaseAudioFocus() {
+ AudioManager am = (AudioManager)mActivity.getSystemService(Context.AUDIO_SERVICE);
+ int result = am.abandonAudioFocus(null);
+ if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
+ Log.v(TAG, "Audio focus release failed");
+ }
+ }
+
+ private boolean isVideoCaptureIntent() {
+ String action = mActivity.getIntent().getAction();
+ return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
+ }
+
+ private void resetScreenOn() {
+ mHandler.removeMessages(CLEAR_SCREEN_DELAY);
+ mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ private void keepScreenOnAwhile() {
+ mHandler.removeMessages(CLEAR_SCREEN_DELAY);
+ mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
+ }
+
+ private void keepScreenOn() {
+ mHandler.removeMessages(CLEAR_SCREEN_DELAY);
+ mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+
+ private void setProModeVisible() {
+ String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
+ boolean promode = false;
+ if (scene != null) {
+ int mode = Integer.parseInt(scene);
+ if (mode == SettingsManager.SCENE_MODE_PROMODE_INT) {
+ promode = true;
+ }
+ }
+ mUI.initializeProMode(!mPaused && promode);
+ }
+
+ boolean checkSessionAndBuilder(CameraCaptureSession session, CaptureRequest.Builder builder) {
+ return session != null && builder != null;
+ }
}
diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java
index 88460b865..1bb20e9f7 100644
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -38,8 +38,10 @@ import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
import android.text.TextUtils;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
@@ -49,12 +51,14 @@ import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
-
import com.android.camera.ui.AutoFitSurfaceView;
import com.android.camera.ui.Camera2FaceView;
import com.android.camera.ui.CameraControls;
@@ -77,6 +81,7 @@ import org.codeaurora.snapcam.R;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
public class CaptureUI implements FocusOverlayManager.FocusUI,
PreviewGestures.SingleTapListener,
@@ -184,15 +189,30 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
private PauseButton mPauseButton;
private RotateImageView mMuteButton;
private ImageView mSeekbarToggleButton;
+ private View mProModeCloseButton;
+ private RotateLayout mSceneModeLabelRect;
+ private LinearLayout mSceneModeLabelView;
+ private TextView mSceneModeName;
+ private ImageView mSceneModeLabelCloseIcon;
+ private AlertDialog mSceneModeInstructionalDialog = null;
int mPreviewWidth;
int mPreviewHeight;
private boolean mIsVideoUI = false;
+ private boolean mIsSceneModeLabelClose = false;
private void previewUIReady() {
if((mSurfaceHolder != null && mSurfaceHolder.getSurface().isValid())) {
mModule.onPreviewUIReady();
- mActivity.updateThumbnail(mThumbnail);
+ if (mIsVideoUI && mThumbnail != null) {
+ mThumbnail.setVisibility(View.INVISIBLE);
+ mThumbnail = null;
+ mActivity.updateThumbnail(mThumbnail);
+ } else if (!mIsVideoUI){
+ if (mThumbnail == null)
+ mThumbnail = (ImageView) mRootView.findViewById(R.id.preview_thumb);
+ mActivity.updateThumbnail(mThumbnail);
+ }
}
}
@@ -208,7 +228,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
return mDisplaySize;
}
- public CaptureUI(CameraActivity activity, CaptureModule module, View parent) {
+ public CaptureUI(CameraActivity activity, final CaptureModule module, View parent) {
mActivity = activity;
mModule = module;
mRootView = parent;
@@ -278,15 +298,26 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
mMakeupButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
- toggleMakeup();
+ if (module != null && !module.isAllSessionClosed()) {
+ toggleMakeup();
+ updateMenus();
+ }
}
});
setMakeupButtonIcon();
mFlashButton = (FlashToggleButton) mRootView.findViewById(R.id.flash_button);
+ mProModeCloseButton = mRootView.findViewById(R.id.promode_close_button);
+ mProModeCloseButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mSettingsManager.setValue(SettingsManager.KEY_SCENE_MODE, "" + SettingsManager.SCENE_MODE_AUTO_INT);
+ }
+ });
initFilterModeButton();
initSceneModeButton();
initSwitchCamera();
initFlashButton();
+ updateMenus();
mRecordingTimeView = (TextView) mRootView.findViewById(R.id.recording_time);
mRecordingTimeRect = (RotateLayout) mRootView.findViewById(R.id.recording_time_rect);
@@ -316,6 +347,17 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
RotateImageView muteButton = (RotateImageView) mRootView.findViewById(R.id.mute_button);
muteButton.setVisibility(View.GONE);
+ mSceneModeLabelRect = (RotateLayout)mRootView.findViewById(R.id.scene_mode_label_rect);
+ mSceneModeName = (TextView)mRootView.findViewById(R.id.scene_mode_label);
+ mSceneModeLabelCloseIcon = (ImageView)mRootView.findViewById(R.id.scene_mode_label_close);
+ mSceneModeLabelCloseIcon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mIsSceneModeLabelClose = true;
+ mSceneModeLabelRect.setVisibility(View.GONE);
+ }
+ });
+
mCameraControls = (OneUICameraControls) mRootView.findViewById(R.id.camera_controls);
mFaceView = (Camera2FaceView) mRootView.findViewById(R.id.face_view);
@@ -359,7 +401,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
mRenderOverlay.requestLayout();
mActivity.setPreviewGestures(mGestures);
- ((ViewGroup)mRootView).removeView(mRecordingTimeRect);
+ mRecordingTimeRect.setVisibility(View.GONE);
showFirstTimeHelp();
}
@@ -367,8 +409,8 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
String value = mSettingsManager.getValue(SettingsManager.KEY_MAKEUP);
if(value != null && !mIsVideoUI) {
if(value.equals("0")) {
- mSettingsManager.setValue(SettingsManager.KEY_MAKEUP, "10");
- mMakeupSeekBar.setProgress(10);
+ mSettingsManager.setValue(SettingsManager.KEY_MAKEUP, "50");
+ mMakeupSeekBar.setProgress(50);
mMakeupSeekBarLayout.setVisibility(View.VISIBLE);
mSeekbarBody.setVisibility(View.VISIBLE);
mSeekbarToggleButton.setImageResource(R.drawable.seekbar_hide);
@@ -408,6 +450,8 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
initFilterModeButton();
initFlashButton();
setMakeupButtonIcon();
+ showSceneModeLabel();
+ updateMenus();
if(mModule.isTrackingFocusSettingOn()) {
mTrackingFocusRenderer.setVisible(false);
mTrackingFocusRenderer.setVisible(true);
@@ -425,6 +469,12 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
}
+ public void initializeProMode(boolean promode) {
+ mCameraControls.setProMode(promode);
+ if (promode) mVideoButton.setVisibility(View.INVISIBLE);
+ else mVideoButton.setVisibility(View.VISIBLE);
+ }
+
// called from onResume but only the first time
public void initializeFirstTime() {
// Initialize shutter button.
@@ -477,6 +527,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
mFilterLayout = null;
}
}
+ updateMenus();
}
public void openSettingsMenu() {
@@ -514,6 +565,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
public void initFlashButton() {
mFlashButton.init(false);
+ enableView(mFlashButton, SettingsManager.KEY_FLASH_MODE);
}
public void initSceneModeButton() {
@@ -538,16 +590,28 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
String value = mSettingsManager.getValue(SettingsManager.KEY_COLOR_EFFECT);
if (value == null) return;
+ enableView(mFilterModeSwitcher, SettingsManager.KEY_COLOR_EFFECT);
+
mFilterModeSwitcher.setVisibility(View.VISIBLE);
mFilterModeSwitcher.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addFilterMode();
adjustOrientation();
+ updateMenus();
}
});
}
+ private void enableView(View view, String key) {
+ Map<String, SettingsManager.Values> map = mSettingsManager.getValuesMap();
+ SettingsManager.Values values = map.get(key);
+ if ( values != null ) {
+ boolean enabled = values.overriddenValue == null;
+ view.setEnabled(enabled);
+ }
+ }
+
public void showTimeLapseUI(boolean enable) {
if (mTimeLapseLabel != null) {
mTimeLapseLabel.setVisibility(enable ? View.VISIBLE : View.GONE);
@@ -563,17 +627,128 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
mVideoButton.setImageResource(R.drawable.video_stop);
mRecordingTimeView.setText("");
- ((ViewGroup)mRootView).addView(mRecordingTimeRect);
+ mRecordingTimeRect.setVisibility(View.VISIBLE);
mMuteButton.setVisibility(View.VISIBLE);
} else {
mFlashButton.setVisibility(View.VISIBLE);
mFlashButton.init(false);
mVideoButton.setImageResource(R.drawable.video_capture);
- ((ViewGroup)mRootView).removeView(mRecordingTimeRect);
+ mRecordingTimeRect.setVisibility(View.GONE);
mMuteButton.setVisibility(View.INVISIBLE);
}
}
+ private boolean needShowInstructional() {
+ boolean needShow = true;
+ final SharedPreferences pref = mActivity.getSharedPreferences(
+ ComboPreferences.getGlobalSharedPreferencesName(mActivity), Context.MODE_PRIVATE);
+ int index = mSettingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE);
+ if ( index < 1 ) {
+ needShow = false;
+ }else{
+ final String instructionalKey = SettingsManager.KEY_SCENE_MODE + "_" + index;
+ needShow = pref.getBoolean(instructionalKey, false) ? false : true;
+ }
+
+ return needShow;
+
+ }
+
+ private void showSceneInstructionalDialog(int orientation) {
+ LayoutInflater inflater =
+ (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view = inflater.inflate(R.layout.scene_mode_instructional, null);
+
+ final int index = mSettingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE);
+ TextView name = (TextView)view.findViewById(R.id.scene_mode_name);
+ CharSequence sceneModeNameArray[] =
+ mSettingsManager.getEntries(SettingsManager.KEY_SCENE_MODE);
+ name.setText(sceneModeNameArray[index]);
+
+ ImageView icon = (ImageView)view.findViewById(R.id.scene_mode_icon);
+ int[] resId = mSettingsManager.getResource(SettingsManager.KEY_SCEND_MODE_INSTRUCTIONAL,
+ SettingsManager.RESOURCE_TYPE_THUMBNAIL);
+ icon.setImageResource(resId[index]);
+
+ TextView instructional = (TextView)view.findViewById(R.id.scene_mode_instructional);
+ CharSequence instructionalArray[] =
+ mSettingsManager.getEntries(SettingsManager.KEY_SCEND_MODE_INSTRUCTIONAL);
+ if ( instructionalArray[index].length() == 0 ) {
+ //For now, not all scene mode has instructional
+ return;
+ }
+ instructional.setText(instructionalArray[index]);
+
+ final CheckBox remember = (CheckBox)view.findViewById(R.id.remember_selected);
+ Button ok = (Button)view.findViewById(R.id.scene_mode_instructional_ok);
+ ok.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+
+ if ( remember.isChecked()) {
+ final SharedPreferences pref = mActivity.getSharedPreferences(
+ ComboPreferences.getGlobalSharedPreferencesName(mActivity),
+ Context.MODE_PRIVATE);
+
+ String instructionalKey = SettingsManager.KEY_SCENE_MODE + "_" + index;
+ SharedPreferences.Editor editor = pref.edit();
+ editor.putBoolean(instructionalKey, true);
+ editor.commit();
+ }
+ mSceneModeInstructionalDialog.dismiss();
+ mSceneModeInstructionalDialog = null;
+ }
+ });
+
+ mSceneModeInstructionalDialog =
+ new AlertDialog.Builder(mActivity, AlertDialog.THEME_HOLO_LIGHT)
+ .setView(view).create();
+ try {
+ mSceneModeInstructionalDialog.show();
+ }catch(Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ if ( orientation != 0 ) {
+ rotationSceneModeInstructionalDialog(view, orientation);
+ }
+ }
+
+ private int getScreenWidth() {
+ DisplayMetrics metric = new DisplayMetrics();
+ mActivity.getWindowManager().getDefaultDisplay().getMetrics(metric);
+ return metric.widthPixels < metric.heightPixels ? metric.widthPixels : metric.heightPixels;
+ }
+
+ private void rotationSceneModeInstructionalDialog(View view, int orientation) {
+ view.setRotation(-orientation);
+ int screenWidth = getScreenWidth();
+ int dialogSize = screenWidth*9/10;
+ Window dialogWindow = mSceneModeInstructionalDialog.getWindow();
+ WindowManager.LayoutParams lp = dialogWindow.getAttributes();
+ dialogWindow.setGravity(Gravity.CENTER);
+ lp.width = lp.height = dialogSize;
+ dialogWindow.setAttributes(lp);
+ if ( orientation == 180 ) {
+ dialogSize -= 40;
+ RelativeLayout layout = (RelativeLayout)view.findViewById(R.id.mode_layout_rect);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(dialogSize, dialogSize);
+ layout.setLayoutParams(params);
+ }
+ }
+
+ private void showSceneModeLabel() {
+ mIsSceneModeLabelClose = false;
+ int index = mSettingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE);
+ CharSequence sceneModeNameArray[] = mSettingsManager.getEntries(SettingsManager.KEY_SCENE_MODE);
+ if ( index > 0 && index < sceneModeNameArray.length ) {
+ mSceneModeName.setText(sceneModeNameArray[index]);
+ mSceneModeLabelRect.setVisibility(View.VISIBLE);
+ }else{
+ mSceneModeLabelRect.setVisibility(View.GONE);
+ }
+ }
+
+
public void resetTrackingFocus() {
if(mModule.isTrackingFocusSettingOn()) {
mTrackingFocusRenderer.setVisible(false);
@@ -582,25 +757,26 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
public void hideUIwhileRecording() {
- mCameraControls.setWillNotDraw(true);
+ mCameraControls.setVideoMode(true);
mFrontBackSwitcher.setVisibility(View.INVISIBLE);
mFilterModeSwitcher.setVisibility(View.INVISIBLE);
mSceneModeSwitcher.setVisibility(View.INVISIBLE);
-
String value = mSettingsManager.getValue(SettingsManager.KEY_MAKEUP);
if(value != null && value.equals("0")) {
mMakeupButton.setVisibility(View.INVISIBLE);
}
mIsVideoUI = true;
+ mPauseButton.setVisibility(View.VISIBLE);
}
public void showUIafterRecording() {
- mCameraControls.setWillNotDraw(false);
+ mCameraControls.setVideoMode(false);
mFrontBackSwitcher.setVisibility(View.VISIBLE);
mFilterModeSwitcher.setVisibility(View.VISIBLE);
mSceneModeSwitcher.setVisibility(View.VISIBLE);
mMakeupButton.setVisibility(View.VISIBLE);
mIsVideoUI = false;
+ mPauseButton.setVisibility(View.INVISIBLE);
}
public void addFilterMode() {
@@ -860,9 +1036,33 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
public void cleanUpMenus() {
showUI();
+ updateMenus();
mActivity.setSystemBarsVisibility(false);
}
+ public void updateMenus() {
+ boolean enableMakeupMenu = true;
+ boolean enableFilterMenu = true;
+ boolean enableSceneMenu = true;
+ String makeupValue = mSettingsManager.getValue(SettingsManager.KEY_MAKEUP);
+ int colorEffect = mSettingsManager.getValueIndex(SettingsManager.KEY_COLOR_EFFECT);
+ String sceneMode = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
+ if (makeupValue != null && !makeupValue.equals("0")) {
+ enableSceneMenu = false;
+ enableFilterMenu = false;
+ } else if (colorEffect != 0 || mFilterMenuStatus == FILTER_MENU_ON){
+ enableSceneMenu = false;
+ enableMakeupMenu = false;
+ }else if ( sceneMode != null && !sceneMode.equals("0")){
+ enableMakeupMenu = false;
+ enableFilterMenu = false;
+ }
+
+ mMakeupButton.setEnabled(enableMakeupMenu);
+ mFilterModeSwitcher.setEnabled(enableFilterMenu);
+ mSceneModeSwitcher.setEnabled(enableSceneMenu);
+ }
+
public boolean arePreviewControlsVisible() {
return !mUIhidden;
}
@@ -879,6 +1079,15 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
}
+ /**
+ * Enables or disables the video button.
+ */
+ public void enableVideo(boolean enabled) {
+ if (mVideoButton != null) {
+ mVideoButton.setEnabled(enabled);
+ }
+ }
+
private boolean handleBackKeyOnMenu() {
if (mFilterMenuStatus == FILTER_MENU_ON) {
removeFilterMenu(true);
@@ -1143,13 +1352,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
}
if (mRecordingTimeRect != null) {
- if (orientation == 180) {
- mRecordingTimeRect.setOrientation(0, false);
- mRecordingTimeView.setRotation(180);
- } else {
- mRecordingTimeView.setRotation(0);
- mRecordingTimeRect.setOrientation(orientation, false);
- }
+ mRecordingTimeView.setRotation(-orientation);
}
if (mFaceView != null) {
mFaceView.setDisplayRotation(orientation);
@@ -1160,6 +1363,24 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
if (mZoomRenderer != null) {
mZoomRenderer.setOrientation(orientation);
}
+
+ if ( mSceneModeLabelRect != null ) {
+ if (orientation == 180) {
+ mSceneModeName.setRotation(180);
+ mSceneModeLabelCloseIcon.setRotation(180);
+ mSceneModeLabelRect.setOrientation(0, false);
+ } else {
+ mSceneModeName.setRotation(0);
+ mSceneModeLabelCloseIcon.setRotation(0);
+ mSceneModeLabelRect.setOrientation(orientation, false);
+ }
+ }
+
+ if ( mSceneModeInstructionalDialog != null && mSceneModeInstructionalDialog.isShowing()) {
+ mSceneModeInstructionalDialog.dismiss();
+ mSceneModeInstructionalDialog = null;
+ showSceneInstructionalDialog(orientation);
+ }
}
public int getOrientation() {
@@ -1282,6 +1503,23 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
@Override
public void onSettingsChanged(List<SettingsManager.SettingState> settings) {
+ for( SettingsManager.SettingState state : settings) {
+ if (state.key.equals(SettingsManager.KEY_COLOR_EFFECT)) {
+ enableView(mFilterModeSwitcher, SettingsManager.KEY_COLOR_EFFECT);
+ } else if (state.key.equals(SettingsManager.KEY_SCENE_MODE)) {
+ String value = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
+ if ( value.equals("104") ) {//panorama
+ mSceneModeLabelRect.setVisibility(View.GONE);
+ }else{
+ if ( needShowInstructional() ) {
+ showSceneInstructionalDialog(mOrientation);
+ }
+ showSceneModeLabel();
+ }
+ }else if(state.key.equals(SettingsManager.KEY_FLASH_MODE) ) {
+ enableView(mFlashButton, SettingsManager.KEY_FLASH_MODE);
+ }
+ }
}
public void startSelfieFlash() {
@@ -1315,6 +1553,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
public void showSurfaceView() {
+ Log.d(TAG, "showSurfaceView");
mSurfaceView.getHolder().setFixedSize(mPreviewWidth, mPreviewHeight);
mSurfaceView.setAspectRatio(mPreviewHeight, mPreviewWidth);
mSurfaceView.setVisibility(View.VISIBLE);
@@ -1359,4 +1598,9 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
}
}
+
+ public ImageView getVideoButton() {
+ return mVideoButton;
+ }
+
}
diff --git a/src/com/android/camera/ComboPreferences.java b/src/com/android/camera/ComboPreferences.java
index 1979d1b5a..401289fc3 100644
--- a/src/com/android/camera/ComboPreferences.java
+++ b/src/com/android/camera/ComboPreferences.java
@@ -68,12 +68,12 @@ public class ComboPreferences implements
}
}
- private static String getLocalSharedPreferencesName(
+ public static String getLocalSharedPreferencesName(
Context context, int cameraId) {
return context.getPackageName() + "_preferences_" + cameraId;
}
- private static String getGlobalSharedPreferencesName(Context context) {
+ public static String getGlobalSharedPreferencesName(Context context) {
return context.getPackageName() + "_preferences_camera";
}
diff --git a/src/com/android/camera/PanoCaptureModule.java b/src/com/android/camera/PanoCaptureModule.java
index ff5715e20..c6045d1c3 100644
--- a/src/com/android/camera/PanoCaptureModule.java
+++ b/src/com/android/camera/PanoCaptureModule.java
@@ -271,10 +271,12 @@ public class PanoCaptureModule implements CameraModule, PhotoController {
mCameraOpened = false;
mSurfaceReady = false;
mActivity = activity;
-
+ SettingsManager settingsManager = SettingsManager.getInstance();
+ settingsManager.init();
mUI = new PanoCaptureUI(activity, this, parent);
mContentResolver = mActivity.getContentResolver();
mLocationManager = new LocationManager(mActivity, null);
+
}
public void changePanoStatus(boolean newStatus, boolean isCancelling) {
diff --git a/src/com/android/camera/PanoCaptureUI.java b/src/com/android/camera/PanoCaptureUI.java
index 3ab43f915..5e9692908 100644
--- a/src/com/android/camera/PanoCaptureUI.java
+++ b/src/com/android/camera/PanoCaptureUI.java
@@ -24,16 +24,29 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.Camera.Face;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
+
+import android.view.Window;
+import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
import com.android.camera.ui.AutoFitSurfaceView;
import com.android.camera.ui.CameraControls;
@@ -41,6 +54,7 @@ import com.android.camera.ui.CameraRootView;
import com.android.camera.ui.FocusIndicator;
import com.android.camera.ui.ModuleSwitcher;
import com.android.camera.ui.PanoCaptureProcessView;
+import com.android.camera.ui.RotateLayout;
import com.android.camera.util.CameraUtil;
import org.codeaurora.snapcam.R;
@@ -60,6 +74,12 @@ public class PanoCaptureUI implements
private ShutterButton mShutterButton;
private ModuleSwitcher mSwitcher;
private CameraControls mCameraControls;
+ private RotateLayout mSceneModeLabelRect;
+ private LinearLayout mSceneModeLabelView;
+ private TextView mSceneModeName;
+ private ImageView mSceneModeLabelCloseIcon;
+ private AlertDialog mSceneModeInstructionalDialog = null;
+
// Small indicators which show the camera settings in the viewfinder.
private OnScreenIndicators mOnScreenIndicators;
@@ -74,6 +94,7 @@ public class PanoCaptureUI implements
private ImageView mThumbnail;
private int mOrientation;
+ private boolean mIsSceneModeLabelClose = false;
public void clearSurfaces() {
mSurfaceHolder = null;
@@ -193,12 +214,26 @@ public class PanoCaptureUI implements
}
});
+ mSceneModeLabelRect = (RotateLayout)mRootView.findViewById(R.id.scene_mode_label_rect);
+ mSceneModeName = (TextView)mRootView.findViewById(R.id.scene_mode_label);
+ mSceneModeName.setText(R.string.pref_camera_scenemode_entry_panorama);
+ mSceneModeLabelCloseIcon = (ImageView)mRootView.findViewById(R.id.scene_mode_label_close);
+ mSceneModeLabelCloseIcon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mIsSceneModeLabelClose = true;
+ mSceneModeLabelRect.setVisibility(View.GONE);
+ }
+ });
initIndicators();
Point size = new Point();
mActivity.getWindowManager().getDefaultDisplay().getSize(size);
calculateMargins(size);
mCameraControls.setMargins(mTopMargin, mBottomMargin);
+ if ( needShowInstructional() ) {
+ showSceneInstructionalDialog(mOrientation);
+ }
}
private void calculateMargins(Point size) {
@@ -381,6 +416,24 @@ public class PanoCaptureUI implements
mOrientation = orientation;
mCameraControls.setOrientation(orientation, animation);
mPreviewProcessView.setOrientation(orientation);
+
+ if ( mSceneModeLabelRect != null ) {
+ if (orientation == 180) {
+ mSceneModeName.setRotation(180);
+ mSceneModeLabelCloseIcon.setRotation(180);
+ mSceneModeLabelRect.setOrientation(0, false);
+ } else {
+ mSceneModeName.setRotation(0);
+ mSceneModeLabelCloseIcon.setRotation(0);
+ mSceneModeLabelRect.setOrientation(orientation, false);
+ }
+ }
+
+ if ( mSceneModeInstructionalDialog != null && mSceneModeInstructionalDialog.isShowing()) {
+ mSceneModeInstructionalDialog.dismiss();
+ mSceneModeInstructionalDialog = null;
+ showSceneInstructionalDialog(orientation);
+ }
}
public int getOrientation() {
@@ -391,4 +444,83 @@ public class PanoCaptureUI implements
public void onErrorListener(int error) {
}
+
+ private boolean needShowInstructional() {
+ final SharedPreferences pref = mActivity.getSharedPreferences(
+ ComboPreferences.getGlobalSharedPreferencesName(mActivity), Context.MODE_PRIVATE);
+ SettingsManager settingsManager = SettingsManager.getInstance();
+ int index = settingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE);
+ final String instructionalKey = SettingsManager.KEY_SCENE_MODE + "_" + index;
+ return !pref.getBoolean(instructionalKey, false);
+ }
+
+ private void showSceneInstructionalDialog(int orientation) {
+ LayoutInflater inflater =
+ (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view = inflater.inflate(R.layout.scene_mode_instructional, null);
+
+ TextView name = (TextView)view.findViewById(R.id.scene_mode_name);
+ name.setText(R.string.pref_camera_scenemode_entry_panorama);
+
+ ImageView icon = (ImageView)view.findViewById(R.id.scene_mode_icon);
+ icon.setImageResource(R.drawable.ic_scene_mode_black_panorama);
+
+ TextView instructional = (TextView)view.findViewById(R.id.scene_mode_instructional);
+ instructional.setText(R.string.pref_camera2_scene_mode_panorama_instructional_content);
+
+ final CheckBox remember = (CheckBox)view.findViewById(R.id.remember_selected);
+ Button ok = (Button)view.findViewById(R.id.scene_mode_instructional_ok);
+ ok.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ SharedPreferences pref = mActivity.getSharedPreferences(
+ ComboPreferences.getGlobalSharedPreferencesName(mActivity),
+ Context.MODE_PRIVATE);
+ int index =
+ SettingsManager.getInstance().getValueIndex(SettingsManager.KEY_SCENE_MODE);
+ String instructionalKey = SettingsManager.KEY_SCENE_MODE + "_" + index;
+ if ( remember.isChecked()) {
+ SharedPreferences.Editor editor = pref.edit();
+ editor.putBoolean(instructionalKey, true);
+ editor.commit();
+ }
+ mSceneModeInstructionalDialog.dismiss();
+ mSceneModeInstructionalDialog = null;
+ }
+ });
+ mSceneModeInstructionalDialog =
+ new AlertDialog.Builder(mActivity, AlertDialog.THEME_HOLO_LIGHT)
+ .setView(view).create();
+ try {
+ mSceneModeInstructionalDialog.show();
+ }catch(Exception e){
+ e.printStackTrace();
+ return;
+ }
+ if ( orientation != 0 ) {
+ rotationSceneModeInstructionalDialog(view, orientation);
+ }
+ }
+
+ private int getScreenWidth() {
+ DisplayMetrics metric = new DisplayMetrics();
+ mActivity.getWindowManager().getDefaultDisplay().getMetrics(metric);
+ return metric.widthPixels < metric.heightPixels ? metric.widthPixels : metric.heightPixels;
+ }
+
+ private void rotationSceneModeInstructionalDialog(View view, int orientation) {
+ view.setRotation(-orientation);
+ int screenWidth = getScreenWidth();
+ int dialogSize = screenWidth*9/10;
+ Window dialogWindow = mSceneModeInstructionalDialog.getWindow();
+ WindowManager.LayoutParams lp = dialogWindow.getAttributes();
+ dialogWindow.setGravity(Gravity.CENTER);
+ lp.width = lp.height = dialogSize;
+ dialogWindow.setAttributes(lp);
+ if ( orientation == 180 ) {
+ dialogSize -= 40;
+ RelativeLayout layout = (RelativeLayout)view.findViewById(R.id.mode_layout_rect);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(dialogSize, dialogSize);
+ layout.setLayoutParams(params);
+ }
+ }
}
diff --git a/src/com/android/camera/PauseButton.java b/src/com/android/camera/PauseButton.java
index a785050fd..6511e0e08 100644..100755
--- a/src/com/android/camera/PauseButton.java
+++ b/src/com/android/camera/PauseButton.java
@@ -36,11 +36,13 @@ import android.view.MotionEvent;
import android.view.View;
import android.util.Log;
+import com.android.camera.ui.RotateImageView;
+
/**
* A button designed to be used for the on-screen recording
* pausing-continue button.
*/
-public class PauseButton extends ImageView {
+public class PauseButton extends RotateImageView {
public interface OnPauseButtonListener {
void onButtonPause();
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index cfdd8af12..2d67fa9c0 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -629,7 +629,7 @@ public class PhotoModule
private void locationFirstRun() {
/* Do not prompt if the preference is already set, this is a secure
* camera session, or the prompt has already been triggered. */
- if (RecordLocationPreference.isSet(mPreferences) ||
+ if (RecordLocationPreference.isSet(mPreferences, CameraSettings.KEY_RECORD_LOCATION) ||
mActivity.isSecureCamera() || mLocationPromptTriggered) {
return;
}
@@ -912,7 +912,8 @@ public class PhotoModule
}
// Initialize location service.
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
mUI.initializeFirstTime();
@@ -943,7 +944,8 @@ public class PhotoModule
// onResume.
private void initializeSecondTime() {
// Start location update if needed.
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
MediaSaveService s = mActivity.getMediaSaveService();
if (s != null) {
@@ -2360,7 +2362,7 @@ public class PhotoModule
String zsl = mPreferences.getString(CameraSettings.KEY_ZSL,
mActivity.getString(R.string.pref_camera_zsl_default));
mUI.overrideSettings(CameraSettings.KEY_ZSL, zsl);
- mUI.startCountDown(seconds, isShutterSoundOn());
+ mUI.startCountDown(seconds, playSound);
} else {
mSnapshotOnIdle = false;
initiateSnap();
@@ -4673,7 +4675,8 @@ public class PhotoModule
// ignore the events after "onPause()"
if (mPaused) return;
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
if(needRestart()){
Log.v(TAG, "Restarting Preview... Camera Mode Changed");
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index 250bfa603..442c65d94 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -728,7 +728,7 @@ public class PhotoUI implements PieListener,
// make sure the correct value was found
// otherwise use auto index
mOnScreenIndicators.updateWBIndicator(wbIndex < 0 ? 2 : wbIndex);
- boolean location = RecordLocationPreference.get(prefs);
+ boolean location = RecordLocationPreference.get(prefs, CameraSettings.KEY_RECORD_LOCATION);
mOnScreenIndicators.updateLocationIndicator(location);
}
diff --git a/src/com/android/camera/RecordLocationPreference.java b/src/com/android/camera/RecordLocationPreference.java
index b88f5e4ed..088ff663f 100644
--- a/src/com/android/camera/RecordLocationPreference.java
+++ b/src/com/android/camera/RecordLocationPreference.java
@@ -40,18 +40,17 @@ public class RecordLocationPreference extends IconListPreference {
@Override
public String getValue() {
- return get(getSharedPreferences()) ? VALUE_ON : VALUE_OFF;
+ return get(getSharedPreferences(), getKey()) ? VALUE_ON : VALUE_OFF;
}
- public static boolean get(SharedPreferences pref) {
- String value = pref.getString(
- CameraSettings.KEY_RECORD_LOCATION, VALUE_NONE);
+ public static boolean get(SharedPreferences pref, String key) {
+ String value = pref.getString(key, VALUE_NONE);
return VALUE_ON.equals(value);
}
- public static boolean isSet(SharedPreferences pref) {
+ public static boolean isSet(SharedPreferences pref, String key) {
String value = pref.getString(
- CameraSettings.KEY_RECORD_LOCATION, VALUE_NONE);
+ key, VALUE_NONE);
return !VALUE_NONE.equals(value);
}
}
diff --git a/src/com/android/camera/SettingsActivity.java b/src/com/android/camera/SettingsActivity.java
index 503927904..e97073f58 100644
--- a/src/com/android/camera/SettingsActivity.java
+++ b/src/com/android/camera/SettingsActivity.java
@@ -89,6 +89,20 @@ public class SettingsActivity extends PreferenceActivity {
}
};
+ private SettingsManager.Listener mListener = new SettingsManager.Listener(){
+ @Override
+ public void onSettingsChanged(List<SettingsManager.SettingState> settings){
+ Map<String, SettingsManager.Values> map = mSettingsManager.getValuesMap();
+ for( SettingsManager.SettingState state : settings) {
+ SettingsManager.Values values = map.get(state.key);
+ boolean enabled = values.overriddenValue == null;
+ Preference pref = findPreference(state.key);
+ if (pref != null) {
+ pref.setEnabled(enabled);
+ }
+ }
+ }
+ };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -102,6 +116,7 @@ public class SettingsActivity extends PreferenceActivity {
finish();
return;
}
+ mSettingsManager.registerListener(mListener);
addPreferencesFromResource(R.xml.setting_menu_preferences);
mSharedPreferences = getPreferenceManager().getSharedPreferences();
@@ -207,12 +222,16 @@ public class SettingsActivity extends PreferenceActivity {
private void updatePreferenceButton(String key) {
Preference pref = findPreference(key);
- if (pref != null && pref instanceof ListPreference) {
- ListPreference pref2 = (ListPreference) pref;
- if (pref2.getEntryValues().length == 1) {
- pref2.setEnabled(false);
- } else {
- pref2.setEnabled(true);
+ if (pref != null ) {
+ if( pref instanceof ListPreference) {
+ ListPreference pref2 = (ListPreference) pref;
+ if (pref2.getEntryValues().length == 1) {
+ pref2.setEnabled(false);
+ } else {
+ pref2.setEnabled(true);
+ }
+ }else {
+ pref.setEnabled(false);
}
}
}
@@ -243,6 +262,12 @@ public class SettingsActivity extends PreferenceActivity {
finish();
}
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mSettingsManager.unregisterListener(mListener);
+ }
+
private void setShowInLockScreen() {
// Change the window flags so that secure camera can show when locked
Window win = getWindow();
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index f64d64a01..6adbcfb64 100644
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -86,15 +86,17 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final int SCENE_MODE_NIGHT_INT = 5;
// Custom-Scenemodes start from 100
- public static final int SCENE_MODE_DUAL_INT = 100;
- public static final int SCENE_MODE_OPTIZOOM_INT = 101;
- public static final int SCENE_MODE_UBIFOCUS_INT = 102;
- public static final int SCENE_MODE_BESTPICTURE_INT = 103;
- public static final int SCENE_MODE_PANORAMA_INT = 104;
- public static final int SCENE_MODE_CHROMAFLASH_INT = 105;
- public static final int SCENE_MODE_BLURBUSTER_INT = 106;
- public static final int SCENE_MODE_SHARPSHOOTER_INT = 107;
- public static final int SCENE_MODE_TRACKINGFOCUS_INT = 108;
+ public static final int SCENE_MODE_CUSTOM_START = 100;
+ public static final int SCENE_MODE_DUAL_INT = SCENE_MODE_CUSTOM_START;
+ public static final int SCENE_MODE_OPTIZOOM_INT = SCENE_MODE_CUSTOM_START + 1;
+ public static final int SCENE_MODE_UBIFOCUS_INT = SCENE_MODE_CUSTOM_START + 2;
+ public static final int SCENE_MODE_BESTPICTURE_INT = SCENE_MODE_CUSTOM_START + 3;
+ public static final int SCENE_MODE_PANORAMA_INT = SCENE_MODE_CUSTOM_START + 4;
+ public static final int SCENE_MODE_CHROMAFLASH_INT = SCENE_MODE_CUSTOM_START + 5;
+ public static final int SCENE_MODE_BLURBUSTER_INT = SCENE_MODE_CUSTOM_START + 6;
+ public static final int SCENE_MODE_SHARPSHOOTER_INT = SCENE_MODE_CUSTOM_START + 7;
+ public static final int SCENE_MODE_TRACKINGFOCUS_INT = SCENE_MODE_CUSTOM_START + 8;
+ public static final int SCENE_MODE_PROMODE_INT = SCENE_MODE_CUSTOM_START + 9;
public static final String SCENE_MODE_DUAL_STRING = "100";
public static final String KEY_CAMERA_SAVEPATH = "pref_camera2_savepath_key";
public static final String KEY_RECORD_LOCATION = "pref_camera2_recordlocation_key";
@@ -110,6 +112,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final String KEY_FILTER_MODE = "pref_camera2_filter_mode_key";
public static final String KEY_COLOR_EFFECT = "pref_camera2_coloreffect_key";
public static final String KEY_SCENE_MODE = "pref_camera2_scenemode_key";
+ public static final String KEY_SCEND_MODE_INSTRUCTIONAL = "pref_camera2_scenemode_instructional";
public static final String KEY_REDEYE_REDUCTION = "pref_camera2_redeyereduction_key";
public static final String KEY_CAMERA_ID = "pref_camera2_id_key";
public static final String KEY_PICTURE_SIZE = "pref_camera2_picturesize_key";
@@ -134,6 +137,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final String KEY_SHUTTER_SOUND = "pref_camera2_shutter_sound_key";
public static final String KEY_DEVELOPER_MENU = "pref_camera2_developer_menu_key";
public static final String KEY_RESTORE_DEFAULT = "pref_camera2_restore_default_key";
+ public static final String KEY_FOCUS_DISTANCE = "pref_camera2_focus_distance_key";
private static final String TAG = "SnapCam_SettingsManager";
private static SettingsManager sInstance;
@@ -419,12 +423,20 @@ public class SettingsManager implements ListMenu.SettingsListener {
mListeners.add(listener);
}
+ public void unregisterListener(Listener listener) {
+ mListeners.remove(listener);
+ }
+
private void notifyListeners(List<SettingState> changes) {
for (Listener listener : mListeners) {
listener.onSettingsChanged(changes);
}
}
+ public int getCurrentCameraId() {
+ return mCameraId;
+ }
+
public String getValue(String key) {
Values values = mValuesMap.get(key);
if (values == null) return null;
@@ -439,6 +451,28 @@ public class SettingsManager implements ListMenu.SettingsListener {
return pref.findIndexOfValue(value);
}
+ private boolean setFocusValue(String key, float value) {
+ boolean result = false;
+ String prefName = ComboPreferences.getLocalSharedPreferencesName(mContext, mCameraId);
+ SharedPreferences sharedPreferences = mContext.getSharedPreferences(prefName,
+ Context.MODE_PRIVATE);
+ float prefValue = sharedPreferences.getFloat(key, 0.5f);
+ if (prefValue != value) {
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putFloat(key, value);
+ editor.apply();
+ result = true;
+ }
+ return result;
+ }
+
+ public float getFocusValue(String key) {
+ String prefName = ComboPreferences.getLocalSharedPreferencesName(mContext, mCameraId);
+ SharedPreferences sharedPreferences = mContext.getSharedPreferences(prefName,
+ Context.MODE_PRIVATE);
+ return sharedPreferences.getFloat(key, 0.5f);
+ }
+
public boolean isOverriden(String key) {
Values values = mValuesMap.get(key);
return values.overriddenValue != null;
@@ -467,6 +501,17 @@ public class SettingsManager implements ListMenu.SettingsListener {
}
}
+ public void setFocusDistance(String key, float value, float minFocus) {
+ boolean isSuccess = setFocusValue(key, value);
+ if (isSuccess) {
+ List<SettingState> list = new ArrayList<>();
+ Values values = new Values("" + value * minFocus, null);
+ SettingState ss = new SettingState(KEY_FOCUS_DISTANCE, values);
+ list.add(ss);
+ notifyListeners(list);
+ }
+ }
+
private void updateMapAndNotify(ListPreference pref) {
String key = pref.getKey();
List changed = checkDependencyAndUpdate(key);
@@ -521,6 +566,9 @@ public class SettingsManager implements ListMenu.SettingsListener {
ListPreference flashMode = mPreferenceGroup.findPreference(KEY_FLASH_MODE);
ListPreference colorEffect = mPreferenceGroup.findPreference(KEY_COLOR_EFFECT);
ListPreference sceneMode = mPreferenceGroup.findPreference(KEY_SCENE_MODE);
+ ListPreference sceneModeInstructional =
+ mPreferenceGroup.findPreference(KEY_SCEND_MODE_INSTRUCTIONAL);
+
ListPreference cameraIdPref = mPreferenceGroup.findPreference(KEY_CAMERA_ID);
ListPreference pictureSize = mPreferenceGroup.findPreference(KEY_PICTURE_SIZE);
ListPreference exposure = mPreferenceGroup.findPreference(KEY_EXPOSURE);
@@ -560,6 +608,13 @@ public class SettingsManager implements ListMenu.SettingsListener {
}
}
+ if ( sceneModeInstructional != null ) {
+ if (filterUnsupportedOptions(sceneModeInstructional,
+ getSupportedSceneModes(cameraId)) ){
+ mFilteredKeys.add(sceneModeInstructional.getKey());
+ }
+ }
+
if (cameraIdPref != null) buildCameraId();
if (pictureSize != null) {
@@ -996,6 +1051,11 @@ public class SettingsManager implements ListMenu.SettingsListener {
return modes;
}
+ public float getMinimumFocusDistance(int cameraId) {
+ return mCharacteristics.get(cameraId)
+ .get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
+ }
+
private List<String> getSupportedWhiteBalanceModes(int cameraId) {
int[] whiteBalanceModes = mCharacteristics.get(cameraId).get(CameraCharacteristics
.CONTROL_AWB_AVAILABLE_MODES);
@@ -1020,6 +1080,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
if (BlurbusterFilter.isSupportedStatic()) modes.add(SCENE_MODE_BLURBUSTER_INT + "");
if (SharpshooterFilter.isSupportedStatic()) modes.add(SCENE_MODE_SHARPSHOOTER_INT + "");
if (TrackingFocusFrameListener.isSupportedStatic()) modes.add(SCENE_MODE_TRACKINGFOCUS_INT + "");
+ modes.add("" + SCENE_MODE_PROMODE_INT);
for (int mode : sceneModes) {
modes.add("" + mode);
}
@@ -1040,6 +1101,11 @@ public class SettingsManager implements ListMenu.SettingsListener {
return mCharacteristics.get(cameraId).get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
}
+ public StreamConfigurationMap getStreamConfigurationMap(int cameraId){
+ return mCharacteristics.get(cameraId)
+ .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ }
+
public List<String> getSupportedColorEffects(int cameraId) {
int[] flashModes = mCharacteristics.get(cameraId).get(CameraCharacteristics
.CONTROL_AVAILABLE_EFFECTS);
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 21ad36fcf..e420addcb 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -1158,7 +1158,8 @@ public class VideoModule implements CameraModule,
mOrientationManager.resume();
// Initialize location service.
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
if (mPreviewing) {
@@ -2798,7 +2799,8 @@ public class VideoModule implements CameraModule,
// startPreview().
if (mCameraDevice == null) return;
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
readVideoPreferences();
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index c68d895ea..e853783a6 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -721,7 +721,7 @@ public class VideoUI implements PieRenderer.PieListener,
public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) {
mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode());
- boolean location = RecordLocationPreference.get(prefs);
+ boolean location = RecordLocationPreference.get(prefs, CameraSettings.KEY_RECORD_LOCATION);
mOnScreenIndicators.updateLocationIndicator(location);
}
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index 7a3b114d1..2d4ec1419 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -1046,7 +1046,8 @@ public class WideAnglePanoramaModule
mOrientationManager.resume();
// Initialize location service.
- boolean recordLocation = RecordLocationPreference.get(mPreferences);
+ boolean recordLocation = RecordLocationPreference.get(mPreferences,
+ CameraSettings.KEY_RECORD_LOCATION);
mLocationManager.recordLocation(recordLocation);
mUI.initDisplayChangeListener();
UsageStatistics.onContentViewChanged(
diff --git a/src/com/android/camera/imageprocessor/FrameProcessor.java b/src/com/android/camera/imageprocessor/FrameProcessor.java
index a2ae18c1c..519d77458 100644..100755
--- a/src/com/android/camera/imageprocessor/FrameProcessor.java
+++ b/src/com/android/camera/imageprocessor/FrameProcessor.java
@@ -40,6 +40,7 @@ import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.Type;
+import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.widget.Toast;
@@ -155,10 +156,15 @@ public class FrameProcessor {
mRsRotator.set_width(width);
mRsRotator.set_height(height);
mRsRotator.set_pad(stridePad);
- if(mModule.getMainCameraCharacteristics() != null &&
- mModule.getMainCameraCharacteristics().get(CameraCharacteristics.SENSOR_ORIENTATION) == 270) {
- mRsRotator.set_gFlip(true);
+ int degree = 90;
+ if(mModule.getMainCameraCharacteristics() != null) {
+ degree = mModule.getMainCameraCharacteristics().
+ get(CameraCharacteristics.SENSOR_ORIENTATION);
+ if (mModule.getMainCameraId() == CaptureModule.FRONT_ID) {
+ degree = Math.abs(degree - 90);
+ }
}
+ mRsRotator.set_degree(degree);
mRsYuvToRGB.set_gIn(mProcessAllocation);
mRsYuvToRGB.set_width(height);
mRsYuvToRGB.set_height(width);
diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java
index 9039a9dce..b85d7f1ca 100644
--- a/src/com/android/camera/ui/CameraControls.java
+++ b/src/com/android/camera/ui/CameraControls.java
@@ -247,7 +247,6 @@ public class CameraControls extends RotatableLayout {
} else {
mHdrSwitcher.setEnabled(enable);
}
- mSceneModeSwitcher.setEnabled(enable);
mPreview.setEnabled(enable);
}
diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java
index 6420fd2c3..7e1f28d52 100644..100755
--- a/src/com/android/camera/ui/CountDownView.java
+++ b/src/com/android/camera/ui/CountDownView.java
@@ -153,16 +153,21 @@ public class CountDownView extends FrameLayout {
public void setOrientation(int orientation) {
mRemainingSecondsView.setRotation(-orientation);
-
mCountDownTitle.setRotation(-orientation);
+ int width = getResources().getDisplayMetrics().widthPixels;
+ int height = mCountDownTitle.getMeasuredHeight();
+ if (height == 0) {
+ measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
+ height = mCountDownTitle.getMeasuredHeight();
+ }
int dx = 0, dy = 0;
switch (orientation) {
case 90:
- dy = (mCountDownTitle.getWidth() - mCountDownTitle.getHeight()) / 2;
+ dy = (width - height) / 2;
dx = -dy;
break;
case 270:
- dx = dy = (mCountDownTitle.getWidth() - mCountDownTitle.getHeight()) / 2;
+ dx = dy = (width - height) / 2;
break;
case 180:
break;
diff --git a/src/com/android/camera/ui/OneUICameraControls.java b/src/com/android/camera/ui/OneUICameraControls.java
index 63e1b5b4d..3dce60d22 100644..100755
--- a/src/com/android/camera/ui/OneUICameraControls.java
+++ b/src/com/android/camera/ui/OneUICameraControls.java
@@ -24,24 +24,28 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
-import org.codeaurora.snapcam.R;
-
import com.android.camera.Storage;
import com.android.camera.imageprocessor.filter.BeautificationFilter;
+import org.codeaurora.snapcam.R;
+
public class OneUICameraControls extends RotatableLayout {
private static final String TAG = "CAM_Controls";
private View mShutter;
private View mVideoShutter;
+ private View mPauseButton;
private View mFlashButton;
private View mMute;
private View mFrontBackSwitcher;
@@ -53,6 +57,8 @@ public class OneUICameraControls extends RotatableLayout {
private View mMakeupSeekBarLowText;
private View mMakeupSeekBarHighText;
private View mMakeupSeekBarLayout;
+ private ViewGroup mProModeLayout;
+ private View mProModeCloseButton;
private ArrowTextView mRefocusToast;
@@ -75,10 +81,31 @@ public class OneUICameraControls extends RotatableLayout {
private int mWidth;
private int mHeight;
private boolean mVisible;
+ private boolean mIsVideoMode = false;
+ private int mBottomLargeSize;
+ private int mBottomSmallSize;
+
+ private ProMode mProMode;
+ private ImageView mExposureIcon;
+ private ImageView mManualIcon;
+ private ImageView mWhiteBalanceIcon;
+ private ImageView mIsoIcon;
+ private TextView mExposureText;
+ private TextView mManualText;
+ private TextView mWhiteBalanceText;
+ private TextView mIsoText;
+ private boolean mProModeOn = false;
+ private LinearLayout mExposureLayout;
+ private LinearLayout mManualLayout;
+ private LinearLayout mWhiteBalanceLayout;
+ private LinearLayout mIsoLayout;
+ private RotateLayout mExposureRotateLayout;
+ private RotateLayout mManualRotateLayout;
+ private RotateLayout mWhiteBalanceRotateLayout;
+ private RotateLayout mIsoRotateLayout;
public OneUICameraControls(Context context, AttributeSet attrs) {
super(context, attrs);
-
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
@@ -103,6 +130,7 @@ public class OneUICameraControls extends RotatableLayout {
super.onFinishInflate();
mShutter = findViewById(R.id.shutter_button);
mVideoShutter = findViewById(R.id.video_button);
+ mPauseButton = findViewById(R.id.video_pause);
mFrontBackSwitcher = findViewById(R.id.front_back_switcher);
mTsMakeupSwitcher = findViewById(R.id.ts_makeup_switcher);
mMakeupSeekBarLowText = findViewById(R.id.makeup_low_text);
@@ -117,11 +145,92 @@ public class OneUICameraControls extends RotatableLayout {
mFilterModeSwitcher = findViewById(R.id.filter_mode_switcher);
mRemainingPhotos = (LinearLayout) findViewById(R.id.remaining_photos);
mRemainingPhotosText = (TextView) findViewById(R.id.remaining_photos_text);
+ mProModeLayout = (ViewGroup) findViewById(R.id.pro_mode_layout);
+ mProModeCloseButton = findViewById(R.id.promode_close_button);
+
+ mExposureIcon = (ImageView) findViewById(R.id.exposure);
+ mManualIcon = (ImageView) findViewById(R.id.manual);
+ mWhiteBalanceIcon = (ImageView) findViewById(R.id.white_balance);
+ mIsoIcon = (ImageView) findViewById(R.id.iso);
+ mExposureText = (TextView) findViewById(R.id.exposure_value);
+ mManualText = (TextView) findViewById(R.id.manual_value);
+ mWhiteBalanceText = (TextView) findViewById(R.id.white_balance_value);
+ mIsoText = (TextView) findViewById(R.id.iso_value);
+ mProMode = (ProMode) findViewById(R.id.promode_slider);
+ mProMode.initialize(this);
+
+ mExposureLayout = (LinearLayout) findViewById(R.id.exposure_layout);
+ mManualLayout = (LinearLayout) findViewById(R.id.manual_layout);
+ mWhiteBalanceLayout = (LinearLayout) findViewById(R.id.white_balance_layout);
+ mIsoLayout = (LinearLayout) findViewById(R.id.iso_layout);
+
+ mExposureRotateLayout = (RotateLayout) findViewById(R.id.exposure_rotate_layout);
+ mManualRotateLayout = (RotateLayout) findViewById(R.id.manual_rotate_layout);
+ mWhiteBalanceRotateLayout = (RotateLayout) findViewById(R.id.white_balance_rotate_layout);
+ mIsoRotateLayout = (RotateLayout) findViewById(R.id.iso_rotate_layout);
+
+ mExposureLayout.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ resetProModeIcons();
+ int mode = mProMode.getMode();
+ if (mode == ProMode.EXPOSURE_MODE) {
+ mProMode.setMode(ProMode.NO_MODE);
+ } else {
+ mExposureIcon.setImageResource(R.drawable.icon_exposure_blue);
+ mProMode.setMode(ProMode.EXPOSURE_MODE);
+ }
+ }
+ });
+ mManualLayout.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ resetProModeIcons();
+ int mode = mProMode.getMode();
+ if (mode == ProMode.MANUAL_MODE) {
+ mProMode.setMode(ProMode.NO_MODE);
+ } else {
+ mManualIcon.setImageResource(R.drawable.icon_manual_blue);
+ mProMode.setMode(ProMode.MANUAL_MODE);
+ }
+ }
+ });
+ mWhiteBalanceLayout.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ resetProModeIcons();
+ int mode = mProMode.getMode();
+ if (mode == ProMode.WHITE_BALANCE_MODE) {
+ mProMode.setMode(ProMode.NO_MODE);
+ } else {
+ mWhiteBalanceIcon.setImageResource(R.drawable.icon_white_balance_blue);
+ mProMode.setMode(ProMode.WHITE_BALANCE_MODE);
+ }
+ }
+ });
+ mIsoLayout.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ resetProModeIcons();
+ int mode = mProMode.getMode();
+ if (mode == ProMode.ISO_MODE) {
+ mProMode.setMode(ProMode.NO_MODE);
+ } else {
+ mIsoIcon.setImageResource(R.drawable.icon_iso_blue);
+ mProMode.setMode(ProMode.ISO_MODE);
+ }
+ }
+ });
+
mViews = new View[]{
mSceneModeSwitcher, mFilterModeSwitcher, mFrontBackSwitcher,
- mTsMakeupSwitcher, mFlashButton, mShutter, mPreview, mVideoShutter
+ mTsMakeupSwitcher, mFlashButton, mShutter, mPreview, mVideoShutter,
+ mPauseButton
};
-
+ mBottomLargeSize = getResources().getDimensionPixelSize(
+ R.dimen.one_ui_bottom_large);
+ mBottomSmallSize = getResources().getDimensionPixelSize(
+ R.dimen.one_ui_bottom_small);
if(!BeautificationFilter.isSupportedStatic()) {
mTsMakeupSwitcher.setVisibility(View.GONE);
mTsMakeupSwitcher = null;
@@ -142,6 +251,14 @@ public class OneUICameraControls extends RotatableLayout {
if(mMakeupSeekBar != null) {
mMakeupSeekBar.setMinimumWidth(mWidth/2);
}
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(mWidth/ 4,mWidth/4);
+ mExposureLayout.setLayoutParams(lp);
+
+ mManualLayout.setLayoutParams(lp);
+ mWhiteBalanceLayout.setLayoutParams(lp);
+ mIsoLayout.setLayoutParams(lp);
+ initializeProMode(mProModeOn);
}
public boolean isControlRegion(int x, int y) {
@@ -205,17 +322,34 @@ public class OneUICameraControls extends RotatableLayout {
int rotation = getUnifiedRotation();
setLocation(mSceneModeSwitcher, true, 0);
setLocation(mFilterModeSwitcher, true, 1);
- setLocation(mFrontBackSwitcher, true, 2);
- setLocation(mTsMakeupSwitcher, true, 3);
- setLocation(mFlashButton, true, 4);
- setLocation(mPreview, false, 0);
- setLocation(mShutter, false, 2);
- setLocation(mVideoShutter, false, 3.15f);
+ if (mIsVideoMode) {
+ setLocation(mMute, true, 2);
+ setLocation(mTsMakeupSwitcher, true, 3);
+ setLocation(mFlashButton, true, 4);
+ setLocation(mPauseButton, false, 3.15f);
+ setLocation(mShutter, false , 0.85f);
+ setLocation(mVideoShutter, false, 2);
+ } else {
+ setLocation(mFrontBackSwitcher, true, 2);
+ setLocation(mTsMakeupSwitcher, true, 3);
+ setLocation(mFlashButton, true, 4);
+ setLocation(mPreview, false, 0);
+ setLocation(mShutter, false, 2);
+ setLocation(mVideoShutter, false, 3.15f);
+ }
setLocationCustomBottom(mMakeupSeekBarLayout, 0, 1);
+ setLocation(mProModeCloseButton, false, 4);
layoutToast(mRefocusToast, w, h, rotation);
}
+ private void setBottomButtionSize(View view, int width, int height) {
+ FrameLayout.LayoutParams layout = (FrameLayout.LayoutParams)view.getLayoutParams();
+ layout.height = height;
+ layout.width = width;
+ view.setLayoutParams(layout);
+ }
+
private void layoutToast(final View v, int w, int h, int rotation) {
int tw = v.getMeasuredWidth();
int th = v.getMeasuredHeight();
@@ -271,6 +405,17 @@ public class OneUICameraControls extends RotatableLayout {
mVisible = true;
}
+ public void setVideoMode(boolean videoMode) {
+ mIsVideoMode = videoMode;
+ if (mIsVideoMode) {
+ setBottomButtionSize(mVideoShutter, mBottomLargeSize, mBottomLargeSize);
+ setBottomButtionSize(mShutter, mBottomSmallSize, mBottomSmallSize);
+ } else {
+ setBottomButtionSize(mShutter, mBottomLargeSize, mBottomLargeSize);
+ setBottomButtionSize(mVideoShutter, mBottomSmallSize, mBottomSmallSize);
+ }
+ }
+
private void layoutRemaingPhotos() {
int rl = mPreview.getLeft();
int rt = mPreview.getTop();
@@ -324,7 +469,7 @@ public class OneUICameraControls extends RotatableLayout {
View[] views = {
mSceneModeSwitcher, mFilterModeSwitcher, mFrontBackSwitcher,
mTsMakeupSwitcher, mFlashButton, mPreview, mMute, mShutter, mVideoShutter,
- mMakeupSeekBarLowText, mMakeupSeekBarHighText
+ mMakeupSeekBarLowText, mMakeupSeekBarHighText, mPauseButton
};
for (View v : views) {
@@ -332,6 +477,11 @@ public class OneUICameraControls extends RotatableLayout {
((Rotatable) v).setOrientation(orientation, animation);
}
}
+ mExposureRotateLayout.setOrientation(orientation, animation);
+ mManualRotateLayout.setOrientation(orientation, animation);
+ mWhiteBalanceRotateLayout.setOrientation(orientation, animation);
+ mIsoRotateLayout.setOrientation(orientation, animation);
+ mProMode.setOrientation(orientation);
layoutRemaingPhotos();
}
@@ -377,4 +527,47 @@ public class OneUICameraControls extends RotatableLayout {
mPath.lineTo(x1, y1);
}
}
+
+ public void setProMode(boolean promode) {
+ mProModeOn = promode;
+ initializeProMode(mProModeOn);
+ resetProModeIcons();
+ mProMode.reinit();
+ }
+
+ private void resetProModeIcons() {
+ mExposureIcon.setImageResource(R.drawable.icon_exposure);
+ mManualIcon.setImageResource(R.drawable.icon_manual);
+ mWhiteBalanceIcon.setImageResource(R.drawable.icon_white_balance);
+ mIsoIcon.setImageResource(R.drawable.icon_iso);
+ }
+
+ public void initializeProMode(boolean promode) {
+ if (!promode) {
+ mProMode.setMode(ProMode.NO_MODE);
+ mProModeLayout.setVisibility(INVISIBLE);
+ mProModeCloseButton.setVisibility(INVISIBLE);
+ return;
+ }
+ mProModeLayout.setVisibility(VISIBLE);
+ mProModeCloseButton.setVisibility(VISIBLE);
+ mProModeLayout.setY(mHeight - mBottom - mProModeLayout.getHeight());
+ }
+
+ public void updateProModeText(int mode, String value) {
+ switch (mode) {
+ case ProMode.EXPOSURE_MODE:
+ mExposureText.setText(value);
+ break;
+ case ProMode.MANUAL_MODE:
+ mManualText.setText(value);
+ break;
+ case ProMode.WHITE_BALANCE_MODE:
+ mWhiteBalanceText.setText(value);
+ break;
+ case ProMode.ISO_MODE:
+ mIsoText.setText(value);
+ break;
+ }
+ }
}
diff --git a/src/com/android/camera/ui/PanoCaptureProcessView.java b/src/com/android/camera/ui/PanoCaptureProcessView.java
index 2b37fd61e..95e9a095f 100644
--- a/src/com/android/camera/ui/PanoCaptureProcessView.java
+++ b/src/com/android/camera/ui/PanoCaptureProcessView.java
@@ -120,6 +120,7 @@ public class PanoCaptureProcessView extends View implements SensorEventListener
private static final boolean DEBUG = false; //TODO: This has to be false before release
private BitmapArrayOutputStream mBitmapStream;
private static boolean mIsSupported = false;
+ private Object mBitmapStreamLock = new Object();
private boolean mIsFrameProcessing = false;
enum PANO_STATUS {
@@ -337,13 +338,15 @@ public class PanoCaptureProcessView extends View implements SensorEventListener
public void onPause() {
mSensorManager.unregisterListener(this, mRotationSensor);
- if(mBitmapStream != null) {
- try {
- mBitmapStream.close();
- } catch (IOException e) {
- //Ignore
+ synchronized (mBitmapStreamLock) {
+ if(mBitmapStream != null) {
+ try {
+ mBitmapStream.close();
+ } catch (IOException e) {
+ //Ignore
+ }
+ mBitmapStream = null;
}
- mBitmapStream = null;
}
}
@@ -510,13 +513,16 @@ public class PanoCaptureProcessView extends View implements SensorEventListener
}
private void doTask(BitmapTask bitmapTask) {
- if(mBitmapStream == null) {
- mBitmapStream = new BitmapArrayOutputStream(1024*1204);
+ int rtv = -1;
+ synchronized (mBitmapStreamLock) {
+ if(mBitmapStream == null) {
+ mBitmapStream = new BitmapArrayOutputStream(1024*1204);
+ }
+ mBitmapStream.reset();
+ bitmapTask.bitmap.compress(Bitmap.CompressFormat.JPEG, 100, mBitmapStream);
+ rtv = callNativeProcessKeyFrame(mBitmapStream.toByteArray(), mBitmapStream.size(),
+ bitmapTask.x, bitmapTask.y, 0, bitmapTask.dir);
}
- mBitmapStream.reset();
- bitmapTask.bitmap.compress(Bitmap.CompressFormat.JPEG, 100, mBitmapStream);
- int rtv = callNativeProcessKeyFrame(mBitmapStream.toByteArray(), mBitmapStream.size(),
- bitmapTask.x, bitmapTask.y, 0, bitmapTask.dir);
if(rtv < 0) {
mShouldFinish = true;
stopPano(false, mActivity.getResources().getString(R.string.panocapture_direction_is_changed));
diff --git a/src/com/android/camera/ui/ProMode.java b/src/com/android/camera/ui/ProMode.java
new file mode 100644
index 000000000..b55d0c425
--- /dev/null
+++ b/src/com/android/camera/ui/ProMode.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.camera.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.graphics.Point;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.camera.SettingsManager;
+
+import org.codeaurora.snapcam.R;
+
+import java.util.ArrayList;
+
+public class ProMode extends View {
+ public static final int NO_MODE = -1;
+ public static final int EXPOSURE_MODE = 0;
+ public static final int MANUAL_MODE = 1;
+ public static final int WHITE_BALANCE_MODE = 2;
+ public static final int ISO_MODE = 3;
+ private static final int DRAG_Y_THRESHOLD = 100;
+ private static final int DRAG_X_THRESHOLD = 30;
+ private static final int BLUE = 0xff4693fb;
+ private static final int SELECTED_DOT_SIZE = 20;
+ private static final int DOT_SIZE = 10;
+ private static final int[] wbIcons = {R.drawable.auto, R.drawable.incandecent,
+ R.drawable.fluorescent, R.drawable.sunlight, R.drawable.cloudy};
+ private static final int[] wbIconsBlue = {R.drawable.auto_blue, R.drawable.incandecent_blue,
+ R.drawable.fluorescent_blue, R.drawable.sunlight_blue, R.drawable.cloudy_blue};
+ private static final int WB_ICON_SIZE = 80;
+ private PathMeasure mCurveMeasure;
+ private int mCurveLeft;
+ private int mCurveRight;
+ private float mSlider = -1;
+ private Paint mPaint = new Paint();
+ private int mNums;
+ private int mIndex;
+ private Point[] mPoints;
+ private float mClickThreshold;
+ private int mStride;
+ private SettingsManager mSettingsManager;
+ private int mMode = NO_MODE;
+ private Context mContext;
+ private ViewGroup mParent;
+ private float minFocus;
+ private OneUICameraControls mUI;
+ private int mWidth;
+ private int mHeight;
+ private int mCurveY;
+ private ArrayList<View> mAddedViews;
+ private float curveCoordinate[] = new float[2];
+ private Path mCurvePath = new Path();
+ private int mCurveHeight;
+ private int mOrientation;
+
+ public ProMode(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ mPaint.setStrokeWidth(7f);
+ mSettingsManager = SettingsManager.getInstance();
+ }
+
+ private void init() {
+ init(EXPOSURE_MODE);
+ init(WHITE_BALANCE_MODE);
+ init(ISO_MODE);
+ mUI.updateProModeText(MANUAL_MODE, "Manual");
+ }
+
+ private void init(int mode) {
+ String key = getKey(mode);
+ if (key == null) return;
+ int index = mSettingsManager.getValueIndex(key);
+ CharSequence[] cc = mSettingsManager.getEntries(key);
+ mUI.updateProModeText(mode, cc[index].toString());
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ if (mMode != NO_MODE) {
+ mPaint.setColor(Color.WHITE);
+ mPaint.setStyle(Paint.Style.STROKE);
+ canvas.drawPath(mCurvePath, mPaint);
+ }
+ mPaint.setStyle(Paint.Style.FILL);
+ if (mMode == MANUAL_MODE) {
+ mPaint.setColor(Color.WHITE);
+ canvas.drawCircle(mCurveLeft, mCurveY, DOT_SIZE, mPaint);
+ canvas.drawCircle(mCurveRight, mCurveY, DOT_SIZE, mPaint);
+ mPaint.setColor(BLUE);
+ if (mSlider >= 0f) {
+ mCurveMeasure.getPosTan(mCurveMeasure.getLength() * mSlider, curveCoordinate, null);
+ canvas.drawCircle(curveCoordinate[0], curveCoordinate[1], SELECTED_DOT_SIZE,
+ mPaint);
+ }
+ } else {
+ for (int i = 0; i < mNums; i++) {
+ if (i == mIndex) {
+ mPaint.setColor(BLUE);
+ canvas.drawCircle(mPoints[i].x, mPoints[i].y, SELECTED_DOT_SIZE, mPaint);
+ } else {
+ mPaint.setColor(Color.WHITE);
+ canvas.drawCircle(mPoints[i].x, mPoints[i].y, DOT_SIZE, mPaint);
+ }
+ }
+ }
+ }
+
+ public void initialize(OneUICameraControls ui) {
+ mParent = (ViewGroup) getParent();
+ mUI = ui;
+ init();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mWidth = right - left;
+ mHeight = bottom - top;
+
+ mCurveLeft = mWidth / 10;
+ mCurveRight = mWidth - mCurveLeft;
+ mCurveHeight = mWidth / 7;
+ mCurveY = (int) (mHeight * 0.67);
+
+ float cx = (mCurveLeft + mCurveRight) / 2;
+ mCurvePath.reset();
+ mCurvePath.moveTo(mCurveLeft, mCurveY);
+ mCurvePath.quadTo(cx, mCurveY - mCurveHeight, mCurveRight, mCurveY);
+ mCurveMeasure = new PathMeasure(mCurvePath, false);
+ }
+
+ public void reinit() {
+ init();
+ }
+
+ public void setOrientation(int orientation) {
+ mOrientation = orientation;
+ if (mAddedViews != null) {
+ int rotation = mOrientation;
+ if (rotation == 90 || rotation == 270) rotation += 180;
+ rotation %= 360;
+ for (View v : mAddedViews) {
+ v.setRotation(rotation);
+ }
+ }
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ public void setMode(int mode) {
+ mMode = mode;
+ removeViews();
+ if (mMode == NO_MODE) {
+ setVisibility(INVISIBLE);
+ return;
+ } else {
+ setVisibility(VISIBLE);
+ }
+ mIndex = -1;
+ String key = currentKey();
+ if (mMode == MANUAL_MODE) {
+ minFocus = mSettingsManager
+ .getMinimumFocusDistance(mSettingsManager.getCurrentCameraId());
+ float value = mSettingsManager.getFocusValue(SettingsManager.KEY_FOCUS_DISTANCE);
+ setSlider(value);
+ int stride = mCurveRight - mCurveLeft;
+ for (int i = 0; i < 2; i++) {
+ TextView v = new TextView(mContext);
+ String s = "infinity";
+ if (i == 1) s = "macro";
+ v.setText(s);
+ v.setTextColor(Color.WHITE);
+ v.measure(0, 0);
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(v.getMeasuredWidth(),
+ v.getMeasuredHeight());
+ v.setLayoutParams(lp);
+ v.setX(mCurveLeft + i * stride - v.getMeasuredWidth() / 2);
+ v.setY(mCurveY - 2 * v.getMeasuredHeight());
+ mParent.addView(v);
+ mAddedViews.add(v);
+ }
+ } else {
+ if (key == null) return;
+ CharSequence[] cc = mSettingsManager.getEntries(key);
+ int length = mSettingsManager.getEntryValues(key).length;
+ int index = mSettingsManager.getValueIndex(key);
+ updateSlider(length);
+
+ for (int i = 0; i < length; i++) {
+ View v;
+ if (mMode == WHITE_BALANCE_MODE) {
+ v = new ImageView(mContext);
+ ((ImageView) v).setImageResource(wbIcons[i]);
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+ WB_ICON_SIZE, WB_ICON_SIZE);
+ v.setLayoutParams(lp);
+ v.setX(mPoints[i].x - WB_ICON_SIZE / 2);
+ v.setY(mPoints[i].y - 2 * WB_ICON_SIZE);
+ } else {
+ v = new TextView(mContext);
+ ((TextView) v).setText(cc[i]);
+ ((TextView) v).setTextColor(Color.WHITE);
+ v.measure(0, 0);
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(v.getMeasuredWidth(),
+ v.getMeasuredHeight());
+ v.setLayoutParams(lp);
+ v.setX(mPoints[i].x - v.getMeasuredWidth() / 2);
+ v.setY(mPoints[i].y - 2 * v.getMeasuredHeight());
+ }
+
+
+ mParent.addView(v);
+ mAddedViews.add(v);
+ }
+ setIndex(index, true);
+ }
+ setOrientation(mOrientation);
+ }
+
+ private String getKey(int mode) {
+ switch (mode) {
+ case EXPOSURE_MODE:
+ return SettingsManager.KEY_EXPOSURE;
+ case WHITE_BALANCE_MODE:
+ return SettingsManager.KEY_WHITE_BALANCE;
+ case ISO_MODE:
+ return SettingsManager.KEY_ISO;
+ }
+ return null;
+ }
+
+ private String currentKey() {
+ return getKey(mMode);
+ }
+
+ private void updateSlider(int n) {
+ mNums = n;
+ mStride = (mCurveRight - mCurveLeft) / (mNums - 1);
+ mClickThreshold = mStride * 0.45f;
+ mPoints = new Point[mNums];
+
+ float slide = 1f / (mNums - 1);
+ for (int i = 0; i < mNums; i++) {
+ mCurveMeasure.getPosTan(mCurveMeasure.getLength() * (slide * i), curveCoordinate, null);
+ mPoints[i] = new Point((int) curveCoordinate[0], (int) curveCoordinate[1]);
+ }
+
+ invalidate();
+ }
+
+ public void setSlider(float slider) {
+ mSlider = slider;
+ mSettingsManager.setFocusDistance(SettingsManager.KEY_FOCUS_DISTANCE, mSlider, minFocus);
+ mUI.updateProModeText(mMode, "Manual");
+ invalidate();
+ }
+
+ private void setIndex(int index, boolean force) {
+ if (mIndex == index && !force) return;
+ if (mIndex != -1) {
+ View v = mAddedViews.get(mIndex);
+ if (v instanceof TextView) {
+ ((TextView) v).setTextColor(Color.WHITE);
+ } else if (v instanceof ImageView) {
+ if (mMode == WHITE_BALANCE_MODE) {
+ ((ImageView) v).setImageResource(wbIcons[mIndex]);
+ }
+ }
+ }
+
+ mIndex = index;
+ String key = currentKey();
+ View v = mAddedViews.get(mIndex);
+ if (v instanceof TextView) {
+ ((TextView) v).setTextColor(BLUE);
+ } else if (v instanceof ImageView) {
+ if (mMode == WHITE_BALANCE_MODE) {
+ ((ImageView) v).setImageResource(wbIconsBlue[mIndex]);
+ }
+ }
+ if (key != null) mSettingsManager.setValueIndex(key, mIndex);
+ CharSequence[] cc = mSettingsManager.getEntries(key);
+ mUI.updateProModeText(mMode, cc[mIndex].toString());
+ invalidate();
+ }
+
+ private void removeViews() {
+ ViewGroup vg = (ViewGroup) getParent();
+ if (mAddedViews != null) {
+ for (int i = 0; i < mAddedViews.size(); i++) {
+ vg.removeView(mAddedViews.get(i));
+ }
+ }
+ mAddedViews = new ArrayList<View>();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mMode == MANUAL_MODE) {
+ float slider = getSlider(event.getX(), event.getY());
+ if (slider >= 0) {
+ setSlider(slider);
+ }
+ } else {
+ int idx = findButton(event.getX(), event.getY());
+ if (idx != -1) {
+ setIndex(idx, false);
+ }
+ return true;
+ }
+ return true;
+ }
+
+ private int findButton(float x, float y) {
+ for (int i = 0; i < mNums; i++) {
+ float xdiff = Math.abs(mPoints[i].x - x);
+ float ydiff = Math.abs(mPoints[i].y - y);
+ float dist = xdiff * xdiff + ydiff * ydiff;
+ if (dist < mClickThreshold * mClickThreshold) return i;
+ }
+ return -1;
+ }
+
+ private float getSlider(float x, float y) {
+ if (x > mCurveLeft - DRAG_X_THRESHOLD && x < mCurveRight + DRAG_X_THRESHOLD
+ && y > mCurveY - mCurveHeight - DRAG_Y_THRESHOLD
+ && y < mCurveY + DRAG_Y_THRESHOLD) {
+ if (x < mCurveLeft) x = mCurveLeft;
+ if (x > mCurveRight) x = mCurveRight;
+ return (x - mCurveLeft) / (mCurveRight - mCurveLeft);
+ } else {
+ return -1;
+ }
+ }
+
+}
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 838f8d950..cb414bac0 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -71,9 +71,22 @@ import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
+import java.util.ArrayList;
import java.util.Locale;
+import android.util.Range;
import java.util.StringTokenizer;
+import com.android.camera.SettingsManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.utils.SurfaceUtils;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
/**
* Collection of utility functions used in this package.
*/
@@ -1275,4 +1288,85 @@ public class CameraUtil {
(long) rhs.getWidth() * rhs.getHeight());
}
}
+
+ public static List<CaptureRequest> createHighSpeedRequestList(CaptureRequest request
+ ,int cameraId) throws CameraAccessException {
+ if (request == null) {
+ throw new IllegalArgumentException("Input capture request must not be null");
+ }
+ Collection<Surface> outputSurfaces = request.getTargets();
+ Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+
+ StreamConfigurationMap config =
+ SettingsManager.getInstance().getStreamConfigurationMap(cameraId);
+ SurfaceUtils.checkConstrainedHighSpeedSurfaces(outputSurfaces, fpsRange, config);
+
+ // Request list size: to limit the preview to 30fps, need use maxFps/30; to maximize
+ // the preview frame rate, should use maxBatch size for that high speed stream
+ // configuration. We choose the former for now.
+ int requestListSize = fpsRange.getUpper() / 30;
+ List<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
+
+ // Prepare the Request builders: need carry over the request controls.
+ // First, create a request builder that will only include preview or recording target.
+ CameraMetadataNative requestMetadata = new CameraMetadataNative(request.getNativeCopy());
+ // Note that after this step, the requestMetadata is mutated (swapped) and can not be used
+ // for next request builder creation.
+ CaptureRequest.Builder singleTargetRequestBuilder = new CaptureRequest.Builder(
+ requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+ singleTargetRequestBuilder.setTag(cameraId);
+
+ // Overwrite the capture intent to make sure a good value is set.
+ Iterator<Surface> iterator = outputSurfaces.iterator();
+ Surface firstSurface = iterator.next();
+ Surface secondSurface = null;
+ if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(firstSurface)) {
+ singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
+ } else {
+ // Video only, or preview + video
+ singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ }
+ singleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
+
+ // Second, Create a request builder that will include both preview and recording targets.
+ CaptureRequest.Builder doubleTargetRequestBuilder = null;
+ if (outputSurfaces.size() == 2) {
+ // Have to create a new copy, the original one was mutated after a new
+ // CaptureRequest.Builder creation.
+ requestMetadata = new CameraMetadataNative(request.getNativeCopy());
+ doubleTargetRequestBuilder = new CaptureRequest.Builder(
+ requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+ doubleTargetRequestBuilder.setTag(cameraId);
+ doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
+ CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ doubleTargetRequestBuilder.addTarget(firstSurface);
+ secondSurface = iterator.next();
+ doubleTargetRequestBuilder.addTarget(secondSurface);
+ doubleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
+ // Make sure singleTargetRequestBuilder contains only recording surface for
+ // preview + recording case.
+ Surface recordingSurface = firstSurface;
+ if (!SurfaceUtils.isSurfaceForHwVideoEncoder(recordingSurface)) {
+ recordingSurface = secondSurface;
+ }
+ singleTargetRequestBuilder.addTarget(recordingSurface);
+ } else {
+ // Single output case: either recording or preview.
+ singleTargetRequestBuilder.addTarget(firstSurface);
+ }
+
+ // Generate the final request list.
+ for (int i = 0; i < requestListSize; i++) {
+ if (i == 0 && doubleTargetRequestBuilder != null) {
+ // First request should be recording + preview request
+ requestList.add(doubleTargetRequestBuilder.build());
+ } else {
+ requestList.add(singleTargetRequestBuilder.build());
+ }
+ }
+
+ return Collections.unmodifiableList(requestList);
+ }
}
diff --git a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
index 595df8122..944bf0800 100644..100755
--- a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
+++ b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
@@ -52,6 +52,7 @@ import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.InputConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
@@ -623,18 +624,26 @@ public class ClearSightImageProcessor {
ReprocessableImage bayer = mBayerFrames.peek();
ReprocessableImage mono = mMonoFrames.peek();
+ long bayerTsSOF = bayer.mCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP);
+ long bayerTsEOF = bayerTsSOF + bayer.mCaptureResult.get(
+ CaptureResult.SENSOR_EXPOSURE_TIME);
+ long monoTsSOF = mono.mCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP);
+ long monoTsEOF = monoTsSOF + mono.mCaptureResult.get(
+ CaptureResult.SENSOR_EXPOSURE_TIME);
+
+
Log.d(TAG,
- "checkForValidFramePair - bayer ts: "
- + bayer.mImage.getTimestamp() + " mono ts: "
- + mono.mImage.getTimestamp());
+ "checkForValidFramePair - bayer ts SOF: "
+ + bayerTsSOF + ", EOF: " + bayerTsEOF
+ + ", mono ts SOF: " + monoTsSOF + ", EOF: " + monoTsEOF);
Log.d(TAG,
- "checkForValidFramePair - difference: "
- + Math.abs(bayer.mImage.getTimestamp()
- - mono.mImage.getTimestamp()));
+ "checkForValidFramePair - difference SOF: "
+ + Math.abs(bayerTsSOF - monoTsSOF)
+ + ", EOF: " + Math.abs(bayerTsEOF - monoTsEOF));
// if timestamps are within threshold, keep frames
- if (Math.abs(bayer.mImage.getTimestamp()
- - mono.mImage.getTimestamp()) > mTimestampThresholdNs) {
- if(bayer.mImage.getTimestamp() > mono.mImage.getTimestamp()) {
+ if ((Math.abs(bayerTsSOF - monoTsSOF) > mTimestampThresholdNs) &&
+ (Math.abs(bayerTsEOF - monoTsEOF) > mTimestampThresholdNs)) {
+ if(bayerTsSOF > monoTsSOF) {
Log.d(TAG, "checkForValidFramePair - toss mono");
// no match, toss
mono = mMonoFrames.poll();
@@ -903,6 +912,12 @@ public class ClearSightImageProcessor {
mImageEncodeHandler.obtainMessage(MSG_START_CAPTURE).sendToTarget();
short encodeRequest = 0;
+ /* In same case, timeout will reset ClearSightNativeEngine object, so fields
+ in the object is not initial, need to return and skip process.
+ */
+ if (ClearSightNativeEngine.getInstance().getReferenceImage(true) == null) {
+ return;
+ }
long csTs = ClearSightNativeEngine.getInstance().getReferenceImage(true).getTimestamp();
CaptureRequest.Builder csRequest = createEncodeReprocRequest(
ClearSightNativeEngine.getInstance().getReferenceResult(true), CAM_TYPE_BAYER);
@@ -1028,6 +1043,8 @@ public class ClearSightImageProcessor {
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
+ } catch (IllegalStateException e1) {
+ e1.printStackTrace();
}
}
}