summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Haeberling <haeberling@google.com>2014-03-11 09:14:53 -0700
committerSascha Haeberling <haeberling@google.com>2014-03-11 09:14:53 -0700
commit7cb8c791df0bcb48b2c3f2f34d7c7538c619b592 (patch)
tree7fdaab826c87ff9394b10f943a8b7187516924e8
parentcc855959c9a643a08bb10a41253720c04580dfe5 (diff)
downloadandroid_packages_apps_Camera2-7cb8c791df0bcb48b2c3f2f34d7c7538c619b592.tar.gz
android_packages_apps_Camera2-7cb8c791df0bcb48b2c3f2f34d7c7538c619b592.tar.bz2
android_packages_apps_Camera2-7cb8c791df0bcb48b2c3f2f34d7c7538c619b592.zip
Spring cleaning. Throwing out old cruft.
Change-Id: I99952405a0036c4a518b31e543a72a84dbe07995
-rw-r--r--AndroidManifest.xml7
-rw-r--r--res/layout/count_down_to_capture.xml35
-rw-r--r--res/layout/countdown_setting_popup.xml101
-rw-r--r--res/layout/crop_actionbar.xml25
-rw-r--r--res/layout/crop_activity.xml54
-rw-r--r--res/layout/effect_setting_item.xml29
-rw-r--r--res/layout/effect_setting_popup.xml68
-rw-r--r--res/layout/in_line_setting_check_box.xml31
-rw-r--r--res/layout/in_line_setting_menu.xml27
-rw-r--r--res/layout/list_pref_setting_popup.xml41
-rw-r--r--res/layout/more_setting_popup.xml26
-rw-r--r--res/layout/rotate_dialog.xml110
-rw-r--r--res/layout/rotate_text_toast.xml39
-rw-r--r--res/layout/setting_item.xml27
-rw-r--r--res/layout/settings_list_layout.xml26
-rw-r--r--res/layout/settings_selector.xml27
-rw-r--r--res/layout/time_interval_picker.xml65
-rw-r--r--res/layout/time_interval_popup.xml87
-rw-r--r--res/values/styles.xml98
-rw-r--r--src/com/android/camera/PhotoModule.java25
-rw-r--r--src/com/android/camera/Storage.java2
-rw-r--r--src/com/android/camera/crop/BoundedRect.java366
-rw-r--r--src/com/android/camera/crop/CropActivity.java695
-rw-r--r--src/com/android/camera/crop/CropDrawingUtils.java186
-rw-r--r--src/com/android/camera/crop/CropExtras.java121
-rw-r--r--src/com/android/camera/crop/CropMath.java258
-rw-r--r--src/com/android/camera/crop/CropObject.java328
-rw-r--r--src/com/android/camera/crop/CropView.java377
-rw-r--r--src/com/android/camera/crop/GeometryMathUtils.java181
-rw-r--r--src/com/android/camera/crop/SaveImage.java538
-rw-r--r--src/com/android/camera/crop/Utils.java340
-rw-r--r--src/com/android/camera/ui/AbstractSettingPopup.java44
-rw-r--r--src/com/android/camera/ui/CountDownView.java131
-rw-r--r--src/com/android/camera/ui/CountdownTimerPopup.java145
-rw-r--r--src/com/android/camera/ui/InLineSettingCheckBox.java82
-rw-r--r--src/com/android/camera/ui/InLineSettingItem.java94
-rw-r--r--src/com/android/camera/ui/InLineSettingMenu.java78
-rw-r--r--src/com/android/camera/ui/RotateTextToast.java59
-rw-r--r--src/com/android/camera/util/ImageLoader.java (renamed from src/com/android/camera/crop/ImageLoader.java)26
39 files changed, 21 insertions, 4978 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index da72d9ead..59f251c70 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -134,13 +134,6 @@
</activity>
<activity
- android:name="com.android.camera.crop.CropActivity"
- android:label="@string/crop_action"
- android:theme="@style/Theme.Crop"
- android:configChanges="keyboardHidden|orientation|screenSize">
- </activity>
-
- <activity
android:name="com.android.camera.settings.CameraSettingsActivity"
android:label="@string/mode_settings"
android:theme="@style/Theme.CameraSettings"
diff --git a/res/layout/count_down_to_capture.xml b/res/layout/count_down_to_capture.xml
deleted file mode 100644
index 68276ad40..000000000
--- a/res/layout/count_down_to_capture.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<com.android.camera.ui.CountDownView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/count_down_to_capture"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible" >
- <TextView android:id="@+id/remaining_seconds"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:textSize="160sp"
- android:textColor="@android:color/white"
- android:gravity="center" />
- <TextView android:id="@+id/count_down_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="10dp"
- android:paddingTop="20dp"
- android:textSize="20sp"
- android:textColor="@android:color/white"
- android:text="@string/count_down_title_text" />
-</com.android.camera.ui.CountDownView> \ No newline at end of file
diff --git a/res/layout/countdown_setting_popup.xml b/res/layout/countdown_setting_popup.xml
deleted file mode 100644
index 22acd9251..000000000
--- a/res/layout/countdown_setting_popup.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<com.android.camera.ui.CountdownTimerPopup xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingPopupWindow">
-
- <LinearLayout android:orientation="vertical"
- android:background="@color/popup_background"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/big_setting_popup_window_width">
-
- <TextView
- android:id="@+id/title"
- style="@style/PopupTitleText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:gravity="center_vertical|center_horizontal"
- android:minHeight="@dimen/popup_title_frame_min_height" />
-
- <View style="@style/PopupTitleSeparator" />
-
- <LinearLayout
- android:id="@+id/time_duration_picker"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:orientation="vertical" >
-
- <TextView
- android:id="@+id/set_time_interval_title"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:paddingTop="5dip"
- android:text="@string/set_duration"
- android:textAppearance="?android:attr/textAppearanceMedium" />
- <!-- A number picker to set timer -->
-
- <NumberPicker
- android:id="@+id/duration"
- android:layout_width="160dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:focusable="false" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <View
- android:background="#40ffffff"
- android:layout_width="match_parent"
- android:layout_height="1dip" />
- <LinearLayout
- android:id="@+id/timer_sound"
- style="@style/SettingRow" >
-
- <TextView android:id="@+id/beep_title"
- style="@style/SettingItemTitle"
- android:text="@string/pref_camera_timer_sound_title" />
-
- <CheckBox android:id="@+id/sound_check_box"
- android:layout_gravity="center_vertical|right"
- android:layout_width="wrap_content"
- android:layout_height="match_parent" />
- </LinearLayout>
-
- <View
- android:background="#40ffffff"
- android:layout_width="match_parent"
- android:layout_height="1dip" />
-
- <Button
- android:id="@+id/timer_set_button"
- style="?android:attr/buttonBarButtonStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:text="@string/time_lapse_interval_set"
- android:textAppearance="?android:attr/textAppearanceMedium" />
- </LinearLayout>
- </LinearLayout>
-</com.android.camera.ui.CountdownTimerPopup>
diff --git a/res/layout/crop_actionbar.xml b/res/layout/crop_actionbar.xml
deleted file mode 100644
index 1259d3f95..000000000
--- a/res/layout/crop_actionbar.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2012 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.
--->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:textAllCaps="true"
- android:text="@string/crop_save"
- android:gravity="center_vertical"
- android:textSize="14sp"
- android:drawableLeft="@drawable/menu_save_photo"
- android:drawablePadding="8dip" /> \ No newline at end of file
diff --git a/res/layout/crop_activity.xml b/res/layout/crop_activity.xml
deleted file mode 100644
index a2841e61a..000000000
--- a/res/layout/crop_activity.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/mainView">
-
- <LinearLayout
- android:id="@+id/mainPanel"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="vertical" >
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <com.android.camera.crop.CropView
- android:id="@+id/cropView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <ProgressBar
- android:id="@+id/loading"
- style="@android:style/Widget.Holo.ProgressBar.Large"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- android:indeterminateOnly="true"
- android:background="@android:color/transparent" />
-
- </FrameLayout>
-
- </LinearLayout>
-
-</FrameLayout>
diff --git a/res/layout/effect_setting_item.xml b/res/layout/effect_setting_item.xml
deleted file mode 100644
index 655625c18..000000000
--- a/res/layout/effect_setting_item.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- tools:ignore="UseCompoundDrawables"
- style="@style/EffectSettingItem">
-
- <ImageView android:id="@+id/image"
- android:layout_height="@dimen/effect_setting_item_icon_width"
- android:layout_width="@dimen/effect_setting_item_icon_width"
- android:layout_gravity="center_horizontal"
- android:scaleType="fitCenter"
- android:adjustViewBounds="true" />
- <TextView android:id="@+id/text"
- style="@style/EffectSettingItemTitle"/>
-</LinearLayout>
diff --git a/res/layout/effect_setting_popup.xml b/res/layout/effect_setting_popup.xml
deleted file mode 100644
index 63b7ab458..000000000
--- a/res/layout/effect_setting_popup.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.camera.ui.EffectSettingPopup xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingPopupWindow">
- <LinearLayout android:orientation="vertical"
- android:background="@color/popup_background"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/big_setting_popup_window_width">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/popup_title_frame_min_height">
- <TextView android:id="@+id/title"
- style="@style/PopupTitleText" />
- </FrameLayout>
- <View style="@style/PopupTitleSeparator" />
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView android:id="@+id/clear_effects"
- android:text="@string/clear_effects"
- style="@style/EffectSettingTypeTitle"
- android:textSize="@dimen/effect_setting_clear_text_size"
- android:minHeight="@dimen/effect_setting_clear_text_min_height"
- android:background="@drawable/bg_pressed"/>
- <TextView android:id="@+id/effect_silly_faces_title"
- android:text="@string/effect_silly_faces"
- android:visibility="gone"
- style="@style/EffectSettingTypeTitle"/>
- <View android:id="@+id/effect_silly_faces_title_separator"
- android:visibility="gone"
- style="@style/EffectTypeSeparator"/>
- <com.android.camera.ui.ExpandedGridView android:id="@+id/effect_silly_faces"
- style="@style/EffectSettingGrid"/>
- <View android:id="@+id/effect_background_separator"
- android:visibility="gone"
- style="@style/EffectTitleSeparator"/>
- <TextView android:id="@+id/effect_background_title"
- android:text="@string/effect_background"
- android:visibility="gone"
- style="@style/EffectSettingTypeTitle"/>
- <View android:id="@+id/effect_background_title_separator"
- android:visibility="gone"
- style="@style/EffectTypeSeparator"/>
- <com.android.camera.ui.ExpandedGridView android:id="@+id/effect_background"
- android:visibility="gone"
- style="@style/EffectSettingGrid"/>
- </LinearLayout>
- </ScrollView>
- </LinearLayout>
-</com.android.camera.ui.EffectSettingPopup>
diff --git a/res/layout/in_line_setting_check_box.xml b/res/layout/in_line_setting_check_box.xml
deleted file mode 100644
index a4d9bba21..000000000
--- a/res/layout/in_line_setting_check_box.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.camera.ui.InLineSettingCheckBox xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingRow">
- <TextView android:id="@+id/title"
- style="@style/SettingItemTitle" />
-
- <!-- The Switch widget always aligns to the right, so we have to wrap it in a frame layout. -->
- <FrameLayout
- android:layout_width="@dimen/setting_item_text_width"
- android:layout_height="match_parent">
- <CheckBox android:id="@+id/setting_check_box"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="match_parent" />
- </FrameLayout>
-</com.android.camera.ui.InLineSettingCheckBox>
diff --git a/res/layout/in_line_setting_menu.xml b/res/layout/in_line_setting_menu.xml
deleted file mode 100644
index f45f10ff7..000000000
--- a/res/layout/in_line_setting_menu.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.camera.ui.InLineSettingMenu xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingRow"
- android:background="@drawable/bg_pressed_exit_fading">
- <TextView android:id="@+id/title"
- style="@style/SettingItemTitle" />
-
- <TextView android:id="@+id/current_setting"
- style="@style/SettingItemText" />
-
-</com.android.camera.ui.InLineSettingMenu>
-
diff --git a/res/layout/list_pref_setting_popup.xml b/res/layout/list_pref_setting_popup.xml
deleted file mode 100644
index 5bfaa52e6..000000000
--- a/res/layout/list_pref_setting_popup.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2011, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.camera.ui.ListPrefSettingPopup xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingPopupWindow">
-
- <LinearLayout android:orientation="vertical"
- android:background="@color/popup_background"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/setting_popup_window_width">
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/popup_title_frame_min_height">
- <TextView android:id="@+id/title"
- style="@style/PopupTitleText" />
- </FrameLayout>
-
- <View style="@style/PopupTitleSeparator" />
-
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <ListView android:id="@+id/settingList"
- style="@style/SettingItemList"
- android:choiceMode="singleChoice" />
- </FrameLayout>
- </LinearLayout>
-</com.android.camera.ui.ListPrefSettingPopup>
diff --git a/res/layout/more_setting_popup.xml b/res/layout/more_setting_popup.xml
deleted file mode 100644
index 3ccde856c..000000000
--- a/res/layout/more_setting_popup.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2010, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.camera.ui.MoreSettingPopup xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingPopupWindow">
-
- <FrameLayout
- android:background="@color/popup_background"
- android:layout_width="@dimen/big_setting_popup_window_width"
- android:layout_height="wrap_content">
- <ListView android:id="@+id/settingList"
- style="@style/SettingItemList" />
- </FrameLayout>
-</com.android.camera.ui.MoreSettingPopup>
diff --git a/res/layout/rotate_dialog.xml b/res/layout/rotate_dialog.xml
deleted file mode 100644
index c62ce915b..000000000
--- a/res/layout/rotate_dialog.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/rotate_dialog_root_layout"
- android:clickable="true"
- android:gravity="center"
- android:visibility="gone"
- android:background="#55000000"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.android.camera.ui.RotateLayout
- android:id="@+id/rotate_dialog_layout"
- android:gravity="center"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_gravity="center"
- android:background="@color/popup_background"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <LinearLayout android:id="@+id/rotate_dialog_title_layout"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/rotate_dialog_title"
- style="@style/TextAppearance.DialogWindowTitle"
- android:gravity="center_vertical"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="64dp"/>
- <View style="@style/PopupTitleSeparator" />
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:background="@color/popup_background"
- android:padding="9dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <ProgressBar
- android:id="@+id/rotate_dialog_spinner"
- android:layout_gravity="center_vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- <TextView
- style="@style/TextAppearance.Medium"
- android:id="@+id/rotate_dialog_text"
- android:layout_gravity="center_vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
-
- <ImageView android:background="@drawable/list_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout android:id="@+id/rotate_dialog_button_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:minHeight="48dp"
- android:orientation="horizontal">
-
- <Button android:id="@+id/rotate_dialog_button2"
- style="@style/Widget.Button.Borderless"
- android:gravity="center"
- android:maxLines="2"
- android:minHeight="48dp"
- android:textSize="14sp"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="wrap_content" />
- <ImageView android:background="@drawable/list_divider"
- android:layout_width="wrap_content"
- android:layout_height="match_parent" />
- <Button android:id="@+id/rotate_dialog_button1"
- style="@style/Widget.Button.Borderless"
- android:gravity="center"
- android:maxLines="2"
- android:minHeight="48dp"
- android:textSize="14sp"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="wrap_content" />
- </LinearLayout>
- </LinearLayout>
- </com.android.camera.ui.RotateLayout>
-</FrameLayout>
diff --git a/res/layout/rotate_text_toast.xml b/res/layout/rotate_text_toast.xml
deleted file mode 100644
index 2c89b6f59..000000000
--- a/res/layout/rotate_text_toast.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.camera.ui.RotateLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/rotate_toast"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:visibility="gone">
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/toast_frame_holo">
- <TextView
- android:id="@+id/message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:textAppearanceMedium"
- android:textColor="@android:color/white"
- android:shadowColor="#BB000000"
- android:shadowRadius="2.75" />
- </FrameLayout>
-</com.android.camera.ui.RotateLayout>
-
-
diff --git a/res/layout/setting_item.xml b/res/layout/setting_item.xml
deleted file mode 100644
index 857100362..000000000
--- a/res/layout/setting_item.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2011, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.camera.ui.CheckedLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- tools:ignore="UseCompoundDrawables"
- style="@style/SettingRow">
- <TextView android:id="@+id/text"
- style="@style/SettingItemTitle" />
- <ImageView android:id="@+id/image"
- android:layout_height="@dimen/setting_item_icon_width"
- android:layout_width="@dimen/setting_item_icon_width"
- android:scaleType="fitCenter"
- android:adjustViewBounds="true" />
-</com.android.camera.ui.CheckedLinearLayout>
diff --git a/res/layout/settings_list_layout.xml b/res/layout/settings_list_layout.xml
deleted file mode 100644
index 24ccf9092..000000000
--- a/res/layout/settings_list_layout.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<com.android.camera.settings.SettingsView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/settings_list_layout"
- android:fillViewport="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:divider="@color/mode_selector_text_color"
- android:dividerHeight="2dp"
- android:background="@color/mode_selector_background_light" >
-</com.android.camera.settings.SettingsView> \ No newline at end of file
diff --git a/res/layout/settings_selector.xml b/res/layout/settings_selector.xml
deleted file mode 100644
index 282518858..000000000
--- a/res/layout/settings_selector.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/setting_text"
- android:layout_gravity="left"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:gravity="center_vertical"
- android:textSize="16sp"
- android:textColor="@color/mode_selector_text_color"
-/> \ No newline at end of file
diff --git a/res/layout/time_interval_picker.xml b/res/layout/time_interval_picker.xml
deleted file mode 100644
index d2a946273..000000000
--- a/res/layout/time_interval_picker.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2012, 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.
--->
-
-<!-- Layout of time interval picker -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/time_interval_picker"
- android:orientation="vertical"
- android:layout_height="wrap_content"
- android:layout_width="match_parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/set_time_interval_title"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="5dip"
- android:gravity="center"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/set_time_interval"/>
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="16dip"
- android:paddingRight="16dip" >
-
- <!-- time interval duration -->
- <NumberPicker
- android:id="@+id/duration"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:focusable="false" />
-
- <!-- time interval duration units (seconds/minutes/hours) -->
- <NumberPicker
- android:id="@+id/duration_unit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="2"
- android:layout_marginLeft="20dip"
- android:focusable="false" />
-
- </LinearLayout>
-</LinearLayout>
-
diff --git a/res/layout/time_interval_popup.xml b/res/layout/time_interval_popup.xml
deleted file mode 100644
index 9cf224a7a..000000000
--- a/res/layout/time_interval_popup.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2011, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.camera.ui.TimeIntervalPopup xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SettingPopupWindow">
-
- <LinearLayout android:orientation="vertical"
- android:background="@color/popup_background"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/big_setting_popup_window_width">
-
- <LinearLayout android:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="match_parent">
- <TextView android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:ellipsize="end"
- android:layout_weight="1"
- android:minHeight="@dimen/popup_title_frame_min_height"
- style="@style/PopupTitleText" />
- <Switch
- android:id="@+id/time_lapse_switch"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:layout_marginRight="8dp"
- android:layout_gravity="right|center_vertical" />
- </LinearLayout>
-
- <View style="@style/PopupTitleSeparator" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/set_time_interval_help_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="16dip"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:paddingBottom="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/set_time_interval_help"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal" >
- <include layout="@layout/time_interval_picker"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:divider="?android:attr/dividerHorizontal"
- android:showDividers="beginning"
- android:dividerPadding="0dip">
- <Button android:id="@+id/time_lapse_interval_set_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAppearance="?android:attr/textAppearanceMedium"
- style="?android:attr/buttonBarButtonStyle"
- android:text="@string/time_lapse_interval_set" />
- </LinearLayout>
- </LinearLayout>
-
-</com.android.camera.ui.TimeIntervalPopup>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 558058339..d5802b001 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -30,14 +30,6 @@
<item name="android:actionBarStyle">@style/Camera.ActionBar</item>
</style>
- <style name="Theme.Crop" parent="Theme.GalleryBase">
- <item name="android:displayOptions"></item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:actionBarStyle">@style/Camera.ActionBar</item>
- <item name="android:colorBackground">@null</item>
- <item name="android:colorBackgroundCacheHint">@null</item>
- <item name="android:windowBackground">@drawable/crop_tiled_background</item>
- </style>
<style name="Camera.ActionBar" parent="android:Widget.Holo.Light.ActionBar">
<item name="android:displayOptions">useLogo|showHome|homeAsUp</item>
<item name="android:background">@drawable/actionbar_translucent</item>
@@ -72,41 +64,6 @@
<item name="android:layout_height">2dp</item>
<item name="android:background">@color/popup_title_color</item>
</style>
- <style name="SettingItemList">
- <item name="android:orientation">vertical</item>
- <item name="android:paddingBottom">3dp</item>
- <item name="android:layout_gravity">center</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:listSelector">@drawable/bg_pressed</item>
- </style>
- <style name="SettingItemTitle">
- <item name="android:textSize">@dimen/setting_item_text_size</item>
- <item name="android:gravity">left|center_vertical</item>
- <item name="android:textColor">@color/primary_text</item>
- <item name="android:singleLine">true</item>
- <item name="android:layout_weight">1</item>
- <item name="android:layout_width">0dp</item>
- <item name="android:layout_height">match_parent</item>
- </style>
- <style name="SettingItemText">
- <item name="android:layout_width">@dimen/setting_item_text_width</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_gravity">center_vertical</item>
- <item name="android:gravity">center</item>
- <item name="android:singleLine">true</item>
- <item name="android:textColor">@color/primary_text</item>
- <item name="android:textSize">@dimen/setting_item_text_size</item>
- </style>
- <style name="SettingRow">
- <item name="android:gravity">center_vertical</item>
- <item name="android:orientation">horizontal</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/setting_row_height</item>
- <item name="android:paddingLeft">@dimen/setting_item_list_margin</item>
- <item name="android:paddingRight">@dimen/setting_item_list_margin</item>
- <item name="android:background">@drawable/setting_picker</item>
- </style>
<style name="OnViewfinderLabel">
<item name="android:gravity">center</item>
<item name="android:layout_width">wrap_content</item>
@@ -124,61 +81,6 @@
<style name="PanoCustomDialogText">
<item name="android:textAppearance">@android:style/TextAppearance.Medium</item>
</style>
- <style name="EffectSettingGrid">
- <item name="android:layout_marginLeft">@dimen/setting_item_list_margin</item>
- <item name="android:layout_marginRight">@dimen/setting_item_list_margin</item>
- <item name="android:paddingBottom">3dp</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:numColumns">3</item>
- <item name="android:verticalSpacing">3dp</item>
- <item name="android:horizontalSpacing">3dp</item>
- <item name="android:choiceMode">singleChoice</item>
- </style>
- <style name="EffectSettingItem">
- <item name="android:orientation">vertical</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:paddingTop">9dp</item>
- <item name="android:paddingBottom">9dp</item>
- <item name="android:paddingLeft">2dp</item>
- <item name="android:paddingRight">2dp</item>
- <item name="android:background">@drawable/setting_picker</item>
- </style>
- <style name="EffectSettingItemTitle">
- <item name="android:textSize">@dimen/effect_setting_item_text_size</item>
- <item name="android:gravity">center</item>
- <item name="android:textColor">@android:color/white</item>
- <item name="android:singleLine">true</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:paddingTop">1dp</item>
- </style>
- <style name="EffectSettingTypeTitle">
- <item name="android:textSize">@dimen/effect_setting_type_text_size</item>
- <item name="android:gravity">left|center_vertical</item>
- <item name="android:textColor">@android:color/white</item>
- <item name="android:alpha">0.7</item>
- <item name="android:singleLine">true</item>
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:minHeight">@dimen/effect_setting_type_text_min_height</item>
- <item name="android:paddingLeft">@dimen/effect_setting_type_text_left_padding</item>
- </style>
- <style name="EffectTypeSeparator">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_marginLeft">8dp</item>
- <item name="android:layout_marginRight">8dp</item>
- <item name="android:layout_marginBottom">14dp</item>
- <item name="android:layout_height">2dp</item>
- <item name="android:background">#2c2c2c</item>
- </style>
- <style name="EffectTitleSeparator">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">2dp</item>
- <item name="android:paddingBottom">4dp</item>
- <item name="android:background">@android:drawable/divider_horizontal_dark</item>
- </style>
<style name="TextAppearance.DialogWindowTitle" parent="">
<item name="android:textSize">22sp</item>
<item name="android:textColor">@color/holo_blue_light</item>
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 9b8a7dcc5..8396830c4 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -45,6 +45,7 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.OrientationEventListener;
import android.view.View;
+
import com.android.camera.PhotoModule.NamedImages.NamedEntity;
import com.android.camera.app.AppController;
import com.android.camera.app.CameraAppUI;
@@ -65,7 +66,6 @@ import com.android.camera.hardware.HardwareSpecImpl;
import com.android.camera.module.ModuleController;
import com.android.camera.settings.SettingsManager;
import com.android.camera.settings.SettingsUtil;
-import com.android.camera.ui.RotateTextToast;
import com.android.camera.util.ApiHelper;
import com.android.camera.util.CameraUtil;
import com.android.camera.util.GcamHelper;
@@ -99,8 +99,7 @@ public class PhotoModule
// Messages defined for the UI thread handler.
private static final int MSG_FIRST_TIME_INIT = 1;
private static final int MSG_SET_CAMERA_PARAMETERS_WHEN_IDLE = 2;
- private static final int MSG_SHOW_TAP_TO_FOCUS_TOAST = 3;
- private static final int MSG_SWITCH_TO_GCAM_MODULE = 4;
+ private static final int MSG_SWITCH_TO_GCAM_MODULE = 3;
// The subset of parameters we need to update in setCameraParameters().
private static final int UPDATE_PARAM_INITIALIZE = 1;
@@ -304,11 +303,6 @@ public class PhotoModule
break;
}
- case MSG_SHOW_TAP_TO_FOCUS_TOAST: {
- module.showTapToFocusToast();
- break;
- }
-
case MSG_SWITCH_TO_GCAM_MODULE: {
module.mActivity.onModeSelected(module.mGcamModeIndex);
}
@@ -965,12 +959,6 @@ public class PhotoModule
return;
}
mOrientation = CameraUtil.roundOrientation(orientation, mOrientation);
-
- // Show the toast after getting the first orientation changed.
- if (mHandler.hasMessages(MSG_SHOW_TAP_TO_FOCUS_TOAST)) {
- mHandler.removeMessages(MSG_SHOW_TAP_TO_FOCUS_TOAST);
- showTapToFocusToast();
- }
}
@Override
@@ -1793,15 +1781,6 @@ public class PhotoModule
}
}
- private void showTapToFocusToast() {
- // TODO: Use a toast?
- new RotateTextToast(mActivity, R.string.tap_to_focus, 0).show();
- // Clear the preference.
- SettingsManager settingsManager = mActivity.getSettingsManager();
- settingsManager.setBoolean(
- SettingsManager.SETTING_CAMERA_FIRST_USE_HINT_SHOWN, false);
- }
-
private void initializeCapabilities() {
mInitialParams = mCameraDevice.getParameters();
mFocusAreaSupported = CameraUtil.isFocusAreaSupported(mInitialParams);
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index f5aaf9464..d7628f2ab 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -30,10 +30,10 @@ import android.provider.MediaStore.Images.ImageColumns;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
-import com.android.camera.crop.ImageLoader;
import com.android.camera.data.LocalData;
import com.android.camera.exif.ExifInterface;
import com.android.camera.util.ApiHelper;
+import com.android.camera.util.ImageLoader;
import java.io.File;
import java.io.FileOutputStream;
diff --git a/src/com/android/camera/crop/BoundedRect.java b/src/com/android/camera/crop/BoundedRect.java
deleted file mode 100644
index 172bd722f..000000000
--- a/src/com/android/camera/crop/BoundedRect.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.camera.crop;
-
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-import java.util.Arrays;
-
-/**
- * Maintains invariant that inner rectangle is constrained to be within the
- * outer, rotated rectangle.
- */
-public class BoundedRect {
- private float rot;
- private RectF outer;
- private RectF inner;
- private float[] innerRotated;
-
- public BoundedRect(float rotation, Rect outerRect, Rect innerRect) {
- rot = rotation;
- outer = new RectF(outerRect);
- inner = new RectF(innerRect);
- innerRotated = CropMath.getCornersFromRect(inner);
- rotateInner();
- if (!isConstrained())
- reconstrain();
- }
-
- public BoundedRect(float rotation, RectF outerRect, RectF innerRect) {
- rot = rotation;
- outer = new RectF(outerRect);
- inner = new RectF(innerRect);
- innerRotated = CropMath.getCornersFromRect(inner);
- rotateInner();
- if (!isConstrained())
- reconstrain();
- }
-
- public void resetTo(float rotation, RectF outerRect, RectF innerRect) {
- rot = rotation;
- outer.set(outerRect);
- inner.set(innerRect);
- innerRotated = CropMath.getCornersFromRect(inner);
- rotateInner();
- if (!isConstrained())
- reconstrain();
- }
-
- /**
- * Sets inner, and re-constrains it to fit within the rotated bounding rect.
- */
- public void setInner(RectF newInner) {
- if (inner.equals(newInner))
- return;
- inner = newInner;
- innerRotated = CropMath.getCornersFromRect(inner);
- rotateInner();
- if (!isConstrained())
- reconstrain();
- }
-
- /**
- * Sets rotation, and re-constrains inner to fit within the rotated bounding rect.
- */
- public void setRotation(float rotation) {
- if (rotation == rot)
- return;
- rot = rotation;
- innerRotated = CropMath.getCornersFromRect(inner);
- rotateInner();
- if (!isConstrained())
- reconstrain();
- }
-
- public void setToInner(RectF r) {
- r.set(inner);
- }
-
- public void setToOuter(RectF r) {
- r.set(outer);
- }
-
- public RectF getInner() {
- return new RectF(inner);
- }
-
- public RectF getOuter() {
- return new RectF(outer);
- }
-
- /**
- * Tries to move the inner rectangle by (dx, dy). If this would cause it to leave
- * the bounding rectangle, snaps the inner rectangle to the edge of the bounding
- * rectangle.
- */
- public void moveInner(float dx, float dy) {
- Matrix m0 = getInverseRotMatrix();
-
- RectF translatedInner = new RectF(inner);
- translatedInner.offset(dx, dy);
-
- float[] translatedInnerCorners = CropMath.getCornersFromRect(translatedInner);
- float[] outerCorners = CropMath.getCornersFromRect(outer);
-
- m0.mapPoints(translatedInnerCorners);
- float[] correction = {
- 0, 0
- };
-
- // find correction vectors for corners that have moved out of bounds
- for (int i = 0; i < translatedInnerCorners.length; i += 2) {
- float correctedInnerX = translatedInnerCorners[i] + correction[0];
- float correctedInnerY = translatedInnerCorners[i + 1] + correction[1];
- if (!CropMath.inclusiveContains(outer, correctedInnerX, correctedInnerY)) {
- float[] badCorner = {
- correctedInnerX, correctedInnerY
- };
- float[] nearestSide = CropMath.closestSide(badCorner, outerCorners);
- float[] correctionVec =
- GeometryMathUtils.shortestVectorFromPointToLine(badCorner, nearestSide);
- correction[0] += correctionVec[0];
- correction[1] += correctionVec[1];
- }
- }
-
- for (int i = 0; i < translatedInnerCorners.length; i += 2) {
- float correctedInnerX = translatedInnerCorners[i] + correction[0];
- float correctedInnerY = translatedInnerCorners[i + 1] + correction[1];
- if (!CropMath.inclusiveContains(outer, correctedInnerX, correctedInnerY)) {
- float[] correctionVec = {
- correctedInnerX, correctedInnerY
- };
- CropMath.getEdgePoints(outer, correctionVec);
- correctionVec[0] -= correctedInnerX;
- correctionVec[1] -= correctedInnerY;
- correction[0] += correctionVec[0];
- correction[1] += correctionVec[1];
- }
- }
-
- // Set correction
- for (int i = 0; i < translatedInnerCorners.length; i += 2) {
- float correctedInnerX = translatedInnerCorners[i] + correction[0];
- float correctedInnerY = translatedInnerCorners[i + 1] + correction[1];
- // update translated corners with correction vectors
- translatedInnerCorners[i] = correctedInnerX;
- translatedInnerCorners[i + 1] = correctedInnerY;
- }
-
- innerRotated = translatedInnerCorners;
- // reconstrain to update inner
- reconstrain();
- }
-
- /**
- * Attempts to resize the inner rectangle. If this would cause it to leave
- * the bounding rect, clips the inner rectangle to fit.
- */
- public void resizeInner(RectF newInner) {
- Matrix m = getRotMatrix();
- Matrix m0 = getInverseRotMatrix();
-
- float[] outerCorners = CropMath.getCornersFromRect(outer);
- m.mapPoints(outerCorners);
- float[] oldInnerCorners = CropMath.getCornersFromRect(inner);
- float[] newInnerCorners = CropMath.getCornersFromRect(newInner);
- RectF ret = new RectF(newInner);
-
- for (int i = 0; i < newInnerCorners.length; i += 2) {
- float[] c = {
- newInnerCorners[i], newInnerCorners[i + 1]
- };
- float[] c0 = Arrays.copyOf(c, 2);
- m0.mapPoints(c0);
- if (!CropMath.inclusiveContains(outer, c0[0], c0[1])) {
- float[] outerSide = CropMath.closestSide(c, outerCorners);
- float[] pathOfCorner = {
- newInnerCorners[i], newInnerCorners[i + 1],
- oldInnerCorners[i], oldInnerCorners[i + 1]
- };
- float[] p = GeometryMathUtils.lineIntersect(pathOfCorner, outerSide);
- if (p == null) {
- // lines are parallel or not well defined, so don't resize
- p = new float[2];
- p[0] = oldInnerCorners[i];
- p[1] = oldInnerCorners[i + 1];
- }
- // relies on corners being in same order as method
- // getCornersFromRect
- switch (i) {
- case 0:
- case 1:
- ret.left = (p[0] > ret.left) ? p[0] : ret.left;
- ret.top = (p[1] > ret.top) ? p[1] : ret.top;
- break;
- case 2:
- case 3:
- ret.right = (p[0] < ret.right) ? p[0] : ret.right;
- ret.top = (p[1] > ret.top) ? p[1] : ret.top;
- break;
- case 4:
- case 5:
- ret.right = (p[0] < ret.right) ? p[0] : ret.right;
- ret.bottom = (p[1] < ret.bottom) ? p[1] : ret.bottom;
- break;
- case 6:
- case 7:
- ret.left = (p[0] > ret.left) ? p[0] : ret.left;
- ret.bottom = (p[1] < ret.bottom) ? p[1] : ret.bottom;
- break;
- default:
- break;
- }
- }
- }
- float[] retCorners = CropMath.getCornersFromRect(ret);
- m0.mapPoints(retCorners);
- innerRotated = retCorners;
- // reconstrain to update inner
- reconstrain();
- }
-
- /**
- * Attempts to resize the inner rectangle. If this would cause it to leave
- * the bounding rect, clips the inner rectangle to fit while maintaining
- * aspect ratio.
- */
- public void fixedAspectResizeInner(RectF newInner) {
- Matrix m = getRotMatrix();
- Matrix m0 = getInverseRotMatrix();
-
- float aspectW = inner.width();
- float aspectH = inner.height();
- float aspRatio = aspectW / aspectH;
- float[] corners = CropMath.getCornersFromRect(outer);
-
- m.mapPoints(corners);
- float[] oldInnerCorners = CropMath.getCornersFromRect(inner);
- float[] newInnerCorners = CropMath.getCornersFromRect(newInner);
-
- // find fixed corner
- int fixed = -1;
- if (inner.top == newInner.top) {
- if (inner.left == newInner.left)
- fixed = 0; // top left
- else if (inner.right == newInner.right)
- fixed = 2; // top right
- } else if (inner.bottom == newInner.bottom) {
- if (inner.right == newInner.right)
- fixed = 4; // bottom right
- else if (inner.left == newInner.left)
- fixed = 6; // bottom left
- }
- // no fixed corner, return without update
- if (fixed == -1)
- return;
- float widthSoFar = newInner.width();
- int moved = -1;
- for (int i = 0; i < newInnerCorners.length; i += 2) {
- float[] c = {
- newInnerCorners[i], newInnerCorners[i + 1]
- };
- float[] c0 = Arrays.copyOf(c, 2);
- m0.mapPoints(c0);
- if (!CropMath.inclusiveContains(outer, c0[0], c0[1])) {
- moved = i;
- if (moved == fixed)
- continue;
- float[] l2 = CropMath.closestSide(c, corners);
- float[] l1 = {
- newInnerCorners[i], newInnerCorners[i + 1],
- oldInnerCorners[i], oldInnerCorners[i + 1]
- };
- float[] p = GeometryMathUtils.lineIntersect(l1, l2);
- if (p == null) {
- // lines are parallel or not well defined, so set to old
- // corner
- p = new float[2];
- p[0] = oldInnerCorners[i];
- p[1] = oldInnerCorners[i + 1];
- }
- // relies on corners being in same order as method
- // getCornersFromRect
- float fixed_x = oldInnerCorners[fixed];
- float fixed_y = oldInnerCorners[fixed + 1];
- float newWidth = Math.abs(fixed_x - p[0]);
- float newHeight = Math.abs(fixed_y - p[1]);
- newWidth = Math.max(newWidth, aspRatio * newHeight);
- if (newWidth < widthSoFar)
- widthSoFar = newWidth;
- }
- }
-
- float heightSoFar = widthSoFar / aspRatio;
- RectF ret = new RectF(inner);
- if (fixed == 0) {
- ret.right = ret.left + widthSoFar;
- ret.bottom = ret.top + heightSoFar;
- } else if (fixed == 2) {
- ret.left = ret.right - widthSoFar;
- ret.bottom = ret.top + heightSoFar;
- } else if (fixed == 4) {
- ret.left = ret.right - widthSoFar;
- ret.top = ret.bottom - heightSoFar;
- } else if (fixed == 6) {
- ret.right = ret.left + widthSoFar;
- ret.top = ret.bottom - heightSoFar;
- }
- float[] retCorners = CropMath.getCornersFromRect(ret);
- m0.mapPoints(retCorners);
- innerRotated = retCorners;
- // reconstrain to update inner
- reconstrain();
- }
-
- // internal methods
-
- private boolean isConstrained() {
- for (int i = 0; i < 8; i += 2) {
- if (!CropMath.inclusiveContains(outer, innerRotated[i], innerRotated[i + 1]))
- return false;
- }
- return true;
- }
-
- private void reconstrain() {
- // innerRotated has been changed to have incorrect values
- CropMath.getEdgePoints(outer, innerRotated);
- Matrix m = getRotMatrix();
- float[] unrotated = Arrays.copyOf(innerRotated, 8);
- m.mapPoints(unrotated);
- inner = CropMath.trapToRect(unrotated);
- }
-
- private void rotateInner() {
- Matrix m = getInverseRotMatrix();
- m.mapPoints(innerRotated);
- }
-
- private Matrix getRotMatrix() {
- Matrix m = new Matrix();
- m.setRotate(rot, outer.centerX(), outer.centerY());
- return m;
- }
-
- private Matrix getInverseRotMatrix() {
- Matrix m = new Matrix();
- m.setRotate(-rot, outer.centerX(), outer.centerY());
- return m;
- }
-}
diff --git a/src/com/android/camera/crop/CropActivity.java b/src/com/android/camera/crop/CropActivity.java
deleted file mode 100644
index b5351d34c..000000000
--- a/src/com/android/camera/crop/CropActivity.java
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.crop;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.MediaStore;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.WindowManager;
-import android.widget.Toast;
-
-import com.android.camera2.R;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Activity for cropping an image.
- */
-public class CropActivity extends Activity {
- private static final String LOGTAG = "CropActivity";
- public static final String CROP_ACTION = "com.android.camera.action.CROP";
- private CropExtras mCropExtras = null;
- private LoadBitmapTask mLoadBitmapTask = null;
-
- private int mOutputX = 0;
- private int mOutputY = 0;
- private Bitmap mOriginalBitmap = null;
- private RectF mOriginalBounds = null;
- private int mOriginalRotation = 0;
- private Uri mSourceUri = null;
- private CropView mCropView = null;
- private View mSaveButton = null;
- private boolean finalIOGuard = false;
-
- private static final int SELECT_PICTURE = 1; // request code for picker
-
- private static final int DEFAULT_COMPRESS_QUALITY = 90;
- /**
- * The maximum bitmap size we allow to be returned through the intent.
- * Intents have a maximum of 1MB in total size. However, the Bitmap seems to
- * have some overhead to hit so that we go way below the limit here to make
- * sure the intent stays below 1MB.We should consider just returning a byte
- * array instead of a Bitmap instance to avoid overhead.
- */
- public static final int MAX_BMAP_IN_INTENT = 750000;
-
- // Flags
- private static final int DO_SET_WALLPAPER = 1;
- private static final int DO_RETURN_DATA = 1 << 1;
- private static final int DO_EXTRA_OUTPUT = 1 << 2;
-
- private static final int FLAG_CHECK = DO_SET_WALLPAPER | DO_RETURN_DATA | DO_EXTRA_OUTPUT;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Intent intent = getIntent();
- setResult(RESULT_CANCELED, new Intent());
- mCropExtras = getExtrasFromIntent(intent);
- if (mCropExtras != null && mCropExtras.getShowWhenLocked()) {
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
- }
-
- setContentView(R.layout.crop_activity);
- mCropView = (CropView) findViewById(R.id.cropView);
-
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
- actionBar.setCustomView(R.layout.crop_actionbar);
-
- View mSaveButton = actionBar.getCustomView();
- mSaveButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- startFinishOutput();
- }
- });
- }
- if (intent.getData() != null) {
- mSourceUri = intent.getData();
- startLoadBitmap(mSourceUri);
- } else {
- pickImage();
- }
- }
-
- private void enableSave(boolean enable) {
- if (mSaveButton != null) {
- mSaveButton.setEnabled(enable);
- }
- }
-
- @Override
- protected void onDestroy() {
- if (mLoadBitmapTask != null) {
- mLoadBitmapTask.cancel(false);
- }
- super.onDestroy();
- }
-
- @Override
- public void onConfigurationChanged (Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mCropView.configChanged();
- }
-
- /**
- * Opens a selector in Gallery to chose an image for use when none was given
- * in the CROP intent.
- */
- private void pickImage() {
- Intent intent = new Intent();
- intent.setType("image/*");
- intent.setAction(Intent.ACTION_GET_CONTENT);
- startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)),
- SELECT_PICTURE);
- }
-
- /**
- * Callback for pickImage().
- */
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == RESULT_OK && requestCode == SELECT_PICTURE) {
- mSourceUri = data.getData();
- startLoadBitmap(mSourceUri);
- }
- }
-
- /**
- * Gets screen size metric.
- */
- private int getScreenImageSize() {
- DisplayMetrics outMetrics = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
- return (int) Math.max(outMetrics.heightPixels, outMetrics.widthPixels);
- }
-
- /**
- * Method that loads a bitmap in an async task.
- */
- private void startLoadBitmap(Uri uri) {
- if (uri != null) {
- enableSave(false);
- final View loading = findViewById(R.id.loading);
- loading.setVisibility(View.VISIBLE);
- mLoadBitmapTask = new LoadBitmapTask();
- mLoadBitmapTask.execute(uri);
- } else {
- cannotLoadImage();
- done();
- }
- }
-
- /**
- * Method called on UI thread with loaded bitmap.
- */
- private void doneLoadBitmap(Bitmap bitmap, RectF bounds, int orientation) {
- final View loading = findViewById(R.id.loading);
- loading.setVisibility(View.GONE);
- mOriginalBitmap = bitmap;
- mOriginalBounds = bounds;
- mOriginalRotation = orientation;
- if (bitmap != null && bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
- RectF imgBounds = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
- mCropView.initialize(bitmap, imgBounds, imgBounds, orientation);
- if (mCropExtras != null) {
- int aspectX = mCropExtras.getAspectX();
- int aspectY = mCropExtras.getAspectY();
- mOutputX = mCropExtras.getOutputX();
- mOutputY = mCropExtras.getOutputY();
- if (mOutputX > 0 && mOutputY > 0) {
- mCropView.applyAspect(mOutputX, mOutputY);
-
- }
- float spotX = mCropExtras.getSpotlightX();
- float spotY = mCropExtras.getSpotlightY();
- if (spotX > 0 && spotY > 0) {
- mCropView.setWallpaperSpotlight(spotX, spotY);
- }
- if (aspectX > 0 && aspectY > 0) {
- mCropView.applyAspect(aspectX, aspectY);
- }
- }
- enableSave(true);
- } else {
- Log.w(LOGTAG, "could not load image for cropping");
- cannotLoadImage();
- setResult(RESULT_CANCELED, new Intent());
- done();
- }
- }
-
- /**
- * Display toast for image loading failure.
- */
- private void cannotLoadImage() {
- CharSequence text = getString(R.string.cannot_load_image);
- Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
- toast.show();
- }
-
- /**
- * AsyncTask for loading a bitmap into memory.
- *
- * @see #startLoadBitmap(android.net.Uri)
- * see doneLoadBitmap (android.graphics.Bitmap)
- */
- private class LoadBitmapTask extends AsyncTask<Uri, Void, Bitmap> {
- int mBitmapSize;
- Context mContext;
- Rect mOriginalBounds;
- int mOrientation;
-
- public LoadBitmapTask() {
- mBitmapSize = getScreenImageSize();
- mContext = getApplicationContext();
- mOriginalBounds = new Rect();
- mOrientation = 0;
- }
-
- @Override
- protected Bitmap doInBackground(Uri... params) {
- Uri uri = params[0];
- Bitmap bmap = ImageLoader.loadConstrainedBitmap(uri, mContext, mBitmapSize,
- mOriginalBounds, false);
- mOrientation = ImageLoader.getMetadataRotation(mContext, uri);
- return bmap;
- }
-
- @Override
- protected void onPostExecute(Bitmap result) {
- doneLoadBitmap(result, new RectF(mOriginalBounds), mOrientation);
- }
- }
-
- protected void startFinishOutput() {
- if (finalIOGuard) {
- return;
- } else {
- finalIOGuard = true;
- }
- enableSave(false);
- Uri destinationUri = null;
- int flags = 0;
- if (mOriginalBitmap != null && mCropExtras != null) {
- if (mCropExtras.getExtraOutput() != null) {
- destinationUri = mCropExtras.getExtraOutput();
- if (destinationUri != null) {
- flags |= DO_EXTRA_OUTPUT;
- }
- }
- if (mCropExtras.getSetAsWallpaper()) {
- flags |= DO_SET_WALLPAPER;
- }
- if (mCropExtras.getReturnData()) {
- flags |= DO_RETURN_DATA;
- }
- }
- if (flags == 0) {
- destinationUri = SaveImage.makeAndInsertUri(this, mSourceUri);
- if (destinationUri != null) {
- flags |= DO_EXTRA_OUTPUT;
- }
- }
- if ((flags & FLAG_CHECK) != 0 && mOriginalBitmap != null) {
- RectF photo = new RectF(0, 0, mOriginalBitmap.getWidth(), mOriginalBitmap.getHeight());
- RectF crop = getBitmapCrop(photo);
- startBitmapIO(flags, mOriginalBitmap, mSourceUri, destinationUri, crop,
- photo, mOriginalBounds,
- (mCropExtras == null) ? null : mCropExtras.getOutputFormat(), mOriginalRotation);
- return;
- }
- setResult(RESULT_CANCELED, new Intent());
- done();
- return;
- }
-
- private void startBitmapIO(int flags, Bitmap currentBitmap, Uri sourceUri, Uri destUri,
- RectF cropBounds, RectF photoBounds, RectF currentBitmapBounds, String format,
- int rotation) {
- if (cropBounds == null || photoBounds == null || currentBitmap == null
- || currentBitmap.getWidth() == 0 || currentBitmap.getHeight() == 0
- || cropBounds.width() == 0 || cropBounds.height() == 0 || photoBounds.width() == 0
- || photoBounds.height() == 0) {
- return; // fail fast
- }
- if ((flags & FLAG_CHECK) == 0) {
- return; // no output options
- }
- if ((flags & DO_SET_WALLPAPER) != 0) {
- Toast.makeText(this, R.string.setting_wallpaper, Toast.LENGTH_LONG).show();
- }
-
- final View loading = findViewById(R.id.loading);
- loading.setVisibility(View.VISIBLE);
- BitmapIOTask ioTask = new BitmapIOTask(sourceUri, destUri, format, flags, cropBounds,
- photoBounds, currentBitmapBounds, rotation, mOutputX, mOutputY);
- ioTask.execute(currentBitmap);
- }
-
- private void doneBitmapIO(boolean success, Intent intent) {
- final View loading = findViewById(R.id.loading);
- loading.setVisibility(View.GONE);
- if (success) {
- setResult(RESULT_OK, intent);
- } else {
- setResult(RESULT_CANCELED, intent);
- }
- done();
- }
-
- private class BitmapIOTask extends AsyncTask<Bitmap, Void, Boolean> {
-
- private final WallpaperManager mWPManager;
- InputStream mInStream = null;
- OutputStream mOutStream = null;
- String mOutputFormat = null;
- Uri mOutUri = null;
- Uri mInUri = null;
- int mFlags = 0;
- RectF mCrop = null;
- RectF mPhoto = null;
- RectF mOrig = null;
- Intent mResultIntent = null;
- int mRotation = 0;
-
- // Helper to setup input stream
- private void regenerateInputStream() {
- if (mInUri == null) {
- Log.w(LOGTAG, "cannot read original file, no input URI given");
- } else {
- Utils.closeSilently(mInStream);
- try {
- mInStream = getContentResolver().openInputStream(mInUri);
- } catch (FileNotFoundException e) {
- Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
- }
- }
- }
-
- public BitmapIOTask(Uri sourceUri, Uri destUri, String outputFormat, int flags,
- RectF cropBounds, RectF photoBounds, RectF originalBitmapBounds, int rotation,
- int outputX, int outputY) {
- mOutputFormat = outputFormat;
- mOutStream = null;
- mOutUri = destUri;
- mInUri = sourceUri;
- mFlags = flags;
- mCrop = cropBounds;
- mPhoto = photoBounds;
- mOrig = originalBitmapBounds;
- mWPManager = WallpaperManager.getInstance(getApplicationContext());
- mResultIntent = new Intent();
- mRotation = (rotation < 0) ? -rotation : rotation;
- mRotation %= 360;
- mRotation = 90 * (int) (mRotation / 90); // now mRotation is a multiple of 90
- mOutputX = outputX;
- mOutputY = outputY;
-
- if ((flags & DO_EXTRA_OUTPUT) != 0) {
- if (mOutUri == null) {
- Log.w(LOGTAG, "cannot write file, no output URI given");
- } else {
- try {
- mOutStream = getContentResolver().openOutputStream(mOutUri);
- } catch (FileNotFoundException e) {
- Log.w(LOGTAG, "cannot write file: " + mOutUri.toString(), e);
- }
- }
- }
-
- if ((flags & (DO_EXTRA_OUTPUT | DO_SET_WALLPAPER)) != 0) {
- regenerateInputStream();
- }
- }
-
- @Override
- protected Boolean doInBackground(Bitmap... params) {
- boolean failure = false;
- Bitmap img = params[0];
-
- // Set extra for crop bounds
- if (mCrop != null && mPhoto != null && mOrig != null) {
- RectF trueCrop = CropMath.getScaledCropBounds(mCrop, mPhoto, mOrig);
- Matrix m = new Matrix();
- m.setRotate(mRotation);
- m.mapRect(trueCrop);
- if (trueCrop != null) {
- Rect rounded = new Rect();
- trueCrop.roundOut(rounded);
- mResultIntent.putExtra(CropExtras.KEY_CROPPED_RECT, rounded);
- }
- }
-
- // Find the small cropped bitmap that is returned in the intent
- if ((mFlags & DO_RETURN_DATA) != 0) {
- assert (img != null);
- Bitmap ret = getCroppedImage(img, mCrop, mPhoto);
- if (ret != null) {
- ret = getDownsampledBitmap(ret, MAX_BMAP_IN_INTENT);
- }
- if (ret == null) {
- Log.w(LOGTAG, "could not downsample bitmap to return in data");
- failure = true;
- } else {
- if (mRotation > 0) {
- Matrix m = new Matrix();
- m.setRotate(mRotation);
- Bitmap tmp = Bitmap.createBitmap(ret, 0, 0, ret.getWidth(),
- ret.getHeight(), m, true);
- if (tmp != null) {
- ret = tmp;
- }
- }
- mResultIntent.putExtra(CropExtras.KEY_DATA, ret);
- }
- }
-
- // Do the large cropped bitmap and/or set the wallpaper
- if ((mFlags & (DO_EXTRA_OUTPUT | DO_SET_WALLPAPER)) != 0 && mInStream != null) {
- // Find crop bounds (scaled to original image size)
- RectF trueCrop = CropMath.getScaledCropBounds(mCrop, mPhoto, mOrig);
- if (trueCrop == null) {
- Log.w(LOGTAG, "cannot find crop for full size image");
- failure = true;
- return false;
- }
- Rect roundedTrueCrop = new Rect();
- trueCrop.roundOut(roundedTrueCrop);
-
- if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
- Log.w(LOGTAG, "crop has bad values for full size image");
- failure = true;
- return false;
- }
-
- // Attempt to open a region decoder
- BitmapRegionDecoder decoder = null;
- try {
- decoder = BitmapRegionDecoder.newInstance(mInStream, true);
- } catch (IOException e) {
- Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
- }
-
- Bitmap crop = null;
- if (decoder != null) {
- // Do region decoding to get crop bitmap
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inMutable = true;
- crop = decoder.decodeRegion(roundedTrueCrop, options);
- decoder.recycle();
- }
-
- if (crop == null) {
- // BitmapRegionDecoder has failed, try to crop in-memory
- regenerateInputStream();
- Bitmap fullSize = null;
- if (mInStream != null) {
- fullSize = BitmapFactory.decodeStream(mInStream);
- }
- if (fullSize != null) {
- crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
- roundedTrueCrop.top, roundedTrueCrop.width(),
- roundedTrueCrop.height());
- }
- }
-
- if (crop == null) {
- Log.w(LOGTAG, "cannot decode file: " + mInUri.toString());
- failure = true;
- return false;
- }
- if (mOutputX > 0 && mOutputY > 0) {
- Matrix m = new Matrix();
- RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
- if (mRotation > 0) {
- m.setRotate(mRotation);
- m.mapRect(cropRect);
- }
- RectF returnRect = new RectF(0, 0, mOutputX, mOutputY);
- m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
- m.preRotate(mRotation);
- Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
- (int) returnRect.height(), Bitmap.Config.ARGB_8888);
- if (tmp != null) {
- Canvas c = new Canvas(tmp);
- c.drawBitmap(crop, m, new Paint());
- crop = tmp;
- }
- } else if (mRotation > 0) {
- Matrix m = new Matrix();
- m.setRotate(mRotation);
- Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
- crop.getHeight(), m, true);
- if (tmp != null) {
- crop = tmp;
- }
- }
- // Get output compression format
- CompressFormat cf =
- convertExtensionToCompressFormat(getFileExtension(mOutputFormat));
-
- // If we only need to output to a URI, compress straight to file
- if (mFlags == DO_EXTRA_OUTPUT) {
- if (mOutStream == null
- || !crop.compress(cf, DEFAULT_COMPRESS_QUALITY, mOutStream)) {
- Log.w(LOGTAG, "failed to compress bitmap to file: " + mOutUri.toString());
- failure = true;
- } else {
- mResultIntent.setData(mOutUri);
- }
- } else {
- // Compress to byte array
- ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
- if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
-
- // If we need to output to a Uri, write compressed
- // bitmap out
- if ((mFlags & DO_EXTRA_OUTPUT) != 0) {
- if (mOutStream == null) {
- Log.w(LOGTAG,
- "failed to compress bitmap to file: " + mOutUri.toString());
- failure = true;
- } else {
- try {
- mOutStream.write(tmpOut.toByteArray());
- mResultIntent.setData(mOutUri);
- } catch (IOException e) {
- Log.w(LOGTAG,
- "failed to compress bitmap to file: "
- + mOutUri.toString(), e);
- failure = true;
- }
- }
- }
-
- // If we need to set to the wallpaper, set it
- if ((mFlags & DO_SET_WALLPAPER) != 0 && mWPManager != null) {
- if (mWPManager == null) {
- Log.w(LOGTAG, "no wallpaper manager");
- failure = true;
- } else {
- try {
- mWPManager.setStream(new ByteArrayInputStream(tmpOut
- .toByteArray()));
- } catch (IOException e) {
- Log.w(LOGTAG, "cannot write stream to wallpaper", e);
- failure = true;
- }
- }
- }
- } else {
- Log.w(LOGTAG, "cannot compress bitmap");
- failure = true;
- }
- }
- }
- return !failure; // True if any of the operations failed
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- Utils.closeSilently(mOutStream);
- Utils.closeSilently(mInStream);
- doneBitmapIO(result.booleanValue(), mResultIntent);
- }
-
- }
-
- private void done() {
- finish();
- }
-
- protected static Bitmap getCroppedImage(Bitmap image, RectF cropBounds, RectF photoBounds) {
- RectF imageBounds = new RectF(0, 0, image.getWidth(), image.getHeight());
- RectF crop = CropMath.getScaledCropBounds(cropBounds, photoBounds, imageBounds);
- if (crop == null) {
- return null;
- }
- Rect intCrop = new Rect();
- crop.roundOut(intCrop);
- return Bitmap.createBitmap(image, intCrop.left, intCrop.top, intCrop.width(),
- intCrop.height());
- }
-
- protected static Bitmap getDownsampledBitmap(Bitmap image, int max_size) {
- if (image == null || image.getWidth() == 0 || image.getHeight() == 0 || max_size < 16) {
- throw new IllegalArgumentException("Bad argument to getDownsampledBitmap()");
- }
- int shifts = 0;
- int size = CropMath.getBitmapSize(image);
- while (size > max_size) {
- shifts++;
- size /= 4;
- }
- Bitmap ret = Bitmap.createScaledBitmap(image, image.getWidth() >> shifts,
- image.getHeight() >> shifts, true);
- if (ret == null) {
- return null;
- }
- // Handle edge case for rounding.
- if (CropMath.getBitmapSize(ret) > max_size) {
- return Bitmap.createScaledBitmap(ret, ret.getWidth() >> 1, ret.getHeight() >> 1, true);
- }
- return ret;
- }
-
- /**
- * Gets the crop extras from the intent, or null if none exist.
- */
- protected static CropExtras getExtrasFromIntent(Intent intent) {
- Bundle extras = intent.getExtras();
- if (extras != null) {
- return new CropExtras(extras.getInt(CropExtras.KEY_OUTPUT_X, 0),
- extras.getInt(CropExtras.KEY_OUTPUT_Y, 0),
- extras.getBoolean(CropExtras.KEY_SCALE, true) &&
- extras.getBoolean(CropExtras.KEY_SCALE_UP_IF_NEEDED, false),
- extras.getInt(CropExtras.KEY_ASPECT_X, 0),
- extras.getInt(CropExtras.KEY_ASPECT_Y, 0),
- extras.getBoolean(CropExtras.KEY_SET_AS_WALLPAPER, false),
- extras.getBoolean(CropExtras.KEY_RETURN_DATA, false),
- (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT),
- extras.getString(CropExtras.KEY_OUTPUT_FORMAT),
- extras.getBoolean(CropExtras.KEY_SHOW_WHEN_LOCKED, false),
- extras.getFloat(CropExtras.KEY_SPOTLIGHT_X),
- extras.getFloat(CropExtras.KEY_SPOTLIGHT_Y));
- }
- return null;
- }
-
- protected static CompressFormat convertExtensionToCompressFormat(String extension) {
- return extension.equals("png") ? CompressFormat.PNG : CompressFormat.JPEG;
- }
-
- protected static String getFileExtension(String requestFormat) {
- String outputFormat = (requestFormat == null)
- ? "jpg"
- : requestFormat;
- outputFormat = outputFormat.toLowerCase();
- return (outputFormat.equals("png") || outputFormat.equals("gif"))
- ? "png" // We don't support gif compression.
- : "jpg";
- }
-
- private RectF getBitmapCrop(RectF imageBounds) {
- RectF crop = mCropView.getCrop();
- RectF photo = mCropView.getPhoto();
- if (crop == null || photo == null) {
- Log.w(LOGTAG, "could not get crop");
- return null;
- }
- RectF scaledCrop = CropMath.getScaledCropBounds(crop, photo, imageBounds);
- return scaledCrop;
- }
-}
diff --git a/src/com/android/camera/crop/CropDrawingUtils.java b/src/com/android/camera/crop/CropDrawingUtils.java
deleted file mode 100644
index c799aa350..000000000
--- a/src/com/android/camera/crop/CropDrawingUtils.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.crop;
-
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.drawable.Drawable;
-
-public abstract class CropDrawingUtils {
-
- public static void drawRuleOfThird(Canvas canvas, RectF bounds) {
- Paint p = new Paint();
- p.setStyle(Paint.Style.STROKE);
- p.setColor(Color.argb(128, 255, 255, 255));
- p.setStrokeWidth(2);
- float stepX = bounds.width() / 3.0f;
- float stepY = bounds.height() / 3.0f;
- float x = bounds.left + stepX;
- float y = bounds.top + stepY;
- for (int i = 0; i < 2; i++) {
- canvas.drawLine(x, bounds.top, x, bounds.bottom, p);
- x += stepX;
- }
- for (int j = 0; j < 2; j++) {
- canvas.drawLine(bounds.left, y, bounds.right, y, p);
- y += stepY;
- }
- }
-
- public static void drawCropRect(Canvas canvas, RectF bounds) {
- Paint p = new Paint();
- p.setStyle(Paint.Style.STROKE);
- p.setColor(Color.WHITE);
- p.setStrokeWidth(3);
- canvas.drawRect(bounds, p);
- }
-
- public static void drawShade(Canvas canvas, RectF bounds) {
- int w = canvas.getWidth();
- int h = canvas.getHeight();
- Paint p = new Paint();
- p.setStyle(Paint.Style.FILL);
- p.setColor(Color.BLACK & 0x88000000);
-
- RectF r = new RectF();
- r.set(0,0,w,bounds.top);
- canvas.drawRect(r, p);
- r.set(0,bounds.top,bounds.left,h);
- canvas.drawRect(r, p);
- r.set(bounds.left,bounds.bottom,w,h);
- canvas.drawRect(r, p);
- r.set(bounds.right,bounds.top,w,bounds.bottom);
- canvas.drawRect(r, p);
- }
-
- public static void drawIndicator(Canvas canvas, Drawable indicator, int indicatorSize,
- float centerX, float centerY) {
- int left = (int) centerX - indicatorSize / 2;
- int top = (int) centerY - indicatorSize / 2;
- indicator.setBounds(left, top, left + indicatorSize, top + indicatorSize);
- indicator.draw(canvas);
- }
-
- public static void drawIndicators(Canvas canvas, Drawable cropIndicator, int indicatorSize,
- RectF bounds, boolean fixedAspect, int selection) {
- boolean notMoving = (selection == CropObject.MOVE_NONE);
- if (fixedAspect) {
- if ((selection == CropObject.TOP_LEFT) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.top);
- }
- if ((selection == CropObject.TOP_RIGHT) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.top);
- }
- if ((selection == CropObject.BOTTOM_LEFT) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.bottom);
- }
- if ((selection == CropObject.BOTTOM_RIGHT) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.bottom);
- }
- } else {
- if (((selection & CropObject.MOVE_TOP) != 0) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.centerX(), bounds.top);
- }
- if (((selection & CropObject.MOVE_BOTTOM) != 0) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.centerX(), bounds.bottom);
- }
- if (((selection & CropObject.MOVE_LEFT) != 0) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.left, bounds.centerY());
- }
- if (((selection & CropObject.MOVE_RIGHT) != 0) || notMoving) {
- drawIndicator(canvas, cropIndicator, indicatorSize, bounds.right, bounds.centerY());
- }
- }
- }
-
- public static void drawWallpaperSelectionFrame(Canvas canvas, RectF cropBounds, float spotX,
- float spotY, Paint p, Paint shadowPaint) {
- float sx = cropBounds.width() * spotX;
- float sy = cropBounds.height() * spotY;
- float cx = cropBounds.centerX();
- float cy = cropBounds.centerY();
- RectF r1 = new RectF(cx - sx / 2, cy - sy / 2, cx + sx / 2, cy + sy / 2);
- float temp = sx;
- sx = sy;
- sy = temp;
- RectF r2 = new RectF(cx - sx / 2, cy - sy / 2, cx + sx / 2, cy + sy / 2);
- canvas.save();
- canvas.clipRect(cropBounds);
- canvas.clipRect(r1, Region.Op.DIFFERENCE);
- canvas.clipRect(r2, Region.Op.DIFFERENCE);
- canvas.drawPaint(shadowPaint);
- canvas.restore();
- Path path = new Path();
- path.moveTo(r1.left, r1.top);
- path.lineTo(r1.right, r1.top);
- path.moveTo(r1.left, r1.top);
- path.lineTo(r1.left, r1.bottom);
- path.moveTo(r1.left, r1.bottom);
- path.lineTo(r1.right, r1.bottom);
- path.moveTo(r1.right, r1.top);
- path.lineTo(r1.right, r1.bottom);
- path.moveTo(r2.left, r2.top);
- path.lineTo(r2.right, r2.top);
- path.moveTo(r2.right, r2.top);
- path.lineTo(r2.right, r2.bottom);
- path.moveTo(r2.left, r2.bottom);
- path.lineTo(r2.right, r2.bottom);
- path.moveTo(r2.left, r2.top);
- path.lineTo(r2.left, r2.bottom);
- canvas.drawPath(path, p);
- }
-
- public static void drawShadows(Canvas canvas, Paint p, RectF innerBounds, RectF outerBounds) {
- canvas.drawRect(outerBounds.left, outerBounds.top, innerBounds.right, innerBounds.top, p);
- canvas.drawRect(innerBounds.right, outerBounds.top, outerBounds.right, innerBounds.bottom,
- p);
- canvas.drawRect(innerBounds.left, innerBounds.bottom, outerBounds.right,
- outerBounds.bottom, p);
- canvas.drawRect(outerBounds.left, innerBounds.top, innerBounds.left, outerBounds.bottom, p);
- }
-
- public static Matrix getBitmapToDisplayMatrix(RectF imageBounds, RectF displayBounds) {
- Matrix m = new Matrix();
- CropDrawingUtils.setBitmapToDisplayMatrix(m, imageBounds, displayBounds);
- return m;
- }
-
- public static boolean setBitmapToDisplayMatrix(Matrix m, RectF imageBounds,
- RectF displayBounds) {
- m.reset();
- return m.setRectToRect(imageBounds, displayBounds, Matrix.ScaleToFit.CENTER);
- }
-
- public static boolean setImageToScreenMatrix(Matrix dst, RectF image,
- RectF screen, int rotation) {
- RectF rotatedImage = new RectF();
- dst.setRotate(rotation, image.centerX(), image.centerY());
- if (!dst.mapRect(rotatedImage, image)) {
- return false; // fails for rotations that are not multiples of 90
- // degrees
- }
- boolean rToR = dst.setRectToRect(rotatedImage, screen, Matrix.ScaleToFit.CENTER);
- boolean rot = dst.preRotate(rotation, image.centerX(), image.centerY());
- return rToR && rot;
- }
-
-}
diff --git a/src/com/android/camera/crop/CropExtras.java b/src/com/android/camera/crop/CropExtras.java
deleted file mode 100644
index 12fe2859e..000000000
--- a/src/com/android/camera/crop/CropExtras.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.crop;
-
-import android.net.Uri;
-
-public class CropExtras {
-
- public static final String KEY_CROPPED_RECT = "cropped-rect";
- public static final String KEY_OUTPUT_X = "outputX";
- public static final String KEY_OUTPUT_Y = "outputY";
- public static final String KEY_SCALE = "scale";
- public static final String KEY_SCALE_UP_IF_NEEDED = "scaleUpIfNeeded";
- public static final String KEY_ASPECT_X = "aspectX";
- public static final String KEY_ASPECT_Y = "aspectY";
- public static final String KEY_SET_AS_WALLPAPER = "set-as-wallpaper";
- public static final String KEY_RETURN_DATA = "return-data";
- public static final String KEY_DATA = "data";
- public static final String KEY_SPOTLIGHT_X = "spotlightX";
- public static final String KEY_SPOTLIGHT_Y = "spotlightY";
- public static final String KEY_SHOW_WHEN_LOCKED = "showWhenLocked";
- public static final String KEY_OUTPUT_FORMAT = "outputFormat";
-
- private int mOutputX = 0;
- private int mOutputY = 0;
- private boolean mScaleUp = true;
- private int mAspectX = 0;
- private int mAspectY = 0;
- private boolean mSetAsWallpaper = false;
- private boolean mReturnData = false;
- private Uri mExtraOutput = null;
- private String mOutputFormat = null;
- private boolean mShowWhenLocked = false;
- private float mSpotlightX = 0;
- private float mSpotlightY = 0;
-
- public CropExtras(int outputX, int outputY, boolean scaleUp, int aspectX, int aspectY,
- boolean setAsWallpaper, boolean returnData, Uri extraOutput, String outputFormat,
- boolean showWhenLocked, float spotlightX, float spotlightY) {
- mOutputX = outputX;
- mOutputY = outputY;
- mScaleUp = scaleUp;
- mAspectX = aspectX;
- mAspectY = aspectY;
- mSetAsWallpaper = setAsWallpaper;
- mReturnData = returnData;
- mExtraOutput = extraOutput;
- mOutputFormat = outputFormat;
- mShowWhenLocked = showWhenLocked;
- mSpotlightX = spotlightX;
- mSpotlightY = spotlightY;
- }
-
- public CropExtras(CropExtras c) {
- this(c.mOutputX, c.mOutputY, c.mScaleUp, c.mAspectX, c.mAspectY, c.mSetAsWallpaper,
- c.mReturnData, c.mExtraOutput, c.mOutputFormat, c.mShowWhenLocked,
- c.mSpotlightX, c.mSpotlightY);
- }
-
- public int getOutputX() {
- return mOutputX;
- }
-
- public int getOutputY() {
- return mOutputY;
- }
-
- public boolean getScaleUp() {
- return mScaleUp;
- }
-
- public int getAspectX() {
- return mAspectX;
- }
-
- public int getAspectY() {
- return mAspectY;
- }
-
- public boolean getSetAsWallpaper() {
- return mSetAsWallpaper;
- }
-
- public boolean getReturnData() {
- return mReturnData;
- }
-
- public Uri getExtraOutput() {
- return mExtraOutput;
- }
-
- public String getOutputFormat() {
- return mOutputFormat;
- }
-
- public boolean getShowWhenLocked() {
- return mShowWhenLocked;
- }
-
- public float getSpotlightX() {
- return mSpotlightX;
- }
-
- public float getSpotlightY() {
- return mSpotlightY;
- }
-}
diff --git a/src/com/android/camera/crop/CropMath.java b/src/com/android/camera/crop/CropMath.java
deleted file mode 100644
index 76e877609..000000000
--- a/src/com/android/camera/crop/CropMath.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.crop;
-
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.RectF;
-
-import java.util.Arrays;
-
-public class CropMath {
-
- /**
- * Gets a float array of the 2D coordinates representing a rectangles
- * corners.
- * The order of the corners in the float array is:
- * 0------->1
- * ^ |
- * | v
- * 3<-------2
- *
- * @param r the rectangle to get the corners of
- * @return the float array of corners (8 floats)
- */
-
- public static float[] getCornersFromRect(RectF r) {
- float[] corners = {
- r.left, r.top,
- r.right, r.top,
- r.right, r.bottom,
- r.left, r.bottom
- };
- return corners;
- }
-
- /**
- * Returns true iff point (x, y) is within or on the rectangle's bounds.
- * RectF's "contains" function treats points on the bottom and right bound
- * as not being contained.
- *
- * @param r the rectangle
- * @param x the x value of the point
- * @param y the y value of the point
- * @return
- */
- public static boolean inclusiveContains(RectF r, float x, float y) {
- return !(x > r.right || x < r.left || y > r.bottom || y < r.top);
- }
-
- /**
- * Takes an array of 2D coordinates representing corners and returns the
- * smallest rectangle containing those coordinates.
- *
- * @param array array of 2D coordinates
- * @return smallest rectangle containing coordinates
- */
- public static RectF trapToRect(float[] array) {
- RectF r = new RectF(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY,
- Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
- for (int i = 1; i < array.length; i += 2) {
- float x = array[i - 1];
- float y = array[i];
- r.left = (x < r.left) ? x : r.left;
- r.top = (y < r.top) ? y : r.top;
- r.right = (x > r.right) ? x : r.right;
- r.bottom = (y > r.bottom) ? y : r.bottom;
- }
- r.sort();
- return r;
- }
-
- /**
- * If edge point [x, y] in array [x0, y0, x1, y1, ...] is outside of the
- * image bound rectangle, clamps it to the edge of the rectangle.
- *
- * @param imageBound the rectangle to clamp edge points to.
- * @param array an array of points to clamp to the rectangle, gets set to
- * the clamped values.
- */
- public static void getEdgePoints(RectF imageBound, float[] array) {
- if (array.length < 2)
- return;
- for (int x = 0; x < array.length; x += 2) {
- array[x] = GeometryMathUtils.clamp(array[x], imageBound.left, imageBound.right);
- array[x + 1] = GeometryMathUtils.clamp(array[x + 1], imageBound.top, imageBound.bottom);
- }
- }
-
- /**
- * Takes a point and the corners of a rectangle and returns the two corners
- * representing the side of the rectangle closest to the point.
- *
- * @param point the point which is being checked
- * @param corners the corners of the rectangle
- * @return two corners representing the side of the rectangle
- */
- public static float[] closestSide(float[] point, float[] corners) {
- int len = corners.length;
- float oldMag = Float.POSITIVE_INFINITY;
- float[] bestLine = null;
- for (int i = 0; i < len; i += 2) {
- float[] line = {
- corners[i], corners[(i + 1) % len],
- corners[(i + 2) % len], corners[(i + 3) % len]
- };
- float mag = GeometryMathUtils.vectorLength(
- GeometryMathUtils.shortestVectorFromPointToLine(point, line));
- if (mag < oldMag) {
- oldMag = mag;
- bestLine = line;
- }
- }
- return bestLine;
- }
-
- /**
- * Checks if a given point is within a rotated rectangle.
- *
- * @param point 2D point to check
- * @param bound rectangle to rotate
- * @param rot angle of rotation about rectangle center
- * @return true if point is within rotated rectangle
- */
- public static boolean pointInRotatedRect(float[] point, RectF bound, float rot) {
- Matrix m = new Matrix();
- float[] p = Arrays.copyOf(point, 2);
- m.setRotate(rot, bound.centerX(), bound.centerY());
- Matrix m0 = new Matrix();
- if (!m.invert(m0))
- return false;
- m0.mapPoints(p);
- return inclusiveContains(bound, p[0], p[1]);
- }
-
- /**
- * Checks if a given point is within a rotated rectangle.
- *
- * @param point 2D point to check
- * @param rotatedRect corners of a rotated rectangle
- * @param center center of the rotated rectangle
- * @return true if point is within rotated rectangle
- */
- public static boolean pointInRotatedRect(float[] point, float[] rotatedRect, float[] center) {
- RectF unrotated = new RectF();
- float angle = getUnrotated(rotatedRect, center, unrotated);
- return pointInRotatedRect(point, unrotated, angle);
- }
-
- /**
- * Resizes rectangle to have a certain aspect ratio (center remains
- * stationary).
- *
- * @param r rectangle to resize
- * @param w new width aspect
- * @param h new height aspect
- */
- public static void fixAspectRatio(RectF r, float w, float h) {
- float scale = Math.min(r.width() / w, r.height() / h);
- float centX = r.centerX();
- float centY = r.centerY();
- float hw = scale * w / 2;
- float hh = scale * h / 2;
- r.set(centX - hw, centY - hh, centX + hw, centY + hh);
- }
-
- /**
- * Resizes rectangle to have a certain aspect ratio (center remains
- * stationary) while constraining it to remain within the original rect.
- *
- * @param r rectangle to resize
- * @param w new width aspect
- * @param h new height aspect
- */
- public static void fixAspectRatioContained(RectF r, float w, float h) {
- float origW = r.width();
- float origH = r.height();
- float origA = origW / origH;
- float a = w / h;
- float finalW = origW;
- float finalH = origH;
- if (origA < a) {
- finalH = origW / a;
- r.top = r.centerY() - finalH / 2;
- r.bottom = r.top + finalH;
- } else {
- finalW = origH * a;
- r.left = r.centerX() - finalW / 2;
- r.right = r.left + finalW;
- }
- }
-
- /**
- * Stretches/Scales/Translates photoBounds to match displayBounds, and
- * and returns an equivalent stretched/scaled/translated cropBounds or null
- * if the mapping is invalid.
- * @param cropBounds cropBounds to transform
- * @param photoBounds original bounds containing crop bounds
- * @param displayBounds final bounds for crop
- * @return the stretched/scaled/translated crop bounds that fit within displayBounds
- */
- public static RectF getScaledCropBounds(RectF cropBounds, RectF photoBounds,
- RectF displayBounds) {
- Matrix m = new Matrix();
- m.setRectToRect(photoBounds, displayBounds, Matrix.ScaleToFit.FILL);
- RectF trueCrop = new RectF(cropBounds);
- if (!m.mapRect(trueCrop)) {
- return null;
- }
- return trueCrop;
- }
-
- /**
- * Returns the size of a bitmap in bytes.
- * @param bmap bitmap whose size to check
- * @return bitmap size in bytes
- */
- public static int getBitmapSize(Bitmap bmap) {
- return bmap.getRowBytes() * bmap.getHeight();
- }
-
- /**
- * Constrains rotation to be in [0, 90, 180, 270] rounding down.
- * @param rotation any rotation value, in degrees
- * @return integer rotation in [0, 90, 180, 270]
- */
- public static int constrainedRotation(float rotation) {
- int r = (int) ((rotation % 360) / 90);
- r = (r < 0) ? (r + 4) : r;
- return r * 90;
- }
-
- private static float getUnrotated(float[] rotatedRect, float[] center, RectF unrotated) {
- float dy = rotatedRect[1] - rotatedRect[3];
- float dx = rotatedRect[0] - rotatedRect[2];
- float angle = (float) (Math.atan(dy / dx) * 180 / Math.PI);
- Matrix m = new Matrix();
- m.setRotate(-angle, center[0], center[1]);
- float[] unrotatedRect = new float[rotatedRect.length];
- m.mapPoints(unrotatedRect, rotatedRect);
- unrotated.set(trapToRect(unrotatedRect));
- return angle;
- }
-
-}
diff --git a/src/com/android/camera/crop/CropObject.java b/src/com/android/camera/crop/CropObject.java
deleted file mode 100644
index 4a566b3ef..000000000
--- a/src/com/android/camera/crop/CropObject.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.crop;
-
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-public class CropObject {
- private BoundedRect mBoundedRect;
- private float mAspectWidth = 1;
- private float mAspectHeight = 1;
- private boolean mFixAspectRatio = false;
- private float mRotation = 0;
- private float mTouchTolerance = 45;
- private float mMinSideSize = 20;
-
- public static final int MOVE_NONE = 0;
- // Sides
- public static final int MOVE_LEFT = 1;
- public static final int MOVE_TOP = 2;
- public static final int MOVE_RIGHT = 4;
- public static final int MOVE_BOTTOM = 8;
- public static final int MOVE_BLOCK = 16;
-
- // Corners
- public static final int TOP_LEFT = MOVE_TOP | MOVE_LEFT;
- public static final int TOP_RIGHT = MOVE_TOP | MOVE_RIGHT;
- public static final int BOTTOM_RIGHT = MOVE_BOTTOM | MOVE_RIGHT;
- public static final int BOTTOM_LEFT = MOVE_BOTTOM | MOVE_LEFT;
-
- private int mMovingEdges = MOVE_NONE;
-
- public CropObject(Rect outerBound, Rect innerBound, int outerAngle) {
- mBoundedRect = new BoundedRect(outerAngle % 360, outerBound, innerBound);
- }
-
- public CropObject(RectF outerBound, RectF innerBound, int outerAngle) {
- mBoundedRect = new BoundedRect(outerAngle % 360, outerBound, innerBound);
- }
-
- public void resetBoundsTo(RectF inner, RectF outer) {
- mBoundedRect.resetTo(0, outer, inner);
- }
-
- public void getInnerBounds(RectF r) {
- mBoundedRect.setToInner(r);
- }
-
- public void getOuterBounds(RectF r) {
- mBoundedRect.setToOuter(r);
- }
-
- public RectF getInnerBounds() {
- return mBoundedRect.getInner();
- }
-
- public RectF getOuterBounds() {
- return mBoundedRect.getOuter();
- }
-
- public int getSelectState() {
- return mMovingEdges;
- }
-
- public boolean isFixedAspect() {
- return mFixAspectRatio;
- }
-
- public void rotateOuter(int angle) {
- mRotation = angle % 360;
- mBoundedRect.setRotation(mRotation);
- clearSelectState();
- }
-
- public boolean setInnerAspectRatio(float width, float height) {
- if (width <= 0 || height <= 0) {
- throw new IllegalArgumentException("Width and Height must be greater than zero");
- }
- RectF inner = mBoundedRect.getInner();
- CropMath.fixAspectRatioContained(inner, width, height);
- if (inner.width() < mMinSideSize || inner.height() < mMinSideSize) {
- return false;
- }
- mAspectWidth = width;
- mAspectHeight = height;
- mFixAspectRatio = true;
- mBoundedRect.setInner(inner);
- clearSelectState();
- return true;
- }
-
- public void setTouchTolerance(float tolerance) {
- if (tolerance <= 0) {
- throw new IllegalArgumentException("Tolerance must be greater than zero");
- }
- mTouchTolerance = tolerance;
- }
-
- public void setMinInnerSideSize(float minSide) {
- if (minSide <= 0) {
- throw new IllegalArgumentException("Min dide must be greater than zero");
- }
- mMinSideSize = minSide;
- }
-
- public void unsetAspectRatio() {
- mFixAspectRatio = false;
- clearSelectState();
- }
-
- public boolean hasSelectedEdge() {
- return mMovingEdges != MOVE_NONE;
- }
-
- public static boolean checkCorner(int selected) {
- return selected == TOP_LEFT || selected == TOP_RIGHT || selected == BOTTOM_RIGHT
- || selected == BOTTOM_LEFT;
- }
-
- public static boolean checkEdge(int selected) {
- return selected == MOVE_LEFT || selected == MOVE_TOP || selected == MOVE_RIGHT
- || selected == MOVE_BOTTOM;
- }
-
- public static boolean checkBlock(int selected) {
- return selected == MOVE_BLOCK;
- }
-
- public static boolean checkValid(int selected) {
- return selected == MOVE_NONE || checkBlock(selected) || checkEdge(selected)
- || checkCorner(selected);
- }
-
- public void clearSelectState() {
- mMovingEdges = MOVE_NONE;
- }
-
- public int wouldSelectEdge(float x, float y) {
- int edgeSelected = calculateSelectedEdge(x, y);
- if (edgeSelected != MOVE_NONE && edgeSelected != MOVE_BLOCK) {
- return edgeSelected;
- }
- return MOVE_NONE;
- }
-
- public boolean selectEdge(int edge) {
- if (!checkValid(edge)) {
- // temporary
- throw new IllegalArgumentException("bad edge selected");
- // return false;
- }
- if ((mFixAspectRatio && !checkCorner(edge)) && !checkBlock(edge) && edge != MOVE_NONE) {
- // temporary
- throw new IllegalArgumentException("bad corner selected");
- // return false;
- }
- mMovingEdges = edge;
- return true;
- }
-
- public boolean selectEdge(float x, float y) {
- int edgeSelected = calculateSelectedEdge(x, y);
- if (mFixAspectRatio) {
- edgeSelected = fixEdgeToCorner(edgeSelected);
- }
- if (edgeSelected == MOVE_NONE) {
- return false;
- }
- return selectEdge(edgeSelected);
- }
-
- public boolean moveCurrentSelection(float dX, float dY) {
- if (mMovingEdges == MOVE_NONE) {
- return false;
- }
- RectF crop = mBoundedRect.getInner();
-
- float minWidthHeight = mMinSideSize;
-
- int movingEdges = mMovingEdges;
- if (movingEdges == MOVE_BLOCK) {
- mBoundedRect.moveInner(dX, dY);
- return true;
- } else {
- float dx = 0;
- float dy = 0;
-
- if ((movingEdges & MOVE_LEFT) != 0) {
- dx = Math.min(crop.left + dX, crop.right - minWidthHeight) - crop.left;
- }
- if ((movingEdges & MOVE_TOP) != 0) {
- dy = Math.min(crop.top + dY, crop.bottom - minWidthHeight) - crop.top;
- }
- if ((movingEdges & MOVE_RIGHT) != 0) {
- dx = Math.max(crop.right + dX, crop.left + minWidthHeight)
- - crop.right;
- }
- if ((movingEdges & MOVE_BOTTOM) != 0) {
- dy = Math.max(crop.bottom + dY, crop.top + minWidthHeight)
- - crop.bottom;
- }
-
- if (mFixAspectRatio) {
- float[] l1 = {
- crop.left, crop.bottom
- };
- float[] l2 = {
- crop.right, crop.top
- };
- if (movingEdges == TOP_LEFT || movingEdges == BOTTOM_RIGHT) {
- l1[1] = crop.top;
- l2[1] = crop.bottom;
- }
- float[] b = {
- l1[0] - l2[0], l1[1] - l2[1]
- };
- float[] disp = {
- dx, dy
- };
- float[] bUnit = GeometryMathUtils.normalize(b);
- float sp = GeometryMathUtils.scalarProjection(disp, bUnit);
- dx = sp * bUnit[0];
- dy = sp * bUnit[1];
- RectF newCrop = fixedCornerResize(crop, movingEdges, dx, dy);
-
- mBoundedRect.fixedAspectResizeInner(newCrop);
- } else {
- if ((movingEdges & MOVE_LEFT) != 0) {
- crop.left += dx;
- }
- if ((movingEdges & MOVE_TOP) != 0) {
- crop.top += dy;
- }
- if ((movingEdges & MOVE_RIGHT) != 0) {
- crop.right += dx;
- }
- if ((movingEdges & MOVE_BOTTOM) != 0) {
- crop.bottom += dy;
- }
- mBoundedRect.resizeInner(crop);
- }
- }
- return true;
- }
-
- // Helper methods
-
- private int calculateSelectedEdge(float x, float y) {
- RectF cropped = mBoundedRect.getInner();
-
- float left = Math.abs(x - cropped.left);
- float right = Math.abs(x - cropped.right);
- float top = Math.abs(y - cropped.top);
- float bottom = Math.abs(y - cropped.bottom);
-
- int edgeSelected = MOVE_NONE;
- // Check left or right.
- if ((left <= mTouchTolerance) && ((y + mTouchTolerance) >= cropped.top)
- && ((y - mTouchTolerance) <= cropped.bottom) && (left < right)) {
- edgeSelected |= MOVE_LEFT;
- }
- else if ((right <= mTouchTolerance) && ((y + mTouchTolerance) >= cropped.top)
- && ((y - mTouchTolerance) <= cropped.bottom)) {
- edgeSelected |= MOVE_RIGHT;
- }
-
- // Check top or bottom.
- if ((top <= mTouchTolerance) && ((x + mTouchTolerance) >= cropped.left)
- && ((x - mTouchTolerance) <= cropped.right) && (top < bottom)) {
- edgeSelected |= MOVE_TOP;
- }
- else if ((bottom <= mTouchTolerance) && ((x + mTouchTolerance) >= cropped.left)
- && ((x - mTouchTolerance) <= cropped.right)) {
- edgeSelected |= MOVE_BOTTOM;
- }
- return edgeSelected;
- }
-
- private static RectF fixedCornerResize(RectF r, int moving_corner, float dx, float dy) {
- RectF newCrop = null;
- // Fix opposite corner in place and move sides
- if (moving_corner == BOTTOM_RIGHT) {
- newCrop = new RectF(r.left, r.top, r.left + r.width() + dx, r.top + r.height()
- + dy);
- } else if (moving_corner == BOTTOM_LEFT) {
- newCrop = new RectF(r.right - r.width() + dx, r.top, r.right, r.top + r.height()
- + dy);
- } else if (moving_corner == TOP_LEFT) {
- newCrop = new RectF(r.right - r.width() + dx, r.bottom - r.height() + dy,
- r.right, r.bottom);
- } else if (moving_corner == TOP_RIGHT) {
- newCrop = new RectF(r.left, r.bottom - r.height() + dy, r.left
- + r.width() + dx, r.bottom);
- }
- return newCrop;
- }
-
- private static int fixEdgeToCorner(int moving_edges) {
- if (moving_edges == MOVE_LEFT) {
- moving_edges |= MOVE_TOP;
- }
- if (moving_edges == MOVE_TOP) {
- moving_edges |= MOVE_LEFT;
- }
- if (moving_edges == MOVE_RIGHT) {
- moving_edges |= MOVE_BOTTOM;
- }
- if (moving_edges == MOVE_BOTTOM) {
- moving_edges |= MOVE_RIGHT;
- }
- return moving_edges;
- }
-
-}
diff --git a/src/com/android/camera/crop/CropView.java b/src/com/android/camera/crop/CropView.java
deleted file mode 100644
index a47cb0a36..000000000
--- a/src/com/android/camera/crop/CropView.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.crop;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.DashPathEffect;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.camera2.R;
-
-public class CropView extends View {
- private static final String LOGTAG = "CropView";
-
- private RectF mImageBounds = new RectF();
- private RectF mScreenBounds = new RectF();
- private RectF mScreenImageBounds = new RectF();
- private RectF mScreenCropBounds = new RectF();
- private Rect mShadowBounds = new Rect();
-
- private Bitmap mBitmap;
- private Paint mPaint = new Paint();
-
- private NinePatchDrawable mShadow;
- private CropObject mCropObj = null;
- private Drawable mCropIndicator;
- private int mIndicatorSize;
- private int mRotation = 0;
- private boolean mMovingBlock = false;
- private Matrix mDisplayMatrix = null;
- private Matrix mDisplayMatrixInverse = null;
- private boolean mDirty = false;
-
- private float mPrevX = 0;
- private float mPrevY = 0;
- private float mSpotX = 0;
- private float mSpotY = 0;
- private boolean mDoSpot = false;
-
- private int mShadowMargin = 15;
- private int mMargin = 32;
- private int mOverlayShadowColor = 0xCF000000;
- private int mOverlayWPShadowColor = 0x5F000000;
- private int mWPMarkerColor = 0x7FFFFFFF;
- private int mMinSideSize = 90;
- private int mTouchTolerance = 40;
- private float mDashOnLength = 20;
- private float mDashOffLength = 10;
-
- private enum Mode {
- NONE, MOVE
- }
-
- private Mode mState = Mode.NONE;
-
- public CropView(Context context) {
- super(context);
- setup(context);
- }
-
- public CropView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setup(context);
- }
-
- public CropView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- setup(context);
- }
-
- private void setup(Context context) {
- Resources rsc = context.getResources();
- mShadow = (NinePatchDrawable) rsc.getDrawable(R.drawable.geometry_shadow);
- mCropIndicator = rsc.getDrawable(R.drawable.camera_crop);
- mIndicatorSize = (int) rsc.getDimension(R.dimen.crop_indicator_size);
- mShadowMargin = (int) rsc.getDimension(R.dimen.shadow_margin);
- mMargin = (int) rsc.getDimension(R.dimen.preview_margin);
- mMinSideSize = (int) rsc.getDimension(R.dimen.crop_min_side);
- mTouchTolerance = (int) rsc.getDimension(R.dimen.crop_touch_tolerance);
- mOverlayShadowColor = (int) rsc.getColor(R.color.crop_shadow_color);
- mOverlayWPShadowColor = (int) rsc.getColor(R.color.crop_shadow_wp_color);
- mWPMarkerColor = (int) rsc.getColor(R.color.crop_wp_markers);
- mDashOnLength = rsc.getDimension(R.dimen.wp_selector_dash_length);
- mDashOffLength = rsc.getDimension(R.dimen.wp_selector_off_length);
- }
-
- public void initialize(Bitmap image, RectF newCropBounds, RectF newPhotoBounds, int rotation) {
- mBitmap = image;
- if (mCropObj != null) {
- RectF crop = mCropObj.getInnerBounds();
- RectF containing = mCropObj.getOuterBounds();
- if (crop != newCropBounds || containing != newPhotoBounds
- || mRotation != rotation) {
- mRotation = rotation;
- mCropObj.resetBoundsTo(newCropBounds, newPhotoBounds);
- clearDisplay();
- }
- } else {
- mRotation = rotation;
- mCropObj = new CropObject(newPhotoBounds, newCropBounds, 0);
- clearDisplay();
- }
- }
-
- public RectF getCrop() {
- return mCropObj.getInnerBounds();
- }
-
- public RectF getPhoto() {
- return mCropObj.getOuterBounds();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- if (mDisplayMatrix == null || mDisplayMatrixInverse == null) {
- return true;
- }
- float[] touchPoint = {
- x, y
- };
- mDisplayMatrixInverse.mapPoints(touchPoint);
- x = touchPoint[0];
- y = touchPoint[1];
- switch (event.getActionMasked()) {
- case (MotionEvent.ACTION_DOWN):
- if (mState == Mode.NONE) {
- if (!mCropObj.selectEdge(x, y)) {
- mMovingBlock = mCropObj.selectEdge(CropObject.MOVE_BLOCK);
- }
- mPrevX = x;
- mPrevY = y;
- mState = Mode.MOVE;
- }
- break;
- case (MotionEvent.ACTION_UP):
- if (mState == Mode.MOVE) {
- mCropObj.selectEdge(CropObject.MOVE_NONE);
- mMovingBlock = false;
- mPrevX = x;
- mPrevY = y;
- mState = Mode.NONE;
- }
- break;
- case (MotionEvent.ACTION_MOVE):
- if (mState == Mode.MOVE) {
- float dx = x - mPrevX;
- float dy = y - mPrevY;
- mCropObj.moveCurrentSelection(dx, dy);
- mPrevX = x;
- mPrevY = y;
- }
- break;
- default:
- break;
- }
- invalidate();
- return true;
- }
-
- private void reset() {
- Log.w(LOGTAG, "crop reset called");
- mState = Mode.NONE;
- mCropObj = null;
- mRotation = 0;
- mMovingBlock = false;
- clearDisplay();
- }
-
- private void clearDisplay() {
- mDisplayMatrix = null;
- mDisplayMatrixInverse = null;
- invalidate();
- }
-
- protected void configChanged() {
- mDirty = true;
- }
-
- public void applyFreeAspect() {
- mCropObj.unsetAspectRatio();
- invalidate();
- }
-
- public void applyOriginalAspect() {
- RectF outer = mCropObj.getOuterBounds();
- float w = outer.width();
- float h = outer.height();
- if (w > 0 && h > 0) {
- applyAspect(w, h);
- mCropObj.resetBoundsTo(outer, outer);
- } else {
- Log.w(LOGTAG, "failed to set aspect ratio original");
- }
- }
-
- public void applySquareAspect() {
- applyAspect(1, 1);
- }
-
- public void applyAspect(float x, float y) {
- if (x <= 0 || y <= 0) {
- throw new IllegalArgumentException("Bad arguments to applyAspect");
- }
- // If we are rotated by 90 degrees from horizontal, swap x and y
- if (((mRotation < 0) ? -mRotation : mRotation) % 180 == 90) {
- float tmp = x;
- x = y;
- y = tmp;
- }
- if (!mCropObj.setInnerAspectRatio(x, y)) {
- Log.w(LOGTAG, "failed to set aspect ratio");
- }
- invalidate();
- }
-
- public void setWallpaperSpotlight(float spotlightX, float spotlightY) {
- mSpotX = spotlightX;
- mSpotY = spotlightY;
- if (mSpotX > 0 && mSpotY > 0) {
- mDoSpot = true;
- }
- }
-
- public void unsetWallpaperSpotlight() {
- mDoSpot = false;
- }
-
- /**
- * Rotates first d bits in integer x to the left some number of times.
- */
- private int bitCycleLeft(int x, int times, int d) {
- int mask = (1 << d) - 1;
- int mout = x & mask;
- times %= d;
- int hi = mout >> (d - times);
- int low = (mout << times) & mask;
- int ret = x & ~mask;
- ret |= low;
- ret |= hi;
- return ret;
- }
-
- /**
- * Find the selected edge or corner in screen coordinates.
- */
- private int decode(int movingEdges, float rotation) {
- int rot = CropMath.constrainedRotation(rotation);
- switch (rot) {
- case 90:
- return bitCycleLeft(movingEdges, 1, 4);
- case 180:
- return bitCycleLeft(movingEdges, 2, 4);
- case 270:
- return bitCycleLeft(movingEdges, 3, 4);
- default:
- return movingEdges;
- }
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- if (mBitmap == null) {
- return;
- }
- if (mDirty) {
- mDirty = false;
- clearDisplay();
- }
-
- mImageBounds = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
- mScreenBounds = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
- mScreenBounds.inset(mMargin, mMargin);
-
- // If crop object doesn't exist, create it and update it from master
- // state
- if (mCropObj == null) {
- reset();
- mCropObj = new CropObject(mImageBounds, mImageBounds, 0);
- }
-
- // If display matrix doesn't exist, create it and its dependencies
- if (mDisplayMatrix == null || mDisplayMatrixInverse == null) {
- mDisplayMatrix = new Matrix();
- mDisplayMatrix.reset();
- if (!CropDrawingUtils.setImageToScreenMatrix(mDisplayMatrix, mImageBounds, mScreenBounds,
- mRotation)) {
- Log.w(LOGTAG, "failed to get screen matrix");
- mDisplayMatrix = null;
- return;
- }
- mDisplayMatrixInverse = new Matrix();
- mDisplayMatrixInverse.reset();
- if (!mDisplayMatrix.invert(mDisplayMatrixInverse)) {
- Log.w(LOGTAG, "could not invert display matrix");
- mDisplayMatrixInverse = null;
- return;
- }
- // Scale min side and tolerance by display matrix scale factor
- mCropObj.setMinInnerSideSize(mDisplayMatrixInverse.mapRadius(mMinSideSize));
- mCropObj.setTouchTolerance(mDisplayMatrixInverse.mapRadius(mTouchTolerance));
- }
-
- mScreenImageBounds.set(mImageBounds);
-
- // Draw background shadow
- if (mDisplayMatrix.mapRect(mScreenImageBounds)) {
- int margin = (int) mDisplayMatrix.mapRadius(mShadowMargin);
- mScreenImageBounds.roundOut(mShadowBounds);
- mShadowBounds.set(mShadowBounds.left - margin, mShadowBounds.top -
- margin, mShadowBounds.right + margin, mShadowBounds.bottom + margin);
- mShadow.setBounds(mShadowBounds);
- mShadow.draw(canvas);
- }
-
- mPaint.setAntiAlias(true);
- mPaint.setFilterBitmap(true);
- // Draw actual bitmap
- canvas.drawBitmap(mBitmap, mDisplayMatrix, mPaint);
-
- mCropObj.getInnerBounds(mScreenCropBounds);
-
- if (mDisplayMatrix.mapRect(mScreenCropBounds)) {
-
- // Draw overlay shadows
- Paint p = new Paint();
- p.setColor(mOverlayShadowColor);
- p.setStyle(Paint.Style.FILL);
- CropDrawingUtils.drawShadows(canvas, p, mScreenCropBounds, mScreenImageBounds);
-
- // Draw crop rect and markers
- CropDrawingUtils.drawCropRect(canvas, mScreenCropBounds);
- if (!mDoSpot) {
- CropDrawingUtils.drawRuleOfThird(canvas, mScreenCropBounds);
- } else {
- Paint wpPaint = new Paint();
- wpPaint.setColor(mWPMarkerColor);
- wpPaint.setStrokeWidth(3);
- wpPaint.setStyle(Paint.Style.STROKE);
- wpPaint.setPathEffect(new DashPathEffect(new float[]
- {mDashOnLength, mDashOnLength + mDashOffLength}, 0));
- p.setColor(mOverlayWPShadowColor);
- CropDrawingUtils.drawWallpaperSelectionFrame(canvas, mScreenCropBounds,
- mSpotX, mSpotY, wpPaint, p);
- }
- CropDrawingUtils.drawIndicators(canvas, mCropIndicator, mIndicatorSize,
- mScreenCropBounds, mCropObj.isFixedAspect(), decode(mCropObj.getSelectState(), mRotation));
- }
-
- }
-}
diff --git a/src/com/android/camera/crop/GeometryMathUtils.java b/src/com/android/camera/crop/GeometryMathUtils.java
deleted file mode 100644
index cb5fefe4b..000000000
--- a/src/com/android/camera/crop/GeometryMathUtils.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.crop;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-/*
-import com.android.gallery3d.filtershow.cache.BitmapCache;
-import com.android.gallery3d.filtershow.cache.ImageLoader;
-import com.android.gallery3d.filtershow.filters.FilterCropRepresentation;
-import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation;
-import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation.Mirror;
-import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation;
-import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation.Rotation;
-import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation;
-import com.android.gallery3d.filtershow.pipeline.ImagePreset;
-*/
-
-import java.util.Collection;
-import java.util.Iterator;
-
-public final class GeometryMathUtils {
- private static final String TAG = "GeometryMathUtils";
- public static final float SHOW_SCALE = .9f;
-
- private GeometryMathUtils() {};
-
- // Math operations for 2d vectors
- public static float clamp(float i, float low, float high) {
- return Math.max(Math.min(i, high), low);
- }
-
- public static float[] lineIntersect(float[] line1, float[] line2) {
- float a0 = line1[0];
- float a1 = line1[1];
- float b0 = line1[2];
- float b1 = line1[3];
- float c0 = line2[0];
- float c1 = line2[1];
- float d0 = line2[2];
- float d1 = line2[3];
- float t0 = a0 - b0;
- float t1 = a1 - b1;
- float t2 = b0 - d0;
- float t3 = d1 - b1;
- float t4 = c0 - d0;
- float t5 = c1 - d1;
-
- float denom = t1 * t4 - t0 * t5;
- if (denom == 0)
- return null;
- float u = (t3 * t4 + t5 * t2) / denom;
- float[] intersect = {
- b0 + u * t0, b1 + u * t1
- };
- return intersect;
- }
-
- public static float[] shortestVectorFromPointToLine(float[] point, float[] line) {
- float x1 = line[0];
- float x2 = line[2];
- float y1 = line[1];
- float y2 = line[3];
- float xdelt = x2 - x1;
- float ydelt = y2 - y1;
- if (xdelt == 0 && ydelt == 0)
- return null;
- float u = ((point[0] - x1) * xdelt + (point[1] - y1) * ydelt)
- / (xdelt * xdelt + ydelt * ydelt);
- float[] ret = {
- (x1 + u * (x2 - x1)), (y1 + u * (y2 - y1))
- };
- float[] vec = {
- ret[0] - point[0], ret[1] - point[1]
- };
- return vec;
- }
-
- // A . B
- public static float dotProduct(float[] a, float[] b) {
- return a[0] * b[0] + a[1] * b[1];
- }
-
- public static float[] normalize(float[] a) {
- float length = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]);
- float[] b = {
- a[0] / length, a[1] / length
- };
- return b;
- }
-
- // A onto B
- public static float scalarProjection(float[] a, float[] b) {
- float length = (float) Math.sqrt(b[0] * b[0] + b[1] * b[1]);
- return dotProduct(a, b) / length;
- }
-
- public static float[] getVectorFromPoints(float[] point1, float[] point2) {
- float[] p = {
- point2[0] - point1[0], point2[1] - point1[1]
- };
- return p;
- }
-
- public static float[] getUnitVectorFromPoints(float[] point1, float[] point2) {
- float[] p = {
- point2[0] - point1[0], point2[1] - point1[1]
- };
- float length = (float) Math.sqrt(p[0] * p[0] + p[1] * p[1]);
- p[0] = p[0] / length;
- p[1] = p[1] / length;
- return p;
- }
-
- public static void scaleRect(RectF r, float scale) {
- r.set(r.left * scale, r.top * scale, r.right * scale, r.bottom * scale);
- }
-
- // A - B
- public static float[] vectorSubtract(float[] a, float[] b) {
- int len = a.length;
- if (len != b.length)
- return null;
- float[] ret = new float[len];
- for (int i = 0; i < len; i++) {
- ret[i] = a[i] - b[i];
- }
- return ret;
- }
-
- public static float vectorLength(float[] a) {
- return (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]);
- }
-
- public static float scale(float oldWidth, float oldHeight, float newWidth, float newHeight) {
- if (oldHeight == 0 || oldWidth == 0 || (oldWidth == newWidth && oldHeight == newHeight)) {
- return 1;
- }
- return Math.min(newWidth / oldWidth, newHeight / oldHeight);
- }
-
- public static Rect roundNearest(RectF r) {
- Rect q = new Rect(Math.round(r.left), Math.round(r.top), Math.round(r.right),
- Math.round(r.bottom));
- return q;
- }
-
- private static int getRotationForOrientation(int orientation) {
- switch (orientation) {
- case ImageLoader.ORI_ROTATE_90:
- return 90;
- case ImageLoader.ORI_ROTATE_180:
- return 180;
- case ImageLoader.ORI_ROTATE_270:
- return 270;
- default:
- return 0;
- }
- }
-
-}
diff --git a/src/com/android/camera/crop/SaveImage.java b/src/com/android/camera/crop/SaveImage.java
deleted file mode 100644
index c48e861fe..000000000
--- a/src/com/android/camera/crop/SaveImage.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.crop;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.util.Log;
-
-import com.android.camera.exif.ExifInterface;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.sql.Date;
-import java.text.SimpleDateFormat;
-import java.util.TimeZone;
-
-/**
- * Handles saving edited photo
- */
-public class SaveImage {
- private static final String LOGTAG = "SaveImage";
-
- /**
- * Callback for updates
- */
- public interface Callback {
- void onProgress(int max, int current);
- }
-
- public interface ContentResolverQueryCallback {
- void onCursorResult(Cursor cursor);
- }
-
- private static final String TIME_STAMP_NAME = "_yyyyMMdd_HHmmss";
- private static final String PREFIX_PANO = "PANO";
- private static final String PREFIX_IMG = "IMG";
- private static final String POSTFIX_JPG = ".jpg";
- private static final String AUX_DIR_NAME = ".aux";
-
- private final Context mContext;
- private final Uri mSourceUri;
- private final Callback mCallback;
- private final File mDestinationFile;
- private final Uri mSelectedImageUri;
- private final Bitmap mPreviewImage;
-
- private int mCurrentProcessingStep = 1;
-
- public static final int MAX_PROCESSING_STEPS = 6;
- public static final String DEFAULT_SAVE_DIRECTORY = "EditedOnlinePhotos";
-
- // In order to support the new edit-save behavior such that user won't see
- // the edited image together with the original image, we are adding a new
- // auxiliary directory for the edited image. Basically, the original image
- // will be hidden in that directory after edit and user will see the edited
- // image only.
- // Note that deletion on the edited image will also cause the deletion of
- // the original image under auxiliary directory.
- //
- // There are several situations we need to consider:
- // 1. User edit local image local01.jpg. A local02.jpg will be created in the
- // same directory, and original image will be moved to auxiliary directory as
- // ./.aux/local02.jpg.
- // If user edit the local02.jpg, local03.jpg will be created in the local
- // directory and ./.aux/local02.jpg will be renamed to ./.aux/local03.jpg
- //
- // 2. User edit remote image remote01.jpg from picassa or other server.
- // remoteSavedLocal01.jpg will be saved under proper local directory.
- // In remoteSavedLocal01.jpg, there will be a reference pointing to the
- // remote01.jpg. There will be no local copy of remote01.jpg.
- // If user edit remoteSavedLocal01.jpg, then a new remoteSavedLocal02.jpg
- // will be generated and still pointing to the remote01.jpg
- //
- // 3. User delete any local image local.jpg.
- // Since the filenames are kept consistent in auxiliary directory, every
- // time a local.jpg get deleted, the files in auxiliary directory whose
- // names starting with "local." will be deleted.
- // This pattern will facilitate the multiple images deletion in the auxiliary
- // directory.
-
- /**
- * @param context
- * @param sourceUri The Uri for the original image, which can be the hidden
- * image under the auxiliary directory or the same as selectedImageUri.
- * @param selectedImageUri The Uri for the image selected by the user.
- * In most cases, it is a content Uri for local image or remote image.
- * @param destination Destinaton File, if this is null, a new file will be
- * created under the same directory as selectedImageUri.
- * @param callback Let the caller know the saving has completed.
- * @return the newSourceUri
- */
- public SaveImage(Context context, Uri sourceUri, Uri selectedImageUri,
- File destination, Bitmap previewImage, Callback callback) {
- mContext = context;
- mSourceUri = sourceUri;
- mCallback = callback;
- mPreviewImage = previewImage;
- if (destination == null) {
- mDestinationFile = getNewFile(context, selectedImageUri);
- } else {
- mDestinationFile = destination;
- }
-
- mSelectedImageUri = selectedImageUri;
- }
-
- public static File getFinalSaveDirectory(Context context, Uri sourceUri) {
- File saveDirectory = SaveImage.getSaveDirectory(context, sourceUri);
- if ((saveDirectory == null) || !saveDirectory.canWrite()) {
- saveDirectory = new File(Environment.getExternalStorageDirectory(),
- SaveImage.DEFAULT_SAVE_DIRECTORY);
- }
- // Create the directory if it doesn't exist
- if (!saveDirectory.exists())
- saveDirectory.mkdirs();
- return saveDirectory;
- }
-
- public static File getNewFile(Context context, Uri sourceUri) {
- File saveDirectory = getFinalSaveDirectory(context, sourceUri);
- String filename = new SimpleDateFormat(TIME_STAMP_NAME).format(new Date(
- System.currentTimeMillis()));
- if (hasPanoPrefix(context, sourceUri)) {
- return new File(saveDirectory, PREFIX_PANO + filename + POSTFIX_JPG);
- }
- return new File(saveDirectory, PREFIX_IMG + filename + POSTFIX_JPG);
- }
-
- /**
- * Remove the files in the auxiliary directory whose names are the same as
- * the source image.
- * @param contentResolver The application's contentResolver
- * @param srcContentUri The content Uri for the source image.
- */
- public static void deleteAuxFiles(ContentResolver contentResolver,
- Uri srcContentUri) {
- final String[] fullPath = new String[1];
- String[] queryProjection = new String[] { ImageColumns.DATA };
- querySourceFromContentResolver(contentResolver,
- srcContentUri, queryProjection,
- new ContentResolverQueryCallback() {
- @Override
- public void onCursorResult(Cursor cursor) {
- fullPath[0] = cursor.getString(0);
- }
- }
- );
- if (fullPath[0] != null) {
- // Construct the auxiliary directory given the source file's path.
- // Then select and delete all the files starting with the same name
- // under the auxiliary directory.
- File currentFile = new File(fullPath[0]);
-
- String filename = currentFile.getName();
- int firstDotPos = filename.indexOf(".");
- final String filenameNoExt = (firstDotPos == -1) ? filename :
- filename.substring(0, firstDotPos);
- File auxDir = getLocalAuxDirectory(currentFile);
- if (auxDir.exists()) {
- FilenameFilter filter = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- if (name.startsWith(filenameNoExt + ".")) {
- return true;
- } else {
- return false;
- }
- }
- };
-
- // Delete all auxiliary files whose name is matching the
- // current local image.
- File[] auxFiles = auxDir.listFiles(filter);
- for (File file : auxFiles) {
- file.delete();
- }
- }
- }
- }
-
- public ExifInterface getExifData(Uri source) {
- ExifInterface exif = new ExifInterface();
- String mimeType = mContext.getContentResolver().getType(mSelectedImageUri);
- if (mimeType == null) {
- mimeType = ImageLoader.getMimeType(mSelectedImageUri);
- }
- if (mimeType.equals(ImageLoader.JPEG_MIME_TYPE)) {
- InputStream inStream = null;
- try {
- inStream = mContext.getContentResolver().openInputStream(source);
- exif.readExif(inStream);
- } catch (FileNotFoundException e) {
- Log.w(LOGTAG, "Cannot find file: " + source, e);
- } catch (IOException e) {
- Log.w(LOGTAG, "Cannot read exif for: " + source, e);
- } finally {
- Utils.closeSilently(inStream);
- }
- }
- return exif;
- }
-
- public boolean putExifData(File file, ExifInterface exif, Bitmap image,
- int jpegCompressQuality) {
- boolean ret = false;
- OutputStream s = null;
- try {
- s = exif.getExifWriterStream(file.getAbsolutePath());
- image.compress(Bitmap.CompressFormat.JPEG,
- (jpegCompressQuality > 0) ? jpegCompressQuality : 1, s);
- s.flush();
- s.close();
- s = null;
- ret = true;
- } catch (FileNotFoundException e) {
- Log.w(LOGTAG, "File not found: " + file.getAbsolutePath(), e);
- } catch (IOException e) {
- Log.w(LOGTAG, "Could not write exif: ", e);
- } finally {
- Utils.closeSilently(s);
- }
- return ret;
- }
-
- private void resetProgress() {
- mCurrentProcessingStep = 0;
- }
-
- private void updateProgress() {
- if (mCallback != null) {
- mCallback.onProgress(MAX_PROCESSING_STEPS, ++mCurrentProcessingStep);
- }
- }
-
- private void updateExifData(ExifInterface exif, long time) {
- // Set tags
- exif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME, time,
- TimeZone.getDefault());
- exif.setTag(exif.buildTag(ExifInterface.TAG_ORIENTATION,
- ExifInterface.Orientation.TOP_LEFT));
- // Remove old thumbnail
- exif.removeCompressedThumbnail();
- }
-
- /**
- * Move the source file to auxiliary directory if needed and return the Uri
- * pointing to this new source file. If any file error happens, then just
- * don't move into the auxiliary directory.
- * @param srcUri Uri to the source image.
- * @param dstFile Providing the destination file info to help to build the
- * auxiliary directory and new source file's name.
- * @return the newSourceUri pointing to the new source image.
- */
- private Uri moveSrcToAuxIfNeeded(Uri srcUri, File dstFile) {
- File srcFile = getLocalFileFromUri(mContext, srcUri);
- if (srcFile == null) {
- Log.d(LOGTAG, "Source file is not a local file, no update.");
- return srcUri;
- }
-
- // Get the destination directory and create the auxilliary directory
- // if necessary.
- File auxDiretory = getLocalAuxDirectory(dstFile);
- if (!auxDiretory.exists()) {
- boolean success = auxDiretory.mkdirs();
- if (!success) {
- return srcUri;
- }
- }
-
- // Make sure there is a .nomedia file in the auxiliary directory, such
- // that MediaScanner will not report those files under this directory.
- File noMedia = new File(auxDiretory, ".nomedia");
- if (!noMedia.exists()) {
- try {
- noMedia.createNewFile();
- } catch (IOException e) {
- Log.e(LOGTAG, "Can't create the nomedia");
- return srcUri;
- }
- }
- // We are using the destination file name such that photos sitting in
- // the auxiliary directory are matching the parent directory.
- File newSrcFile = new File(auxDiretory, dstFile.getName());
- // Maintain the suffix during move
- String to = newSrcFile.getName();
- String from = srcFile.getName();
- to = to.substring(to.lastIndexOf("."));
- from = from.substring(from.lastIndexOf("."));
-
- if (!to.equals(from)) {
- String name = dstFile.getName();
- name = name.substring(0, name.lastIndexOf(".")) + from;
- newSrcFile = new File(auxDiretory, name);
- }
-
- if (!newSrcFile.exists()) {
- boolean success = srcFile.renameTo(newSrcFile);
- if (!success) {
- return srcUri;
- }
- }
-
- return Uri.fromFile(newSrcFile);
-
- }
-
- private static File getLocalAuxDirectory(File dstFile) {
- File dstDirectory = dstFile.getParentFile();
- File auxDiretory = new File(dstDirectory + "/" + AUX_DIR_NAME);
- return auxDiretory;
- }
-
- public static Uri makeAndInsertUri(Context context, Uri sourceUri) {
- long time = System.currentTimeMillis();
- String filename = new SimpleDateFormat(TIME_STAMP_NAME).format(new Date(time));
- File saveDirectory = getFinalSaveDirectory(context, sourceUri);
- File file = new File(saveDirectory, filename + ".JPG");
- return linkNewFileToUri(context, sourceUri, file, time, false);
- }
-
- public static void querySource(Context context, Uri sourceUri, String[] projection,
- ContentResolverQueryCallback callback) {
- ContentResolver contentResolver = context.getContentResolver();
- querySourceFromContentResolver(contentResolver, sourceUri, projection, callback);
- }
-
- private static void querySourceFromContentResolver(
- ContentResolver contentResolver, Uri sourceUri, String[] projection,
- ContentResolverQueryCallback callback) {
- Cursor cursor = null;
- try {
- cursor = contentResolver.query(sourceUri, projection, null, null,
- null);
- if ((cursor != null) && cursor.moveToNext()) {
- callback.onCursorResult(cursor);
- }
- } catch (Exception e) {
- // Ignore error for lacking the data column from the source.
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
- private static File getSaveDirectory(Context context, Uri sourceUri) {
- File file = getLocalFileFromUri(context, sourceUri);
- if (file != null) {
- return file.getParentFile();
- } else {
- return null;
- }
- }
-
- /**
- * Construct a File object based on the srcUri.
- * @return The file object. Return null if srcUri is invalid or not a local
- * file.
- */
- private static File getLocalFileFromUri(Context context, Uri srcUri) {
- if (srcUri == null) {
- Log.e(LOGTAG, "srcUri is null.");
- return null;
- }
-
- String scheme = srcUri.getScheme();
- if (scheme == null) {
- Log.e(LOGTAG, "scheme is null.");
- return null;
- }
-
- final File[] file = new File[1];
- // sourceUri can be a file path or a content Uri, it need to be handled
- // differently.
- if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
- if (srcUri.getAuthority().equals(MediaStore.AUTHORITY)) {
- querySource(context, srcUri, new String[] {
- ImageColumns.DATA
- },
- new ContentResolverQueryCallback() {
-
- @Override
- public void onCursorResult(Cursor cursor) {
- file[0] = new File(cursor.getString(0));
- }
- });
- }
- } else if (scheme.equals(ContentResolver.SCHEME_FILE)) {
- file[0] = new File(srcUri.getPath());
- }
- return file[0];
- }
-
- /**
- * Gets the actual filename for a Uri from Gallery's ContentProvider.
- */
- private static String getTrueFilename(Context context, Uri src) {
- if (context == null || src == null) {
- return null;
- }
- final String[] trueName = new String[1];
- querySource(context, src, new String[] {
- ImageColumns.DATA
- }, new ContentResolverQueryCallback() {
- @Override
- public void onCursorResult(Cursor cursor) {
- trueName[0] = new File(cursor.getString(0)).getName();
- }
- });
- return trueName[0];
- }
-
- /**
- * Checks whether the true filename has the panorama image prefix.
- */
- private static boolean hasPanoPrefix(Context context, Uri src) {
- String name = getTrueFilename(context, src);
- return name != null && name.startsWith(PREFIX_PANO);
- }
-
- /**
- * If the <code>sourceUri</code> is a local content Uri, update the
- * <code>sourceUri</code> to point to the <code>file</code>.
- * At the same time, the old file <code>sourceUri</code> used to point to
- * will be removed if it is local.
- * If the <code>sourceUri</code> is not a local content Uri, then the
- * <code>file</code> will be inserted as a new content Uri.
- * @return the final Uri referring to the <code>file</code>.
- */
- public static Uri linkNewFileToUri(Context context, Uri sourceUri,
- File file, long time, boolean deleteOriginal) {
- File oldSelectedFile = getLocalFileFromUri(context, sourceUri);
- final ContentValues values = getContentValues(context, sourceUri, file, time);
-
- Uri result = sourceUri;
-
- // In the case of incoming Uri is just a local file Uri (like a cached
- // file), we can't just update the Uri. We have to create a new Uri.
- boolean fileUri = isFileUri(sourceUri);
-
- if (fileUri || oldSelectedFile == null || !deleteOriginal) {
- result = context.getContentResolver().insert(
- Images.Media.EXTERNAL_CONTENT_URI, values);
- } else {
- context.getContentResolver().update(sourceUri, values, null, null);
- if (oldSelectedFile.exists()) {
- oldSelectedFile.delete();
- }
- }
- return result;
- }
-
- public static Uri updateFile(Context context, Uri sourceUri, File file, long time) {
- final ContentValues values = getContentValues(context, sourceUri, file, time);
- context.getContentResolver().update(sourceUri, values, null, null);
- return sourceUri;
- }
-
- private static ContentValues getContentValues(Context context, Uri sourceUri,
- File file, long time) {
- final ContentValues values = new ContentValues();
-
- time /= 1000;
- values.put(Images.Media.TITLE, file.getName());
- values.put(Images.Media.DISPLAY_NAME, file.getName());
- values.put(Images.Media.MIME_TYPE, "image/jpeg");
- values.put(Images.Media.DATE_TAKEN, time);
- values.put(Images.Media.DATE_MODIFIED, time);
- values.put(Images.Media.DATE_ADDED, time);
- values.put(Images.Media.ORIENTATION, 0);
- values.put(Images.Media.DATA, file.getAbsolutePath());
- values.put(Images.Media.SIZE, file.length());
-
- final String[] projection = new String[] {
- ImageColumns.DATE_TAKEN,
- ImageColumns.LATITUDE, ImageColumns.LONGITUDE,
- };
-
- SaveImage.querySource(context, sourceUri, projection,
- new ContentResolverQueryCallback() {
-
- @Override
- public void onCursorResult(Cursor cursor) {
- values.put(Images.Media.DATE_TAKEN, cursor.getLong(0));
-
- double latitude = cursor.getDouble(1);
- double longitude = cursor.getDouble(2);
- // TODO: Change || to && after the default location
- // issue is fixed.
- if ((latitude != 0f) || (longitude != 0f)) {
- values.put(Images.Media.LATITUDE, latitude);
- values.put(Images.Media.LONGITUDE, longitude);
- }
- }
- });
- return values;
- }
-
- /**
- * @param sourceUri
- * @return true if the sourceUri is a local file Uri.
- */
- private static boolean isFileUri(Uri sourceUri) {
- String scheme = sourceUri.getScheme();
- if (scheme != null && scheme.equals(ContentResolver.SCHEME_FILE)) {
- return true;
- }
- return false;
- }
-
-}
diff --git a/src/com/android/camera/crop/Utils.java b/src/com/android/camera/crop/Utils.java
deleted file mode 100644
index ebbe50458..000000000
--- a/src/com/android/camera/crop/Utils.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.crop;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.Cursor;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-
-public class Utils {
- private static final String TAG = "Utils";
- private static final String DEBUG_TAG = "GalleryDebug";
-
- private static final long POLY64REV = 0x95AC9329AC4BC9B5L;
- private static final long INITIALCRC = 0xFFFFFFFFFFFFFFFFL;
-
- private static long[] sCrcTable = new long[256];
-
- private static final boolean IS_DEBUG_BUILD =
- Build.TYPE.equals("eng") || Build.TYPE.equals("userdebug");
-
- private static final String MASK_STRING = "********************************";
-
- // Throws AssertionError if the input is false.
- public static void assertTrue(boolean cond) {
- if (!cond) {
- throw new AssertionError();
- }
- }
-
- // Throws AssertionError with the message. We had a method having the form
- // assertTrue(boolean cond, String message, Object ... args);
- // However a call to that method will cause memory allocation even if the
- // condition is false (due to autoboxing generated by "Object ... args"),
- // so we don't use that anymore.
- public static void fail(String message, Object... args) {
- throw new AssertionError(
- args.length == 0 ? message : String.format(message, args));
- }
-
- // Throws NullPointerException if the input is null.
- public static <T> T checkNotNull(T object) {
- if (object == null) throw new NullPointerException();
- return object;
- }
-
- // Returns true if two input Object are both null or equal
- // to each other.
- public static boolean equals(Object a, Object b) {
- return (a == b) || (a == null ? false : a.equals(b));
- }
-
- // Returns the next power of two.
- // Returns the input if it is already power of 2.
- // Throws IllegalArgumentException if the input is <= 0 or
- // the answer overflows.
- public static int nextPowerOf2(int n) {
- if (n <= 0 || n > (1 << 30)) throw new IllegalArgumentException("n is invalid: " + n);
- n -= 1;
- n |= n >> 16;
- n |= n >> 8;
- n |= n >> 4;
- n |= n >> 2;
- n |= n >> 1;
- return n + 1;
- }
-
- // Returns the previous power of two.
- // Returns the input if it is already power of 2.
- // Throws IllegalArgumentException if the input is <= 0
- public static int prevPowerOf2(int n) {
- if (n <= 0) throw new IllegalArgumentException();
- return Integer.highestOneBit(n);
- }
-
- // Returns the input value x clamped to the range [min, max].
- public static int clamp(int x, int min, int max) {
- if (x > max) return max;
- if (x < min) return min;
- return x;
- }
-
- // Returns the input value x clamped to the range [min, max].
- public static float clamp(float x, float min, float max) {
- if (x > max) return max;
- if (x < min) return min;
- return x;
- }
-
- // Returns the input value x clamped to the range [min, max].
- public static long clamp(long x, long min, long max) {
- if (x > max) return max;
- if (x < min) return min;
- return x;
- }
-
- public static boolean isOpaque(int color) {
- return color >>> 24 == 0xFF;
- }
-
- public static void swap(int[] array, int i, int j) {
- int temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- }
-
- /**
- * A function thats returns a 64-bit crc for string
- *
- * @param in input string
- * @return a 64-bit crc value
- */
- public static final long crc64Long(String in) {
- if (in == null || in.length() == 0) {
- return 0;
- }
- return crc64Long(getBytes(in));
- }
-
- static {
- // http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c
- long part;
- for (int i = 0; i < 256; i++) {
- part = i;
- for (int j = 0; j < 8; j++) {
- long x = ((int) part & 1) != 0 ? POLY64REV : 0;
- part = (part >> 1) ^ x;
- }
- sCrcTable[i] = part;
- }
- }
-
- public static final long crc64Long(byte[] buffer) {
- long crc = INITIALCRC;
- for (int k = 0, n = buffer.length; k < n; ++k) {
- crc = sCrcTable[(((int) crc) ^ buffer[k]) & 0xff] ^ (crc >> 8);
- }
- return crc;
- }
-
- public static byte[] getBytes(String in) {
- byte[] result = new byte[in.length() * 2];
- int output = 0;
- for (char ch : in.toCharArray()) {
- result[output++] = (byte) (ch & 0xFF);
- result[output++] = (byte) (ch >> 8);
- }
- return result;
- }
-
- public static void closeSilently(Closeable c) {
- if (c == null) return;
- try {
- c.close();
- } catch (IOException t) {
- Log.w(TAG, "close fail ", t);
- }
- }
-
- public static int compare(long a, long b) {
- return a < b ? -1 : a == b ? 0 : 1;
- }
-
- public static int ceilLog2(float value) {
- int i;
- for (i = 0; i < 31; i++) {
- if ((1 << i) >= value) break;
- }
- return i;
- }
-
- public static int floorLog2(float value) {
- int i;
- for (i = 0; i < 31; i++) {
- if ((1 << i) > value) break;
- }
- return i - 1;
- }
-
- public static void closeSilently(ParcelFileDescriptor fd) {
- try {
- if (fd != null) fd.close();
- } catch (Throwable t) {
- Log.w(TAG, "fail to close", t);
- }
- }
-
- public static void closeSilently(Cursor cursor) {
- try {
- if (cursor != null) cursor.close();
- } catch (Throwable t) {
- Log.w(TAG, "fail to close", t);
- }
- }
-
- public static float interpolateAngle(
- float source, float target, float progress) {
- // interpolate the angle from source to target
- // We make the difference in the range of [-179, 180], this is the
- // shortest path to change source to target.
- float diff = target - source;
- if (diff < 0) diff += 360f;
- if (diff > 180) diff -= 360f;
-
- float result = source + diff * progress;
- return result < 0 ? result + 360f : result;
- }
-
- public static float interpolateScale(
- float source, float target, float progress) {
- return source + progress * (target - source);
- }
-
- public static String ensureNotNull(String value) {
- return value == null ? "" : value;
- }
-
- public static float parseFloatSafely(String content, float defaultValue) {
- if (content == null) return defaultValue;
- try {
- return Float.parseFloat(content);
- } catch (NumberFormatException e) {
- return defaultValue;
- }
- }
-
- public static int parseIntSafely(String content, int defaultValue) {
- if (content == null) return defaultValue;
- try {
- return Integer.parseInt(content);
- } catch (NumberFormatException e) {
- return defaultValue;
- }
- }
-
- public static boolean isNullOrEmpty(String exifMake) {
- return TextUtils.isEmpty(exifMake);
- }
-
- public static void waitWithoutInterrupt(Object object) {
- try {
- object.wait();
- } catch (InterruptedException e) {
- Log.w(TAG, "unexpected interrupt: " + object);
- }
- }
-
- public static boolean handleInterrruptedException(Throwable e) {
- // A helper to deal with the interrupt exception
- // If an interrupt detected, we will setup the bit again.
- if (e instanceof InterruptedIOException
- || e instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- return true;
- }
- return false;
- }
-
- /**
- * @return String with special XML characters escaped.
- */
- public static String escapeXml(String s) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0, len = s.length(); i < len; ++i) {
- char c = s.charAt(i);
- switch (c) {
- case '<': sb.append("&lt;"); break;
- case '>': sb.append("&gt;"); break;
- case '\"': sb.append("&quot;"); break;
- case '\'': sb.append("&#039;"); break;
- case '&': sb.append("&amp;"); break;
- default: sb.append(c);
- }
- }
- return sb.toString();
- }
-
- public static String getUserAgent(Context context) {
- PackageInfo packageInfo;
- try {
- packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- } catch (NameNotFoundException e) {
- throw new IllegalStateException("getPackageInfo failed");
- }
- return String.format("%s/%s; %s/%s/%s/%s; %s/%s/%s",
- packageInfo.packageName,
- packageInfo.versionName,
- Build.BRAND,
- Build.DEVICE,
- Build.MODEL,
- Build.ID,
- Build.VERSION.SDK_INT,
- Build.VERSION.RELEASE,
- Build.VERSION.INCREMENTAL);
- }
-
- public static String[] copyOf(String[] source, int newSize) {
- String[] result = new String[newSize];
- newSize = Math.min(source.length, newSize);
- System.arraycopy(source, 0, result, 0, newSize);
- return result;
- }
-
- // Mask information for debugging only. It returns <code>info.toString()</code> directly
- // for debugging build (i.e., 'eng' and 'userdebug') and returns a mask ("****")
- // in release build to protect the information (e.g. for privacy issue).
- public static String maskDebugInfo(Object info) {
- if (info == null) return null;
- String s = info.toString();
- int length = Math.min(s.length(), MASK_STRING.length());
- return IS_DEBUG_BUILD ? s : MASK_STRING.substring(0, length);
- }
-
- // This method should be ONLY used for debugging.
- public static void debug(String message, Object... args) {
- Log.v(DEBUG_TAG, String.format(message, args));
- }
-}
diff --git a/src/com/android/camera/ui/AbstractSettingPopup.java b/src/com/android/camera/ui/AbstractSettingPopup.java
deleted file mode 100644
index a3cf298b5..000000000
--- a/src/com/android/camera/ui/AbstractSettingPopup.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.camera2.R;
-
-// A popup window that shows one or more camera settings.
-abstract public class AbstractSettingPopup extends RotateLayout {
- protected ViewGroup mSettingList;
- protected TextView mTitle;
-
- public AbstractSettingPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- mTitle = (TextView) findViewById(R.id.title);
- mSettingList = (ViewGroup) findViewById(R.id.settingList);
- }
-
- abstract public void reloadPreference();
-}
diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java
deleted file mode 100644
index e7afa3d41..000000000
--- a/src/com/android/camera/ui/CountDownView.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.SoundPool;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.android.camera2.R;
-
-import java.util.Locale;
-
-public class CountDownView extends FrameLayout {
-
- private static final String TAG = "CountDownView";
- private static final int SET_TIMER_TEXT = 1;
- private TextView mRemainingSecondsView;
- private int mRemainingSecs = 0;
- private OnCountDownFinishedListener mListener;
- private final Animation mCountDownAnim;
- private final SoundPool mSoundPool;
- private final int mBeepTwice;
- private final int mBeepOnce;
- private boolean mPlaySound;
- private final Handler mHandler = new MainHandler();
-
- public CountDownView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mCountDownAnim = AnimationUtils.loadAnimation(context, R.anim.count_down_exit);
- // Load the beeps
- mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
- mBeepOnce = mSoundPool.load(context, R.raw.beep_once, 1);
- mBeepTwice = mSoundPool.load(context, R.raw.beep_twice, 1);
- }
-
- public boolean isCountingDown() {
- return mRemainingSecs > 0;
- };
-
- public interface OnCountDownFinishedListener {
- public void onCountDownFinished();
- }
-
- private void remainingSecondsChanged(int newVal) {
- mRemainingSecs = newVal;
- if (newVal == 0) {
- // Countdown has finished
- setVisibility(View.INVISIBLE);
- mListener.onCountDownFinished();
- } else {
- Locale locale = getResources().getConfiguration().locale;
- String localizedValue = String.format(locale, "%d", newVal);
- mRemainingSecondsView.setText(localizedValue);
- // Fade-out animation
- mCountDownAnim.reset();
- mRemainingSecondsView.clearAnimation();
- mRemainingSecondsView.startAnimation(mCountDownAnim);
-
- // Play sound effect for the last 3 seconds of the countdown
- if (mPlaySound) {
- if (newVal == 1) {
- mSoundPool.play(mBeepTwice, 1.0f, 1.0f, 0, 0, 1.0f);
- } else if (newVal <= 3) {
- mSoundPool.play(mBeepOnce, 1.0f, 1.0f, 0, 0, 1.0f);
- }
- }
- // Schedule the next remainingSecondsChanged() call in 1 second
- mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000);
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds);
- }
-
- public void setCountDownFinishedListener(OnCountDownFinishedListener listener) {
- mListener = listener;
- }
-
- public void startCountDown(int sec, boolean playSound) {
- if (sec <= 0) {
- Log.w(TAG, "Invalid input for countdown timer: " + sec + " seconds");
- return;
- }
- setVisibility(View.VISIBLE);
- mPlaySound = playSound;
- remainingSecondsChanged(sec);
- }
-
- public void cancelCountDown() {
- if (mRemainingSecs > 0) {
- mRemainingSecs = 0;
- mHandler.removeMessages(SET_TIMER_TEXT);
- setVisibility(View.INVISIBLE);
- }
- }
-
- private class MainHandler extends Handler {
- @Override
- public void handleMessage(Message message) {
- if (message.what == SET_TIMER_TEXT) {
- remainingSecondsChanged(mRemainingSecs -1);
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/camera/ui/CountdownTimerPopup.java b/src/com/android/camera/ui/CountdownTimerPopup.java
deleted file mode 100644
index 3f3a1ac7d..000000000
--- a/src/com/android/camera/ui/CountdownTimerPopup.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import java.util.Locale;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.NumberPicker;
-import android.widget.NumberPicker.OnValueChangeListener;
-
-import com.android.camera.ListPreference;
-import com.android.camera2.R;
-
-/**
- * This is a popup window that allows users to specify a countdown timer
- */
-
-public class CountdownTimerPopup extends AbstractSettingPopup {
- private static final String TAG = "TimerSettingPopup";
- private NumberPicker mNumberSpinner;
- private String[] mDurations;
- private ListPreference mTimer;
- private ListPreference mBeep;
- private Listener mListener;
- private Button mConfirmButton;
- private View mPickerTitle;
- private CheckBox mTimerSound;
- private View mSoundTitle;
-
- static public interface Listener {
- public void onListPrefChanged(ListPreference pref);
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public CountdownTimerPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void initialize(ListPreference timer, ListPreference beep) {
- mTimer = timer;
- mBeep = beep;
- // Set title.
- mTitle.setText(mTimer.getTitle());
-
- // Duration
- CharSequence[] entries = mTimer.getEntryValues();
- mDurations = new String[entries.length];
- Locale locale = getResources().getConfiguration().locale;
- mDurations[0] = getResources().getString(R.string.setting_off); // Off
- for (int i = 1; i < entries.length; i++)
- mDurations[i] = String.format(locale, "%d", Integer.parseInt(entries[i].toString()));
- int durationCount = mDurations.length;
- mNumberSpinner = (NumberPicker) findViewById(R.id.duration);
- mNumberSpinner.setMinValue(0);
- mNumberSpinner.setMaxValue(durationCount - 1);
- mNumberSpinner.setDisplayedValues(mDurations);
- mNumberSpinner.setWrapSelectorWheel(false);
- mNumberSpinner.setOnValueChangedListener(new OnValueChangeListener() {
- @Override
- public void onValueChange(NumberPicker picker, int oldValue, int newValue) {
- setTimeSelectionEnabled(newValue != 0);
- }
- });
- mConfirmButton = (Button) findViewById(R.id.timer_set_button);
- mPickerTitle = findViewById(R.id.set_time_interval_title);
-
- // Disable focus on the spinners to prevent keyboard from coming up
- mNumberSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
-
- mConfirmButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- updateInputState();
- }
- });
- mTimerSound = (CheckBox) findViewById(R.id.sound_check_box);
- mSoundTitle = findViewById(R.id.beep_title);
- }
-
- private void restoreSetting() {
- int index = mTimer.findIndexOfValue(mTimer.getValue());
- if (index == -1) {
- Log.e(TAG, "Invalid preference value.");
- mTimer.print();
- throw new IllegalArgumentException();
- } else {
- setTimeSelectionEnabled(index != 0);
- mNumberSpinner.setValue(index);
- }
- boolean checked = mBeep.findIndexOfValue(mBeep.getValue()) != 0;
- mTimerSound.setChecked(checked);
- }
-
- @Override
- public void setVisibility(int visibility) {
- if (visibility == View.VISIBLE) {
- if (getVisibility() != View.VISIBLE) {
- // Set the number pickers and on/off switch to be consistent
- // with the preference
- restoreSetting();
- }
- }
- super.setVisibility(visibility);
- }
-
- protected void setTimeSelectionEnabled(boolean enabled) {
- mPickerTitle.setVisibility(enabled ? VISIBLE : INVISIBLE);
- mTimerSound.setEnabled(enabled);
- mSoundTitle.setEnabled(enabled);
- }
-
- @Override
- public void reloadPreference() {
- }
-
- private void updateInputState() {
- mTimer.setValueIndex(mNumberSpinner.getValue());
- mBeep.setValueIndex(mTimerSound.isChecked() ? 1 : 0);
- if (mListener != null) {
- mListener.onListPrefChanged(mTimer);
- mListener.onListPrefChanged(mBeep);
- }
- }
-}
diff --git a/src/com/android/camera/ui/InLineSettingCheckBox.java b/src/com/android/camera/ui/InLineSettingCheckBox.java
deleted file mode 100644
index c3cd1979d..000000000
--- a/src/com/android/camera/ui/InLineSettingCheckBox.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-
-import com.android.camera.ListPreference;
-import com.android.camera2.R;
-
-/* A check box setting control which turns on/off the setting. */
-public class InLineSettingCheckBox extends InLineSettingItem {
- private CheckBox mCheckBox;
-
- OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean desiredState) {
- changeIndex(desiredState ? 1 : 0);
- }
- };
-
- public InLineSettingCheckBox(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mCheckBox = (CheckBox) findViewById(R.id.setting_check_box);
- mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
- }
-
- @Override
- public void initialize(ListPreference preference) {
- super.initialize(preference);
- // Add content descriptions for the increment and decrement buttons.
- mCheckBox.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_check_box, mPreference.getTitle()));
- }
-
- @Override
- protected void updateView() {
- mCheckBox.setOnCheckedChangeListener(null);
- if (mOverrideValue == null) {
- mCheckBox.setChecked(mIndex == 1);
- } else {
- int index = mPreference.findIndexOfValue(mOverrideValue);
- mCheckBox.setChecked(index == 1);
- }
- mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- event.getText().add(mPreference.getTitle());
- return true;
- }
-
- @Override
- public void setEnabled(boolean enable) {
- if (mTitle != null) mTitle.setEnabled(enable);
- if (mCheckBox != null) mCheckBox.setEnabled(enable);
- }
-}
diff --git a/src/com/android/camera/ui/InLineSettingItem.java b/src/com/android/camera/ui/InLineSettingItem.java
deleted file mode 100644
index 288781fda..000000000
--- a/src/com/android/camera/ui/InLineSettingItem.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.camera.ListPreference;
-import com.android.camera2.R;
-
-/**
- * A one-line camera setting could be one of three types: knob, switch or restore
- * preference button. The setting includes a title for showing the preference
- * title which is initialized in the SimpleAdapter. A knob also includes
- * (ex: Picture size), a previous button, the current value (ex: 5MP),
- * and a next button. A switch, i.e. the preference RecordLocationPreference,
- * has only two values on and off which will be controlled in a switch button.
- * Other setting popup window includes several InLineSettingItem items with
- * different types if possible.
- */
-public abstract class InLineSettingItem extends LinearLayout {
- private Listener mListener;
- protected ListPreference mPreference;
- protected int mIndex;
- // Scene mode can override the original preference value.
- protected String mOverrideValue;
- protected TextView mTitle;
-
- static public interface Listener {
- public void onSettingChanged(ListPreference pref);
- }
-
- public InLineSettingItem(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- protected void setTitle(ListPreference preference) {
- mTitle = ((TextView) findViewById(R.id.title));
- mTitle.setText(preference.getTitle());
- }
-
- public void initialize(ListPreference preference) {
- setTitle(preference);
- if (preference == null) return;
- mPreference = preference;
- reloadPreference();
- }
-
- protected abstract void updateView();
-
- protected boolean changeIndex(int index) {
- if (index >= mPreference.getEntryValues().length || index < 0) return false;
- mIndex = index;
- mPreference.setValueIndex(mIndex);
- if (mListener != null) {
- mListener.onSettingChanged(mPreference);
- }
- updateView();
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- return true;
- }
-
- // The value of the preference may have changed. Update the UI.
- public void reloadPreference() {
- mIndex = mPreference.findIndexOfValue(mPreference.getValue());
- updateView();
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public void overrideSettings(String value) {
- mOverrideValue = value;
- updateView();
- }
-}
diff --git a/src/com/android/camera/ui/InLineSettingMenu.java b/src/com/android/camera/ui/InLineSettingMenu.java
deleted file mode 100644
index 1d80741b5..000000000
--- a/src/com/android/camera/ui/InLineSettingMenu.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.TextView;
-
-import com.android.camera.ListPreference;
-import com.android.camera2.R;
-
-/* Setting menu item that will bring up a menu when you click on it. */
-public class InLineSettingMenu extends InLineSettingItem {
- private static final String TAG = "InLineSettingMenu";
- // The view that shows the current selected setting. Ex: 5MP
- private TextView mEntry;
-
- public InLineSettingMenu(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mEntry = (TextView) findViewById(R.id.current_setting);
- }
-
- @Override
- public void initialize(ListPreference preference) {
- super.initialize(preference);
- //TODO: add contentDescription
- }
-
- @Override
- protected void updateView() {
- if (mOverrideValue == null) {
- mEntry.setText(mPreference.getEntry());
- } else {
- int index = mPreference.findIndexOfValue(mOverrideValue);
- if (index != -1) {
- mEntry.setText(mPreference.getEntries()[index]);
- } else {
- // Avoid the crash if camera driver has bugs.
- Log.e(TAG, "Fail to find override value=" + mOverrideValue);
- mPreference.print();
- }
- }
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- event.getText().add(mPreference.getTitle() + mPreference.getEntry());
- return true;
- }
-
- @Override
- public void setEnabled(boolean enable) {
- super.setEnabled(enable);
- if (mTitle != null) mTitle.setEnabled(enable);
- if (mEntry != null) mEntry.setEnabled(enable);
- }
-}
diff --git a/src/com/android/camera/ui/RotateTextToast.java b/src/com/android/camera/ui/RotateTextToast.java
deleted file mode 100644
index ea1268218..000000000
--- a/src/com/android/camera/ui/RotateTextToast.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera.ui;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.camera.util.CameraUtil;
-import com.android.camera2.R;
-
-public class RotateTextToast {
- private static final int TOAST_DURATION = 5000; // milliseconds
- ViewGroup mLayoutRoot;
- RotateLayout mToast;
- Handler mHandler;
-
- public RotateTextToast(Activity activity, int textResourceId, int orientation) {
- mLayoutRoot = (ViewGroup) activity.getWindow().getDecorView();
- LayoutInflater inflater = activity.getLayoutInflater();
- View v = inflater.inflate(R.layout.rotate_text_toast, mLayoutRoot);
- mToast = (RotateLayout) v.findViewById(R.id.rotate_toast);
- TextView tv = (TextView) mToast.findViewById(R.id.message);
- tv.setText(textResourceId);
- mToast.setOrientation(orientation, false);
- mHandler = new Handler();
- }
-
- private final Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- CameraUtil.fadeOut(mToast);
- mLayoutRoot.removeView(mToast);
- mToast = null;
- }
- };
-
- public void show() {
- mToast.setVisibility(View.VISIBLE);
- mHandler.postDelayed(mRunnable, TOAST_DURATION);
- }
-}
diff --git a/src/com/android/camera/crop/ImageLoader.java b/src/com/android/camera/util/ImageLoader.java
index 9062e8550..a05892450 100644
--- a/src/com/android/camera/crop/ImageLoader.java
+++ b/src/com/android/camera/util/ImageLoader.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.camera.crop;
+package com.android.camera.util;
import android.content.ContentResolver;
import android.content.Context;
@@ -33,6 +33,7 @@ import android.webkit.MimeTypeMap;
import com.android.camera.exif.ExifInterface;
import com.android.camera.exif.ExifTag;
+import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -40,7 +41,7 @@ import java.util.List;
public final class ImageLoader {
- private static final String LOGTAG = "ImageLoader";
+ private static final String TAG = "ImageLoader";
public static final String JPEG_MIME_TYPE = "image/jpeg";
public static final int DEFAULT_COMPRESS_QUALITY = 95;
@@ -55,7 +56,6 @@ public final class ImageLoader {
public static final int ORI_TRANSVERSE = ExifInterface.Orientation.LEFT_BOTTOM;
private static final int BITMAP_LOAD_BACKOUT_ATTEMPTS = 5;
- private static final float OVERDRAW_ZOOM = 1.2f;
private ImageLoader() {}
/**
@@ -117,7 +117,7 @@ public final class ImageLoader {
} catch (IllegalStateException e) {
// Do nothing
} finally {
- Utils.closeSilently(cursor);
+ closeSilently(cursor);
}
// Fall back to checking EXIF tags in file.
@@ -148,7 +148,7 @@ public final class ImageLoader {
}
}
} catch (IOException e) {
- Log.w(LOGTAG, "Failed to read EXIF orientation", e);
+ Log.w(TAG, "Failed to read EXIF orientation", e);
}
}
return ORI_NORMAL;
@@ -252,9 +252,9 @@ public final class ImageLoader {
is = context.getContentResolver().openInputStream(uri);
return BitmapFactory.decodeStream(is, null, o);
} catch (FileNotFoundException e) {
- Log.e(LOGTAG, "FileNotFoundException for " + uri, e);
+ Log.e(TAG, "FileNotFoundException for " + uri, e);
} finally {
- Utils.closeSilently(is);
+ closeSilently(is);
}
return null;
}
@@ -424,9 +424,19 @@ public final class ImageLoader {
List<ExifTag> taglist = exif.getAllTags();
return taglist;
} catch (IOException e) {
- Log.w(LOGTAG, "Failed to read EXIF tags", e);
+ Log.w(TAG, "Failed to read EXIF tags", e);
}
}
return null;
}
+
+ private static void closeSilently(Closeable c) {
+ if (c == null) return;
+ try {
+ c.close();
+ } catch (IOException t) {
+ Log.w(TAG, "close fail ", t);
+ }
+ }
+
}