Merge "Voicemail playback, with variable speed ui."
diff --git a/res/drawable-hdpi/btn_dial_action_middle_disable.9.png b/res/drawable-hdpi/btn_dial_action_middle_disable.9.png
deleted file mode 100644
index 5159c74..0000000
--- a/res/drawable-hdpi/btn_dial_action_middle_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_middle_disable_focused.9.png b/res/drawable-hdpi/btn_dial_action_middle_disable_focused.9.png
deleted file mode 100644
index 46935c8..0000000
--- a/res/drawable-hdpi/btn_dial_action_middle_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_middle_normal.9.png b/res/drawable-hdpi/btn_dial_action_middle_normal.9.png
deleted file mode 100644
index e86afd1..0000000
--- a/res/drawable-hdpi/btn_dial_action_middle_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_middle_pressed.9.png b/res/drawable-hdpi/btn_dial_action_middle_pressed.9.png
deleted file mode 100644
index 6d428c9..0000000
--- a/res/drawable-hdpi/btn_dial_action_middle_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_middle_selected.9.png b/res/drawable-hdpi/btn_dial_action_middle_selected.9.png
deleted file mode 100644
index 678d9e0..0000000
--- a/res/drawable-hdpi/btn_dial_action_middle_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_right_disable.9.png b/res/drawable-hdpi/btn_dial_action_right_disable.9.png
deleted file mode 100644
index 4844ee2..0000000
--- a/res/drawable-hdpi/btn_dial_action_right_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_right_disable_focused.9.png b/res/drawable-hdpi/btn_dial_action_right_disable_focused.9.png
deleted file mode 100644
index f25cbc6..0000000
--- a/res/drawable-hdpi/btn_dial_action_right_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_right_normal.9.png b/res/drawable-hdpi/btn_dial_action_right_normal.9.png
deleted file mode 100644
index 54896a3..0000000
--- a/res/drawable-hdpi/btn_dial_action_right_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_right_pressed.9.png b/res/drawable-hdpi/btn_dial_action_right_pressed.9.png
deleted file mode 100644
index 27eddd3..0000000
--- a/res/drawable-hdpi/btn_dial_action_right_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_action_right_selected.9.png b/res/drawable-hdpi/btn_dial_action_right_selected.9.png
deleted file mode 100644
index 131f1c4..0000000
--- a/res/drawable-hdpi/btn_dial_action_right_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_1_no_vm_blk.png b/res/drawable-hdpi/dial_num_1_no_vm_blk.png
deleted file mode 100644
index 8415b05..0000000
--- a/res/drawable-hdpi/dial_num_1_no_vm_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_1_no_vm_wht.png b/res/drawable-hdpi/dial_num_1_no_vm_wht.png
deleted file mode 100644
index beaca97..0000000
--- a/res/drawable-hdpi/dial_num_1_no_vm_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_log_header_incoming_call.png b/res/drawable-hdpi/ic_call_log_header_incoming_call.png
deleted file mode 100755
index 95c0255..0000000
--- a/res/drawable-hdpi/ic_call_log_header_incoming_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_log_header_missed_call.png b/res/drawable-hdpi/ic_call_log_header_missed_call.png
deleted file mode 100755
index 0a43e69..0000000
--- a/res/drawable-hdpi/ic_call_log_header_missed_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_log_header_outgoing_call.png b/res/drawable-hdpi/ic_call_log_header_outgoing_call.png
deleted file mode 100755
index d061ba3..0000000
--- a/res/drawable-hdpi/ic_call_log_header_outgoing_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_log_list_action_call.png b/res/drawable-hdpi/ic_call_log_list_action_call.png
deleted file mode 100644
index f47ada7..0000000
--- a/res/drawable-hdpi/ic_call_log_list_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_middle_disable.9.png b/res/drawable-mdpi/btn_dial_action_middle_disable.9.png
deleted file mode 100644
index e13b958..0000000
--- a/res/drawable-mdpi/btn_dial_action_middle_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_middle_disable_focused.9.png b/res/drawable-mdpi/btn_dial_action_middle_disable_focused.9.png
deleted file mode 100644
index 7c7574f..0000000
--- a/res/drawable-mdpi/btn_dial_action_middle_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_middle_normal.9.png b/res/drawable-mdpi/btn_dial_action_middle_normal.9.png
deleted file mode 100644
index 575793c..0000000
--- a/res/drawable-mdpi/btn_dial_action_middle_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_middle_pressed.9.png b/res/drawable-mdpi/btn_dial_action_middle_pressed.9.png
deleted file mode 100644
index ead7039..0000000
--- a/res/drawable-mdpi/btn_dial_action_middle_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_middle_selected.9.png b/res/drawable-mdpi/btn_dial_action_middle_selected.9.png
deleted file mode 100644
index 957b7b9..0000000
--- a/res/drawable-mdpi/btn_dial_action_middle_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_right_disable.9.png b/res/drawable-mdpi/btn_dial_action_right_disable.9.png
deleted file mode 100644
index de5c271..0000000
--- a/res/drawable-mdpi/btn_dial_action_right_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_right_disable_focused.9.png b/res/drawable-mdpi/btn_dial_action_right_disable_focused.9.png
deleted file mode 100644
index 27bfc02..0000000
--- a/res/drawable-mdpi/btn_dial_action_right_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_right_normal.9.png b/res/drawable-mdpi/btn_dial_action_right_normal.9.png
deleted file mode 100644
index 515e4f4..0000000
--- a/res/drawable-mdpi/btn_dial_action_right_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_right_pressed.9.png b/res/drawable-mdpi/btn_dial_action_right_pressed.9.png
deleted file mode 100644
index 054ebef..0000000
--- a/res/drawable-mdpi/btn_dial_action_right_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_action_right_selected.9.png b/res/drawable-mdpi/btn_dial_action_right_selected.9.png
deleted file mode 100644
index 9c0a76b..0000000
--- a/res/drawable-mdpi/btn_dial_action_right_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_1_no_vm_blk.png b/res/drawable-mdpi/dial_num_1_no_vm_blk.png
deleted file mode 100644
index 75a8ed8..0000000
--- a/res/drawable-mdpi/dial_num_1_no_vm_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_1_no_vm_wht.png b/res/drawable-mdpi/dial_num_1_no_vm_wht.png
deleted file mode 100644
index 8871de5..0000000
--- a/res/drawable-mdpi/dial_num_1_no_vm_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_log_header_incoming_call.png b/res/drawable-mdpi/ic_call_log_header_incoming_call.png
deleted file mode 100644
index 8b75287..0000000
--- a/res/drawable-mdpi/ic_call_log_header_incoming_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_log_header_missed_call.png b/res/drawable-mdpi/ic_call_log_header_missed_call.png
deleted file mode 100644
index 94dd69f..0000000
--- a/res/drawable-mdpi/ic_call_log_header_missed_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_log_header_outgoing_call.png b/res/drawable-mdpi/ic_call_log_header_outgoing_call.png
deleted file mode 100644
index bdedc67..0000000
--- a/res/drawable-mdpi/ic_call_log_header_outgoing_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_log_list_action_call.png b/res/drawable-mdpi/ic_call_log_list_action_call.png
deleted file mode 100644
index f47ada7..0000000
--- a/res/drawable-mdpi/ic_call_log_list_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_middle_disable.9.png b/res/drawable-xhdpi/btn_dial_action_middle_disable.9.png
deleted file mode 100644
index 6da4265..0000000
--- a/res/drawable-xhdpi/btn_dial_action_middle_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_middle_disable_focused.9.png b/res/drawable-xhdpi/btn_dial_action_middle_disable_focused.9.png
deleted file mode 100644
index cddf893..0000000
--- a/res/drawable-xhdpi/btn_dial_action_middle_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_middle_normal.9.png b/res/drawable-xhdpi/btn_dial_action_middle_normal.9.png
deleted file mode 100644
index dc39b98..0000000
--- a/res/drawable-xhdpi/btn_dial_action_middle_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_middle_pressed.9.png b/res/drawable-xhdpi/btn_dial_action_middle_pressed.9.png
deleted file mode 100644
index f092867..0000000
--- a/res/drawable-xhdpi/btn_dial_action_middle_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_middle_selected.9.png b/res/drawable-xhdpi/btn_dial_action_middle_selected.9.png
deleted file mode 100644
index 9577eda..0000000
--- a/res/drawable-xhdpi/btn_dial_action_middle_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_right_disable.9.png b/res/drawable-xhdpi/btn_dial_action_right_disable.9.png
deleted file mode 100644
index fdcd395..0000000
--- a/res/drawable-xhdpi/btn_dial_action_right_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_right_disable_focused.9.png b/res/drawable-xhdpi/btn_dial_action_right_disable_focused.9.png
deleted file mode 100644
index 9f4eeb0..0000000
--- a/res/drawable-xhdpi/btn_dial_action_right_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_right_normal.9.png b/res/drawable-xhdpi/btn_dial_action_right_normal.9.png
deleted file mode 100644
index c6f7e09..0000000
--- a/res/drawable-xhdpi/btn_dial_action_right_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_right_pressed.9.png b/res/drawable-xhdpi/btn_dial_action_right_pressed.9.png
deleted file mode 100644
index bf99581..0000000
--- a/res/drawable-xhdpi/btn_dial_action_right_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_action_right_selected.9.png b/res/drawable-xhdpi/btn_dial_action_right_selected.9.png
deleted file mode 100644
index 5c06f99..0000000
--- a/res/drawable-xhdpi/btn_dial_action_right_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_1_no_vm_blk.png b/res/drawable-xhdpi/dial_num_1_no_vm_blk.png
deleted file mode 100644
index 452eed0..0000000
--- a/res/drawable-xhdpi/dial_num_1_no_vm_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_1_no_vm_wht.png b/res/drawable-xhdpi/dial_num_1_no_vm_wht.png
deleted file mode 100644
index 37d90be..0000000
--- a/res/drawable-xhdpi/dial_num_1_no_vm_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_log_header_incoming_call.png b/res/drawable-xhdpi/ic_call_log_header_incoming_call.png
deleted file mode 100644
index cae35d1..0000000
--- a/res/drawable-xhdpi/ic_call_log_header_incoming_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_log_header_missed_call.png b/res/drawable-xhdpi/ic_call_log_header_missed_call.png
deleted file mode 100644
index cb7395c..0000000
--- a/res/drawable-xhdpi/ic_call_log_header_missed_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_log_header_outgoing_call.png b/res/drawable-xhdpi/ic_call_log_header_outgoing_call.png
deleted file mode 100644
index a17bdf3..0000000
--- a/res/drawable-xhdpi/ic_call_log_header_outgoing_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/btn_dial_textfield_active.xml b/res/drawable/btn_dial_textfield_active.xml
deleted file mode 100644
index f3af301..0000000
--- a/res/drawable/btn_dial_textfield_active.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_dial_textfield_pressed" />
- <item android:state_focused="true"
- android:drawable="@drawable/btn_dial_textfield_selected" />
- <item
- android:drawable="@drawable/btn_dial_textfield_activated" />
-</selector>
-
diff --git a/res/layout-sw580dp/group_detail_fragment.xml b/res/layout-sw580dp/group_detail_fragment.xml
index a824319..7c65036 100644
--- a/res/layout-sw580dp/group_detail_fragment.xml
+++ b/res/layout-sw580dp/group_detail_fragment.xml
@@ -37,8 +37,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/group_detail_border_padding"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorSecondary" />
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorTertiary" />
<View
android:layout_width="match_parent"
diff --git a/res/layout/call_log_action_group.xml b/res/layout/call_log_action_group.xml
deleted file mode 100644
index fa6bb79..0000000
--- a/res/layout/call_log_action_group.xml
+++ /dev/null
@@ -1,40 +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.
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <ImageView
- android:id="@+id/groupIndicator"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="12dip"
- android:paddingRight="13dip"
- android:layout_alignParentRight="true"
- android:gravity="center_vertical"
- android:src="@*android:drawable/expander_ic_minimized"
- />
-
- <View android:id="@+id/divider"
- android:layout_width="1px"
- android:layout_height="match_parent"
- android:layout_marginTop="5dip"
- android:layout_marginBottom="5dip"
- android:layout_toLeftOf="@id/groupIndicator"
- android:layout_marginLeft="11dip"
- android:background="@drawable/divider_vertical_dark"
- />
-
-</merge>
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 2a27fcd..573969b 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -14,21 +14,29 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:orientation="vertical"
>
- <ListView android:id="@android:id/list"
+ <include layout="@layout/call_log_voicemail_status"/>
+ <FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbarStyle="outsideOverlay"
- />
+ android:layout_height="wrap_content"
+ >
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scrollbarStyle="outsideOverlay"
+ />
- <TextView android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/recentCalls_empty"
- android:gravity="center"
- android:textAppearance="?android:attr/textAppearanceLarge"
- />
-</FrameLayout>
+ <TextView android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/recentCalls_empty"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ />
+ </FrameLayout>
+</LinearLayout>
+
diff --git a/res/layout/call_log_voicemail_status.xml b/res/layout/call_log_voicemail_status.xml
new file mode 100644
index 0000000..1abe998
--- /dev/null
+++ b/res/layout/call_log_voicemail_status.xml
@@ -0,0 +1,52 @@
+<?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"
+ android:id="@+id/voicemail_status"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/call_log_voicemail_status_height"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentBottom="true"
+ android:background="?attr/call_log_voicemail_status_background_color"
+ android:baselineAligned="false">
+ <TextView
+ android:id="@+id/voicemail_status_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="14dip"
+ android:paddingRight="14dip"
+ android:textColor="?attr/call_log_voicemail_status_text_color"
+ android:layout_gravity="left"
+ android:layout_weight="5"/>
+ <View android:id="@+id/divider"
+ android:layout_width="1px"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="5dip"
+ android:layout_marginLeft="11dip"
+ android:background="@drawable/divider_vertical_dark"/>
+ <TextView
+ android:id="@+id/voicemail_status_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:paddingLeft="14dip"
+ android:paddingRight="14dip"
+ android:textColor="?attr/call_log_voicemail_status_text_color"
+ android:gravity="right"
+ android:layout_alignParentRight="true"
+ android:clickable="true"
+ />
+</LinearLayout>
diff --git a/res/layout/edit_date_picker.xml b/res/layout/edit_date_picker.xml
index ca5e281..c18d607 100644
--- a/res/layout/edit_date_picker.xml
+++ b/res/layout/edit_date_picker.xml
@@ -23,5 +23,6 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="@dimen/editor_field_left_padding"
+ android:layout_marginRight="@dimen/editor_field_right_padding"
android:textAppearance="?android:attr/textAppearanceMedium"
style="@android:style/Widget.Holo.Light.Spinner" />
\ No newline at end of file
diff --git a/res/layout/edit_field_list.xml b/res/layout/edit_field_list.xml
index ba715c7..f9e6565 100644
--- a/res/layout/edit_field_list.xml
+++ b/res/layout/edit_field_list.xml
@@ -23,4 +23,5 @@
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/editor_field_left_padding"
+ android:paddingRight="@dimen/editor_field_right_padding"
android:orientation="vertical" />
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 207a255..3bc1bc6 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -50,6 +50,9 @@
<!-- Left padding of a field in the Editor -->
<dimen name="editor_field_left_padding">5dip</dimen>
+ <!-- Right padding of a field in the Editor -->
+ <dimen name="editor_field_right_padding">5dip</dimen>
+
<!-- Top padding of a field in the Editor -->
<dimen name="editor_field_top_padding">10dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 534fc4e..54bb5ed 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1569,6 +1569,12 @@
(Contacts themselves will not be deleted.)
</string>
+ <!-- Subtitle of the group detail page that describes how many people are in the current group [CHAR LIMIT=30] -->
+ <plurals name="num_contacts_in_group">
+ <item quantity="one"><xliff:g id="count">%1$d</xliff:g> person from <xliff:g id="account_type">%2$s</xliff:g></item>
+ <item quantity="other"><xliff:g id="count">%1$d</xliff:g> people from <xliff:g id="account_type">%2$s</xliff:g></item>
+ </plurals>
+
<!-- Toast displayed when the user creates a new contact and attempts to join it
with another before entering any data [CHAR LIMIT=256] -->
<string name="toast_join_with_empty_contact">Please enter contact name before joining
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4638b2e..43ea301 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -49,6 +49,10 @@
<item name="call_log_primary_background_color">#000000</item>
<item name="call_log_secondary_text_color">#FFFFFF</item>
<item name="call_log_secondary_background_color">#333333</item>
+ <!-- VoicemailStatus -->
+ <item name="call_log_voicemail_status_height">40dip</item>
+ <item name="call_log_voicemail_status_background_color">#FFFFE0</item>
+ <item name="call_log_voicemail_status_text_color">#000000</item>
</style>
<style name="CallDetailActivityTheme" parent="android:Theme.Holo">
@@ -161,6 +165,12 @@
<attr name="call_log_list_header_background" format="reference" />
</declare-styleable>
+ <declare-styleable name="VoicemailStatus">
+ <attr name="call_log_voicemail_status_height" format="dimension" />
+ <attr name="call_log_voicemail_status_background_color" format="color" />
+ <attr name="call_log_voicemail_status_text_color" format="color" />
+ </declare-styleable>
+
<style name="PeopleTheme" parent="android:Theme.Holo.Light.SplitActionBarWhenNarrow">
<item name="list_item_height">?android:attr/listPreferredItemHeight</item>
<item name="activated_background">@drawable/list_item_activated_background</item>
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 11888a5..9fd1b03 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -109,7 +109,7 @@
PhoneLookup.LABEL,
PhoneLookup.NUMBER,
PhoneLookup.NORMALIZED_NUMBER,
- PhoneLookup.PHOTO_ID,
+ PhoneLookup.PHOTO_URI,
};
static final int COLUMN_INDEX_ID = 0;
static final int COLUMN_INDEX_NAME = 1;
@@ -117,7 +117,7 @@
static final int COLUMN_INDEX_LABEL = 3;
static final int COLUMN_INDEX_NUMBER = 4;
static final int COLUMN_INDEX_NORMALIZED_NUMBER = 5;
- static final int COLUMN_INDEX_PHOTO_ID = 6;
+ static final int COLUMN_INDEX_PHOTO_URI = 6;
@Override
protected void onCreate(Bundle icicle) {
@@ -249,7 +249,7 @@
// We know that all calls are from the same number and the same contact, so pick the first.
mNumber = details[0].number.toString();
final long personId = details[0].personId;
- final long photoId = details[0].photoId;
+ final Uri photoUri = details[0].photoUri;
// Set the details header, based on the first phone call.
mPhoneCallDetailsHelper.setPhoneCallDetails(mPhoneCallDetailsViews,
@@ -356,7 +356,7 @@
ListView historyList = (ListView) findViewById(R.id.history);
historyList.setAdapter(
new CallDetailHistoryAdapter(this, mInflater, mCallTypeHelper, details));
- loadContactPhotos(photoId);
+ loadContactPhotos(photoUri);
}
/** Return the phone call details for a given call log URI. */
@@ -385,7 +385,7 @@
int numberType = 0;
CharSequence numberLabel = "";
long personId = -1L;
- long photoId = 0L;
+ Uri photoUri = null;
// If this is not a regular number, there is no point in looking it up in the contacts.
if (!mPhoneNumberHelper.canPlaceCallsTo(number)) {
numberText = mPhoneNumberHelper.getDisplayNumber(number, null);
@@ -399,7 +399,8 @@
if (phonesCursor != null && phonesCursor.moveToFirst()) {
personId = phonesCursor.getLong(COLUMN_INDEX_ID);
nameText = phonesCursor.getString(COLUMN_INDEX_NAME);
- photoId = phonesCursor.getLong(COLUMN_INDEX_PHOTO_ID);
+ String photoUriString = phonesCursor.getString(COLUMN_INDEX_PHOTO_URI);
+ photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
candidateNumberText = PhoneNumberUtils.formatNumber(
phonesCursor.getString(COLUMN_INDEX_NUMBER),
phonesCursor.getString(COLUMN_INDEX_NORMALIZED_NUMBER),
@@ -419,7 +420,7 @@
}
}
return new PhoneCallDetails(number, numberText, new int[]{ callType }, date, duration,
- nameText, numberType, numberLabel, personId, photoId);
+ nameText, numberType, numberLabel, personId, photoUri);
} finally {
if (callCursor != null) {
callCursor.close();
@@ -428,8 +429,8 @@
}
/** Load the contact photos and places them in the corresponding views. */
- private void loadContactPhotos(final long photoId) {
- mContactPhotoManager.loadPhoto(mContactBackgroundView, photoId);
+ private void loadContactPhotos(Uri photoUri) {
+ mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri);
}
private String getVoicemailNumber() {
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
index 6ab47aa..d4786d9 100644
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ b/src/com/android/contacts/PhoneCallDetails.java
@@ -16,6 +16,7 @@
package com.android.contacts;
+import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -45,19 +46,22 @@
public final CharSequence numberLabel;
/** The id of the contact associated with this phone call. */
public final long personId;
- /** The photo id of the contact associated with this phone call. */
- public final long photoId;
+ /**
+ * The photo uri of the picture of the contact that is associated with this phone call or
+ * null if there is none.
+ */
+ public final Uri photoUri;
/** Create the details for a call with a number not associated with a contact. */
public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
long date, long duration) {
- this(number, formattedNumber, callTypes, date, duration, "", 0, "", -1L, 0L);
+ this(number, formattedNumber, callTypes, date, duration, "", 0, "", -1L, null);
}
/** Create the details for a call with a number associated with a contact. */
public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
long date, long duration, CharSequence name, int numberType, CharSequence numberLabel,
- long personId, long photoId) {
+ long personId, Uri photoUri) {
this.number = number;
this.formattedNumber = formattedNumber;
this.callTypes = callTypes;
@@ -67,6 +71,6 @@
this.numberType = numberType;
this.numberLabel = numberLabel;
this.personId = personId;
- this.photoId = photoId;
+ this.photoUri = photoUri;
}
}
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 0637fd5..de262b2 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -172,9 +172,8 @@
}
@Override
- public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
- boolean globalSearch) {
- // Ignore search key press
+ public boolean onSearchRequested() {
+ return true; // Don't respond to the search key.
}
@Override
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index 1ee7f1d..6655c81 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -120,9 +120,8 @@
}
@Override
- public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
- boolean globalSearch) {
- // Ignore search key press
+ public boolean onSearchRequested() {
+ return true; // Don't respond to the search key.
}
@Override
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 635c130..dcd35fa 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -92,8 +92,7 @@
}
@Override
- public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
- boolean globalSearch) {
- // Ignore search key press
+ public boolean onSearchRequested() {
+ return true; // Don't respond to the search key.
}
}
diff --git a/src/com/android/contacts/activities/GroupEditorActivity.java b/src/com/android/contacts/activities/GroupEditorActivity.java
index ecadcec..b2553a4 100644
--- a/src/com/android/contacts/activities/GroupEditorActivity.java
+++ b/src/com/android/contacts/activities/GroupEditorActivity.java
@@ -83,9 +83,8 @@
}
@Override
- public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
- boolean globalSearch) {
- // Ignore search key press
+ public boolean onSearchRequested() {
+ return true; // Don't respond to the search key.
}
@Override
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 77b978d..ee36d8f 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -90,6 +90,7 @@
import android.widget.Toast;
import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Displays a list to browse contacts. For xlarge screens, this also displays a detail-pane on
@@ -101,6 +102,7 @@
ContactListFilterController.ContactListFilterListener, ProviderStatusListener {
private static final String TAG = "PeopleActivity";
+ private static final Boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
private static final int SUBACTIVITY_NEW_CONTACT = 2;
private static final int SUBACTIVITY_EDIT_CONTACT = 3;
@@ -118,8 +120,6 @@
private ActionBarAdapter mActionBarAdapter;
- private boolean mSearchMode;
-
private ContactDetailFragment mContactDetailFragment;
private ContactDetailUpdatesFragment mContactDetailUpdatesFragment;
private final ContactDetailFragmentListener mContactDetailFragmentListener =
@@ -136,8 +136,6 @@
private StrequentContactListFragment.Listener mFavoritesFragmentListener =
new StrequentContactListFragmentListener();
- private boolean mSearchInitiated;
-
private ContactListFilterController mContactListFilterController;
private ContactsUnavailableFragment mContactsUnavailableFragment;
@@ -182,13 +180,24 @@
*/
private boolean mFragmentInitialized;
+ /** Sequential ID assigned to each instance; used for logging */
+ private final int mInstanceId;
+ private static final AtomicInteger sNextInstanceId = new AtomicInteger();
+
public PeopleActivity() {
+ mInstanceId = sNextInstanceId.getAndIncrement();
mIntentResolver = new ContactsIntentResolver(this);
mContactListFilterController = new ContactListFilterController(this);
mContactListFilterController.addListener(this);
mProviderStatusLoader = new ProviderStatusLoader(this);
}
+ @Override
+ public String toString() {
+ // Shown on logcat
+ return String.format("%s@%d", getClass().getSimpleName(), mInstanceId);
+ }
+
public boolean areContactsAvailable() {
return mProviderStatus == ProviderStatus.STATUS_NORMAL;
}
@@ -225,7 +234,7 @@
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
- if (!processIntent()) {
+ if (!processIntent(false)) {
finish();
return;
}
@@ -237,7 +246,7 @@
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
- if (!processIntent()) {
+ if (!processIntent(true)) {
finish();
return;
}
@@ -252,13 +261,18 @@
* Resolve the intent and initialize {@link #mRequest}, and launch another activity if redirect
* is needed.
*
+ * @param forNewIntent set true if it's called from {@link #onNewIntent(Intent)}.
* @return {@code true} if {@link PeopleActivity} should continue running. {@code false}
* if it shouldn't, in which case the caller should finish() itself and shouldn't do
* farther initialization.
*/
- private boolean processIntent() {
+ private boolean processIntent(boolean forNewIntent) {
// Extract relevant information from the intent
mRequest = mIntentResolver.resolveIntent(getIntent());
+ if (DEBUG) {
+ Log.d(TAG, this + " processIntent: forNewIntent=" + forNewIntent
+ + " intent=" + getIntent() + " request=" + mRequest);
+ }
if (!mRequest.isValid()) {
setResult(RESULT_CANCELED);
return false;
@@ -452,6 +466,7 @@
if (fromRequest) {
ContactListFilter filter = null;
int actionCode = mRequest.getActionCode();
+ boolean searchMode = mRequest.isSearchMode();
switch (actionCode) {
case ContactsRequest.ACTION_ALL_CONTACTS:
filter = ContactListFilter.createFilterWithType(
@@ -476,25 +491,17 @@
}
}
- mSearchMode = mRequest.isSearchMode();
if (filter != null) {
mContactListFilterController.setContactListFilter(filter, false);
- mSearchMode = false;
- } else if (mRequest.getActionCode() == ContactsRequest.ACTION_ALL_CONTACTS) {
- mContactListFilterController.setContactListFilter(
- ContactListFilter.createFilterWithType(
- ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), false);
+ searchMode = false;
}
if (mRequest.getContactUri() != null) {
- mSearchMode = false;
+ searchMode = false;
}
- mAllFragment.setContactsRequest(mRequest);
+ mActionBarAdapter.setSearchMode(searchMode);
configureContactListFragmentForRequest();
-
- } else {
- mSearchMode = mActionBarAdapter.isSearchMode();
}
configureContactListFragment();
@@ -787,13 +794,15 @@
}
private void configureContactListFragmentForRequest() {
+ mAllFragment.setContactsRequest(mRequest);
+
Uri contactUri = mRequest.getContactUri();
if (contactUri != null) {
mAllFragment.setSelectedContactUri(contactUri);
}
- mAllFragment.setSearchMode(mRequest.isSearchMode());
- mAllFragment.setQueryString(mRequest.getQueryString(), false);
+ mAllFragment.setSearchMode(mActionBarAdapter.isSearchMode());
+ mAllFragment.setQueryString(mActionBarAdapter.getQueryString(), false);
if (mRequest.isDirectorySearchEnabled()) {
mAllFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
@@ -807,10 +816,11 @@
}
private void configureContactListFragment() {
- mAllFragment.setSearchMode(mSearchMode);
+ final boolean searchMode = mActionBarAdapter.isSearchMode();
+ mAllFragment.setSearchMode(searchMode);
final boolean useTwoPane = PhoneCapabilityTester.isUsingTwoPanes(this);
- mAllFragment.setVisibleScrollbarEnabled(!mSearchMode);
+ mAllFragment.setVisibleScrollbarEnabled(!searchMode);
mAllFragment.setVerticalScrollbarPosition(
useTwoPane
? View.SCROLLBAR_POSITION_LEFT
@@ -1322,13 +1332,9 @@
}
@Override
- public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
- boolean globalSearch) {
- if (mAllFragment != null && mAllFragment.isAdded() && !globalSearch) {
- mAllFragment.startSearch(initialQuery);
- } else {
- super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
- }
+ public boolean onSearchRequested() { // Search key pressed.
+ mActionBarAdapter.setSearchMode(true);
+ return true;
}
@Override
@@ -1419,12 +1425,6 @@
mActionBarAdapter.setQueryString(query);
mActionBarAdapter.setSearchMode(true);
return true;
- } else if (!mRequest.isSearchMode()) {
- if (!mSearchInitiated) {
- mSearchInitiated = true;
- startSearch(query, false, null, false);
- return true;
- }
}
}
}
@@ -1435,7 +1435,7 @@
@Override
public void onBackPressed() {
- if (mSearchMode && mActionBarAdapter != null) {
+ if (mActionBarAdapter.isSearchMode()) {
mActionBarAdapter.setSearchMode(false);
} else {
super.onBackPressed();
@@ -1460,7 +1460,6 @@
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
mActionBarAdapter.onSaveInstanceState(outState);
if (mContactDetailLayoutController != null) {
mContactDetailLayoutController.onSaveInstanceState(outState);
@@ -1475,7 +1474,6 @@
@Override
protected void onRestoreInstanceState(Bundle inState) {
super.onRestoreInstanceState(inState);
- mSearchMode = inState.getBoolean(KEY_SEARCH_MODE);
if (mContactDetailLayoutController != null) {
mContactDetailLayoutController.onRestoreInstanceState(inState);
}
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 783d06b..7db5281 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -25,6 +25,7 @@
import com.android.contacts.R;
import com.android.contacts.activities.DialtactsActivity;
import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
+import com.android.contacts.calllog.VoicemailStatusHelper.StatusMessage;
import com.android.contacts.util.ExpirableCache;
import com.android.internal.telephony.CallerInfo;
import com.google.common.annotations.VisibleForTesting;
@@ -63,8 +64,10 @@
import android.view.ViewTreeObserver;
import android.widget.ListView;
import android.widget.QuickContactBadge;
+import android.widget.TextView;
import java.util.LinkedList;
+import java.util.List;
/**
@@ -126,7 +129,7 @@
PhoneLookup.LABEL,
PhoneLookup.NUMBER,
PhoneLookup.NORMALIZED_NUMBER,
- PhoneLookup.PHOTO_ID,
+ PhoneLookup.PHOTO_THUMBNAIL_URI,
PhoneLookup.LOOKUP_KEY};
public static final int PERSON_ID = 0;
@@ -135,7 +138,7 @@
public static final int LABEL = 3;
public static final int MATCHED_NUMBER = 4;
public static final int NORMALIZED_NUMBER = 5;
- public static final int PHOTO_ID = 6;
+ public static final int THUMBNAIL_URI = 6;
public static final int LOOKUP_KEY = 7;
}
@@ -151,6 +154,11 @@
private boolean mShowOptionsMenu;
+ private VoicemailStatusHelper mVoicemailStatusHelper;
+ private View mStatusMessageView;
+ private TextView mStatusMessageText;
+ private TextView mStatusMessageAction;
+
public static final class ContactInfo {
public long personId;
public String name;
@@ -159,7 +167,7 @@
public String number;
public String formattedNumber;
public String normalizedNumber;
- public long photoId;
+ public Uri thumbnailUri;
public String lookupKey;
public static ContactInfo EMPTY = new ContactInfo();
@@ -171,7 +179,7 @@
public String name;
public int numberType;
public String numberLabel;
- public long photoId;
+ public Uri thumbnailUri;
public String lookupKey;
}
@@ -307,8 +315,7 @@
resources.getDrawable(R.drawable.ic_call_outgoing_holo_dark),
resources.getDrawable(R.drawable.ic_call_missed_holo_dark),
resources.getDrawable(R.drawable.ic_call_voicemail_holo_dark));
- Drawable callDrawable = resources.getDrawable(
- R.drawable.ic_call_log_list_action_call);
+ Drawable callDrawable = resources.getDrawable(R.drawable.ic_dial_action_call);
Drawable playDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_action_play);
@@ -377,15 +384,15 @@
mContactInfoCache.expireAll();
}
- private void enqueueRequest(String number, boolean immediate, int position,
- String name, int numberType, String numberLabel, long photoId, String lookupKey) {
+ private void enqueueRequest(String number, boolean immediate, int position, String name,
+ int numberType, String numberLabel, Uri thumbnailUri, String lookupKey) {
CallerInfoQuery ciq = new CallerInfoQuery();
ciq.number = number;
ciq.position = position;
ciq.name = name;
ciq.numberType = numberType;
ciq.numberLabel = numberLabel;
- ciq.photoId = photoId;
+ ciq.thumbnailUri = thumbnailUri;
ciq.lookupKey = lookupKey;
synchronized (mRequests) {
mRequests.add(ciq);
@@ -466,8 +473,11 @@
info.number = dataTableCursor.getString(
dataTableCursor.getColumnIndex(Data.DATA1));
info.normalizedNumber = null; // meaningless for SIP addresses
- info.photoId = dataTableCursor.getLong(
- dataTableCursor.getColumnIndex(Data.PHOTO_ID));
+ final String thumbnailUriString = dataTableCursor.getString(
+ dataTableCursor.getColumnIndex(Data.PHOTO_THUMBNAIL_URI));
+ info.thumbnailUri = thumbnailUriString == null
+ ? null
+ : Uri.parse(thumbnailUriString);
info.lookupKey = dataTableCursor.getString(
dataTableCursor.getColumnIndex(Data.LOOKUP_KEY));
@@ -494,7 +504,11 @@
.getString(PhoneQuery.MATCHED_NUMBER);
info.normalizedNumber = phonesCursor
.getString(PhoneQuery.NORMALIZED_NUMBER);
- info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
+ final String thumbnailUriString = phonesCursor.getString(
+ PhoneQuery.THUMBNAIL_URI);
+ info.thumbnailUri = thumbnailUriString == null
+ ? null
+ : Uri.parse(thumbnailUriString);
info.lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
infoUpdated = true;
@@ -735,7 +749,7 @@
mContactInfoCache.put(number, info);
Log.d(TAG, "Contact info missing: " + number);
// Request the contact details immediately since they are currently missing.
- enqueueRequest(number, true, c.getPosition(), "", 0, "", 0L, "");
+ enqueueRequest(number, true, c.getPosition(), "", 0, "", null, "");
} else if (info != ContactInfo.EMPTY) { // Has been queried
if (cachedInfo.isExpired()) {
Log.d(TAG, "Contact info expired: " + number);
@@ -745,7 +759,7 @@
// The contact info is no longer up to date, we should request it. However, we
// do not need to request them immediately.
enqueueRequest(number, false, c.getPosition(), info.name, info.type, info.label,
- info.photoId, info.lookupKey);
+ info.thumbnailUri, info.lookupKey);
}
// Format and cache phone number for found contact
@@ -763,7 +777,7 @@
final String name = info.name;
final int ntype = info.type;
final String label = info.label;
- final long photoId = info.photoId;
+ final Uri thumbnailUri = info.thumbnailUri;
final String lookupKey = info.lookupKey;
// Assumes the call back feature is on most of the
// time. For private and unknown numbers: hide it.
@@ -777,7 +791,7 @@
details = new PhoneCallDetails(number, formattedNumber, callTypes, date, duration);
} else {
details = new PhoneCallDetails(number, formattedNumber, callTypes, date, duration,
- name, ntype, label, personId, photoId);
+ name, ntype, label, personId, thumbnailUri);
}
final boolean isNew = isNewSection(c);
@@ -787,7 +801,7 @@
final boolean isHighlighted = isNew;
mCallLogViewsHelper.setPhoneCallDetails(views, details, useIcons, isHighlighted);
if (views.photoView != null) {
- bindQuickContact(views.photoView, photoId, personId, lookupKey);
+ bindQuickContact(views.photoView, thumbnailUri, personId, lookupKey);
}
@@ -817,10 +831,10 @@
return callTypes;
}
- private void bindQuickContact(QuickContactBadge view, long photoId, long contactId,
+ private void bindQuickContact(QuickContactBadge view, Uri thumbnailUri, long contactId,
String lookupKey) {
view.assignContactUri(getContactUri(contactId, lookupKey));
- mContactPhotoManager.loadPhoto(view, photoId);
+ mContactPhotoManager.loadPhoto(view, thumbnailUri);
}
private Uri getContactUri(long contactId, String lookupKey) {
@@ -875,7 +889,12 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- return inflater.inflate(R.layout.call_log_fragment, container, false);
+ View view = inflater.inflate(R.layout.call_log_fragment, container, false);
+ mVoicemailStatusHelper = new VoicemailStatusHelperImpl(getActivity().getContentResolver());
+ mStatusMessageView = view.findViewById(R.id.voicemail_status);
+ mStatusMessageText = (TextView) view.findViewById(R.id.voicemail_status_message);
+ mStatusMessageAction = (TextView) view.findViewById(R.id.voicemail_status_action);
+ return view;
}
@Override
@@ -901,12 +920,42 @@
startQuery();
resetNewCallsFlag();
-
+ updateVoicemailStatusMessage();
super.onResume();
mAdapter.mPreDrawListener = null; // Let it restart the thread after next draw
}
+ private void updateVoicemailStatusMessage() {
+ // TODO: make call to mVoicemailStatusHelper asynchronously.
+ List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages();
+ if (messages.size() == 0) {
+ mStatusMessageView.setVisibility(View.GONE);
+ } else {
+ mStatusMessageView.setVisibility(View.VISIBLE);
+ // TODO: Change the code to show all messages. For now just pick the first message.
+ final StatusMessage message = messages.get(0);
+ if (message.statusMessageId != -1) {
+ mStatusMessageText.setText(message.statusMessageId);
+ }
+ if (message.actionMessageId != -1) {
+ mStatusMessageAction.setText(message.actionMessageId);
+ }
+ if (message.actionUri != null) {
+ mStatusMessageAction.setClickable(true);
+ mStatusMessageAction.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().startActivity(
+ new Intent(Intent.ACTION_VIEW, message.actionUri));
+ }
+ });
+ } else {
+ mStatusMessageAction.setClickable(false);
+ }
+ }
+ }
+
@Override
public void onPause() {
super.onPause();
diff --git a/src/com/android/contacts/calllog/VoicemailStatusHelper.java b/src/com/android/contacts/calllog/VoicemailStatusHelper.java
index d4a3965..607d31a 100644
--- a/src/com/android/contacts/calllog/VoicemailStatusHelper.java
+++ b/src/com/android/contacts/calllog/VoicemailStatusHelper.java
@@ -30,7 +30,7 @@
* this class to check if any message needs to be shown.
*/
public interface VoicemailStatusHelper {
- public class Message {
+ public class StatusMessage {
/** Package of the source on behalf of which this message has to be shown.*/
public final String sourcePackage;
/** The string resource id of the status message that should be shown. */
@@ -39,7 +39,7 @@
public final int actionMessageId;
/** URI for the corrective action, where applicable. Null if no action URI is available. */
public final Uri actionUri;
- public Message(String sourcePackage, int statusMessageId, int actionMessageId,
+ public StatusMessage(String sourcePackage, int statusMessageId, int actionMessageId,
Uri actionUri) {
this.sourcePackage = sourcePackage;
this.statusMessageId = statusMessageId;
@@ -52,5 +52,5 @@
* Returns a list of messages, in the order or priority that should be shown to the user. An
* empty list is returned if no message needs to be shown.
*/
- public List<Message> getStatusMessages();
+ public List<StatusMessage> getStatusMessages();
}
diff --git a/src/com/android/contacts/calllog/VoicemailStatusHelperImpl.java b/src/com/android/contacts/calllog/VoicemailStatusHelperImpl.java
index 9738fd7..690f102 100644
--- a/src/com/android/contacts/calllog/VoicemailStatusHelperImpl.java
+++ b/src/com/android/contacts/calllog/VoicemailStatusHelperImpl.java
@@ -133,26 +133,26 @@
mContentResolver = contentResolver;
}
- /** A wrapper on {@link Message} which additionally stores the priority of the message. */
- private static class MessageWrapper {
- private final Message mMessage;
+ /** A wrapper on {@link StatusMessage} which additionally stores the priority of the message. */
+ private static class MessageStatusWithPriority {
+ private final StatusMessage mMessage;
private final int mPriority;
- public MessageWrapper(Message message, int priority) {
+ public MessageStatusWithPriority(StatusMessage message, int priority) {
mMessage = message;
mPriority = priority;
}
}
@Override
- public List<Message> getStatusMessages() {
+ public List<StatusMessage> getStatusMessages() {
Cursor cursor = null;
try {
cursor = mContentResolver.query(Status.CONTENT_URI, PROJECTION, null, null, null);
- List<MessageWrapper> messages =
- new ArrayList<VoicemailStatusHelperImpl.MessageWrapper>();
+ List<MessageStatusWithPriority> messages =
+ new ArrayList<VoicemailStatusHelperImpl.MessageStatusWithPriority>();
while(cursor.moveToNext()) {
- MessageWrapper message = getMessageForStatusEntry(cursor);
+ MessageStatusWithPriority message = getMessageForStatusEntry(cursor);
if (message != null) {
messages.add(message);
}
@@ -164,16 +164,16 @@
}
}
- private List<Message> reorderMessages(List<MessageWrapper> messageWrappers) {
- Collections.sort(messageWrappers, new Comparator<MessageWrapper>() {
+ private List<StatusMessage> reorderMessages(List<MessageStatusWithPriority> messageWrappers) {
+ Collections.sort(messageWrappers, new Comparator<MessageStatusWithPriority>() {
@Override
- public int compare(MessageWrapper msg1, MessageWrapper msg2) {
+ public int compare(MessageStatusWithPriority msg1, MessageStatusWithPriority msg2) {
return msg1.mPriority - msg2.mPriority;
}
});
- List<Message> reorderMessages = new ArrayList<VoicemailStatusHelper.Message>();
+ List<StatusMessage> reorderMessages = new ArrayList<VoicemailStatusHelper.StatusMessage>();
// Copy the ordered message objects into the final list.
- for (MessageWrapper messageWrapper : messageWrappers) {
+ for (MessageStatusWithPriority messageWrapper : messageWrappers) {
reorderMessages.add(messageWrapper.mMessage);
}
return reorderMessages;
@@ -182,7 +182,7 @@
/**
* Returns the message for the status entry pointed to by the cursor.
*/
- private MessageWrapper getMessageForStatusEntry(Cursor cursor) {
+ private MessageStatusWithPriority getMessageForStatusEntry(Cursor cursor) {
final String sourcePackage = cursor.getString(SOURCE_PACKAGE_INDEX);
if (sourcePackage == null) {
return null;
@@ -203,8 +203,8 @@
} else if (action == Action.CONFIGURE_VOICEMAIL) {
actionUri = Uri.parse(cursor.getString(SETTINGS_URI_INDEX));
}
- return new MessageWrapper(
- new Message(sourcePackage, overallState.getMessageId(), action.getMessageId(),
+ return new MessageStatusWithPriority(
+ new StatusMessage(sourcePackage, overallState.getMessageId(), action.getMessageId(),
actionUri),
overallState.getPriority());
}
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index bf93d26..41d564a 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -106,6 +106,9 @@
String data = DateUtils.formatDate(getContext(), getEntry().getAsString(column));
if (TextUtils.isEmpty(data)) {
data = " ";
+ setDeleteButtonVisible(false);
+ } else {
+ setDeleteButtonVisible(true);
}
mDateView.setText(data);
}
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index b472279..8ca7a05 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -194,9 +194,9 @@
if (view instanceof Editor) {
Editor editor = (Editor) view;
+ editor.setDeletable(true);
editor.setValues(mKind, entry, mState, mReadOnly, mViewIdGenerator);
editor.setEditorListener(this);
- editor.setDeletable(true);
}
mEditors.addView(view);
return view;
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index af5ae65..ddecf5a 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -73,6 +73,7 @@
private EntityDelta mState;
private boolean mReadOnly;
private boolean mWasEmpty = true;
+ private boolean mIsDeletable = true;
private EditType mType;
@@ -185,8 +186,8 @@
/**
* Creates or removes the remove button. Doesn't do anything if already correctly configured
*/
- private void setupDeleteButton(boolean shouldExist) {
- if (shouldExist) {
+ private void setupDeleteButton() {
+ if (mIsDeletable) {
mDeleteContainer.setVisibility(View.VISIBLE);
mDelete.setEnabled(!mReadOnly && isEnabled());
} else {
@@ -194,6 +195,12 @@
}
}
+ public void setDeleteButtonVisible(boolean visible) {
+ if (mIsDeletable) {
+ mDeleteContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+ }
+
protected void onOptionalFieldVisibilityChange() {
if (mListener != null) {
mListener.onRequest(EditorListener.EDITOR_FORM_CHANGED);
@@ -207,7 +214,8 @@
@Override
public void setDeletable(boolean deletable) {
- setupDeleteButton(deletable);
+ mIsDeletable = deletable;
+ setupDeleteButton();
}
@Override
@@ -267,8 +275,10 @@
if (mWasEmpty != isEmpty) {
if (isEmpty) {
mListener.onRequest(EditorListener.FIELD_TURNED_EMPTY);
+ if (mIsDeletable) mDeleteContainer.setVisibility(View.GONE);
} else {
mListener.onRequest(EditorListener.FIELD_TURNED_NON_EMPTY);
+ if (mIsDeletable) mDeleteContainer.setVisibility(View.VISIBLE);
}
mWasEmpty = isEmpty;
}
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index a689a0c..ad1c7b6 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -195,6 +195,9 @@
final String value = entry.getAsString(column);
fieldView.setText(value);
+ // Show the delete button if we have a non-null value
+ setDeleteButtonVisible(value != null);
+
// Prepare listener for writing changes
fieldView.addTextChangedListener(new TextWatcher() {
@Override
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index c5f6ef4..7f0536f 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -23,6 +23,8 @@
import com.android.contacts.interactions.GroupDeletionDialogFragment;
import com.android.contacts.list.ContactTileAdapter;
import com.android.contacts.list.ContactTileAdapter.DisplayType;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
import android.app.Activity;
import android.app.Fragment;
@@ -90,10 +92,12 @@
private ContactTileAdapter mAdapter;
private ContactPhotoManager mPhotoManager;
+ private AccountTypeManager mAccountTypeManager;
private Uri mGroupUri;
private long mGroupId;
private String mGroupName;
+ private String mAccountTypeString;
private boolean mOptionsMenuEditable;
private boolean mCloseActivityAfterDelete;
@@ -105,6 +109,7 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
+ mAccountTypeManager = AccountTypeManager.getInstance(mContext);
Resources res = getResources();
int columnCount = res.getInteger(R.integer.contact_tile_column_count);
@@ -214,7 +219,7 @@
return;
}
}
- updateSize(null);
+ updateSize(-1);
updateTitle(null);
}
@@ -235,7 +240,7 @@
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- updateSize(Integer.toString(data.getCount()));
+ updateSize(data.getCount());
mAdapter.loadFromCursor(data);
}
@@ -246,6 +251,7 @@
private void bindGroupMetaData(Cursor cursor) {
cursor.moveToPosition(-1);
if (cursor.moveToNext()) {
+ mAccountTypeString = cursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
mGroupId = cursor.getLong(GroupMetaDataLoader.GROUP_ID);
mGroupName = cursor.getString(GroupMetaDataLoader.TITLE);
updateTitle(mGroupName);
@@ -265,11 +271,26 @@
}
}
- private void updateSize(String size) {
- if (mGroupSize != null) {
- mGroupSize.setText(size);
+ /**
+ * Display the count of the number of group members.
+ * @param size of the group (can be -1 if no size could be determined)
+ */
+ private void updateSize(int size) {
+ String groupSizeString;
+ if (size == -1) {
+ groupSizeString = null;
} else {
- mListener.onGroupSizeUpdated(size);
+ String groupSizeTemplateString = getResources().getQuantityString(
+ R.plurals.num_contacts_in_group, size);
+ AccountType accountType = mAccountTypeManager.getAccountType(mAccountTypeString);
+ groupSizeString = String.format(groupSizeTemplateString, size,
+ accountType.getDisplayLabel(mContext));
+ }
+
+ if (mGroupSize != null) {
+ mGroupSize.setText(groupSizeString);
+ } else {
+ mListener.onGroupSizeUpdated(groupSizeString);
}
}
diff --git a/src/com/android/contacts/list/ContactsRequest.java b/src/com/android/contacts/list/ContactsRequest.java
index 469cd1d..b7e21b4 100644
--- a/src/com/android/contacts/list/ContactsRequest.java
+++ b/src/com/android/contacts/list/ContactsRequest.java
@@ -89,6 +89,22 @@
private boolean mDirectorySearchEnabled = true;
private Uri mContactUri;
+ @Override
+ public String toString() {
+ return "{ContactsRequest:mValid=" + mValid
+ + " mActionCode=" + mActionCode
+ + " mRedirectIntent=" + mRedirectIntent
+ + " mTitle=" + mTitle
+ + " mSearchMode=" + mSearchMode
+ + " mQueryString=" + mQueryString
+ + " mIncludeProfile=" + mIncludeProfile
+ + " mGroupName=" + mGroupName
+ + " mLegacyCompatibilityMode=" + mLegacyCompatibilityMode
+ + " mDirectorySearchEnabled=" + mDirectorySearchEnabled
+ + " mContactUri=" + mContactUri
+ + "}";
+ }
+
/**
* Copies all fields.
*/
diff --git a/tests/src/com/android/contacts/activities/CallLogActivityTests.java b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
index dfb6d0c..8900c5e 100644
--- a/tests/src/com/android/contacts/activities/CallLogActivityTests.java
+++ b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
@@ -26,6 +26,7 @@
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.telephony.PhoneNumberUtils;
@@ -69,8 +70,8 @@
/** A test value for the person id of a contact. */
private static final long TEST_PERSON_ID = 1;
- /** A test value for the photo id of a contact. */
- private static final long TEST_PHOTO_ID = 2;
+ /** A test value for the photo uri of a contact. */
+ private static final Uri TEST_THUMBNAIL_URI = Uri.parse("something://picture/2");
/** A test value for the lookup key for contacts. */
private static final String TEST_LOOKUP_KEY = "contact_id";
/** A test value for the country ISO of the phone number in the call log. */
@@ -177,7 +178,6 @@
View view = mAdapter.newStandAloneView(getActivity(), mParentView);
mAdapter.bindStandAloneView(view, getActivity(), mCursor);
assertNotNull(view.findViewById(R.id.call_icon));
- assertNull(view.findViewById(R.id.groupIndicator));
}
@MediumTest
@@ -187,7 +187,6 @@
View view = mAdapter.newChildView(getActivity(), mParentView);
mAdapter.bindChildView(view, getActivity(), mCursor);
assertNotNull(view.findViewById(R.id.call_icon));
- assertNull(view.findViewById(R.id.groupIndicator));
}
@MediumTest
@@ -400,7 +399,7 @@
}
contactInfo.formattedNumber = formattedNumber;
contactInfo.normalizedNumber = number;
- contactInfo.photoId = TEST_PHOTO_ID;
+ contactInfo.thumbnailUri = TEST_THUMBNAIL_URI;
contactInfo.lookupKey = TEST_LOOKUP_KEY;
mAdapter.injectContactInfoForTest(number, contactInfo);
}
diff --git a/tests/src/com/android/contacts/calllog/VoicemailStatusHelperImplTest.java b/tests/src/com/android/contacts/calllog/VoicemailStatusHelperImplTest.java
index d577d4c..c6bff13 100644
--- a/tests/src/com/android/contacts/calllog/VoicemailStatusHelperImplTest.java
+++ b/tests/src/com/android/contacts/calllog/VoicemailStatusHelperImplTest.java
@@ -28,7 +28,7 @@
import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
import com.android.contacts.R;
-import com.android.contacts.calllog.VoicemailStatusHelper.Message;
+import com.android.contacts.calllog.VoicemailStatusHelper.StatusMessage;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -50,7 +50,8 @@
private static final Uri TEST_SETTINGS_URI = Uri.parse("http://www.visual.voicemail.setup");
private static final Uri TEST_VOICEMAIL_URI = Uri.parse("tel:901");
- private static final int ACTION_MSG_CALL_VOICEMAIL = R.string.voicemail_status_action_call_server;
+ private static final int ACTION_MSG_CALL_VOICEMAIL =
+ R.string.voicemail_status_action_call_server;
private static final int ACTION_MSG_CONFIGURE = R.string.voicemail_status_action_configure;
private static final int STATUS_MSG_VOICEMAIL_NOT_AVAILABLE =
@@ -166,7 +167,7 @@
// package2 with valuesNoNotificationNoDataChannel. Package2 should be above.
updateEntryForPackage(TEST_PACKAGE_1, valuesNoNotificationGoodDataChannel);
updateEntryForPackage(TEST_PACKAGE_2, valuesNoNotificationNoDataChannel);
- List<Message> messages = mStatusHelper.getStatusMessages();
+ List<StatusMessage> messages = mStatusHelper.getStatusMessages();
assertEquals(2, messages.size());
assertEquals(TEST_PACKAGE_1, messages.get(1).sourcePackage);
assertEquals(TEST_PACKAGE_2, messages.get(0).sourcePackage);
@@ -189,13 +190,13 @@
private void checkExpectedMessage(String sourcePackage, ContentValues values,
int expectedStatusMsg, int expectedActionMsg, Uri expectedUri) {
- List<Message> messages = mStatusHelper.getStatusMessages();
+ List<StatusMessage> messages = mStatusHelper.getStatusMessages();
assertEquals(1, messages.size());
checkMessageMatches(messages.get(0), sourcePackage, expectedStatusMsg, expectedActionMsg,
expectedUri);
}
- private void checkMessageMatches(Message message, String expectedSourcePackage,
+ private void checkMessageMatches(StatusMessage message, String expectedSourcePackage,
int expectedStatusMsg, int expectedActionMsg, Uri expectedUri) {
assertEquals(expectedSourcePackage, message.sourcePackage);
assertEquals(expectedStatusMsg, message.statusMessageId);
@@ -209,7 +210,7 @@
private void checkNoMessages(String sourcePackage, ContentValues values) {
assertEquals(1, updateEntryForPackage(sourcePackage, values));
- List<Message> messages = mStatusHelper.getStatusMessages();
+ List<StatusMessage> messages = mStatusHelper.getStatusMessages();
assertEquals(0, messages.size());
}