diff options
author | Sascha Haeberling <haeberling@google.com> | 2014-03-11 09:14:53 -0700 |
---|---|---|
committer | Sascha Haeberling <haeberling@google.com> | 2014-03-11 09:14:53 -0700 |
commit | 7cb8c791df0bcb48b2c3f2f34d7c7538c619b592 (patch) | |
tree | 7fdaab826c87ff9394b10f943a8b7187516924e8 | |
parent | cc855959c9a643a08bb10a41253720c04580dfe5 (diff) | |
download | android_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
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("<"); break; - case '>': sb.append(">"); break; - case '\"': sb.append("""); break; - case '\'': sb.append("'"); break; - case '&': sb.append("&"); 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); + } + } + } |